Prolog事实清单

时间:2014-08-31 18:27:37

标签: prolog

我想创建知识库中包含的所有考试(A,B)的列表:

exam([a, 26]).
exam([b, 30]).
exam([c, 20]).
exam([d, 19]).

我知道我可以简单地使用:

exams(L) :- findall(X, exam(X), L).

但是既然我想写自己的角色,我写了以下内容:

exams([exam([A,B])]) :- exam([A,B]).
exams([exam([A,B])|Ex]) :- \+(member(exam([A,B]),Ex)), exams(Ex).

为什么使用像这样的查询? - 考试(X)。系统的答案如下:

?- exams(X).
X = [exam([a, 26])] ;
X = [exam([b, 30])] ;
X = [exam([c, 20])] ;
X = [exam([d, 19])] ;
false.

并且如果以下查询返回true,则不会向我提供任何超过一次考试的列表:

?- exams([exam([a,26]),exam([b,30])]).
true .

1 个答案:

答案 0 :(得分:1)

可能性是

exams(L) :- exams([], R), !, reverse(R, L).

exams(S, L) :- exam(E), \+ memberchk(exam(E), S), exams([exam(E)|S], L).
exams(L, L).

但是,除了学习Prolog控制流程之外,我在这样的解决方案中看不到任何价值。 也许你应该详细说明强迫你避免findall / 3的原因......