0

我使用SWI Prolog的時候,下面的代碼是在我的作業中使用(代碼是不是作業,但需要編寫課程要求的方法):序言越來越inifinite循環詢問另一種解決方案

nat(0). 
nat(s(X)) :- 
    nat(X). 

plus(0,N,N) :- 
    nat(N). 
plus(s(M),N,s(Z)) :- 
    plus(M,N,Z). 

times(0,N,0) :- 
    nat(N). 
times(s(M),N,Z) :- 
    times(M,N,W), 
    plus(W,N,Z). 

exp(s(M),0,0) :- 
    nat(M). 
exp(0,s(M),s(0)) :- 
    nat(M). 
exp(s(N),X,Z) :- 
    exp(N,X,Y), 
    times(X,Y,Z). 

exp(a,b,c)表示c=b^a

它直接從書上抄:「序言的藝術:高級編程技術」。

當我運行以下查詢:

exp(s(s(0)),L,s(s(s(s(0))))). 

我得到一個答案:

L = s(s(0)) 

但是,當我要求輸入另外一個答案;

L = s(s(0)) ; 

我得到一個無限循環(以堆棧錯誤結束),我期待得到錯誤。

什麼是代碼的問題?是否有一個代碼可以執行相同的操作(具有相同的自然數表示形式),但按照我所描述的方式運行?如果是這樣,一些提示或建議將會很有幫助。

在此先感謝。

+0

什麼順序的'EXP/3'。指'EXP(A,b,C)''C = b^A'? – 2015-03-31 11:01:01

+0

是的,我將其添加到的問題。 – PrologNewb 2015-03-31 11:04:42

+0

[相關](http://stackoverflow.com/questions/9740271/prolog-predicate-infinite-loop)。 – false 2015-03-31 15:08:07

回答

0

對於給定的程序,它運行到一個無限循環是正常的:如果你打電話給exp/3,第二個元素沒有實例化,它開始分支所有可能的值L。換句話說,如果查詢:

exp(s(s(0)),L,s(s(s(s(0))))). 

它的作用:

我實例Ls(0),是s(0)(因此1)正確嗎?
不!我例化了Ls(s(0))是正確的?
是返回2。等一下,用戶要求更多的答案....
3是否正確?否
4是否正確?否
是...是否正確? (你的想法)

每次做出的嘗試時,堆棧上升一個層次更深的(因爲它需要一個多層面構建s(X)X ...

你可以嘗試用另一種方式:有一個邏輯上界。結果(第三個參數),所以你可以先實例第二個參數作爲第三和測試,然後再遞減第二個參數,直到找到正確的結果

+0

要求你快速回答,我明白爲什麼它現在進入一個無限循環,但我對你的建議有點困惑,爲了簡單起見,讓我們考慮一下我給出的例子,你的意思是我應該看看L作爲s(s(s(s)))= 4,然後我應該測試4^2 =? 4,no - > 3^2 =? 4,no-> 2^2 =? 4,是的。 - >; - > 2^1 =? 4,no,2^0 =? 4,沒有 - >錯誤。 ? – PrologNewb 2015-03-31 11:37:31