:-use_module(library(clpfd)). :-use_module(library(lists)). pf( Primary, Tertiary ) :- constrain(Primary,Tertiary,Energy), labeling([ff,minimize(Energy)],Tertiary), my_print(Energy,Tertiary). constrain(Primary,Tertiary,Energy) :- length(Primary,N), M is 2*N, length(Tertiary,M), domain(Tertiary,1,M), starting_point(Tertiary,N), avoid_self_loops(Tertiary), next_constraints(Tertiary), energy_constraint(Primary,Tertiary,Energy). starting_point(Tertiary,N) :- N1 is N + 1, Tertiary = [N,N,N,N1|_]. avoid_self_loops(Tertiary):- positions_to_integers(Tertiary, ListaInteri), all_different(ListaInteri). positions_to_integers([X,Y|R], [I|S]):- I #= X*100+Y, positions_to_integers(R,S). positions_to_integers([],[]). next_constraints([_,_]). next_constraints([X1,Y1,X2,Y2|C]) :- next(X1,Y1,X2,Y2), next_constraints([X2,Y2|C]). next(X1,Y1,X2,Y2):- domain([Dx,Dy],0,1), Dx #= abs(X1-X2), Dy #= abs(Y1-Y2), Dx + Dy #= 1. energy_constraint([_],_,0). energy_constraint([A,B|Primary],[XA,YA,XB,YB|Tertiary],E) :- energy_contribution_of_A(A,XA,YA,Primary,Tertiary,E1), energy_constraint([B|Primary],[XB,YB|Tertiary],E2), E #= E1 + E2. energy_contribution_of_A(_,_,_,[],[],0). energy_contribution_of_A(A,XA,YA,[B|Primary],[XB,YB|Tertiary],E):- energy(A,XA,YA,B,XB,YB,C), energy_contribution_of_A(A,XA,YA,Primary,Tertiary,E1), E #= E1 + C. energy(h,XA,YA,h,XB,YB,C) :- C in {0,-1}, DX #= abs(XA - XB), DY #= abs(YA - YB), 1 #= DX + DY #<=> C #= -1. energy(h,_,_,p,_,_,0). energy(p,_,_,h,_,_,0). energy(p,_,_,p,_,_,0). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% my_print(Energy,Tertiary) :- write('Energy: '),write(Energy),nl, myprint(0,Tertiary). myprint(4,[X,Y|Tertiary]) :- !, write('('),write(X),write(' , '),write(Y),write(')'),nl, myprint(0,Tertiary). myprint(N,[X,Y|Tertiary]) :- !, M is N + 1, write('('),write(X),write(' , '),write(Y),write(') ; '), myprint(M,Tertiary). myprint(_,_). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%