
symmetric3(M, M_l) :-
	M = [_,_,_], M_l = l(l(l([]))),
%	cti:{n(M) >= n(M_l)},
	symmetric(M, M_l).

symmetric(M, M_l) :-
	transpose(M, M, M_l, M_l).

% an improved transpose

transpose2(M, T) :-
	cti:{n(M) >= n(M_l)},
	cti:{n(T) >= n(T_l)},
	transpose2(M, T, M_l, T_l),
	cti:{n(M) = n(T)}.

transpose2([],[], [], []).
transpose2(M, T, M_l, T_l) :-
	M = [_|_], M_l = l(_),
	T = [_|_], T_l = l(_),
	transpose(M, T, M_l, T_l).

% Source: http://www.cs.kuleuven.ac.be/~dtai/prototypes/dppd/transpose.html
transpose(Xs,[], Xs_l, []) :-
	nullrows(Xs, Xs_l).
transpose(Xs,[Y|Ys], Xs_l, l(Ys_l)) :-
	makerow(Xs,Y,Zs, Xs_l, Y_l, Zs_l),
	transpose(Zs,Ys, Zs_l, Ys_l).

makerow([],[],[], [], [], []).
makerow([[X|Xs]|Ys],[X|Xs1],[Xs|Zs], l(Ys_l), l(Xs1_l), l(Zs_l)) :-
	makerow(Ys,Xs1,Zs, Ys_l, Xs1_l, Zs_l).

nullrows([], []).
nullrows([[]|Ns], l(Ns_l)) :-
	nullrows(Ns, Ns_l).


nullrowsx(X) :-
	cti:{n(M) > n(X)},
	nullrows(X).


n_n(N, M) :-
	nullrows(N,_),
	nullrows(M,_),
	N = M.