Prolog Zip功能

时间:2014-04-04 06:33:48

标签: prolog

我在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

2 个答案:

答案 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

此规则说[]Yszip([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}}。