我需要构造一个谓词compare_to_predicate / 3。它接收给定的谓词和数字列表,并继续使用该谓词比较列表中的每个元素
给定的谓词是
- is_odd
- is_even
- greater_than(X)
例如:
?- compare_to_predicate([8,13,1,500], [is_odd], X).
X = [13, 1].
?- compare_to_predicate([8,13,1,500], [greater_than, 10], X).
X = [13, 500].
到目前为止我想出的是:
is_odd(X):- 1 is mod(X,2).
is_even(X):- 0 is mod(X,2).
greater_than(X,Y):- X<Y.
compare_to_predicate([],_,[]).
compare_to_predicate([H|Tail],Functor,[H|X]):- Term =.. [Functor,H], Term, compare_to_predicate(Tail,Functor,X).
我有很多问题:
1)
?- compare_to_predicate([2,10,8,300],is_even,X).
将产生
X = [2, 10, 8, 300].
但是
compare_to_predicate([2,10,8,301],is_even,X).
将产生
false.
我认为它与遇到一个不会在is_even上返回true的数字的谓词有关,然后用false结束整个compare_to_predicate。在这种情况下解决方案以某种方式使它忽略奇数而不是评估它们?如果是这样,我该怎么做?
2)
似乎我传入compare_to_predicate的给定谓词必须具有中所见的类型List
?- compare_to_predicate([8,13,1,500], [is_odd], X).
和
?- compare_to_predicate([8,13,1,500], [greater_than, 10], X).
我目前只是将正常谓词传递给Term。我不太确定我应该怎么做
似乎是compare_to_predicate([H|Tail],[Functor],[H|X]):- Term =.. [Functor,H], Term, compare_to_predicate(Tail,[Functor],X)
在这里做了诀窍。最后:
3)
?- compare_to_predicate([8,13,1,500], [greater_than, 10], X).
似乎我需要使compare_to_predicate能够接受具有不同arity的谓词,如此处所示。解决方案应该是这样的吗?
(Term =.. [Functor,A]; Term=.. [Functor,A,B]).
任何帮助将不胜感激。
答案 0 :(得分:1)
您需要决定compare_to_predicate/3
应该对未达到目标的值做什么。我基本上可以看到三种方式:
顺便说一句,你不需要用=../2
进行手术这个术语;如果您执行call/N
之类的操作,call(greater(10), 20)
会做正确的事情,因此您可以让用户像这样调用您的谓词:compare_to_predicate([1,2,3,4], greater(2), X)
并使用调用来构建目标。
做第一个非常简单:
filter([], _, []).
filter([X|Xs], P, Result) :-
filter(Xs, P, Xs1),
(call(P, X) -> Result = [X|Xs1] ; Result = Xs1).
做第二个也很简单:
forall([], _, []).
forall([X|Xs], P, [X|Xs]) :- call(P, X), forall(Xs, P, Xs).
做第三个并不是非常困难:
foreach([], _).
foreach([X|Xs], G) :- once(call(G, X) ; true), foreach(Xs, G).