Prolog bagof、setof、findall谓词

Prolog bagof、setof、findall谓词,prolog,prolog-setof,Prolog,Prolog Setof,如何使用bagof,setof在Prolog中查询具有3个或更多属性的数据库事实。例如,我定义了一个数据库学生(姓名、年级、运动、性别)。我想找一份参加某项运动的学生名单,比如板球。我当前的查询 sport_list(L):- bagof(S,N^G^D^students(N,G,S,D),L), S = cricket. student(patash,5,rugby,male). student(naomi,3,netball,female). stu

如何使用
bagof
setof
在Prolog中查询具有3个或更多属性的数据库事实。例如,我定义了一个数据库
学生(姓名、年级、运动、性别)
。我想找一份参加某项运动的学生名单,比如板球。我当前的查询

sport_list(L):- 
        bagof(S,N^G^D^students(N,G,S,D),L),
           S = cricket.

student(patash,5,rugby,male).
student(naomi,3,netball,female).
student(lepo,6,_,male).
student(diamal,4,cricket,male).
student(bonga,5,chess,female).
student(imi,6,cricket,male).
student(ayanda,3,_,female).

您可以对您的知识库进行建模,以便第三个参数是
none
,而不是

student(lepo,6,none,male).
student(ayanda,3,none,female).
然后,您可以定义一个谓词,该谓词将体育学生描述为那些没有运动的学生:

athletic(S) :-
   dif(X,none),
   student(S,_,X,_).
随后在运动单目标列表/1中使用竞技/1:

sport_list(L):- 
   bagof(S,athletic(S),L).
这将产生预期的结果:

   ?- sport_list(L).
L = [patash,naomi,diamal,bonga,imi]

setof/3
bagof/3
的文档表明第一个参数是您希望收集的术语。在本例中,这将是student name变量。第二个参数应该是条件,第三个参数是要收集到的列表。所以:
setof(N,G^D^学生(N,G,cricket,D,L)。
你的
bagof
呼叫将体育收集到
L
,然后尝试将
S
cricket
统一起来。没有收集姓名。如果
student/4
查询的结果中没有任何冗余问题,可以使用
findall(N,students(N,u,cricket,u),L)。
谢谢您的回答,但是我如何排除不参加体育运动的学生的姓名?当我尝试返回没有运动的学生时。请显示您的事实。更改
bagof
中的条件(第二个参数)以排除
S
是变量的情况。请参阅
var/1
文档。尝试一些方法。不要让我们为你做所有的工作。:)更简单的方法是,使用atom而不是匿名变量(
\uu
)来表示“不运动”。为什么不使用
none
'no sport'
?这将解决问题,而无需附加逻辑。匿名变量将匹配任何内容。