How to transfer matrix to prolog

How to transfer a list, for example [[1,2,3][4,5,6][6,7,8]] in [[1,4,6],[2,7,8],[3,6,9]] ?

To portray this: I would like to flip the matrix 90 degrees to the left. How can i do this?

+7
list matrix transpose prolog flip
source share
8 answers

Not sure if your example is correct, but I get it.

If you use SWI-PROLOG, you can use the CLPFD module , for example:

:- use_module(library(clpfd)).

Allows the use of the transpose/2 predicate, for example:

 1 ?- transpose([[1,2,3],[4,5,6],[6,7,8]], X). X = [[1, 4, 6], [2, 5, 7], [3, 6, 8]]. 

Otherwise (if there is no SWI-PROLOG), you can simply use this implementation (which was old in clpfd SWI):

 transpose([], []). transpose([F|Fs], Ts) :- transpose(F, [F|Fs], Ts). transpose([], _, []). transpose([_|Rs], Ms, [Ts|Tss]) :- lists_firsts_rests(Ms, Ts, Ms1), transpose(Rs, Ms1, Tss). lists_firsts_rests([], [], []). lists_firsts_rests([[F|Os]|Rest], [F|Fs], [Os|Oss]) :- lists_firsts_rests(Rest, Fs, Oss). 

For the updated version, which uses the built-in foldl and maplist modules, see clpfd.pl .

+7
source share

This is the smallest solution I could come up with.

The code

 transpose([[]|_], []). transpose(Matrix, [Row|Rows]) :- transpose_1st_col(Matrix, Row, RestMatrix), transpose(RestMatrix, Rows). transpose_1st_col([], [], []). transpose_1st_col([[H|T]|Rows], [H|Hs], [T|Ts]) :- transpose_1st_col(Rows, Hs, Ts). 

Test

 :- transpose([[1,2,3], [4,5,6], [7,8,9]], R), print(R). 

Print:

 [[1,4,7], [2,5,8], [3,6,9]] 

explanation

This works so that transpose will recursively call transpose_1st_col which fetches and transposes the first column of the matrix. For example:

 :- transpose_1st_col([[1,2,3], [4,5,6], [7,8,9]], Row, RestMatrix), print(Row), print(RestMatrix). 

will print

 [1,4,7] 

and

 [[2,3], [5,6], [8,9]] 

This is repeated until the input matrix is ​​empty, after which all columns are transposed. Then the transposed columns are combined into a transposed matrix.

+4
source share

Here's a snippet of a larger answer :

 % transposed(+A, ?B) iff matrix B is transposed matrix A transposed(A, B) :- transposed(A, [], B). transposed(M, X, X) :- empty(M), !. transposed(M, A, X) :- columns(M, Hs, Ts), transposed(Ts, [Hs|A], X). % empty(+A) iff A is empty list or a list of empty lists empty([[]|A]) :- empty(A). empty([]). % columns(+M, ?Hs, ?Ts) iff Hs is the first column % of matrix M and Ts is the rest of matrix M columns([[Rh|Rt]|Rs], [Rh|Hs], [Rt|Ts]) :- columns(Rs, Hs, Ts). columns([[]], [], []). columns([], [], []). 
+2
source share

Iterative approach:

 trans([H|R],[H1|R1]):-trans2([H|R],[H|R],[],[H1|R1],0),!. trans2([A|_],_,_,[],N):-length(A,N). trans2(M,[],H1,[H1|R1],N):-N1 is N+1, trans2(M,M,[],R1,N1). trans2(M,[H|R],L,[H1|R1],N):-nth0(N,H,X), append(L,[X],L1),trans2(M,R,L1,[H1|R1],N). 
0
source share

My solution with full names for a better understanding:

 % emptyMatrix(Line, EmptyMatrix) emptyMatrix([],[]). emptyMatrix([_|T1],[[]|T2]):-emptyMatrix(T1,T2). % only length of parameter 'Line' is interesting. It ignores its content. % appendElement(Element, InputList, OutputList) appendElement(E,[],[E]). appendElement(E,[H|T],[H|L]):-appendElement(E,T,L). % appendTransposed(NestedList, InputMatrix, OutputMatrix) appendTransposed([],[],[]). appendTransposed([X|T1],[],[[X]|T3]):-appendTransposed(T1,[],T3). appendTransposed([X|T1],[R|T2],[C|T3]):-appendElement(X,R,C),appendTransposed(T1,T2,T3). % transposeMatrix(InputMatrix, TransposedMatrix) transposeMatrix([L|M],T):-emptyMatrix(L,A),transpose([L|M],T,A). transpose([],T,T). transpose([L|M],T,A):-appendTransposed(L,A,B),transpose(M,T,B). 

A 'string' may be col or string.

The idea is to add elements to the empty matrix lists. (for example, all elements of the first row = first elements of all columns => all elements of the first i-th row = i-th elements of all cols)

It works on my machine, as this session protocol shows:

 5 ?- transposeMatrix([[1,2],[3,4]],T). T = [[1, 3], [2, 4]] ; false. 6 ?- transposeMatrix([[1],[2]],T). T = [[1, 2]] ; false. 7 ?- transposeMatrix([[1,2,3],[4,5,6]],T). T = [[1, 4], [2, 5], [3, 6]] ; false. 8 ?- transposeMatrix([[1]],T). T = [[1]] ; false. 
0
source share

simpler approach:

 trans(M, [P|T]):- first(M, P, A), trans(A, T). trans(Empty, []):- empty(Empty). empty([[]|T]):- empty(T). empty([[]]). first([[P|A]|R], [P|Ps], [A|As]):- first(R, Ps, As). first([], [], []). 

effective also

 [debug] 36 ?- time(trans([[1,2,3],[4,5,6],[7,8,9]],A)). % 21 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips) A = [[1,4,7],[2,5,8],[3,6,9]] ; % 12 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips) false. 
0
source share

Another approach:

 delete_one_list([], []). delete_one_list([[_|L]|LLs], [L|Ls]) :- delete_one_list(LLs, Ls). transpose_helper([], []). transpose_helper([[X|_]|Xs], [X|Ys]) :- transpose_helper(Xs, Ys). transpose([[]|_], []). transpose(List, [L|Ls]) :- transpose_helper(List, L), delete_one_list(List, NewList), transpose(NewList, Ls). 
0
source share

Another simple approach:

 transpose(M0, M) :- nonvar(M0), findall(L, maplist(nth1(_), M0, L), M). ?- transpose([[1,2,3],[4,5,6],[7,8,9]], M). M = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]. ' 
0
source share

All Articles