Prolog:检查简单事实的传递性

时间:2017-02-27 21:16:34

标签: prolog predicate failure-slice transitive-closure transitivity

我的目的是在Prolog中实现一个简单的例子(仅供我自己)传递。

这些是我的事实:

trust_direct(p1, p2).
trust_direct(p1, p3).
trust_direct(p2, p4).
trust_direct(p2, p5).
trust_direct(p5, p6).
trust_direct(p6, p7).
trust_direct(p7, p8).
trust_direct(p100, p200).

我已经编写了这个谓词来检查A是否信任C,只要信任B CA信任的B就是如此这个trusts(A, B) :- trust_direct(A, B). trusts(A, C) :- trusts(A, B), trusts(B, C).

true

例如,trusts(p1, p2)trusts(p1, p5)的谓词返回trusts(p5, p6),但ERROR: Out of local stack已返回trusts

Prolog是否迅速淹没了堆栈?

或者我的想法/实现url:/path/坏/浪费系统内存?

1 个答案:

答案 0 :(得分:3)

,Prolog很快就充斥着本地堆栈。

要看到这一点,只需 考虑以下程序片段就足够了:

trusts(A, C) :-
        trusts(A, B),
        false,
        trusts(B, C).

这称为:我已插入false/0,因此可以忽略false/0 之后的所有内容。我用删除文本表示可以忽略的部分。

这意味着该代码段实际上等同于:

trusts(A, C) :-
        trusts(A, B),
        false.

现在,使用上述任何一个片段,我们立即得到:

?- trusts(p5, p6).
ERROR: Out of local stack

要解决此问题,您必须更改剩余的片段。因此,这样的片段可以作为问题的解释

例如,请考虑以下版本:

trusts(A, B) :-
        trust_direct(A, B).
trusts(A, C) :-
        trust_direct(A, B),
        trusts(B, C).

示例查询:

?- trusts(p5, p6).
true ;
false.

现在按预期工作。它在声明上等同于您发布的版本,并具有更好的终止属性:

?- trusts(X, Y), false.
false.

这表明该程序现在普遍终止

替代解决方案是: