% Generatore di problemi random. % Dati N, D, P e Q genera un problema. % NOTA: Distrugge anche il problema eventualmente presente. :- dynamic(constraint/2). :- dynamic(consistent/4). :- dynamic(function/1). :- dynamic(repeatable/0). :- dynamic(weight/1). rep(X) :- var(X),!, (repeatable -> X=true ; X=false). rep(true) :- assert(repeatable). rep(false) :- retract_all(repeatable). % Questo per ora genera 2 funzioni, andrebbe modificato (modificando in qualche modo % l'interfaccia) se si vuole un caso + generale generate(N,D,P,Q) :- (repeatable -> seed(3), write(rep) ; true), writeln(gen), destroy_problem, unary_constraints(N,D), build_constraint_matrix(N,P), % save_constraint_matrix, build_data_matrix(N,D,Q), generate_functions(N,2),!, % questo cut e' solo per motivi di efficienza, non cambia la semantica % save_data_matrix. (repeatable -> save_problem ; true). build_index_list(N,N,[N]) :- !. build_index_list(N1,N2,[N1|T]) :- Ntemp is N1+1, build_index_list(Ntemp,N2,T). build_constraint_matrix(N,P) :- N1 is N-1, build_index_list(1,N1,Li), % create_const_matrix(N), put_random(N,P,Li). %create_const_matrix(N) :- % make_local_array(const(N,N),byte). put_random(_,_,[]):-!. put_random(N,P,[I|T]) :- I1 is I+1, build_index_list(I1,N,L), put_random_line(I,P,L), put_random(N,P,T). put_random_line(_,_,[]) :-!. put_random_line(I,P,[J|T]) :- frandom(X), (X
% setval(const(I,J),1), setval(const(J,I),1),
assert(constraint(I,J))
; % setval(const(I,J),0), setval(const(J,I),0)
true),
put_random_line(I,P,T).
build_data_matrix(N,D,Q) :-
findall([I,J], constraint(I,J), L),
insert_constraints(L,N,D,Q).
insert_constraints([],_,_,_) :-!.
insert_constraints([[I,J]|T],N,D,Q) :-
D1 is D-2,
build_index_list(0,D1,Li),
for_x(D,Q,Li,I,J),
insert_constraints(T,N,D,Q).
for_x(_,_,[],_,_) :- !.
for_x(D,Q,[X|T],I,J) :-
I1 is X+1,
% assert(consistent(I,J,X,[X])),
D1 is D-1,
build_index_list(I1,D1,Ly),
for_y(D,Q,Ly,I,J,X),
for_x(D,Q,T,I,J).
for_y(_,_,[],_,_,_) :- !.
for_y(D,Q,[Y|T],I,J,X) :-
frandom(Rand),
(Rand
add_element(I,J,X,Y),
add_element(J,I,Y,X)
; true),
for_y(D,Q,T,I,J,X).
add_element(I,J,X,Y) :-
( consistent(I,J,X,L)
-> (memberchk(Y,L) -> true
; L1 = [Y|L],
retract(consistent(I,J,X,L)),
assert(consistent(I,J,X,L1)))
; assert(consistent(I,J,X,[Y]))),!.
% Mette i vincoli unari (ogni elemento e' consistente con se stesso)
unary_constraints(N,D) :-
build_index_list(1,N,Ln),
for_n(Ln,D).
for_n([],_) :- !.
for_n([X|T],D) :-
D1 is D-1,
build_index_list(0,D1,Ld),
for_d(Ld,X), for_n(T,D).
for_d([],_) :- !.
for_d([D|T],X) :-
assert(consistent(X,X,D,[D])), for_d(T,X).
destroy_problem :-
retract_all(constraint(_,_)),
retract_all(consistent(_,_,_,_)),
retract_all(function(_)).
%%%%%%%%%%%%%%%%% Generazione delle funzioni obiettivo %%%%%%%%%%%%%%%%%%%%%%%%
% Genero una lista di pesi casuale e considero la funzione lineare associata.
%generate_weights(N,NF) :-
% (for(I,1,NF), foreach( do
% gen_weights(N,I,
% INIZIO GENERAZIONE FUNZIONI OBIETTIVO OBSOLETA %%%%%%%%%%%%%%%%%%%
% Genera una funzione di N variabili che e` una somma di coeffic1enti +1, 0, -1
% delle N variabili
% Vabbe`, per ora (semplice) non genera lo zero: solo +1 o -1
generate_function(N) :-
gen_fun(N,F,_),
assert(function(F)).
% Genera la funzione F di N variabili; il 3 parametro restituisce anche N
% nel formato s(s(s(0)))
gen_fun(N,F,C) :-
N1 is N-1, gen_fun1(N1,F,C).
gen_fun1(0,0,0):- !.
gen_fun1(N,F,s(C)) :-
frandom(R),
N1 is N-1,
gen_fun1(N1,F1,C),
( R<0.5
-> F = F1 + s(C)
; F = F1 - s(C) ).
% Genera NF funzioni di N variabili e le asserisce.
generate_functions(_,0).
generate_functions(N,NF) :-
generate_function(N),
NF1 is NF-1,
generate_functions(N,NF1).
get_functions(FList) :-
findall(F,function(F),FList).
save_problem :-
open("problema.pl",write,file),
findall(constraint(A,B),constraint(A,B),L),
save_list(L,file),
findall(consistent(A,B,C,D),consistent(A,B,C,D),L1),
save_list(L1,file),
findall(function(X),function(X),L2),
save_list(L2,file),
close(file).
save_list([],_).
save_list([H|T],F) :-
writeln(F,H),
save_list(T,F).