2016-11-18 165 views
0

我正在編寫代表卡片遊戲規則的程序。但是,我正在用下面的代碼進入一個無限循環。Prolog中的無限循環。我如何防止這種情況?

succ(seven_of_hearts,eight_of_hearts). 
succ(eight_of_hearts,nine_of_hearts). 
succ(nine_of_hearts,ten_of_hearts). 
succ(ten_of_hearts,jack_of_hearts). 
succ(jack_of_hearts,queen_of_hearts). 
succ(queen_of_hearts,king_of_hearts). 
succ(king_of_hearts,ace_of_hearts). 
succ(X,Y) :- 
    succ(X,Z), 
    succ(Z,Y), 
    !. 

beats(X,Y) :- 
    succ(Y,X). 

基本上,我用這幾句嘗試建立用於確定系統是否一個卡擊敗了另一根據我已經建立了SUCC(或繼承)的關係。所以我運行的查詢是beats(X,Y),其中X和Y以及原子對應於卡片。如果該查詢爲true,則該查詢成功終止。例如,如果我查詢節拍(jack_of_hearts,seven_of_hearts),它將返回true並終止。

但是,如果查詢爲false,則查詢將進入無限循環。例如,當我查詢節拍(seven_of_hearts,jack_of_hearts)。我追蹤了查詢,發現由於最後一個succ語句的遞歸性質,查詢跟隨succ語句鏈一直到seven_of_hearts,或者一直到ace_of_hearts,然後不斷嘗試評估succ (seven_of_hearts,X)或succ(ace_of_hearts,X)而不是返回false。

我有兩個問題:使用這個當前結構,我怎麼能防止這個?或者,如果這是不可能的,我可以用什麼替代結構來實現我的目標?

編輯: 這裏是我的跟蹤對失敗的查詢的一個截圖:

Call: (267) beats(seven_of_hearts, jack_of_hearts) ? creep 
Call: (268) succ(jack_of_hearts, seven_of_hearts) ? creep 
    Call: (269) succ(jack_of_hearts, _G7104) ? creep 
    Exit: (269) succ(jack_of_hearts, queen_of_hearts) ? creep 
    Call: (269) succ(queen_of_hearts, seven_of_hearts) ? creep 
    Call: (270) succ(queen_of_hearts, _G7104) ? creep 
    Exit: (270) succ(queen_of_hearts, king_of_hearts) ? creep 
    Call: (270) succ(king_of_hearts, seven_of_hearts) ? creep 
    Call: (271) succ(king_of_hearts, _G7104) ? creep 
    Exit: (271) succ(king_of_hearts, ace_of_hearts) ? creep 
    Call: (271) succ(ace_of_hearts, seven_of_hearts) ? creep 
    Call: (272) false ? creep 
    Fail: (272) false ? creep 
    Redo: (271) succ(ace_of_hearts, seven_of_hearts) ? creep 
    Call: (272) succ(ace_of_hearts, _G7104) ? creep 
    Call: (273) false ? creep 
    Fail: (273) false ? creep 
    Redo: (272) succ(ace_of_hearts, _G7104) ? creep 
    Call: (273) succ(ace_of_hearts, _G7104) ? creep 
    Call: (274) false ? creep 
    Fail: (274) false ? creep 
    Redo: (273) succ(ace_of_hearts, _G7104) ? creep 
    Call: (274) succ(ace_of_hearts, _G7104) ? creep 
    Call: (275) false ? creep 

回答

1

你的斷言顯然一直自稱:succ(X, Y) :- succ(Y, X), ...。一個簡單的解決方案就是不要使用與您的謂詞相同的名稱。擺脫您的succ/2謂詞(離開事實),贊成:

successor(X, Y) :- succ(X, Y). 
successor(X, Y) :- succ(X, Z), succ(Z, Y). 

beats(X, Y) :- successor(Y, X). 
相關問題