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


%-------------------------------------------------------------------------------
% RULE FAMILIES CONTAINED HEREIN :-
%
% assoc        : associativity of "and", "or" & "<->"
% commut       : commutativity of "and", "or" & "<->"
% distrib      : distributivity of "and" over "or" and vice versa
% equivalence  : simplification of logical "<->" expressions
% implies      : simplification of logical "->" expressions
% logical      : general logical simplification rules
% logical_and  : simplification of logical "and" expressions
% logical_not  : simplification of logical "not" expressions
% logical_or   : simplification of logical "or" expressions
%-------------------------------------------------------------------------------
% MODEL DECLARATIONS FOR THIS FILE :-
%
% rule_family assoc:
%         X and Y requires [ X:any, Y:any ] &
%         X or Y  requires [ X:any, Y:any ] &
%         X <-> Y requires [ X:any, Y:any ].
%
% rule_family commut:
%         X and Y requires [ X:any, Y:any ] &
%         X or Y  requires [ X:any, Y:any ] &
%         X <-> Y requires [ X:any, Y:any ].
%
% rule_family distrib:
%         X and Y requires [ X:any, Y:any ] &
%         X or Y  requires [ X:any, Y:any ].
%
% rule_family equivalence:
%         X <-> Y requires [ X:any, Y:any ].
%
% rule_family implies:
%         X -> Y requires  [ X:any, Y:any ].
%
% rule_family logical_and:
%         X and Y requires [ X:any, Y:any ].
%
% rule_family logical_not:
%         not X   requires [ X:any ].
%
% rule_family logical_or:
%         X or Y  requires [ X:any, Y:any ].
%
% rule_family logical:
%         not X   requires [ X:any ]        &
%         X and Y requires [ X:any, Y:any ] &
%         X or Y  requires [ X:any, Y:any ] &
%         X -> Y  requires [ X:any, Y:any ] &
%         X <-> Y requires [ X:any, Y:any ].
%-------------------------------------------------------------------------------


/*** SIMPLIFICATION OF LOGICAL EXPRESSIONS Rules ***/

/*** Simplification of logical "not" expressions ***/

logical_not(1):   not true      may_be_replaced_by   false.
logical_not(2):   not false     may_be_replaced_by   true.
logical_not(3):   not not A     may_be_replaced_by   A.


/*** Simplification of logical "and" expressions ***/

logical_and(1):   A and true    may_be_replaced_by   A.
logical_and(2):   true and A    may_be_replaced_by   A.
logical_and(3):   A and false   may_be_replaced_by   false.
logical_and(4):   false and A   may_be_replaced_by   false.
logical_and(5):   A and A       may_be_replaced_by   A.
logical_and(6):   A and not A   may_be_replaced_by   false.
logical_and(7):   (not A) and A may_be_replaced_by   false.


/*** Simplification of logical "or" expressions ***/

logical_or(1):    A or false    may_be_replaced_by   A.
logical_or(2):    false or A    may_be_replaced_by   A.
logical_or(3):    A or true     may_be_replaced_by   true.
logical_or(4):    true or A     may_be_replaced_by   true.
logical_or(5):    A or A        may_be_replaced_by   A.
logical_or(6):    A or not A    may_be_replaced_by   true.
logical_or(7):    (not A) or A  may_be_replaced_by   true.


/*** Simplification of logical "->" expressions ***/

implies(1):       A -> true     may_be_replaced_by   true.
implies(2):       A -> false    may_be_replaced_by   not A.
implies(3):       true -> A     may_be_replaced_by   A.
implies(4):       false -> A    may_be_replaced_by   true.
implies(5):       A -> A        may_be_replaced_by   true.
implies(6):       A -> not A    may_be_replaced_by   not A.
implies(7):       (not A) -> A  may_be_replaced_by   A.


/*** Simplification of logical "<->" expressions ***/

equivalence(1):   A <-> true    may_be_replaced_by   A.
equivalence(2):   true <-> A    may_be_replaced_by   A.
equivalence(3):   A <-> false   may_be_replaced_by   not A.
equivalence(4):   false <-> A   may_be_replaced_by   not A.
equivalence(5):   A <-> A       may_be_replaced_by   true.
equivalence(6):   A <-> not A   may_be_replaced_by   false.
equivalence(7):   (not A) <-> A may_be_replaced_by   false.


/*** ASSOCIATIVITY of "and", "or" & "<->" Rules ***/

assoc(5):       A and (B and C) & (A and B) and C are_interchangeable.
assoc(6):       A or (B or C)   & (A or B) or C   are_interchangeable.
assoc(7):       A <-> (B <-> C) & (A <-> B) <-> C are_interchangeable.


/*** COMMUTATIVITY of "and", "or" & "<->" Rules ***/

commut(3):      A and B         may_be_replaced_by B and A.
commut(4):      A or B          may_be_replaced_by B or A.
commut(5):      A <-> B         may_be_replaced_by B <-> A.


/*** DISTRIBUTIVITY of "and" and "or" over each other Rules ***/

distrib(5):     (A and B) or C   &   (A or C) and (B or C)  are_interchangeable.
distrib(6):     (A and B) or C   &   (C or A) and (C or B)  are_interchangeable.
distrib(7):     C or (A and B)   &   (C or A) and (C or B)  are_interchangeable.
distrib(8):     C or (A and B)   &   (A or C) and (B or C)  are_interchangeable.
distrib(9):     (A or B) and C   &   (A and C) or (B and C) are_interchangeable.
distrib(10):    (A or B) and C   &   (C and A) or (C and B) are_interchangeable.
distrib(11):    C and (A or B)   &   (C and A) or (C and B) are_interchangeable.
distrib(12):    C and (A or B)   &   (A and C) or (B and C) are_interchangeable.


/*** Other handy logical equivalences (DeMorgan, etc.) ***/

logical(1):     not (A or B)     &   (not A) and (not B)    are_interchangeable.
logical(2):     not (A and B)    &   (not A) or (not B)     are_interchangeable.
logical(3):     A -> B           &   (not A) or B           are_interchangeable.
logical(4):     A <-> B          &   (A -> B) and (B -> A)  are_interchangeable.
logical(5):     A -> (B -> C)    may_be_replaced_by         (A and B) -> C.
