2012-11-15 23 views
2

我是Prolog的初學者,我想我可以嘗試編寫一個簡單的測試來檢查一組整數mod K(L)是否是一個組。我開始試圖找出所述集合是否可加,即。如果L的每兩個元素之和也是L.尋找一套在Prolog中是否具有附加的mod K

的元件I寫道:

group(A,K):-member(B,A),member(C,A),As is B+C, Bs is mod(As,K), member(Bs,A). 

我然後用這個嘗試了:

trace. group([0,1,2],3). 

這自然產生所有可能的總和,並且正確地回答所有這些答案都是正確的。

但所有這些情況後,最後打印如下:

1 1 Redo: group([0,1,2],3) ? 
    6 2 Redo: member(1,[0,1,2]) ? 
    6 2 Fail: member(1,[0,1,2]) ? 
    1 1 Fail: group([0,1,2],3) ? 
    no 

爲什麼程序會檢查這個最後的情況下,對我來說,似乎荒謬?

最後一種情況在此之前是:

1 1 Redo: group([0,1,2],3) ? 
    6 2 Redo: member(0,[0,1,2]) ? 
    6 2 Fail: member(0,[0,1,2]) ? 
    3 2 Redo: member(1,[0,1,2]) ? 
    3 2 Exit: member(2,[0,1,2]) ? 
    4 2 Call: _158 is 2+2 ? 
    4 2 Exit: 4 is 2+2 ? 
    5 2 Call: _186 is 4 mod 3 ? 
    5 2 Exit: 1 is 4 mod 3 ? 
    6 2 Call: member(1,[0,1,2]) ? 
    6 2 Exit: member(1,[0,1,2]) ? 
    1 1 Exit: group([0,1,2],3) ? 

    true 

它做什麼它應該。

回答

1

使用示蹤劑達到這樣的目的不是很有幫助。它向你展示了許多無關緊要的細節。相反,要集中精力解決問題。專注於有意義的名字。對於該組,您使用A,對於元素使用BC。這可以改善!

您目前的測試是什麼這樣的:

存在着一組其總和模K是在同一組的兩個元素。

要測試的是什麼:

對於所有的X,Y在S:((X + Y)MOD K)S中

操作本身可以寫成:Z is (X+Y) mod K

示蹤劑如何向你解釋?

 
group(S, K) :- 
    \+ (
     member(X,S), member(Y,S), Z is (X+Y) mod K, 
     \+ member(Z,S) 
    ). 

?- group([0,1,2],3). 
true. 

?- group([0,2],3). 
false. 
+0

我正在使用示蹤劑,因爲我剛剛發現它,並認爲它可能能夠揭示爲什麼最終答案是否定的,即使正確的答案應該是。另外,我確定是否存在一個集合中的兩個元素,它們的和模K在同一個集合中,並且就我所知,對於所有情況,它都進行了這個測試,但是它進行了最後一次檢查對我來說似乎很神祕。@false – Valtteri

+1

@Valtteri:唯一令人感到神祕的是跟蹤器產生的純粹細節。這不值得一看。什麼是相關的是你的程序意味着什麼! – false

+0

是的,你在解決方案中使用否定。這是合乎邏輯的。謝謝。而沙漠69的答案解釋了爲什麼最後沒有。至少我希望我明白了...... – Valtteri

0

我覺得示蹤劑向你展示了追蹤器跟隨的所有不同分支。爲此,它似乎否定了它嘗試過的最後一個分支的成功聲明之一,所以這次它將採用不同的解決方案。

看看整個執行過程中,你肯定會看到失敗的謂詞是真的,如第二次評估中的Fail: (7) lists:member(0, [0, 1, 2])

[trace] ?- group([0, 1, 2], 3). 
    Call: (6) group([0, 1, 2], 3) ? creep 
    Call: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(0, [0, 1, 2]) ? creep 
    Call: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(0, [0, 1, 2]) ? creep 
^ Call: (7) _G721 is 0+0 ? creep 
^ Exit: (7) 0 is 0+0 ? creep 
^ Call: (7) _G724 is 0 mod 3 ? creep 
^ Exit: (7) 0 is 0 mod 3 ? creep 
    Call: (7) lists:member(0, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(0, [0, 1, 2]) ? creep 
    Exit: (6) group([0, 1, 2], 3) ? creep 
true ; 
    Redo: (7) lists:member(0, [0, 1, 2]) ? creep 
    Fail: (7) lists:member(0, [0, 1, 2]) ? creep 
    Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(1, [0, 1, 2]) ? creep 
^ Call: (7) _G721 is 0+1 ? creep 
^ Exit: (7) 1 is 0+1 ? creep 
^ Call: (7) _G724 is 1 mod 3 ? creep 
^ Exit: (7) 1 is 1 mod 3 ? creep 
    Call: (7) lists:member(1, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(1, [0, 1, 2]) ? creep 
    Exit: (6) group([0, 1, 2], 3) ? creep 
true ; 
    Redo: (7) lists:member(1, [0, 1, 2]) ? creep 
    Fail: (7) lists:member(1, [0, 1, 2]) ? creep 
    Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(2, [0, 1, 2]) ? creep 
^ Call: (7) _G721 is 0+2 ? creep 
^ Exit: (7) 2 is 0+2 ? creep 
^ Call: (7) _G724 is 2 mod 3 ? creep 
^ Exit: (7) 2 is 2 mod 3 ? creep 
    Call: (7) lists:member(2, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(2, [0, 1, 2]) ? creep 
    Exit: (6) group([0, 1, 2], 3) ? creep 
true ; 
    Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(1, [0, 1, 2]) ? creep 
    Call: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(0, [0, 1, 2]) ? creep 
^ Call: (7) _G721 is 1+0 ? creep 
^ Exit: (7) 1 is 1+0 ? creep 
^ Call: (7) _G724 is 1 mod 3 ? creep 
^ Exit: (7) 1 is 1 mod 3 ? creep 
    Call: (7) lists:member(1, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(1, [0, 1, 2]) ? creep 
    Exit: (6) group([0, 1, 2], 3) ? creep 
true ; 
    Redo: (7) lists:member(1, [0, 1, 2]) ? creep 
    Fail: (7) lists:member(1, [0, 1, 2]) ? creep 
    Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(1, [0, 1, 2]) ? creep 
^ Call: (7) _G721 is 1+1 ? creep 
^ Exit: (7) 2 is 1+1 ? creep 
^ Call: (7) _G724 is 2 mod 3 ? creep 
^ Exit: (7) 2 is 2 mod 3 ? creep 
    Call: (7) lists:member(2, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(2, [0, 1, 2]) ? creep 
    Exit: (6) group([0, 1, 2], 3) ? creep 
true ; 
    Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(2, [0, 1, 2]) ? creep 
^ Call: (7) _G721 is 1+2 ? creep 
^ Exit: (7) 3 is 1+2 ? creep 
^ Call: (7) _G724 is 3 mod 3 ? creep 
^ Exit: (7) 0 is 3 mod 3 ? creep 
    Call: (7) lists:member(0, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(0, [0, 1, 2]) ? creep 
    Exit: (6) group([0, 1, 2], 3) ? creep 
true ; 
    Redo: (7) lists:member(0, [0, 1, 2]) ? creep 
    Fail: (7) lists:member(0, [0, 1, 2]) ? creep 
    Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(2, [0, 1, 2]) ? creep 
    Call: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(0, [0, 1, 2]) ? creep 
^ Call: (7) _G721 is 2+0 ? creep 
^ Exit: (7) 2 is 2+0 ? creep 
^ Call: (7) _G724 is 2 mod 3 ? creep 
^ Exit: (7) 2 is 2 mod 3 ? creep 
    Call: (7) lists:member(2, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(2, [0, 1, 2]) ? creep 
    Exit: (6) group([0, 1, 2], 3) ? creep 
true ; 
    Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(1, [0, 1, 2]) ? creep 
^ Call: (7) _G721 is 2+1 ? creep 
^ Exit: (7) 3 is 2+1 ? creep 
^ Call: (7) _G724 is 3 mod 3 ? creep 
^ Exit: (7) 0 is 3 mod 3 ? creep 
    Call: (7) lists:member(0, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(0, [0, 1, 2]) ? creep 
    Exit: (6) group([0, 1, 2], 3) ? creep 
true ; 
    Redo: (7) lists:member(0, [0, 1, 2]) ? creep 
    Fail: (7) lists:member(0, [0, 1, 2]) ? creep 
    Redo: (7) lists:member(_G718, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(2, [0, 1, 2]) ? creep 
^ Call: (7) _G721 is 2+2 ? creep 
^ Exit: (7) 4 is 2+2 ? creep 
^ Call: (7) _G724 is 4 mod 3 ? creep 
^ Exit: (7) 1 is 4 mod 3 ? creep 
    Call: (7) lists:member(1, [0, 1, 2]) ? creep 
    Exit: (7) lists:member(1, [0, 1, 2]) ? creep 
    Exit: (6) group([0, 1, 2], 3) ? creep 
true ; 
    Redo: (7) lists:member(1, [0, 1, 2]) ? creep 
    Fail: (7) lists:member(1, [0, 1, 2]) ? creep 
    Fail: (6) group([0, 1, 2], 3) ? creep 
false. 
+0

啊,我明白了。所以起初它找出了一個解決方案(0,0),但是後來,因爲我問是否有其他解決方案,它必須從以前的案例中失敗一個正確的解決方案來產生另一個案例的測試,最後它必須失敗一個關鍵的測試,它回答不。有趣並且非常有意義。也許我應該測試一下是否有不屬於該集合的解決方案。但是謝謝你的回答。@ desert69 – Valtteri