1

我的目的是在 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).

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

Prolog 会这么快地淹没堆栈吗?

还是我的想法/实施trusts不良/浪费系统内存?

4

1 回答 1

3

的,Prolog 如此迅速地淹没了本地堆栈。

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

信任(A,C):-
        信托(A,B),
        信任(B,C)

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

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

信任(A,C):-
        信托(A,B),
        错误的。

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

?- 信任(p5,p6)。
错误:超出本地堆栈

要摆脱这个问题,你必须改变剩余的 fragment。出于这个原因,这样的片段用作问题的解释

例如,考虑以下版本:

信任(A,B):-
        信任直接(A,B)。
信任(A,C):-
        信任直接(A,B),
        信任(B,C)。

示例查询:

?- 信任(p5,p6)。
真的 ;
错误的。

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

?- 信任(X,Y),错误的。

这表明程序现在普遍终止

替代解决方案是:

于 2017-02-27T21:24:47.120 回答