0

几个小时以来一直被困在一个问题上,此时我真的需要帮助。

目标是创建一个谓词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 列表为空时,我无法理解递归调用的终止。

4

1 回答 1

1

您在功能数据模型中编写代码,但 Prolog 有一个关系数据模型。那么你的规则应该是

prereq1(C1,C2) :- prereqs(C1,L),member(C2,L),prereq1(C2,C3).

但这也不能成功,因为当遇到一个的先决条件列表的课程时,递归调用总是会失败。注意,初始部分是可以的:

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。有了这个,你应该已经完成​​了你的任务。当成员将获得空列表时,将“隐式”处理终止 - 在我给出的示例中这将发生多次。

于 2013-04-25T08:32:30.210 回答