Prolog filter a list of all elements for which a custom goal fails

六月ゝ 毕业季﹏ 提交于 2019-12-10 20:51:59

问题


I am trying to write a predicate filter(List, PredName, Result) that filters a List of all its elements for which the goal PredName fails and subsequently returns the Result list. The predicate PredName/1 should be defined when calling the procedure filter/3 and could for example be:

test(N) :- N >= 0

A query could then be made like following:

?- filter([-6,7,-1,0], test, L)
L = [7, 0];
no

回答1:


If you are using SWI-Prolog you could use the exclude predicate from the "apply" library




回答2:


I'm sure a builtin operation exists to do this... but essentially you are just trying to do a findall on the member of the list that pass the predicate. Try this implementation of filter out. The second arg to findall is run until all results are exhausted and all values of M are collected into Result.

filter(List,PredName,Result) :-
  findall(M, ( member(M, List), call(PredName,M)), Result).



回答3:


One way to do that is using recursion and 'call' predicate

filter([],_,[]).
filter([H|T], PredName, [H|S]) :-  call(PredName,H),filter(T,PredName,S),!.
filter([H|T], PredName, S) :- filter(T,PredName,S).

other way to that is instead of call you can use =.. (univ) operator.

filter([],_,[]).
filter2([H|T], PredName, [H|S]) :-  Goal =.. [PredName,H],Goal,filter(T,PredName,S),!.
filter([H|T], PredName, S) :- filter(T,PredName,S).

=.. operator takes a list that contains predicate name and its arguments and returns newly created term. for example:

?-X =.. [f,a,b].
X = f(a, b).


来源:https://stackoverflow.com/questions/6682641/prolog-filter-a-list-of-all-elements-for-which-a-custom-goal-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!