:- use_module(library(clpb)). :- use_module(library(lists)). % crea 4 matrici NxN di variabili booleane % S per stench - B per breeze % W per wumpus - P per pit init_constraints(S,B,W,P,N):- matrix(N,S), matrix(N,B), matrix(N,W), matrix(N,P), matrix_to_list(W,WL), % esiste esattamente un wumpus sat(card([1],WL)), constrain(S,W,N), constrain(B,P,N). % M è una matrice NxN, rappresentata come % una lista di N liste lunghe N matrix(N,M):- make_matrix(N,N,M). make_matrix(N,0,[]):-!. make_matrix(N,NN,[R|M]):- N1 is NN-1, make_matrix(N,N1,M), length(R,N). matrix_to_list([],[]). matrix_to_list([R|M], L) :- matrix_to_list(M,L1), append(R,L1,L). % costruisce i vincoli che legano M1 e M2 % dove M1 è Stench o Breeze e M2 è, rispettivamente, % o Wumpus o Pit. % N è la dimensione della griglia. constrain(M1,M2,N):- constrain_col(M1,M2,N,N). constrain_col(_,_,0,_). constrain_col(M1,M2,I,N):- constrain_row(M1,M2,I,N,N), I1 is I-1, constrain_col(M1,M2,I1,N). constrain_row(_,_,_,0,_). constrain_row(M1,M2,I,J,N):- constrain_elem(M1,M2,I,J,N), J1 is J-1, constrain_row(M1,M2,I,J1,N). constrain_elem(M1,M2,I,J,N):- adjlist(I,J,N,L), mk_constr(M1,M2,I,J,L). % Considera separatamente i casi di 2, 3 o 4 adiacenti mk_constr(M1,M2,I,J,[[I1,J1],[I2,J2]]):- elem(M1,I,J,M1IJ), elem(M2,I1,J1,M2I1J1), elem(M2,I2,J2,M2I2J2), sat(M1IJ =< (M2I1J1 + M2I2J2)), sat(~M1IJ =< ~M2I1J1), sat(~M1IJ =< ~M2I2J2). mk_constr(M1,M2,I,J,[[I1,J1],[I2,J2],[I3,J3]]):- elem(M1,I,J,M1IJ), elem(M2,I1,J1,M2I1J1), elem(M2,I2,J2,M2I2J2), elem(M2,I3,J3,M2I3J3), sat(M1IJ =< (M2I1J1 + M2I2J2 + M2I3J3)), sat(~M1IJ =< ~M2I1J1), sat(~M1IJ =< ~M2I2J2), sat(~M1IJ =< ~M2I3J3). mk_constr(M1,M2,I,J,[[I1,J1],[I2,J2],[I3,J3],[I4,J4]]):- elem(M1,I,J,M1IJ), elem(M2,I1,J1,M2I1J1), elem(M2,I2,J2,M2I2J2), elem(M2,I3,J3,M2I3J3), elem(M2,I4,J4,M2I4J4), sat(M1IJ =< (M2I1J1 + M2I2J2 + M2I3J3 + M2I4J4)), sat(~M1IJ =< ~M2I1J1), sat(~M1IJ =< ~M2I2J2), sat(~M1IJ =< ~M2I3J3), sat(~M1IJ =< ~M2I4J4). % X è l'elemento (I,J) della matrice M elem(M,I,J,X):- nth(I,M,C), nth(J,C,X). % L è la lista degli adiacenti a (I,J) in una % matrice NxN adjlist(I,J,N,L):- add(e,I,J,N,[],L1), add(n,I,J,N,L1,L2), add(w,I,J,N,L2,L3), add(s,I,J,N,L3,L). add(e,I,J,N,L,[[I1,J]|L]):- I < N, I1 is I+1. add(e,I,J,N,L,L):- I = N. add(n,I,J,N,L,[[I,J1]|L]):- J < N, J1 is J+1. add(n,I,J,N,L,L):- J = N. add(w,I,J,N,L,[[I1,J]|L]):- I > 1, I1 is I-1. add(w,I,J,N,L,L):- I = 1. add(s,I,J,N,L,[[I,J1]|L]):- J > 1, J1 is J-1. add(s,I,J,N,L,L):- J = 1.