我的目的是在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
C
和A
信任的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/
坏/浪费系统内存?
答案 0 :(得分:3)
是,Prolog很快就充斥着本地堆栈。
要看到这一点,只需 考虑以下程序片段就足够了:
trusts(A, C) :- trusts(A, B), false,trusts(B, C).
这称为failure-slice:我已插入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.
这表明该程序现在普遍终止。
替代解决方案是: