Filter 如何在Prolog中过滤具有多个条件的列表?

Filter 如何在Prolog中过滤具有多个条件的列表?,filter,prolog,Filter,Prolog,我可以通过以下步骤根据1个条件筛选列表: 使用findall 使用include隔离符合条件的元素 但当有多个条件需要尊重时,如何进行?在这种特殊情况下,条件的数量和条件本身是未知的,因此谓词必须适用于所有上下文 以下是如何生成条件以及如何调用条件的示例: goal(drinkingAge,(person(_,_,A))) :- person(_,_,A), A > 21. %has at least 21 years old 并给他们打电话给一个人: goal(drinkingAg

我可以通过以下步骤根据1个条件筛选列表:

  • 使用
    findall
  • 使用
    include
    隔离符合条件的元素
但当有多个条件需要尊重时,如何进行?在这种特殊情况下,条件的数量和条件本身是未知的,因此谓词必须适用于所有上下文

以下是如何生成条件以及如何调用条件的示例:

goal(drinkingAge,(person(_,_,A))) :- person(_,_,A), A > 21. %has at least 21 years old
并给他们打电话给一个人:

goal(drinkingAge,(person("Tom",male,24))).
返回
true

目前,我可以使用以下条件筛选具有1个条件的列表:

findall(person(A,B,C),person(A,B,C),L).
include(goal(drinkingAge), L, ReturnList).
您没有说明“所有上下文”是如何表示的,但是,由于将1个参数的通用目标作为第一个参数(更准确地说,是该目标的名称),您可以相应地构造该目标

例如,如果您需要实现列表中的一系列单参数目标,则:

succeed_all_goals_for_value([],_).
succeed_all_goals_for_value([Goal|Goals],Value) :-
   call(Goal,Value),                         
   succeed_all_goals_for_value(Goals,Value). 
然后可以调用
include/3
。例如,假设定义了
number/1
odd/1
notprime/1

?- include(
       succeed_all_goals_for_value([number,odd,notprime]), 
       List,
       ListFiltered).
更具体的
目标/2
语法

我们现在可以变得更加具体。以下是一种可能性,包括测试用例:

%---
%助手
%成功实现所有目标(+目标,+要素)。
% ---
%如果没有目标,就很容易成功
成功实现所有目标([],)。
%否则,完成目标并成功实现每个目标!
%有很多方法可以做到这一点。。。
成功实现所有目标([GoalName | GoalNames],元素):-
目标(目标名称、要素),
成功实现所有目标(目标名称、要素)。
% ---
%使用筛选目标调用include/3
%检查所有条件的结合
% ---
myfilter(目标名称、列表、列表筛选):-
包括(
实现所有目标(目标名称),
列表
列表(已过滤)。
% ---
%一点测试
% ---
%如果第二个论点是一个已经到了饮酒年龄的人,那么就成功了
目标(饮酒年龄,人(u,u,A)):-A>21。
%如果第二个论点是一个男性,则成功
目标(男性,个人(u,男性,u))。
:-开始测试(myfilter)。
测试(1):-
我的过滤器(
[饮酒年龄,男性],
[个人(吉恩,男,22岁),个人(弗朗索瓦,女,17岁)],
列表过滤),
断言(ListFiltered==[个人(jean,男性,22)])。
测试(2):-
我的过滤器(
[男],,
[个人(吉恩,男,22岁),个人(弗朗索瓦,女,17岁)],
列表过滤),
断言(ListFiltered==[个人(jean,男性,22)])。
:-结束_测试(myfilter)。
因此:

?- [greatfilter].
true.

?- run_tests.
% PL-Unit: myfilter .. done
% All 2 tests passed
true.
您没有说明“所有上下文”是如何表示的,但是,由于将1个参数的通用目标作为第一个参数(更准确地说,是该目标的名称),您可以相应地构造该目标

例如,如果您需要实现列表中的一系列单参数目标,则:

succeed_all_goals_for_value([],_).
succeed_all_goals_for_value([Goal|Goals],Value) :-
   call(Goal,Value),                         
   succeed_all_goals_for_value(Goals,Value). 
然后可以调用
include/3
。例如,假设定义了
number/1
odd/1
notprime/1

?- include(
       succeed_all_goals_for_value([number,odd,notprime]), 
       List,
       ListFiltered).
更具体的
目标/2
语法

我们现在可以变得更加具体。以下是一种可能性,包括测试用例:

%---
%助手
%成功实现所有目标(+目标,+要素)。
% ---
%如果没有目标,就很容易成功
成功实现所有目标([],)。
%否则,完成目标并成功实现每个目标!
%有很多方法可以做到这一点。。。
成功实现所有目标([GoalName | GoalNames],元素):-
目标(目标名称、要素),
成功实现所有目标(目标名称、要素)。
% ---
%使用筛选目标调用include/3
%检查所有条件的结合
% ---
myfilter(目标名称、列表、列表筛选):-
包括(
实现所有目标(目标名称),
列表
列表(已过滤)。
% ---
%一点测试
% ---
%如果第二个论点是一个已经到了饮酒年龄的人,那么就成功了
目标(饮酒年龄,人(u,u,A)):-A>21。
%如果第二个论点是一个男性,则成功
目标(男性,个人(u,男性,u))。
:-开始测试(myfilter)。
测试(1):-
我的过滤器(
[饮酒年龄,男性],
[个人(吉恩,男,22岁),个人(弗朗索瓦,女,17岁)],
列表过滤),
断言(ListFiltered==[个人(jean,男性,22)])。
测试(2):-
我的过滤器(
[男],,
[个人(吉恩,男,22岁),个人(弗朗索瓦,女,17岁)],
列表过滤),
断言(ListFiltered==[个人(jean,男性,22)])。
:-结束_测试(myfilter)。
因此:

?- [greatfilter].
true.

?- run_tests.
% PL-Unit: myfilter .. done
% All 2 tests passed
true.

在SWI Prolog中,您可以使用lambda表达式来建立过滤条件。例如:

?- include([X]>>(number(X), X mod 2 =:= 1), [1,a,2,[b,c],"def",3,4,g,5], R).
R = [1, 3, 5].

?- include([X]>>(number(X) ; atom(X)), [1,a,2,[b,c],"def",3,4,g,5], R).
R = [1, a, 2, 3, 4, g, 5].

?- include([X]>>not(number(X) ; atom(X)), [1,a,2,[b,c],"def",3,4,g,5], R).
R = [[b, c], "def"].

在SWI Prolog中,您可以使用lambda表达式来建立过滤条件。例如:

?- include([X]>>(number(X), X mod 2 =:= 1), [1,a,2,[b,c],"def",3,4,g,5], R).
R = [1, 3, 5].

?- include([X]>>(number(X) ; atom(X)), [1,a,2,[b,c],"def",3,4,g,5], R).
R = [1, a, 2, 3, 4, g, 5].

?- include([X]>>not(number(X) ; atom(X)), [1,a,2,[b,c],"def",3,4,g,5], R).
R = [[b, c], "def"].

我的目标格式是预先确定的,不是
odd(x)
,而是
goals(odd,x)
,我无法更改。现在,
successful\u all\u goals\u for\u value
中的调用总是返回false,我应该更改函数中的某些内容吗?@JavaDumbell你能给你的问题添加一个具体的例子吗?我刚刚给问题添加了一个具体的例子,如果你想了解更多信息,请告诉我。@JavaDumbell好的,我明白了。这有点间接,因为
goal(drinkingAge,(person(u,u,a))
基本上将谓词名
drinkingAge
放入谓词名
goal
,只说
drinkingAge(person(u,u,a)):-Age>21就更容易了。
(让我想起高中时,在下午的线性代数课上,有两个同伴在课后被完全抹黑,但我离题了)@JavaDumbell添加了一些代码我的目标格式是预先确定的,不是
odd(x)
,而是
goals(odd,x)
我无法更改此值。现在,
successful\u all\u goals\u for\u value
中的调用总是返回false,我是否应该更改函数中的某些内容?@JavaDumbell你能为你的问题添加一个具体的示例吗?我刚刚为问题添加了一个具体的示例,如果你想了解更多信息,请告诉我