%make constraints for 2 lists to be equal element by element
equal([], []).
equal([X|Xs], [Y|Ys]):-
	X #= Y, 
	equal(Xs, Ys).

%makes constraints guaranteeing that each row of a matrix is made of distinct elements.
all_rows_different([]).
all_rows_different([M|Matrix]):-
	alldifferent(M), 
	all_rows_different(Matrix).

%Matrix[Row,Column] = X
get_matrix_ij(Matrix, Row, Column, X):-
	nth(Row, Matrix, List),
	nth(Column, List, X).

%T is the transposition of Matrice
transpose(Matrice, T):-
	Matrice = [M | _],
	length(M, Len),
	length(Acc, Len),
	transpose(Matrice, T, Acc),
	!.
transpose([], T, T).
transpose([Row|Matrice], T, Acc):-
	add_column(Acc, Row, Acc1), 
	transpose(Matrice, T, Acc1).

%executes Goal with each element of list L
foreach([], _).
foreach([X|L], Goal):-
	call(Goal, X), 
	foreach(L, Goal).

%useful for nested foreach.
foreach([], _, _).
foreach([X|L], Goal, Y):-
	call(Goal, Y, X), 
	foreach(L, Goal, Y).

