% -----------------------------------------------------------------------------
%  (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.
% 
% =============================================================================


/*** SIMPLIFY -- top-level checker command ***/
simplify :-
   movenots ;
   split_hyps ;
   split_concs ;
   do_implication ;
   equivalence.
simplify :- !.


/*** MOVENOTS - move nots as far into expressions as possible ***/
movenots:-
   retractall(hn(_)),
   assertz(hn(1)),
   repeat,
      hn(N),
      (
         gethyp(N,H),
         negin(H,H1),
         assertz(hyp(N,H1)),
         (
            H1=H
         ;
            H1\=H,
            assertz(logfact(newhyp, hyp(N,H1))),
            new_hyp_message(N, H1)                              /* CFR018 */
         )
      ;
         hn(N)
      ),
      M is N+1,
      retract(hn(N)),
      assertz(hn(M)),
      bigger_than_all_hyps(M),
      !,
      fail.


bigger_than_all_hyps(M) :-
        hyp(N,_),
        N>=M,
        !,
        fail.
bigger_than_all_hyps(_) :- !.


/*** GETHYP(N,H) - instantiates H to the Nth hypothesis & retracts it ***/
gethyp(N,H) :-
   hyp(N,H),
   retract(hyp(N,H)), !.


/*** SPLIT_HYPS - split conjunction hypotheses into two or more hypotheses ***/
split_hyps :-
   retract(hyp(_N,A and B)),
   add_new_hyp(A,1),
   add_new_hyp(B,1),
   !,
   split_hyps.


/*** SPLIT_CONCS - split conjunction conclusions into separate conclusions ***/
split_concs :-
   retract(conc(_N,A and B)),
   add_new_conc(A,1),
   add_new_conc(B,1),
   !,
   split_concs.


/*** DO_IMPLICATION - given "A" and "A -> B", add "B" as a hypothesis; given
                      "not B" and "A -> B", add "not A" as a hypothesis ***/
/*** ADDED 4/3/85 -- needs improvement for generality ***/
do_implication :-
   hyp(_,A -> B),
   hyp(_,A),
   add_new_hyp(B,1),
   fail.

do_implication :-
   hyp(_,A -> B),
   hyp(_,(not B)),
   negin((not A),C),
   add_new_hyp(C,1),
   fail.


/*** EQUIVALENCE - given "A" and "A <-> B" or "B <-> A", add "B";
                   given "not A" and "A <-> B" or "B <-> A", add "not B" ***/
equivalence :-
   hyp(_,A <-> B),
   hyp(_,A),
   add_new_hyp(B,1),
   fail.

equivalence :-
   hyp(_,A <-> B),
   hyp(_,B),
   add_new_hyp(A,1),
   fail.

equivalence :-
   hyp(_,A <-> B),
   hyp(_,not(A)),
   negin(not(B),C),
   add_new_hyp(C,1),
   fail.

equivalence :-
   hyp(_,A <-> B),
   hyp(_,not(B)),
   negin(not(A),C),
   add_new_hyp(C,1),
   fail.
%###############################################################################
%END-OF-FILE
