如何在prolog中附加列表列表

时间:2015-09-22 10:45:41

标签: list prolog

我想附加一个这样的列表列表:append(Ls,L),L的第一个元素是Ls中第一个列表的第一个元素,L的第二个元素是第二个列表中的第一个元素对于Ls中的所有列表,Ls等等。在此之后,L的下一个元素是Ls中第一个列表的第二个元素,依此类推,直到从Ls中的所有列表中取出两个元素。在此之后,得到Ls中所有列表的第三个元素,依此类推,直到Ls中所有列表的所有元素都包含在L中。

forexample: 我有一个列表Ls=[[a,b],[c,d],[e,f]] 并希望得到这个L=[a,c,e,b,d,f] 或者我{​​{1}}我希望得到Ls=[[1,2,3],[4,5,6]]

4 个答案:

答案 0 :(得分:2)

如果您想练习实现递归谓词,可以使用继续这样做:

matrix_transposed_items(Mss,Xs) :-
   notlonger_than(Mss,Xs),
   phrase(matrix_tconcat(Mss),Xs).

matrix_tconcat([]) --> [].
matrix_tconcat([Cs|Css]) -->
   row_rows_rest_(Cs,Css,Mss),
   matrix_tconcat(Mss).

row_rows_rest_([],Css,[]) --> 
   { emptylists(Css) }.
row_rows_rest_([X|Xs],Xss,[Xs|Mss]) -->
   [X],
   nonemptyrows_rest(Xss,Mss).

nonemptyrows_rest([],[]) --> [].
nonemptyrows_rest([[X|Xs]|Xss],[Xs|Mss]) -->
   [X],
   nonemptyrows_rest(Xss,Mss).

以上代码基于三个辅助谓词,可以这样定义:

nil_or_cons([]).
nil_or_cons([_|_]).

notlonger_than([],Bs) :-
   nil_or_cons(Bs).
notlonger_than([_|As],[_|Bs]) :-
   notlonger_than(As,Bs).

emptylists([]).
emptylists([[]|Xs]) :-
   emptylists(Xs).

让我们运行一些查询!首先,我们使用一些二次矩阵:

?- matrix_transposed_items([[1,2,3],[4,5,6],[7,8,9]],Xs).
Xs = [1,4,7,2,5,8,3,6,9].                            % succeeds deterministically

接下来,OP给出的非二次使用情况:

?- matrix_transposed_items([[a,b],[c,d],[e,f]],Ls).
Ls = [a,c,e,b,d,f].                                  % succeeds deterministically

?- matrix_transposed_items([[1,2,3],[4,5,6]],Ls).
Ls = [1,4,2,5,3,6].                                  % succeeds deterministically

我们也试着去“其他方向”!

?- matrix_transposed_items(Mss,[1,2,3,4,5,6,7,8,9,10]).
  Mss = [[1,2,3,4,5,6,7,8,9,10]]
; Mss = [[1,3,5,7,9],[2,4,6,8,10]]
; Mss = [[1,6],[2,7],[3,8],[4,9],[5,10]]
; Mss = [[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]]
; false.                                             % terminates universally

答案 1 :(得分:1)

如果您使用SWI-Prolog,您可以这样继续:

?- use_module(library(clpfd),[transpose/2]).
true.

以下是OP提供的示例查询:

?- Mss=[[1,2,3],[4,5,6]], transpose(Mss,Tss), append(Tss,Xs).
Mss = [[1,2,3],[4,5,6]], Tss = [[1,4],[2,5],[3,6]], Xs = [1,4,2,5,3,6].

答案 2 :(得分:1)

这不是关系解决方案,而是说明了问题的递归方法:

zipflat(Lists, Result) :-
    zipflat_aux(Lists, ResultLists),
    append(ResultLists, Result).

zipflat_aux(Lists, [Heads|ZipTails]) :-
    maplist(head_tail, Lists, Heads, Tails),
    zipflat_aux(Tails, ZipTails), !.
zipflat_aux([[]|_], []).

head_tail([H|T], H, T).

剪切(!)消除了不需要的选择点。

答案 3 :(得分:0)

因为append / 2有不同的含义,我们称之为zip / 2

zip([A|As], Zip) :-
    findall(Es, (   nth1(P, A, _),
            findall(E, (member(L, [A|As]), nth1(P, L, E)), Es)
    ), Ts), append(Ts, Zip) /*flatten(Ts, Zip)*/ .