在prolog中,您不能分配變量,然後重新分配他們。變量被統一和實例化。一旦實例化,它們就不能在子句中重新實例化。所以,如果你有這樣一個條款內:
W = X,
...
W = I,
然後第一W
是統一的X
(=/2
是統一的運營商)。這意味着它們或者現在都具有相同的實例化值(如果至少有一個實例化之前),或者它們的值將在後面強制爲相同的實例化。當稍後遇到W = I
時,則I
必須與W
一致,否則該子句將失敗。如果I
具有與實例W
(並因此X
)不同的具體值,則該子句將必然失敗。
讓我們看到它發生(請注意我的名字改爲my_append
因爲Prolog的拒絕重新定義內置謂詞,append
):
my_append([],U,U).
my_append([X|U1], U2, [W|U3]) :-
W = X,
my_append(U1, [X|U2], [I|Quyruk]),
write('I = '), write(I), write('; W = '), write(W), nl,
W = I,
U3 = Quyruk.
如果我們運行:
?- my_append([1], [1,2], L).
I = 1; W = 1
L = [1,2,3]
yes
生活是美好的。現在讓我們嘗試:
| ?- my_append([1,2], [3,4], L).
I = 2; W = 2 % This will be OK
I = 2; W = 1 % Uh oh... trouble
no
序言不能統一1
和2
,正如我上面描述。他們是兩個不同的價值觀。因此,謂詞由於W = I
聲明而失敗。
解決的辦法是比你嘗試什麼簡單一些(儘管你很接近):
% Append empty to list gives the same list
my_append([], U, U).
% Append of [X|U1] and U2 is just append U1 and [X|U2]
% Or, thought of another way, you are moving elements of the first list
% over to the head of the second one at a time
my_append([X|U1], U2, U3) :-
my_append(U1, [X|U2], U3).
| ?- my_append([1,2,3],[4,5,6],L).
L = [3,2,1,4,5,6]
yes
這樣做的實質是在你的代碼。其他變量正在阻礙(正如C.B.指出的那樣)。 :)
爲什麼不只是:'my_append(L1,L2,L3): - 反向(L1,L4),追加(L4,L2,L3)。在prolog中'='不像其他語言那樣賦值。它*統一*。一旦通過統一實例化一個變量,你就不能在一個子句中改變它。所以一旦你做了'W = X',這就統一了它們,'W = I'將會一直失敗,除非'I'和'X'('I'和'W')碰巧用相同的值實例化。 – lurker
append([1],[2,3],U)。 - >返回[1,2,3], 當我把第一個列表的長度「1」(當第一個列表只有一個元素時)代碼是完美的;但是當我把第一個列表的長度> 1(當第一個列表有多個元素時)代碼返回錯誤 – user3174737