Prolog集合列表';头

Prolog集合列表';头,prolog,Prolog,当我删除“W是X”时,此代码会附加前两个列表。 这段代码有一些不必要的变量,比如“W是X”,但它们与我的问题有关 当我在“:-”和“,”之间将任何值设置为“W”时,像“W是X”或“W=3”或“W=6”——返回false 为什么我不能在代码中的那个位置设置W的任何值,但我可以在代码的末尾设置“W=I” 查询是append([1,2],[3],U)。我想在这个代码处获取[2,1,3] 在追加([1,2,3],[4,5,6],U)。我想得到[3,2,1,4,5,6] 追加([1],[2,3],U)。返

当我删除“W是X”时,此代码会附加前两个列表。

这段代码有一些不必要的变量,比如“W是X”,但它们与我的问题有关

当我在“:-”和“,”之间将任何值设置为“W”时,像“W是X”“W=3”或“W=6”——返回false

为什么我不能在代码中的那个位置设置W的任何值,但我可以在代码的末尾设置“W=I”

查询是
append([1,2],[3],U)。
我想在这个代码处获取
[2,1,3]
追加([1,2,3],[4,5,6],U)。
我想得到
[3,2,1,4,5,6]


追加([1],[2,3],U)。
返回
[1,2,3]
,当我取第一个列表“1”(当第一个列表只有一个元素)的长度时,代码是完美的;但是当我取第一个列表的长度>1时(当第一个列表有多个元素时),代码返回false。

is运算符专门用于比较或统一整数
W=I
正在尝试将W与I统一(无论类型如何)。当您将
W
X
统一(假设X是整数)时,您已经统一了
W
,如果
X\=I
(不统一),您将返回false

在您的示例中,
W
1
相统一,但您尝试将其与
2
相统一

您有很多不必要的变量,下面是append的一个非常简单的实现:

append([],U,U).
append([X|U1],U2,[W|U3]) :- **W  = X** , append(U1,[X|U2],[I|Quyruk]) , 
                            **W  = I**, U3 = Quyruk .

要了解代码中的错误,让我们来浏览一下

append([],XS,XS).

append([X|XS],YS,[X|ZS]):- append(XS,YS,ZS).
我将使用
X1,X2,…
来区分不同的绑定

在第一次调用中,
X
1
相结合,
U1
[2,3]
相结合,
U2
[4,5,6]
相结合<进入horn子句之前,code>W和U3尚未绑定

W是X
W
1
统一起来

append(U1[X|U2],[I|qyruk])
正在调用
append([2,3],[1,4,5,6],[I|qyruk])
。您应该已经看到您的递归没有正常工作。

在prolog中,您不能分配变量,然后重新分配它们。变量是统一的和实例化的。一旦实例化,它们就不能在子句中重新实例化。因此,如果你在一个子句中有这样的内容:

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).
然后首先用
X
统一
W
=/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
Prolog无法统一
1
2
,正如我前面所述。它们是两种不同的价值观。因此谓词由于
W=I
语句而失败

解决方案比您正在尝试的要简单一点(尽管您非常接近):


这一点的实质是在您的代码中。那些其他的变量只是在妨碍(正如C.B.所指出的)

当我写“W=X”或“W=3”时,它再次返回false,为什么“W=X”false“W=i”true?@user3174737我想看看你的递归,为什么你可以使用原始变量来统一变量。比如,当你可以直接使用
qyruk
时,为什么你要将
U3
qyruk
统一起来?我是prolog的初学者,我知道最好的答案是append([],XS,XS)。附加([X|XS],YS[X|ZS]):-append(XS,YS,ZS)。但是我在尝试不同的方法我不是在寻找最好的解决方案,我只想知道为什么我不能设置“W=3”或“W=X”,后台的问题是什么?我不能在代码的最后设置“W=I”,为什么在开始时它返回false,但在最后它不会产生问题要理解我的代码出了什么问题,让我们来看看这个附加([1,2],[3],U)。我想在append([1,2,3],[4,5,6],U)的这个代码中得到[2,1,3]。想得到[3,2,1,4,5,6]为什么不只是:
my_append(L1,L2,L3):-reverse(L1,L4),append(L4,L2,L3)。
?在prolog中,不像在其他语言中那样赋值。它统一了。一旦通过统一实例化了变量,就不能在子句中更改它。因此,一旦你做了
W=X
,这将使它们统一起来,并且
W=I
将始终失败,除非
I
X
I
W
)恰好用相同的值实例化。append([1],[2,3],U)。->返回[1,2,3],当我取第一个列表“1”(当第一个列表只有一个元素)的长度时,代码是完美的;但是当我取第一个列表的长度>1时(当第一个列表有多个元素时),代码返回falseappend([1],[2,3],U)。->返回[1,2,3],当我取第一个列表“1”(当第一个列表只有一个元素)的长度时,代码是完美的;但是当我取第一个列表的长度>1(当第一个列表有多个元素时)时,代码返回false为什么当第一个列表的长度大于1(>1)时,代码返回false?@user3174737查看我的更新答案,其中显示了我对失败的解释示例。
?- 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
% 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