
% sudoku_cst
sudoku0(L):-
	length(L,9),
	cst_lg(L),
	cst_cl(L),
	cst_carre(L),
	enum0(L),
	disp(L). 
sudoku1(L):-
	length(L,9),
	cst_lg(L),
	cst_cl(L),
	cst_carre(L),
	enum1(L),
        disp(L).
  
cst_lg([L1|L]):-
	length(L1,9),
	fd_domain(L1,1,9),
	fd_all_different(L1),
	cst_lg(L).  
cst_lg([]).

cst_cl([[E1|L1],[E2|L2],[E3|L3],[E4|L4],[E5|L5],[E6|L6],[E7|L7],[E8|L8],[E9|L9]]):-
	fd_all_different([E1,E2,E3,E4,E5,E6,E7,E8,E9]),
	cst_cl([L1,L2,L3,L4,L5,L6,L7,L8,L9]).
cst_cl([[],[],[],[],[],[],[],[],[]]).
cst_carre([[E1,E2,E3|L1],[E4,E5,E6|L2],[E7,E8,E9|L3],
	[F1,F2,F3|L4],[F4,F5,F6|L5],[F7,F8,F9|L6],
	[G1,G2,G3|L7],[G4,G5,G6|L8],[G7,G8,G9|L9]]):-
	fd_all_different([E1,E2,E3,E4,E5,E6,E7,E8,E9]),
	fd_all_different([F1,F2,F3,F4,F5,F6,F7,F8,F9]),
	fd_all_different([G1,G2,G3,G4,G5,G6,G7,G8,G9]),
	cst_carre([L1,L2,L3,L4,L5,L6,L7,L8,L9]).
cst_carre([[],[],[],[],[],[],[],[],[]]).

enum0(Ls) :-
  flatten(Ls,L),
  fd_labelingff(L).

enum1(Ls) :-
  my_labeling(Ls).
  
my_labeling([]).
my_labeling([L|Ls]) :-
  fd_labelingff(L),
  my_labeling(Ls).

  
disp([]).
disp([L1|L]):- writelg(L1), nl, disp(L).

writelg([]).
writelg([E1,E2,E3|L]):- write(E1), write(' '), write(E2), write(' '), write(E3), write('   '), writelg(L).

test0:-
   L=[
     [2,A2,A3,  A4,A5,1,  A7,3,A9],
     [B1,3,B3,  B4,B5,B6,  B7,B8,B9],
     [C1,C2,4,  C4,3,C6,  C7,6,8],

     [D1,D2,D3,  D4,D5,D6,  D7,D8,4],
     [1,E2,E3,  2,E5,E6,  8,E8,E9],
     [F1,9,F3,  F4,F5,7,  F7,5,F9],

     [7,G2,5,  G4,G5,G6,  G7,G8,G9],
     [H1,H2,H3,  H4,4,H6,  9,H8,H9],
     [I1,I2,6,  I4,1,8,  4,I8,I9]
     ],
	sudoku0(L).
test1:-
   L=[
     [2,A2,A3,  A4,A5,1,  A7,3,A9],
     [B1,3,B3,  B4,B5,B6,  B7,B8,B9],
     [C1,C2,4,  C4,3,C6,  C7,6,8],

     [D1,D2,D3,  D4,D5,D6,  D7,D8,4],
     [1,E2,E3,  2,E5,E6,  8,E8,E9],
     [F1,9,F3,  F4,F5,7,  F7,5,F9],

     [7,G2,5,  G4,G5,G6,  G7,G8,G9],
     [H1,H2,H3,  H4,4,H6,  9,H8,H9],
     [I1,I2,6,  I4,1,8,  4,I8,I9]
     ],
	sudoku1(L).

sudoku2([
     A1,A2,A3,  A4,A5,A6,  A7,A8,A9,
     B1,B2,B3,  B4,B5,B6,  B7,B8,B9,
     C1,C2,C3,  C4,C5,C6,  C7,C8,C9,

     D1,D2,D3,  D4,D5,D6,  D7,D8,D9,
     E1,E2,E3,  E4,E5,E6,  E7,E8,E9,
     F1,F2,F3,  F4,F5,F6,  F7,F8,F9,

     G1,G2,G3,  G4,G5,G6,  G7,G8,G9,
     H1,H2,H3,  H4,H5,H6,  H7,H8,H9,
     I1,I2,I3,  I4,I5,I6,  I7,I8,I9],T) :-

   fd_domain([
     A1,A2,A3,  A4,A5,A6,  A7,A8,A9,
     B1,B2,B3,  B4,B5,B6,  B7,B8,B9,
     C1,C2,C3,  C4,C5,C6,  C7,C8,C9,

     D1,D2,D3,  D4,D5,D6,  D7,D8,D9,
     E1,E2,E3,  E4,E5,E6,  E7,E8,E9,
     F1,F2,F3,  F4,F5,F6,  F7,F8,F9,

     G1,G2,G3,  G4,G5,G6,  G7,G8,G9,
     H1,H2,H3,  H4,H5,H6,  H7,H8,H9,
     I1,I2,I3,  I4,I5,I6,  I7,I8,I9],1,9),
  
 % Contraintes all_diff pour les lignes
   fd_all_different([A1,A2,A3,  A4,A5,A6,  A7,A8,A9]),
   fd_all_different([B1,B2,B3,  B4,B5,B6,  B7,B8,B9]),
   fd_all_different([C1,C2,C3,  C4,C5,C6,  C7,C8,C9]),
   fd_all_different([D1,D2,D3,  D4,D5,D6,  D7,D8,D9]),
   fd_all_different([E1,E2,E3,  E4,E5,E6,  E7,E8,E9]),
   fd_all_different([F1,F2,F3,  F4,F5,F6,  F7,F8,F9]),
   fd_all_different([G1,G2,G3,  G4,G5,G6,  G7,G8,G9]),
   fd_all_different([H1,H2,H3,  H4,H5,H6,  H7,H8,H9]),
   fd_all_different([I1,I2,I3,  I4,I5,I6,  I7,I8,I9]),
 
 % Contraintes all_diff pour les colonnes
   fd_all_different([A1,B1,C1,D1,E1,F1,G1,H1,I1]),
   fd_all_different([A2,B2,C2,D2,E2,F2,G2,H2,I2]),
   fd_all_different([A3,B3,C3,D3,E3,F3,G3,H3,I3]),
   fd_all_different([A4,B4,C4,D4,E4,F4,G4,H4,I4]),
   fd_all_different([A5,B5,C5,D5,E5,F5,G5,H5,I5]),
   fd_all_different([A6,B6,C6,D6,E6,F6,G6,H6,I6]),
   fd_all_different([A7,B7,C7,D7,E7,F7,G7,H7,I7]),
   fd_all_different([A8,B8,C8,D8,E8,F8,G8,H8,I8]),
   fd_all_different([A9,B9,C9,D9,E9,F9,G9,H9,I9]),

 % Contraintes all_diff pour les chacun des carrés
  fd_all_different([A1,A2,A3, B1,B2,B3, C1,C2,C3]),
  fd_all_different([A4,A5,A6, B4,B5,B6, C4,C5,C6]),
  fd_all_different([A7,A8,A9, B7,B8,B9, C7,C8,C9]),
  fd_all_different([D1,D2,D3, E1,E2,E3, F1,F2,F3]), 
  fd_all_different([D4,D5,D6, E4,E5,E6, F4,F5,F6]),
  fd_all_different([D7,D8,D9, E7,E8,E9, F7,F8,F9]), 
  fd_all_different([G1,G2,G3, H1,H2,H3, I1,I2,I3]),
  fd_all_different([G4,G5,G6, H4,H5,H6, I4,I5,I6]),
  fd_all_different([G7,G8,G9, H7,H8,H9, I7,I8,I9]),

 % Enumeration
  fd_labelingff([
     A1,A2,A3,  A4,A5,A6,  A7,A8,A9,
     B1,B2,B3,  B4,B5,B6,  B7,B8,B9,
     C1,C2,C3,  C4,C5,C6,  C7,C8,C9,

     D1,D2,D3,  D4,D5,D6,  D7,D8,D9,
     E1,E2,E3,  E4,E5,E6,  E7,E8,E9,
     F1,F2,F3,  F4,F5,F6,  F7,F8,F9,

     G1,G2,G3,  G4,G5,G6,  G7,G8,G9,
     H1,H2,H3,  H4,H5,H6,  H7,H8,H9,
     I1,I2,I3,  I4,I5,I6,  I7,I8,I9]),
cpu_time(T),
% Ecriture grille
     nl,
     write([A1,A2,A3,  A4,A5,A6,  A7,A8,A9]),nl,
          write([B1,B2,B3,  B4,B5,B6,  B7,B8,B9]),nl,
          write([C1,C2,C3,  C4,C5,C6,  C7,C8,C9]),nl,
nl,
          write([D1,D2,D3,  D4,D5,D6,  D7,D8,D9]),nl,
          write([E1,E2,E3,  E4,E5,E6,  E7,E8,E9]),nl,
          write([F1,F2,F3,  F4,F5,F6,  F7,F8,F9]),nl,
nl,
          write([G1,G2,G3,  G4,G5,G6,  G7,G8,G9]),nl,
          write([H1,H2,H3,  H4,H5,H6,  H7,H8,H9]),nl,
          write([I1,I2,I3,  I4,I5,I6,  I7,I8,I9]),nl .


/* Tests
[1] ?-sudoku1(L,P).

L = [
1,2,3,  4,5,6,  7,8,9,
4,5,6,  8,9,7,  1,2,3,
7,8,9,  1,2,3,  4,5,6,

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

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

sudoku([
     A1,A2,A3,  A4,A5,A6,  A7,A8,A9,
     B1,B2,B3,  B4,B5,B6,  B7,B8,B9,
     C1,C2,C3,  C4,C5,C6,  C7,C8,C9,

     D1,D2,D3,  D4,D5,D6,  D7,D8,D9,
     E1,E2,E3,  E4,E5,E6,  E7,E8,E9,
     F1,F2,F3,  F4,F5,F6,  F7,F8,F9,

     G1,G2,G3,  G4,G5,G6,  G7,G8,G9,
     H1,H2,H3,  H4,H5,H6,  H7,H8,H9,
     I1,I2,I3,  I4,I5,I6,  I7,I8,I9],T).
sudoku([
     A1,A2,A3,  A4,A5,A6,  A7,A8,A9,
     B1,B2,B3,  B4,B5,B6,  B7,B8,B9,
     C1,C2,C3,  C4,C5,C6,  C7,C8,C9,

     D1,D2,D3,  D4,D5,D6,  D7,D8,D9,
     E1,E2,E3,  E4,E5,E6,  E7,E8,E9,
     F1,F2,F3,  F4,F5,F6,  F7,F8,F9,

     G1,G2,G3,  G4,G5,G6,  G7,G8,G9,
     H1,H2,H3,  H4,H5,H6,  H7,H8,H9,
     I1,I2,I3,  I4,I5,I6,  I7,I8,I9],T) .
sudoku([
     8,7,5,      2,9,6,     3,1,4,
     6,1,9,      3,4,7,     2,8,5,
     4, 2,3,     5,1,8,     7,6, 9,

     5,3,6,     8,7, 1,    4,9,2,
     7,4, 1,    9,E5,2,     E7,5, 8,
     F1,8, 2,   4, 6, 5,   F7,F8,F9,

     1,G2,G3,   G4,G5,G6,  5,G8,7,
     H1,H2,7,   1,H5,H6,   H7,H8,6,
     2,I2,8,    I4,I5,I6,  9,I8,I9],T).
  


sudoku([
     2,A2,A3,  A4,A5,1,  A7,3,A9,
     B1,3,B3,  B4,B5,B6,  B7,B8,B9,
     C1,C2,4,  C4,3,C6,  C7,6,8,

     D1,D2,D3,  D4,D5,D6,  D7,D8,4,
     1,E2,E3,  2,E5,E6,  8,E8,E9,
     F1,9,F3,  F4,F5,7,  F7,5,F9,

     7,G2,5,  G4,G5,G6,  G7,G8,G9,
     H1,H2,H3,  H4,4,H6,  9,H8,H9,
     I1,I2,6,  I4,1,8,  4,I8,I9],T)


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

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

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

T= 4001

*/
