% -----------------------------------------------------------------------------
%  (C) Altran Praxis Limited
% -----------------------------------------------------------------------------
% 
%  The SPARK toolset is free software; you can redistribute it and/or modify it
%  under terms of the GNU General Public License as published by the Free
%  Software Foundation; either version 3, or (at your option) any later
%  version. The SPARK toolset is distributed in the hope that it will be
%  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
%  Public License for more details. You should have received a copy of the GNU
%  General Public License distributed with the SPARK toolset; see file
%  COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
%  the license.
% 
% =============================================================================


/*** FORWARDCHAIN -- top-level checker command ***/
forwardchain :-
        (
           command_arg(expression,HC#N)
        ;
           prompt_user('FORWARD_CHAIN -- For which hypothesis/conclusion?', 'Type h#N or c#N as appropriate ... '),
           rread(F),
           F=HC#N
        ),
        !,
        retract(logfact(command, forwardchain)),
        asserta(logfact(command, forwardchain(HC#N))),
        forward_chain(HC,N), !.

forward_chain(h,NUMBER) :-
   hyp(NUMBER,FORMULA),
   (
      FORMULA=(X -> Y),
      forward_prove(X),
      NEWFACT=hyp(NUMBER,Y),
      NEWFORMULA = Y                                            /* CFR026 */
   ;
      FORMULA=(X <-> Y),
      (
         forward_prove(X),
         find_if_save(NUMBER,Y,A),
         A=yes,
         NEWFACT=hyp(NUMBER,Y),
         NEWFORMULA = Y                                         /* CFR026 */
      ;
         forward_prove(Y),
         find_if_save(NUMBER,X,A),
         A=yes,
         NEWFACT=hyp(NUMBER,X),
         NEWFORMULA = X                                         /* CFR026 */
      )
   ),
   retract(hyp(NUMBER,FORMULA)),
   assertz(logfact(newhyp, NEWFACT)),
   assertz(NEWFACT),
   new_hyp_message(NUMBER, NEWFORMULA),                         /* CFR026 */
   !.
forward_chain(c,NUMBER) :-
   conc(NUMBER,FORMULA),
   (
      hyp(N,_ -> FORMULA)
   ;
      hyp(N,_ <-> FORMULA)
   ;
      hyp(N,FORMULA <-> _)
   ),
   forward_chain(h,N),
   done(NUMBER),
   !.


/*** FORWARD_PROVE(F) - try to prove F, displaying tracking messages ***/
forward_prove(X) :-
   nl,
   write('TRYING TO PROVE: '),
   print(X),
   infer(X),
   nl,
   write('PROVED: '),
   print(X),
   nl, !.

forward_prove(X) :-
   nl,
   write('FAILED TO PROVE: '),
   print(X),
   fail.


/*** FIND_IF_SAVE(N,F,A) - show F follows from hypothesis N & ask if save ***/
find_if_save(N,_,_) :-
   nl,
   nl,
   write('From H'),
   print(N),
   put_code(58),  /* ":" */
   put_code(32),  /* " " */
   hyp(N,X),
   print(X),
   nl,
   fail.

find_if_save(_,F,A) :-
   write('Proved: '),
   print(F),
   nl,
   read_answer('Keep this result',A), !.
%###############################################################################
%END-OF-FILE
