1

我的目的是在Prolog中實現一個簡單的例子(僅適用於我自己)的傳遞性。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

Prolog是否很快就淹沒了堆棧?

或者是我的想法/執行trusts壞/浪費系統內存?

回答

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. 

這表明程序現在終止普遍

替代的解決方案是:

+1

尼斯解釋的定義!但是,我還有最後一個問題:如果我們已經有'trust(A,C): - trust_direct(A,B),trusts(B,C)'(調用'trust_direct/2'),爲什麼我們需要第二個「信託(A,B)」: - trust_direct(A,B)。 – daniel451

+0

這是一個很好的問題,非常值得自己發表!請爲此提出一個新問題,讓我們繼續! – mat

+1

這裏是:[簡單的傳遞性檢查的不必要的謂詞定義?](https://stackoverflow.com/questions/42496415/unnecessary-predicate-definition-for-simple-transitivity-checkup) – daniel451