这是程序:
sibling(joe, mary).
sibling(joe, bob).
person(P) :- distinct(sibling(P, _); sibling(_, P)).
以下是查询:
person(P).
我希望得到3个名字,而不是4个。
答案 0 :(得分:3)
简而言之:Prolog会跟踪所有超出目标的变量,包括无关紧要(const purpleElems = Array.from(document.querySelectorAll("li")) // find all the lis
.filter(li => // filter the list of lis
li.textContent.contains('Purple') // see if it has purple
)
)。
问题在于您在此处引入了不是不同的自由变量。确实,如distinct/1
[swi-doc]文档中所指定。上面的功能等效于:
_
现在,如果我们使用distinct(Goal) :-
findall(Goal, Goal, List),
list_to_set(List, Set),
member(Goal, Set).
进行简单调用,则会得到:
sibling(P, _)
或目标为逻辑“或”:
?- Goal = sibling(P, _), distinct(Goal).
Goal = sibling(joe, mary),
P = joe ;
Goal = sibling(joe, bob),
P = joe.
如您所见,?- Goal = (sibling(P, _); sibling(_, P)), distinct(Goal).
Goal = (sibling(joe, mary);sibling(_4908, joe)),
P = joe ;
Goal = (sibling(joe, bob);sibling(_4908, joe)),
P = joe ;
Goal = (sibling(mary, _4904);sibling(joe, mary)),
P = mary ;
Goal = (sibling(bob, _4904);sibling(joe, bob)),
P = bob.
被统一了两次:一次与Goal
,一次与sibling(joe, mary)
。唯一性过滤器不会有任何效果,因为sibling(joe, bob)
与mary
不同。
但是,我们可以在此处定义一个辅助谓词,以摆脱这些变量,例如:
bob
然后我们可以查询:
person(P) :-
sibling(P, _).
person(P) :-
sibling(_, P).
或不使用?- Goal = person(P), distinct(Goal).
Goal = person(joe),
P = joe ;
Goal = person(mary),
P = mary ;
Goal = person(bob),
P = bob.
变量:
Goal