gpt4 book ai didi

prolog - 如何检查 Prolog 中是否存在任何统计子句,而不需要回溯所有不同的路径?

转载 作者:行者123 更新时间:2023-12-02 08:53:02 25 4
gpt4 key购买 nike

假设我有以下内容:

parent(alice, charlie).
parent(bob, charlie).
parent(bob, diane).
parent(alice, diane).
parent(bob, eve).
parent(alice, eve).

% people are siblings of each other if they share a parent
% and aren't the same person.
sibling(A, B) :-
parent(X, A),
parent(X, B),
B \= A.

现在,如果我询问黛安的 sibling ,我会得到查理和伊芙——两次,一次通过鲍勃,一次通过爱丽丝。我只想要一次。
我认为我不能在这里使用剪切,因为这会完全防止回溯。我想要是一种检查任何是否存在的方法。

释义

sibling(A, B) :-
∃(parent(X, A), parent(X, B)),
B \= A.
<小时/>

我尝试了几次剪辑,但没有成功。
我在 (parent(X, A), Parent(X, B)) 上尝试了 findall/3 并检查结果列表是否为非空,但这并不' t 统一 A 或 B。

<小时/>

按照下面的建议使用setof/3是可行的,但我真的想找到一种方法将其合并到sibling/2的定义中,而不是必须使用问题中的它。我真的很希望能够执行以下操作:

?- sibling(diane, X).
X = charlie ;
X = eve ;
false.

或者这个

?sibling(X, Y).
X = charlie,
Y = diane ;
X = charlie,
Y = eve ;
X = diane,
Y = charlie ;
X = diane,
Y = eve ;
X = eve,
Y = charlie ;
X = eve,
Y = diane ;
false.
<小时/>

就像我在下面所说的,我有一个针对这种具体情况的解决方案。我想要想要的,以及我设置赏金的,是一个通用的解决方案。

而不是

sibling(A, B) :-
setof(D, X^(parent(X, A), parent(X, D)), Ds),
member(B, Ds),
B \= A.

我想做

sibling(A, B) :-
exists(X^(parent(X, A), parent(X, B))),
B \= A.

它统一了AB

如何定义exists/1

最佳答案

在Prolog中使用cut是非常微妙的。大多数削减本质上是不正确的,但在某些情况下仍然有效。如果您只想要一个答案,则可以在此处使用剪切。但由于您想要整个集合,所以您运气不好:您需要探索所有答案才能确定该集合。

幸运的是,有一个优雅的快捷方式(双关语):setof/3。所以问一下

?- setof(t, sibling(diane, S), _).

对于 setof/3 的这种用法,最后一个参数没有意义。它实际上是[t]

对于通用目的exists/1,定义

exists(XGoal) :- setof(t, XGoal, _).

这允许使用存在量词。

关于prolog - 如何检查 Prolog 中是否存在任何统计子句,而不需要回溯所有不同的路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20167133/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com