Prolog 在序言中洗牌

Prolog 在序言中洗牌,prolog,Prolog,我试图用prolog编写一个过程,如果L1=[1,2,3]和L2=[4,5,6],那么L3=[1,4,2,5,3,6] 所以shuffle([1,2,3],[4,5,6],[1,4,2,5,3,6]) 到目前为止,我有: shuffle([X],[Y],[X,Y]). shuffle([X|Xs],[Y|Ys],_) :- shuffle(Xs,Ys,Z), shuffle(X,Y,Z). 这是我第一次尝试编写prolog代码,所以我仍然在努力学习语法、规则和所有东西 我理解逻辑,我只是不知道

我试图用prolog编写一个过程,如果L1=[1,2,3]和L2=[4,5,6],那么L3=[1,4,2,5,3,6]

所以
shuffle([1,2,3],[4,5,6],[1,4,2,5,3,6])

到目前为止,我有:

shuffle([X],[Y],[X,Y]).
shuffle([X|Xs],[Y|Ys],_) :- shuffle(Xs,Ys,Z), shuffle(X,Y,Z).
这是我第一次尝试编写prolog代码,所以我仍然在努力学习语法、规则和所有东西

我理解逻辑,我只是不知道如何实现它,所以任何帮助都将不胜感激

谢谢

编辑:我已经猜出来了。如果有人感兴趣,以下是解决方案:

shuffle([X],[Y],[X,Y]).  
shuffle([X|Xs],[Y|Ys],[Z1,Z2|Zs]) :- shuffle([X],[Y],[Z1,Z2]),shuffle(Xs,Ys,Zs).

在这类问题中,通常困难的部分不是Prolog,而是确定解决它的最简单的递归关系。

以下是简单的解决方案:

shuffle([], [], []).
shuffle([X|Xs], [Y|Ys], [X,Y|Zs]) :-
    shuffle(Xs,Ys,Zs).
将其推广到处理长度不等的列表是将基本情况更改为:

shuffle(Xs, [], Xs).
shuffle([], Ys, Ys).
尽管这可能会产生重复的解决方案。如果你不介意谓词是“单向的”,那么可以用一个cut来修复这些问题


(虽然我仍然认为你应该称之为
flatzip
interlace
而不是
shuffle

nice:)顺便说一句,你可以避免第一次调用shuffle:shuffle([X | Xs],[Y | Ys],[X,Y | Zs]):-shuffle(Xs Ys,Ys,Zs)。通常更简单:比OSQR更能显示真正的解决方案,而你原来的循环是回溯!您在哪里调用此
洗牌
?这更接近于
zip
操作。也许
flatzip
会是一个合适的名称。@larsmans:
interlace
-类似于
interspise
?在任何情况下,OP的关系对于
shuffle([],[X],Xs)
等都没有明确规定。@false:我刚刚意识到,在Prolog中,这比在其他语言中更重要,因为它决定了反向操作
shuffle(X,Y,Z)
只有
Z
是确定的还是不确定的。如果你按照你的建议添加更多的事实,最好是列举所有的可能性,以避免重复的答案。例如,
shuffle([X|Xs],[X|Xs],[X|Xs])
@false:对不起,我不明白那句话。我的建议是用这两个备选条款取代第一条。即使如此!查询
shuffle([A],[b],[A,b])
现在为您提供一个答案和一个多余的答案。@false:啊,对了!在这里划伤也行。我认为这是将此操作限制为等长列表的一个很好的理由;)对不起,我听不懂你的语言:切?你是说coupe choix??我对此感到非常抱歉!啊,我应该说是coupe choix
shuffle(Xs, [], Xs).
shuffle([], Ys, Ys).