在Prolog中交换列表的前两个元素

在Prolog中交换列表的前两个元素,prolog,Prolog,我从以下位置进行此练习: 练习4.4 编写一个谓词swap12(List1,List2),检查List1是否为 与列表2相同,只是前两个元素是交换的 这就是我到目前为止所做的: swap12([],[]). swap12([a, b | Ta], [b, a | Tb]) :- swap12(Ta, Tb). 但当我尝试评估这一点时,我得到以下结果: ?- swap12(X, Y). X = Y, Y = [] ; X = [a, b], Y = [b, a] ; X = [a, b, a,

我从以下位置进行此练习:

练习4.4
编写一个谓词swap12(List1,List2),检查List1是否为 与列表2相同,只是前两个元素是交换的

这就是我到目前为止所做的:

swap12([],[]).
swap12([a, b | Ta], [b, a | Tb]) :- swap12(Ta, Tb).
但当我尝试评估这一点时,我得到以下结果:

?- swap12(X, Y).
X = Y, Y = [] ;
X = [a, b],
Y = [b, a] ;
X = [a, b, a, b],
Y = [b, a, b, a] .
swap12(X,Y).
X = [a, b].
Y = [b, a].
X = [a, b, b].
Y = [b, a, a].
我做错了什么

目标是实现以下功能:

?- swap12(X, Y).
X = Y, Y = [] ;
X = [a, b],
Y = [b, a] ;
X = [a, b, a, b],
Y = [b, a, b, a] .
swap12(X,Y).
X = [a, b].
Y = [b, a].
X = [a, b, b].
Y = [b, a, a].
等等,请帮忙

第一条:

swap12([],[]).
表示交换空列表的前两个元素就是空列表。我想,根据定义,也许有人会这么说。但由于空列表没有任何元素,因此可能并不认为它是真的

你的第二条是:

swap12([a, b | Ta], [b, a | Tb]) :- swap12(Ta, Tb).
这就是说,如果您交换
[a,b | Ta]
的前两个元素,结果是
[b,a | Tb]
如果
Tb
Ta
,其前两个元素被交换。这是任何以
a
b
开头的列表的规则,但如果有任何其他前两个元素,则该规则将不起作用,因为
a
b
是原子,而不是变量。因此,例如,
swap12([1,2,3,4],L)
将失败,因为列表以
1
2
开头,而不是
a
b
。此外,您的问题是仅交换前两个元素,而您的解决方案具有对
swap12(Ta,Tb)
的递归调用,该调用将继续递归交换

下面是您的代码真正的功能(它不做您在问题中显示的功能,这意味着您显示的结果是针对您编写的代码的不同版本的)

最后一次执行说明了规则的真正含义。仅当第一个列表为空,或任意数量的
a
b
对,且第二个列表与交换到
b
a
的每个
a
对相同时,该操作才会成功

让我们重新开始。同样的问题是,如果第二个列表是第一个列表,并且只有前两个元素被交换,那么创建一个规则是正确的。至少有两个元素的列表类似于
[X,Y | T]
(前两个元素是
X
Y
-变量)。如果我只想交换前两个元素,我会写,
[Y,X | T]
,因此我交换了
X
Y
,但保留相同的尾部,
T
(我不想交换更多的元素)

因此,规则看起来就像:

swap12([X, Y|T], [Y, X|T]).
这意味着如果我有一个列表
[X,Y | T]
,那么
[Y,X | T]
是同一个列表,但只交换了前两个元素。您可以尝试一下:

?- swap12([a], R).
false.       % fails because `[a]` only has one element!

?- swap12([a,b], R).
R = [b, a].

?- swap12([a,b,c], R).
R = [b, a, c].

?- swap12([a,b,c,d], R).
R = [b, a, c, d].

?- swap12([a,b,c,e,f], R).
R = [b, a, c, e, f].

?- ...

问题是只交换前两个元素。您正在进行一个递归调用,它将交换每个连续的元素对。此外,您使用的是原子,而不是变量。原子以小写字母开头。变量以大写字母或
开头。因此,您应该编写
swap12([A,B | T],[B,A | T])。
这就是交换任何列表的前两个元素所需的全部内容,例如,
swap([A,B,c,d],L)。
将产生
L=[B,A,c,d]
。我不确定我是否理解。你的意思是将
swap12
重新定义为
swap12([A,B | T],[B,A | T])
?或者将不同的参数传递给现有函数?我的意思是重定义。你不需要别的东西<代码>交换([A,B | T],[B,A | T])。
[B,A | T]
[A,B | T]
,前两个元素交换(另外两个元素是相同的,因为它们共享相同的尾部,
T
)。这听起来像是解决问题的完整定义吗?如果你仍然不确定,你应该尝试一下。你能添加一个例子作为问题的答案吗?我提供了一个更详细的例子。