简体   繁体   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]).

Why is the same rule defined twice.为什么相同的规则被定义了两次。 When you run the query if the first rule is true.当您运行查询时,如果第一条规则为真。 Does it resolve.是否解决。

This in a way is at the heart of how Prolog's resolution process.这在某种程度上是 Prolog 解析过程的核心。

Say you define the rule as above in your question, plus, a few facts:假设您在问题中定义了上述规则,另外还有一些事实:

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

And then query然后查询

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

The first rule is tried first (because it's first) and returns:首先尝试第一个规则(因为它是第一个)并返回:

Who = mary

because the isFriendsWith fact matches X to mary.因为 isFriendsWith 事实将 X 与 mary 匹配。

But you're not happy, so you ask for more answers by entering但你不高兴,所以你通过输入询问更多的答案

;

which causes Prolog to backtrack .这导致 Prolog回溯 In effect Prolog is going to retrace its steps, looking for alternative facts and rules.实际上,Prolog 将回溯其步骤,寻找替代的事实和规则。 Here there's no other fact about john being friend with anyone, so the first rule has failed.在这里没有关于约翰与任何人成为朋友的其他事实,所以第一条规则失败了。

The second rule kicks in and Prolog tries to prove (after pattern matching):第二条规则生效,Prolog 试图证明(在模式匹配之后):

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

it finds a fact (again, but it's applying a new rule) that X=mary, which is not in the empty list, then goes off to prove它找到了一个事实(再次,但它应用了一个新规则)X=mary,它不在空列表中,然后去证明

follows(mary, B, [mary])

Which does have a solution as mary is friends with peter, and so the system has proven a second result and answers:这确实有一个解决方案,因为玛丽是彼得的朋友,所以系统已经证明了第二个结果和答案:

Who = mary

If you ask more proofs at this point, the system backtracks again and seeks more applications of the rules.如果此时询问更多证据,系统会再次回溯并寻求规则的更多应用。 With just these two facts there are none, and so the system answers只有这两个事实没有,所以系统回答

no

and returns.并返回。

Overall, your two rules result in the system identifying recursively all the 'follow' paths through the 'isFriendsWith' graph.总体而言,您的两个规则导致系统通过“isFriendsWith”图递归地识别所有“跟随”路径。 The list Seen is there to ensure that it doesn't follow cyclical paths which would cause it to loop indefinitely. Seen 列表是为了确保它不遵循会导致它无限循环的循环路径。

If you find this example confusing, look up examples of backtracking in Prolog first.如果你觉得这个例子令人困惑,首先在 Prolog 中查找回溯的例子。 It is essential to its theorem prover and you will not understand any of Prolog without it.它对其定理证明器至关重要,没有它您将无法理解任何 Prolog。

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

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