我在prolog中提到了。我试图学习拉链功能。问题是这样的。
zip(L1,L2,X):列表X是通过“压缩”前两个参数形成的。
结果应该是这样的:
?- zip([a, b, c], [x, y, z], X).
L = [a, x, b, y, c, z]
?- zip([a, b], [x, y, z], X).
false
?- zip([a, b, c, d], X, [a, p, b, q, c, r, d, s]).
X = [p, q, r, s]
到目前为止我已经这样做了。
我可以得到第1个第3个而不是第2个的结果。任何人都可以帮我解决第二个问题。谢谢
zip([X],[Y],[X,Y]).
zip([], [], []).
zip([X|Xs], [Y|Ys], [X,Y|Zs]) :-
zip(Xs,Ys,Zs).
zip([X|Xs],[],[X|Xs]).
zip([Y|Ys],[],[Y|Ys]).
zip(Xs, [], Xs).
zip([], Ys, Ys).
我如何定义这个功能; allsame(L):列表L包含相同的元素。 我应该得到这个。
?- allsame([b, b, b]).
true
?- allsame([c, c, c, Y, c, c, X, c]).
X = c, Y = c
答案 0 :(得分:4)
你拥有它:
zip([], [], []).
zip([X|Xs], [Y|Ys], [X,Y|Zs]) :- zip(Xs,Ys,Zs).
这足以定义您正在寻求的关系。额外的条款没有帮助。
测试:
?- zip([a, b, c], [x, y, z], X).
X = [a, x, b, y, c, z].
?- zip([a, b], [x, y, z], X).
false.
?- zip([a, b, c, d], X, [a, p, b, q, c, r, d, s]).
X = [p, q, r, s].
答案 1 :(得分:2)
@ m09给出了正确的答案。但我想解释为什么你所拥有的不正确:
(1) zip([X],[Y],[X,Y]).
此规则说[X,Y]
是[X]
与[Y]
压缩后的结果。这是正确的,不会导致问题。该规则对下面的规则是多余的(我将解释......)。
(2) zip([], [], []).
此规则说[]
是您使用[]
[]
进行压缩时获得的正确且简单的拉链规则。
(3) zip([X|Xs], [Y|Ys], [X,Y|Zs]) :-
zip(Xs,Ys,Zs).
此规则表明[X,Y|Zs]
是您使用[X|Xs]
压缩[Y|Ys]
时获得的,如果 Zs
是您获取的内容Xs
Ys
zip([X], [Y], [X,Y])
。这也是合乎逻辑和正确的。请注意,zip([X|[]], [Y|[]], [X,Y|[]]).
为zip([X|[]], [Y|[]], [X,Y|Zs]) :- zip([], [], Zs).
,因此可以从规则(2)和(3)派生。它首先匹配规则(3),Zs
,然后[]
将成为(4) zip([X|Xs],[],[X|Xs]).
(5) zip([Y|Ys],[],[Y|Ys]).
规则(2)`。
[X|Xs]
规则(4)说[X|Xs]
是[]
与zip([a,b,c], [], Z)
压缩后的结果。规则(5)在逻辑上说只有不同的变量名称。这些是不正确的,因为这意味着,例如Z = [a,b,c]
如果(6) zip(Xs, [], Xs).
则为真。
Xs
此规则说Xs
是[]
与[]
压缩后的结果。或者说另一种方式,任何输入,压缩为zip(x, [], Z)
,将再次成为该输入值。它甚至不必是一个清单!这显然是不正确的。 Z = x
之类的查询会在zip(friend(bill,mary), [], Z)
之后成功,而Z = friend(bill,mary)
会在(7) zip([], Ys, Ys).
之后成功。
Ys
此规则说[]
是Ys
与zip([a, b], [x, y, z], X).
压缩后的结果。由于同样的原因(6)不正确,这是不正确的。实际上,这个规则与(2)和(3)相结合是查询zip([b], [y,z], [b,y|T]) :- zip([], [z], T).
将产生结果而不是失败的原因。规则(2)和(3)将递归至zip([], [z], T)
,然后T = [z]
将最终成功执行带有zip([a, b], [x, y, z], X)
的规则(7),并最终产生最终结果X = [a, x, b, y, z]
{{1}}。