如何在保留内部顺序的同时改写Prolog中的列表

时间:2018-07-22 12:30:17

标签: prolog

我试图在保留顺序的同时在一个列表中打印出两个列表的所有可能改组后的变体。

我需要写一个谓词shuffle(L1L2L3),将L1L2进行shuffle,并将结果放入{{1 }},同时保留L3L1的内部顺序。

例如:

L2

到目前为止我所拥有的:

?- shuffle([a,b],[1,2],L).
L = [a,b,1,2] ;
L = [a,1,b,2] ;
L = [a,1,2,b] ;
L = [1,a,b,2] ;
L = [1,a,2,b] ;
L = [1,2,a,b]

结果为:

shuffle([],[],[]).
shuffle([X|Xs],[Y|Ys],[X,Y|Tail]) :-
    shuffle(Xs,Ys,Tail).
shuffle([X|Xs],[Y|Ys],[Y,X|Tail]) :-
    shuffle(Xs,Ys,Tail).

因此,我错过了| ?- shuffle([a,b],[1,2],L). L = [a,1,b,2] ? ; L = [a,1,2,b] ? ; L = [1,a,b,2] ? ; L = [1,a,2,b] L1+L2的“简单追加”的情况...

我的谓语丢失了什么?

1 个答案:

答案 0 :(得分:1)

我们可以使用来简化代码编写

shuffle([A|B],[C|D]) --> [A] , shuffle(B,[C|D]). 
shuffle([A|B],[C|D]) --> [C] , shuffle([A|B],D).
shuffle(A,[]) --> A.
shuffle([],C) --> C.

shuffle( A, B, C) :- phrase( shuffle(A,B), C).

我们要么从一个非空卡位中拿走第一张卡,要么从另一个非空卡位中拿走,但是如果其中一个是空的,我们必须立即使用非空卡位中的所有剩余卡。

不幸的是,这在最后留下了一个额外的选择点:

5 ?- shuffle([a,b],[1,2],C).
C = [a, b, 1, 2] ;
C = [a, 1, b, 2] ;
C = [a, 1, 2, b] ;
C = [1, a, b, 2] ;
C = [1, a, 2, b] ;
C = [1, 2, a, b] ;
false.

关于您的方法,问题在于您试图同时照顾两张卡,而且变得很复杂。最简单的步骤是最简单的。