% ILP-503 (Prof. Dr. Silvio do Lago Pereira)

:- discontiguous raiz/2.
:- discontiguous sucessor/3.

% ---------------------------------------------------------------------
% EXEMPLO 1
% ---------------------------------------------------------------------

expande(Folha, Expandidos, Sucessores) :-
   findall(Sucessor,
           sucessor(Folha, Expandidos, Sucessor),
           Sucessores).

estende(Chave, Folhas, Sucessores, Fronteira) :-
   append(Folhas, Sucessores, Lista),
   sort(Chave, =<, Lista, Fronteira).

% ---------------------------------------------------------------------
% EXEMPLO 5
% ---------------------------------------------------------------------

raiz(3, folha(Estado,[],0)) :-
   inicial(Estado).

sucessor(folha(Estado,Ações,G1),
         Expandidos,
         folha(Sucessor,[Ação|Ações],G2)) :-
   ação(Ação, Estado, Sucessor, G),
   not(member(Sucessor, Expandidos)),
   G2 is G1 + G.

% ---------------------------------------------------------------------
% EXEMPLO 6
% ---------------------------------------------------------------------

bc :-
   raiz(3, Folha),
   bc([Folha], [], Plano, Custo),
   format('Plano: ~w\n', [Plano]),
   format('Custo: ~1f\n', [Custo]).

bc([Folha|Folhas], Expandidos, Plano, Custo) :-
   arg(1, Folha, Estado),
   (   meta(Estado)
   ->  arg(2, Folha, Ações),
       arg(3, Folha, Custo),
       reverse(Ações, Plano)
   ;   expande(Folha, Expandidos, Sucessores),
       estende(3, Folhas, Sucessores, Fronteira),
       bc(Fronteira, [Estado|Expandidos], Plano, Custo) ).

% ---------------------------------------------------------------------
% EXEMPLO 10
% ---------------------------------------------------------------------

raiz(4, folha(Estado,[],0,0)) :-
   inicial(Estado).

sucessor(folha(Estado,Ações,G1,_),
         Expandidos,
         folha(Sucessor,[Ação|Ações],G2,H)) :-
   ação(Ação, Estado, Sucessor, G),
   not(member(Sucessor, Expandidos)),
   G2 is G1 + G,
   h(Sucessor, H).

% ---------------------------------------------------------------------
% EXEMPLO 11
% ---------------------------------------------------------------------

be :-
   raiz(4, Folha),
   be([Folha], [], Plano, Custo),
   format('Plano: ~w\n', [Plano]),
   format('Custo: ~1f\n', [Custo]).

be([Folha|Folhas], Expandidos, Plano, Custo) :-
    arg(1, Folha, Estado),
    (   meta(Estado)
    ->  arg(2, Folha, Ações),
        arg(3, Folha, Custo),
        reverse(Ações, Plano)
    ;   expande(Folha, Expandidos, Sucessores),
        estende(4, Folhas, Sucessores, Fronteira),
        be(Fronteira, [Estado|Expandidos], Plano, Custo) ).

% ---------------------------------------------------------------------
% EXEMPLO 13
% ---------------------------------------------------------------------

raiz(5, folha(Estado,[],0,0,0)) :-
   inicial(Estado).

sucessor(folha(Estado,Ações,G1,_,_),
         Expandidos,
         folha(Sucessor,[Ação|Ações],G2,H,F)) :-
   ação(Ação, Estado, Sucessor, G),
   not(member(Sucessor, Expandidos)),
   G2 is G1 + G,
   h(Sucessor, H),
   F is G2 + H.

% ---------------------------------------------------------------------
% EXEMPLO 14
% ---------------------------------------------------------------------

bo :-
   raiz(5, Folha),
   bo([Folha], [], Plano, Custo),
   format('Plano: ~w\n', [Plano]),
   format('Custo: ~1f\n', [Custo]).

bo([Folha|Folhas], Expandidos, Plano, Custo) :-
    arg(1, Folha, Estado),
    (   meta(Estado)
    ->  arg(2, Folha, Ações),
        arg(3, Folha, Custo),
        reverse(Ações, Plano)
    ;   expande(Folha, Expandidos, Sucessores),
        estende(5, Folhas, Sucessores, Fronteira),
        bo(Fronteira, [Estado|Expandidos], Plano, Custo) ).
