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