append([],U,U).
append([X|U1],U2,[W|U3]) :- **W = X** , append(U1,[X|U2],[I|Quyruk]) ,
**W = I**, U3 = Quyruk .
当我删除“W是X”时,此代码会附加前两个列表。
此代码包含不必要的变量,例如“W is X”,但它们与我的问题有关。
当我在“: - ”和“,追加......”之间将任何值设置为“W”时,如“W是X”或“W = 3”或“W = 6” - 返回false 。
为什么我不能在代码中的那个位置为W设置任何值,但是我可以在代码的末尾设置“W = I”?
查询为append([1,2],[3],U).
我想在此代码中获取[2,1,3]
在append([1,2,3],[4,5,6],U).
,我想获得[3,2,1,4,5,6]
。
append([1],[2,3],U).
返回[1,2,3]
,当我取第一个列表“1”的长度时(当第一个列表只有一个元素时)代码是完美的;但是当我取第一个列表的长度> 1时(当第一个列表有多个元素时),代码返回false。
答案 0 :(得分:0)
is
运算符专门用于比较或统一整数。 W = I
试图将W与I统一(不论类型)。当您使用W
统一X
时(假设X是整数),您已经统一W
,如果X\=I
(未统一),您将返回false。
在您的示例中,W
与1
统一,但之后您尝试将其与2
统一。
你有很多不必要的变量,这是一个非常简单的append实现:
append([],XS,XS).
append([X|XS],YS,[X|ZS]):- append(XS,YS,ZS).
要了解您的代码出了什么问题,让我们一起来看看
append([],U,U).
append([X|U1],U2,[W|U3]) :- W is X , append(U1,[X|U2],[I|Quyruk]) , W = I, U3 = Quyruk .
?-append([1,2,3],[4,5,6],U).
我将使用X1,X2,...
来区分不同的绑定。
在第一次通话中,X
与1
统一,U1
与[2,3]
统一,U2
与[4,5,6]
统一。 W and U3
在进入号角条款之前尚未受约束。
W is X
将W
与1
统一起来。
append(U1,[X|U2],[I|Quyruk])
正在调用append([2,3],[1,4,5,6],[I|Quyruk])
。您应该已经看到递归无法正常工作。
答案 1 :(得分:0)
在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
Prolog无法统一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.指出的那样)。 :)