:-use_module(library(clpfd)).


% N is the dot product of lists V1 and V2.
dot(V1, V2, N) :- maplist(product,V1,V2,P), sumlist(P,N).
product(N1,N2,N3) :- N3 is N1*N2.

% Matrix multiplication with matrices represented
% as lists of lists. M3 is the product of M1 and M2
mmult(M1, M2, M3) :- transpose(M2,MT), maplist(mm_helper(MT), M1, M3).
mm_helper(M2, I1, M3) :- maplist(dot(I1), M2, M3).


suml([],[],[]).

suml(L1,L2,[E1 + E2|R2]):-
    L1 = [E1|T1],
    L2 = [E2|T2],
    suml(T1,T2,R2).



summ([],[],[]).
summ(M1,M2,[Lr|R2]):-
    M1 = [E1|T1],
    M2 = [E2|T2],
    suml(E1,E2,Lr),
    summ(T1,T2,R2).


flatten(List, Flattened):-
  flatten(List, [], Flattened).

flatten([], Flattened, Flattened).
flatten([Item|Tail], L, Flattened):-
  flatten(Item, L1, Flattened),
  flatten(Tail, L, L1).
flatten(Item, Flattened, [Item|Flattened]):-
  \+ is_list(Item).

touspositifs(X):-
    flatten(X,XF),
    tp(XF).

tp([]).
tp(X):-
    X = [E|L],
    E #> 0,
    tp(L).


sc3(X1):-
	 mmult(X1,X1,X2),
	 mmult(X1,X2,X3),
	 mmult(X1,X3,X4),
	 mmult(X1,X4,X5),
	 mmult(X1,X5,X6),
	 mmult(X1,X6,X7),
	 mmult(X1,X7,X8),
	 summ(X1,X2,S2),
	 summ(S2,X3,S3),
	 summ(S3,X4,S4),
	 summ(S4,X5,S5),
	 summ(S5,X6,S6),
	 summ(S6,X7,S7),
	 summ(S7,X8,S8),
	 touspositifs(S8).

bistoc(X):-
	 X=[[M0X0, M0X1, M0X2, M0X3, M0X4, M0X5, M0X6, M0X7], [M1X0, M1X1, M1X2, M1X3, M1X4, M1X5, M1X6, M1X7], [M2X0, M2X1, M2X2, M2X3, M2X4, M2X5, M2X6, M2X7], [M3X0, M3X1, M3X2, M3X3, M3X4, M3X5, M3X6, M3X7], [M4X0, M4X1, M4X2, M4X3, M4X4, M4X5, M4X6, M4X7], [M5X0, M5X1, M5X2, M5X3, M5X4, M5X5, M5X6, M5X7], [M6X0, M6X1, M6X2, M6X3, M6X4, M6X5, M6X6, M6X7], [M7X0, M7X1, M7X2, M7X3, M7X4, M7X5, M7X6, M7X7]],
	 M0X0 in 0..3,
	 M0X1 in 0..1,
	 M0X2 in 0..1,
	 M0X3 is 0 ,
	 M0X4 in 0..1,
	 M0X5 is 0 ,
	 M0X6 is 0 ,
	 M0X7 is 0 ,
	 M1X0 in 0..1,
	 M1X1 in 0..3,
	 M1X2 is 0 ,
	 M1X3 in 0..1,
	 M1X4 is 0 ,
	 M1X5 in 0..1,
	 M1X6 is 0 ,
	 M1X7 is 0 ,
	 M2X0 in 0..1,
	 M2X1 is 0 ,
	 M2X2 in 0..3,
	 M2X3 in 0..1,
	 M2X4 is 0 ,
	 M2X5 is 0 ,
	 M2X6 in 0..1,
	 M2X7 is 0 ,
	 M3X0 is 0 ,
	 M3X1 in 0..1,
	 M3X2 in 0..1,
	 M3X3 in 0..3,
	 M3X4 is 0 ,
	 M3X5 is 0 ,
	 M3X6 is 0 ,
	 M3X7 in 0..1,
	 M4X0 in 0..1,
	 M4X1 is 0 ,
	 M4X2 is 0 ,
	 M4X3 is 0 ,
	 M4X4 in 0..3,
	 M4X5 in 0..1,
	 M4X6 in 0..1,
	 M4X7 is 0 ,
	 M5X0 is 0 ,
	 M5X1 in 0..1,
	 M5X2 is 0 ,
	 M5X3 is 0 ,
	 M5X4 in 0..1,
	 M5X5 in 0..3,
	 M5X6 is 0 ,
	 M5X7 in 0..1,
	 M6X0 is 0 ,
	 M6X1 is 0 ,
	 M6X2 in 0..1,
	 M6X3 is 0 ,
	 M6X4 in 0..1,
	 M6X5 is 0 ,
	 M6X6 in 0..3,
	 M6X7 in 0..1,
	 M7X0 is 0 ,
	 M7X1 is 0 ,
	 M7X2 is 0 ,
	 M7X3 in 0..1,
	 M7X4 is 0 ,
	 M7X5 in 0..1,
	 M7X6 in 0..1,
	 M7X7 in 0..3,
	 M0X0+ M0X1+ M0X2+ M0X3+ M0X4+ M0X5+ M0X6+ M0X7 #=3 ,
	 M1X0+ M1X1+ M1X2+ M1X3+ M1X4+ M1X5+ M1X6+ M1X7 #=3 ,
	 M2X0+ M2X1+ M2X2+ M2X3+ M2X4+ M2X5+ M2X6+ M2X7 #=3 ,
	 M3X0+ M3X1+ M3X2+ M3X3+ M3X4+ M3X5+ M3X6+ M3X7 #=3 ,
	 M4X0+ M4X1+ M4X2+ M4X3+ M4X4+ M4X5+ M4X6+ M4X7 #=3 ,
	 M5X0+ M5X1+ M5X2+ M5X3+ M5X4+ M5X5+ M5X6+ M5X7 #=3 ,
	 M6X0+ M6X1+ M6X2+ M6X3+ M6X4+ M6X5+ M6X6+ M6X7 #=3 ,
	 M7X0+ M7X1+ M7X2+ M7X3+ M7X4+ M7X5+ M7X6+ M7X7 #=3 ,
	 M0X0+ M0X1+ M0X2+ M0X3+ M0X4+ M0X5+ M0X6+ M0X7 #=3 ,
	 M0X0+ M1X0+ M2X0+ M3X0+ M4X0+ M5X0+ M6X0+ M7X0 #=3 ,
	 M1X0+ M1X1+ M1X2+ M1X3+ M1X4+ M1X5+ M1X6+ M1X7 #=3 ,
	 M0X1+ M1X1+ M2X1+ M3X1+ M4X1+ M5X1+ M6X1+ M7X1 #=3 ,
	 M2X0+ M2X1+ M2X2+ M2X3+ M2X4+ M2X5+ M2X6+ M2X7 #=3 ,
	 M0X2+ M1X2+ M2X2+ M3X2+ M4X2+ M5X2+ M6X2+ M7X2 #=3 ,
	 M3X0+ M3X1+ M3X2+ M3X3+ M3X4+ M3X5+ M3X6+ M3X7 #=3 ,
	 M0X3+ M1X3+ M2X3+ M3X3+ M4X3+ M5X3+ M6X3+ M7X3 #=3 ,
	 M4X0+ M4X1+ M4X2+ M4X3+ M4X4+ M4X5+ M4X6+ M4X7 #=3 ,
	 M0X4+ M1X4+ M2X4+ M3X4+ M4X4+ M5X4+ M6X4+ M7X4 #=3 ,
	 M5X0+ M5X1+ M5X2+ M5X3+ M5X4+ M5X5+ M5X6+ M5X7 #=3 ,
	 M0X5+ M1X5+ M2X5+ M3X5+ M4X5+ M5X5+ M6X5+ M7X5 #=3 ,
	 M6X0+ M6X1+ M6X2+ M6X3+ M6X4+ M6X5+ M6X6+ M6X7 #=3 ,
	 M0X6+ M1X6+ M2X6+ M3X6+ M4X6+ M5X6+ M6X6+ M7X6 #=3 ,
	 M7X0+ M7X1+ M7X2+ M7X3+ M7X4+ M7X5+ M7X6+ M7X7 #=3 ,
	 M0X7+ M1X7+ M2X7+ M3X7+ M4X7+ M5X7+ M6X7+ M7X7 #=3 ,
	 label([M0X0, M0X1, M0X2, M0X3, M0X4, M0X5, M0X6, M0X7, M1X0, M1X1, M1X2, M1X3, M1X4, M1X5, M1X6, M1X7, M2X0, M2X1, M2X2, M2X3, M2X4, M2X5, M2X6, M2X7, M3X0, M3X1, M3X2, M3X3, M3X4, M3X5, M3X6, M3X7, M4X0, M4X1, M4X2, M4X3, M4X4, M4X5, M4X6, M4X7, M5X0, M5X1, M5X2, M5X3, M5X4, M5X5, M5X6, M5X7, M6X0, M6X1, M6X2, M6X3, M6X4, M6X5, M6X6, M6X7, M7X0, M7X1, M7X2, M7X3, M7X4, M7X5, M7X6, M7X7]),
	 sc3(X), 
	 open('res3.txt',append,Stream),
	 write(Stream,X),
	 close(Stream).


    

display_m([]).
display_m([El|R]):-
    write(El),
    display_m(R).


solution(L):-
    get_time(T0),
    findall(X,bistoc(X),L),
    get_time(T1),
    DT is T1 - T0,
    write('but : '),writeln(DT),
    display_m(L).




