几个小时一直困在问题上,此时我真的需要帮助。
目标是创建一个谓词 all_prereqs(C,L),它返回课程的所有直接和直接先决条件的列表。我们获得了一系列与其先决条件列表相关的课程。
prereqs(cse115, []).
prereqs(cse116, [cse115]).
prereqs(cse191, [cse115]).
prereqs(cse241, [cse116,cse191]).
prereqs(cse250, [cse116,cse191]).
prereqs(cse305, [cse250]).
prereqs(cse321, [cse341]).
prereqs(cse331, [cse250,mth142]).
prereqs(cse341, [cse241]).
prereqs(cse379, [cse241]).
prereqs(cse380, [cse241]).
prereqs(cse396, [cse250]).
prereqs(cse411, [cse241]).
prereqs(cse421, [cse305]).
prereqs(cse422, [cse421]).
prereqs(cse431, [cse331]).
prereqs(cse435, [cse250,mth309]).
我知道应该有一个帮助类,我尝试了类似
的东西prereq1(C1,C2):- prereqs(C1,L),prereq1(member(C2,L),C3).
当然会返回“否”。 我已经在纸上写下了必须对这些价值观做些什么,但是我对Prolog的经验不足使我无法做到这一点。
任何帮助将不胜感激。
修改
好的,谢谢你提供的信息。有一次我确实有这个想法,但不知道如何在列表为空时终止递归。
prereq1(C1,C2):-prereqs(C1,L),member(T,L),prereq1(T,C3). prereq1(C1,C2):-T\==[].
这只返回true,当prereq列表为空时,我无法理解递归调用的终止。
答案 0 :(得分:1)
您在功能数据模型中编写代码,但Prolog却是关系数据模型。那你的规则应该是
prereq1(C1,C2) :- prereqs(C1,L),member(C2,L),prereq1(C2,C3).
但这也不会成功,因为在使用 empty 先决条件列表的课程中,递归调用将始终失败。注意,初始部分没问题:
prereq2(C1,C2) :- prereqs(C1,L), member(C2,L).
给出所有立即先决条件,然后我们应该通过递归为每个立即添加一个闭包。
prereq2(C1,C2) :- prereqs(C1,L), member(T,L), ...
请自己完成,你会得到
?- prereq2(cse331, L).
L = cse250 ;
L = mth142 ;
L = cse116 ;
L = cse191 ;
L = cse115 ;
L = cse115 ;
false.
请注意副本。 Prolog有一种惯用的方法来处理这个问题:
?- setof(C, prereq2(cse331, C), L).
L = [cse115, cse116, cse191, cse250, mth142].
编辑您的Prolog应警告您规则中的单身人士:
prereq1(C1,C2):-prereqs(C1,L),member(T,L),prereq1(T,C3).
C3
必须成为C2
。有了这个,你应该完成你的任务。当成员被给予空列表时,终止将被“隐式”处理 - 这将在我给出的示例中多次发生。