繁体   English   中英

为什么你在序言中定义了两次规则

[英]why do you define a rule twice in prolog

follows(A, B, Seen) :- not_member(B, Seen); isFriendsWith(A, B).
follows(A, B, Seen) :- isFriendsWith(A, X), not_member(X, Seen), follows(X, B, [X|Seen]).

为什么相同的规则被定义了两次。 当您运行查询时,如果第一条规则为真。 是否解决。

这在某种程度上是 Prolog 解析过程的核心。

假设您在问题中定义了上述规则,另外还有一些事实:

isFriendsWith(john,mary).
isFriendsWith(mary,peter).

然后查询

?- follows(john, Who, []);

首先尝试第一个规则(因为它是第一个)并返回:

Who = mary

因为 isFriendsWith 事实将 X 与 mary 匹配。

但你不高兴,所以你通过输入询问更多的答案

;

这导致 Prolog回溯 实际上,Prolog 将回溯其步骤,寻找替代的事实和规则。 在这里没有关于约翰与任何人成为朋友的其他事实,所以第一条规则失败了。

第二条规则生效,Prolog 试图证明(在模式匹配之后):

isFriendsWith(john, X),
not_member(X, []),
follows(X, B, [X]).

它找到了一个事实(再次,但它应用了一个新规则)X=mary,它不在空列表中,然后去证明

follows(mary, B, [mary])

这确实有一个解决方案,因为玛丽是彼得的朋友,所以系统已经证明了第二个结果和答案:

Who = mary

如果此时询问更多证据,系统会再次回溯并寻求规则的更多应用。 只有这两个事实没有,所以系统回答

no

并返回。

总体而言,您的两个规则导致系统通过“isFriendsWith”图递归地识别所有“跟随”路径。 Seen 列表是为了确保它不遵循会导致它无限循环的循环路径。

如果你觉得这个例子令人困惑,首先在 Prolog 中查找回溯的例子。 它对其定理证明器至关重要,没有它您将无法理解任何 Prolog。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM