# Complete generativity over 2D lists

I’m using: SWI-Prolog version threaded, 64 bits, version 8.4.2

I’m attempting to implement matrices as 2D lists in pure prolog. I want the code to generate a complete set of solutions, in that all possible 2D matrix shapes should be generated/accepted.

But what I’m getting is that I’m able to backtrack on only one of 2 dimensions at a time.

I somewhat understand the trick using `length/2`, but I’m unable to extend it to 2 dimensions. I tried using mutually recursive predicates but failed, although it seemed a like a good idea?

My code looks like this, queried as `matrix_2D(M).` :

``````:- use_module(library(lists)).
% a vector is a flat list
vector([]).
vector([H|T]) :-
var(H),!,
vector(T).
vector([H|T]) :-
atomic(H),dif(H,[]),
vector(T).

% a matrix is a list of vectors
matrix_2D([H|T]) :-
length([H|T],_), %change to length(H,_) for the other dimension
matrix_2D(T,H).
matrix_2D([],V) :-
vector(V).
matrix_2D([Th|Tt],H) :-
same_length(Th,H),
vector(H),
matrix_2D(Tt,Th).
``````

I don’t understand what length([H|T],_) should do… seems totally useless, so I’m waiting for someone to explain it better.
(edit: never mind, it occurred to me that it will work on backtracking…)
Meantime, if your problem is to access columns (not sure either…), an useful pattern could be the use of library(clpfd) transpose/2.

Yes, sorry I should have shown my code with `length(H,_)`, because you are right that `length([H|T],_)` isn’t doing anything here, and is equivalent to commenting `length(H,_)` out.

Actually, I think I can manage with `matrix_2D(M),transpose(M,T).` which indeed generates what I want.

You might be interested this from Jan W. personal GitHub repositories

A prototype SWI-Prolog matrix library

or the SWI-Prolog packs for matrices

or even using one of the R interfaces in the SWI-Prolog packs.

1 Like