我需要使用Prolog的剪切操作从事实数据库中获取第一个、第二个和最后一个事实。我已经找到了获取第一个和第二个事实的方法,但无法找到获取最后一个事实的解决方案。以下是一个示例:
P(jack).P(john).P(alice).P(sarah).P(kyle).
仅选择第一个事实:first(X):-P(X),!.
仅选择第二个事实:second(Y):-P(X),P(Y),X\=Y,P(Y),!.
仅选择最后一个事实:?
回答:
我看不到不使用否定、累加器和成员服务谓词的方法,但由于否定(通过失败)是通过剪切实现的,我的猜测是这样的:
last_(Y) :- collect([], [Y|_]).collect(Seen, L) :- p(X), \+ member(X, Seen), collect([X|Seen], L).collect(All, All).
你可以用一个显式的剪切操作来实现not_contains/2
,代替\+ member(Elem,List)
(读取Elem不在List中)。
顺便说一下,你的second/1
谓词包含了一个冗余的调用:应该这样写
second(Y):-p(X),p(Y),X\=Y,!.