2

Let's say we have a matrix, represented by a list of lists, e.g.: [[1,2,3],[4,5,6],[7,8,9]].

How do I write a predicate that gets [[1,4][4,7][2,5][5,8][3,6][6,9]]?

Thank you in advance!

repeat
  • 18,496
  • 4
  • 54
  • 166
Derrick Park
  • 67
  • 1
  • 4

2 Answers2

3

In the following logically-pure Prolog code I use definite clause grammars :

matrix_adjacentPairs([]) -->
   [].
matrix_adjacentPairs([Xs|Xss]) -->
   list_adjacentPairs(Xs),
   matrix_adjacentPairs(Xss).

list_adjacentPairs([]) -->
   [].
list_adjacentPairs([X|Xs]) -->
   list_adjacentPairs_(Xs,X).                 % use "lagging"

list_adjacentPairs_([],_) -->
   [].
list_adjacentPairs_([X1|Xs],X0) -->
   [[X0,X1]],
   list_adjacentPairs_(Xs,X1).

Here is the query that the OP stated:

:- use_module(library(clpfd)).                % SWI-Prolog transpose/2
:- use_module(library(lists)).                % SICStus Prolog transpose/2

?- transpose([[1,2,3],[4,5,6],[7,8,9]],Tss),
   phrase(matrix_adjacentPairs(Tss),Pss).
Tss = [[1,4,7],[2,5,8],[3,6,9]],
Pss = [[1,4],[4,7],[2,5],[5,8],[3,6],[6,9]].

Edit 2015-04-26

Using meta-predicates foldl/4 and foldadjl/4 with library(lambda), it all boils down to:

:- use_module(library(apply)).
:- use_module(library(lambda)).

?- transpose([[1,2,3],[4,5,6],[7,8,9]],Tss),
   phrase(foldl(foldadjl(\X^Y^[[X,Y]|Xs]^Xs^true),Tss),Pss).
Tss = [[1,4,7],[2,5,8],[3,6,9]],
Pss = [[1,4],[4,7],[2,5],[5,8],[3,6],[6,9]].
Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166
1

I don't know if transpose/2 exists in SICStus Prolog, in SWI-Prolog transpose/2 transposes a matrix, e.g.:

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

Now, here is what you can do in SWI-Prolog:

:- use_module(library(clpfd)).

combis(L, R) :-
    transpose(L, L1),
    create_lst_combis(L1, R).

create_lst_combis([], []).   
create_lst_combis([H | T], R) :-
    create_lst_combis(T, R1),
    create_combis(H, CH),
    append(CH, R1, R).    

create_combis([H , T], [[H, T]]) :- !.  
create_combis([H | T], R) :-
    maplist(create_one_combi(H), T, T1),
    create_combis(T, R1),
    append(T1, R1, R).

create_one_combi(H, V, [H, V]).
repeat
  • 18,496
  • 4
  • 54
  • 166
joel76
  • 5,565
  • 1
  • 18
  • 22