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 .

一种可能性是

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…

的原因

最新更新