Prolog集合列表';头
当我删除“W是X”时,此代码会附加前两个列表。 这段代码有一些不必要的变量,比如“W是X”,但它们与我的问题有关 当我在“:-”和“,”之间将任何值设置为“W”时,像“W是X”或“W=3”或“W=6”——返回false 为什么我不能在代码中的那个位置设置W的任何值,但我可以在代码的末尾设置“W=I” 查询是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)。返
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