在Prolog中交换列表的前两个元素
我从以下位置进行此练习: 练习4.4在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,
编写一个谓词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
)。这听起来像是解决问题的完整定义吗?如果你仍然不确定,你应该尝试一下。你能添加一个例子作为问题的答案吗?我提供了一个更详细的例子。