Prolog-Zip函数

Prolog-Zip函数,prolog,Prolog,我在新南威尔士州的prolog。我正在努力学习zip函数。问题是这样的 zip(L1,L2,X):列表X由“压缩”前2个参数组成 结果应该是这样的: ?- 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] 到目前为止,我已经这样做了。

我在新南威尔士州的prolog。我正在努力学习zip函数。问题是这样的

zip(L1,L2,X):列表X由“压缩”前2个参数组成

结果应该是这样的:

?- 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]
到目前为止,我已经这样做了。 我可以得到第一个第三个的结果,但不能得到第二个。任何人都可以帮我解决第二个问题。多谢各位

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
你做到了:

zip([], [], []).
zip([X|Xs], [Y|Ys], [X,Y|Zs]) :- zip(Xs,Ys,Zs).
仅此一项就足以定义您正在寻找的关系。附加条款没有用

测试:


@m09给出了正确的答案。但我想解释一下为什么你所说的不正确:

(1) zip([X],[Y],[X,Y]).
这条规则说,当你用
[Y]
压缩
[X]
时,你会得到
[X,Y]
。这是正确的,不会导致问题。这条规则与下面的规则(我将解释…)完全是多余的

这条规则说,
[]
是当您使用
[]
压缩
[]
时得到的,这是正确的,也是一条简单的压缩规则

(3) zip([X|Xs], [Y|Ys], [X,Y|Zs]) :-
        zip(Xs,Ys,Zs).
这条规则说,
[X,Y | Zs]
是你用
[Y | Ys]
压缩
[X | Xs]
时得到的,如果
Zs
是你用
Ys
压缩
Xs
时得到的。这也是合乎逻辑和正确的。请注意,
zip([X],[Y],[X,Y])
zip([X |[]],[Y |[]],[X,Y |[]])。
因此它可以从规则(2)和(3)中派生出来。它将首先匹配规则(3),
zip([X |[]],[Y |[]],[X,Y | Zs]):-zip([],[],Zs)。
,然后
Zs
将根据规则(2)变成
[]

规则(4)说当你用
[]
压缩
[X|Xs]
时,你会得到
[X|Xs]
。规则(5)在逻辑上说了完全相同的事情,只是使用了不同的变量名。这些都是不正确的,因为这意味着,例如,如果
Z=[a,b,c],[Z],
是真的,如果
Z=[a,b,c]

(6) zip(Xs, [], Xs).
这条规则说,当你用
[]
压缩
Xs
时,你会得到
Xs
。或者换一种方式说,任何用
[]
压缩的输入都将再次成为该输入值。它甚至不必是一个列表!这显然是错误的。像
zip(x,[],Z)
这样的查询将通过
Z=x
成功,而
zip(朋友(比尔,玛丽),[],Z)
将通过
Z=朋友(比尔,玛丽)
成功


该规则规定,当您使用
Ys
压缩
[]
时,您将得到
Ys
。它不正确,原因与(6)不正确相同。事实上,这个规则加上(2)和(3)是查询
zip([a,b],[x,y,z],x)的原因。
将产生结果而不是失败。规则(2)和(3)将递归到
zip([b],[y,z],[b,y | T]):-zip([],[z],T)。
然后
zip([],[z],T)
将最终在规则(7)中成功地使用
T=[z]
,并最终生成
zip([a,b],[x,y,z],x)
的最终结果。我还是个新手。我还有一件事。我该怎么做才能得到这个。allsame(L):列表L包含相同的元素。e、 g.,?-完全相同([b,b,b])。是吗?-都一样([c,c,c,Y,c,c,c,X,c])。X=c,Y=cIt很不寻常,如果给定前两个参数,谓词就会失败。此外,该名称相当于
交错
或类似名称
zip
通常被认为是一个类似于
map
的函数式回答。我建议比“这条规则说[X,Y | Zs]是你用[Y | Ys]压缩[X | Xs]时得到的,如果Zs是你用[Y | Ys]压缩Xs时得到的。这也是合乎逻辑和正确的。”是“这条规则说[X,Y | Zs]是你用[Y | Ys]压缩[X | Xs这意味着,当您使用Ys压缩Xs时,您将得到Zs。这也是合乎逻辑且正确的。“。一个次要但非常合乎逻辑的区别。@Kintalken谢谢你的好意评论。实际上,在Prolog中,
head:-body
是一个相反的含义:
body->head
。如果<代码>主体<代码>为真(可证明),则<代码>头<代码>为真(或可证明),但不一定是相反的,因为其他条件也可能证明<代码>头<代码>为真(例如,在该例中,当<代码>头<代码>有多个谓词子句时)。换句话说,
可以从
推断出来,但不一定相反。在你的评论中,你展示了对“->”的(常见)误解。“:-”和
->”之间的重要区别是“:-”是语义,而
->`是句法。因此,
a->b
意味着“要使a为真,首先b也必须为真”,但因为syntaktik b必须具有完全由现有形式定义确定的先验存在。因此
a:-b
意味着“如果a为真,那么b也必须为真”(相同),但是!b现在可能没有一个正式的句法存在,它可能是一个短暂的语义决定,也许是一个计算。“暗示”并不意味着“决定”,恰恰相反:如果a暗示b,它意味着因为有一个a通过归纳推理,b一定已经发生了。因此,如果“湿->下雨”,则表示“有湿,一定是下雨了”。但“湿=>雨”的意思是“有雨,所以现在也有湿”。序言“:-”相当于“=>”。在谷歌搜索这个主题时,除了困惑之外,毫无疑问,没有任何规范性的理解。这是一个混乱和错误信息的主要领域。在你的评论中,你写道“头部可以从身体中推断出来,但不一定相反。”但是!“演绎”不仅仅是“推理”(常见错误)的替代品:它有一个特定的含义,尤其是它必须与“归纳”相反<代码>状态(湿)=>位置(室外)和天气(下雨)
是一个声明“如果
(3) zip([X|Xs], [Y|Ys], [X,Y|Zs]) :-
        zip(Xs,Ys,Zs).
(4) zip([X|Xs],[],[X|Xs]).
(5) zip([Y|Ys],[],[Y|Ys]).
(6) zip(Xs, [], Xs).
(7) zip([], Ys, Ys).