2011-04-11 27 views
2

我正在進行prolog任務,目前我非常接近解決方案。所以,這個問題是一個約束滿足問題,我必須找到一組變量的值,以使某些條件成立。具體來說,給定3個單詞(W1,W2,W3),將它們的變量賦值爲W1 + W2 = W3。一個例子是SEND + MORE = MONEY,或者IT + IS = ME。帶變量的Prolog點積(約束滿足)

約束條件是:(1)它們必須正確相加,(2)起始字母不能是0(3),所有變量必須是不同的。它必須適用於一般性的單詞問題。當我嘗試確保它們合起來的時候,我遇到了問題(我遇到了其他條件,並且我理解了這個問題)。第二個字的問題而言,我們應該有:

10*I + 1*T 
+10*I + 1*S 
___________ 
10*M + 1*E 

所以,我做了一個功能,使的10次冪的名單在一定的長度,就像這樣:

powlist(1,L) :- 
    append([1.0],[],L). 
powlist(N,L) :- 
    N1 is N-1, 
    X is 10**N1, 
    powlist(N1,L1), 
    append([X],L1,L), 
    !. 

我也有字母的實際列表,比如[I,T,I,S,M,E]。然後我建立了一個系列列表(我將在後面解釋這部分),從powlist中刪除,所以我們有如下的東西:[10,1,10,1,-10,-1]。我這樣做,所以如果我們在這個係數列表和字母列表之間取得點積,並且它是零,那麼約束就會得到滿足。但是,我無法讓這個點積理論起作用。我現在有這樣一行:

scalar_product(Coefficients, Letters, #=, 0) 

但是,這是給我下面的錯誤:

!參數2中的實例化錯誤是/ 2
!目標:_102是0 + 10.0 * _109

我不確定如何定義點積,因此它可以在變量(而不是原子)上工作。所有其他的代碼完美地工作(我不想把它放在這裏,因爲這是介紹性的prolog課程的一個非常常見的問題,我不想給懶惰的人解答)。你們有什麼建議?

回答

1

您的策略確實很好,至少在SWI-Prolog CLP(FD)使用內置的scalar_product/4時確實很有效。我不熟悉SICStus中這個謂詞的定義,但它的界面看起來與SWI-Prolog中的相同。

我可以提出一些建議。首先,您編寫的代碼的某些方面可能會生成選擇點,在執行回溯時(例如,尋求替代解決方案,例如通過label/1),解釋程序將執行子目標_102 is 0+10.0*_109,其中_109無意中未綁定。你寫了一個包含這樣一行的謂詞嗎?即使不是,我建議仔細檢查你的代碼,以確保它們不會產生不必要的選擇點,例如你的定義powlist/2。我建議你嘗試,而不是以下:

powlist(1, [1]) :- !. 
powlist(N, [F|Fs]) :- 
    N > 1, 
    N1 is N - 1, 
    F is 10 ** N1, 
    powlist(N1, Fs). 

這個版本沒有留下choicepoints的Prolog的解釋回溯到,這可能解決問題(雖然,沒有看到更多的代碼,我根本分辨不出)。否則,如果您是正確的,並且錯誤確實是從scalar_product/4的定義中產生的(儘管我會感到驚訝),那麼也許您可以生成標量產品約束條件並手動將其添加到商店中。例如,考慮:

my_scalar_product([V|Vs], [C|Cs], Op, Value) :- 
    construct_constraint(Vs, Cs, (V * C), Constr), 
    Constraint =.. [Op, Constr, Value], 
    Constraint. 

construct_constraint([], [], Acc, Acc). 
construct_constraint([V|Vs], [F|Fs], Acc, Res) :- 
    construct_constraint(Vs, Fs, '+'(Acc, (V * F)), Res). 

這個版本(my_scalar_product/4)假設相同的接口,內置的scalar_product/4,但它增加了約束的存儲,而不是嘗試使用is/2來執行它。