我正在尝试编写一个谓词
filter(List, PredName, Result)
,过滤其目标List
失败的所有元素的PredName
,并随后返回Result
列表。谓词 PredName/1
应在调用过程 filter/3
时定义,例如可以是:
test(N) :- N >= 0
然后可以像下面这样进行查询:
?- filter([-6,7,-1,0], test, L)
L = [7, 0];
no
我确信存在一个内置操作可以执行此操作...但本质上您只是尝试对传递谓词的列表成员执行 findall 操作。 尝试这个过滤器的实现。 运行 findall 的第二个参数,直到所有结果都用尽并且 M 的所有值都收集到 Result 中。
filter(List,PredName,Result) :-
findall(M, ( member(M, List), call(PredName,M)), Result).
一种方法是使用递归和
call/2
谓词
filter([],_,[]).
filter([H|T], PredName, [H|S]) :- call(PredName,H),filter(T,PredName,S),!.
filter([H|T], PredName, S) :- filter(T,PredName,S).
另一种方法是,您可以使用
call/2
(univ) 运算符,而不是使用 =..
。
filter([],_,[]).
filter2([H|T], PredName, [H|S]) :- Goal =.. [PredName,H],Goal,filter(T,PredName,S),!.
filter([H|T], PredName, S) :- filter(T,PredName,S).
=..
运算符采用包含谓词名称及其参数的列表,并返回新创建的术语。例如:
?-X =.. [f,a,b].
X = f(a, b).