我正在努力为大学课程建立一个知识基础。具体地说,现在我正在尝试制作一个累加器,它将接受一门课程,并提供必须首先参加的所有课程的列表,即课程的前提条件,这些前提条件的前提条件,等等。Based on this chart。
以下是谓词的示例:
prereq(cst250, cst126).
prereq(cst223, cst126).
prereq(cst126, cst116).
prereq(cst105, cst102).
prereq(cst250, cst130).
prereq(cst131, cst130).
prereq(cst130, cst162).
prereq(anth452, wri122).
prereq(hist452, wri122).下面是我在累加器中的尝试:
prereq_chain(Course, PrereqChain):-
%Get the list of prereqs for Course
findall(Prereq, prereq(Course, Prereq), Prereqs),
%Recursive call to all prereqs in X
forall(member(X, Prereqs),
(prereq_chain(X, Y),
%Combine current layer prereqs with deeper
append(Prereqs, Y, Z))),
%Return PrereqChain
PrereqChain = Z.查询所需的输出为:
?- prereq_chain(cst250, PrereqList).
PrereqList = [cst116, cst126, cst162, cst130]相反,我得到的答案是true,以及关于Z是单例的警告。
我看过other posts询问类似的问题,但它们都只有一个向后遍历的通道,而我的解决方案需要多个通道。
提前感谢您的指导。
发布于 2018-08-11 03:30:26
使用forall/2的问题是它不能建立绑定。看看这个人为的例子:
?- forall(member(X, [1,2,3]), append(['hi'], X, R)).
true.如果forall/2为X或R建立了绑定,它将出现在结果中;相反,我们只是获得了true,因为它成功了。因此,您需要使用一个构造,它不只是运行一些计算,而且还会产生一个值。在本例中,您需要的是maplist/3,它接受一个目标和一个参数列表,并构建一个更大的目标,为您返回结果。在您输入以下解决方案后,您将能够在控制台中看到效果。
?- maplist(prereq_chain, [cst126, cst130], X).
X = [[cst116], [cst162]].因此,这里得到了列表中两个类的先决条件列表,但给我们返回了一个列表列表。这就是append/2派上用场的地方,因为它本质上是拉平列表的列表:
?- append([[cst116], [cst162]], X).
X = [cst116, cst162].这是我想出的解决方案:
prereq_chain(Class, Prereqs) :-
findall(Prereq, prereq(Class, Prereq), TopPrereqs),
maplist(prereq_chain, TopPrereqs, MorePrereqs),
append([TopPrereqs|MorePrereqs], Prereqs). https://stackoverflow.com/questions/51791920
复制相似问题