107 lines
3.2 KiB
Prolog
107 lines
3.2 KiB
Prolog
:- include('avl.pl'). % predicats pour gerer des arbres bin. de recherche
|
|
:- include('taquin.pl'). % predicats definissant le systeme a etudier
|
|
|
|
main :-
|
|
% Calcul de H pour la situation de départ
|
|
initial_state(U0),
|
|
heuristique(U0, H0),
|
|
|
|
% initialisations Pf, Pu et Q
|
|
insert([ [H0, H0, 0], U0 ], nil, Pf),
|
|
insert([U0, [H0, H0, 0], nil, nil], nil, Pu),
|
|
empty(Q),
|
|
!,
|
|
|
|
% lancement de Aetoile
|
|
aetoile(Pf, Pu, Q).
|
|
|
|
%*******************************************************************************
|
|
|
|
afficher_solution(_, nil).
|
|
|
|
afficher_solution(Q, S) :-
|
|
belongs([S, [_,_,G], Pere, Action], Q),
|
|
!,
|
|
write_state(S),
|
|
print(Action),
|
|
print(' ('),
|
|
print(G),
|
|
print(')'),
|
|
nl, nl,
|
|
afficher_solution(Q, Pere).
|
|
|
|
%*******************************************************************************
|
|
|
|
% Cas arbres vides -> plus d'état à développer -> pas de solution
|
|
aetoile(Pf, _, _) :-
|
|
empty(Pf),
|
|
!,
|
|
print('Pas de solution : l\'état final n\'est pas atteignable !\n').
|
|
|
|
% Cas état final -> solution trouvée
|
|
aetoile(Pf, Pu, Q) :-
|
|
suppress_min([[F, H, G], Sf], Pf, _),
|
|
final_state(Sf),
|
|
!,
|
|
suppress([Sf, [F, H, G], Pere, A], Pu, _),
|
|
insert([Sf, [F, H, G], Pere, A], Q, Q1),
|
|
print('Solution trouvée :\n'),
|
|
afficher_solution(Q1, Sf).
|
|
|
|
aetoile(Pf, Pu, Q) :-
|
|
suppress_min([[F, H, G], S], Pf, Pf1),
|
|
suppress([S, [F, H, G], Pere, A], Pu, Pu1),
|
|
expand(S, G, Successors),
|
|
loop_successors(Successors, S, Pf1, Pu1, Q, Pf2, Pu2),
|
|
insert([S, [F, H, G], Pere, A], Q, Q1),
|
|
aetoile(Pf2, Pu2, Q1).
|
|
|
|
%*******************************************************************************
|
|
|
|
expand(S, Gs, Successors) :-
|
|
findall([Successor, [F, H, G], Action], (
|
|
rule(Action, Cost, S, Successor),
|
|
G is Gs + Cost,
|
|
heuristique(Successor, H),
|
|
F is G + H
|
|
), Successors).
|
|
|
|
%*******************************************************************************
|
|
|
|
% Cas pas de successseurs
|
|
loop_successors([], _,Pf, Pu, _, Pf, Pu) :- !.
|
|
|
|
% Cas successeur déjà traité : on ignore
|
|
loop_successors([[S,_,_] | Rest], Pere, Pf, Pu, Q, Pf_new, Pu_new) :-
|
|
belongs([S,_,_,_], Q),
|
|
%!,
|
|
loop_successors(Rest, Pere, Pf, Pu, Q, Pf_new, Pu_new),
|
|
!.
|
|
|
|
% Cas successeur déjà connu : on met à jour le coût
|
|
loop_successors([[S, [F, H, G], Action] | Rest], Pere, Pf, Pu, Q, Pf_new, Pu_new) :-
|
|
belongs([S, [F_old,_,_], _, _], Pu),
|
|
%!,
|
|
update_trees(S, H, [F, G, Pere, Action], F_old, Pf, Pf1, Pu, Pu1),
|
|
loop_successors(Rest, Pere, Pf1, Pu1, Q, Pf_new, Pu_new),
|
|
!.
|
|
|
|
% Cas successeur inconnu : on l'ajoute à P
|
|
loop_successors([[S, [F, H, G], Action] | Rest], Pere, Pf, Pu, Q, Pf_new, Pu_new) :-
|
|
insert([S, [F, H, G], Pere, Action], Pu, Pu1),
|
|
insert([[F, H, G], S], Pf, Pf1),
|
|
loop_successors(Rest, Pere, Pf1, Pu1, Q, Pf_new, Pu_new).
|
|
|
|
%*******************************************************************************
|
|
|
|
% Mise à jour des coûts et des parents seulement si plus faible
|
|
update_trees(S, H, [F, G, Pere, Action], F_old, Pf, Pf2, Pu, Pu2) :-
|
|
(F_old is min(F, F_old) ->
|
|
Pf = Pf2,
|
|
Pu = Pu2
|
|
;
|
|
suppress([S,_,_,_], Pu, Pu1),
|
|
insert([S, [F, H, G], Pere, Action], Pu1, Pu2),
|
|
suppress([[F_old,_,_], S], Pf, Pf1),
|
|
insert([[F, H, G], S], Pf1, Pf2)
|
|
).
|