% -----------------------------------------------------------------------------
%  (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 FAMILY CONTAINED HEREIN :-
%
% sets         : properties of FDL set types
%-------------------------------------------------------------------------------
% MODEL DECLARATION FOR THIS FILE :-
%
% rule_family sets:
%         X in Y               requires [ X:any, Y:any ] &
%         X not_in Y           requires [ X:any, Y:any ] &
%         not X                requires [ X:any        ] &
%         X \/ Y               requires [ X:any, Y:any ] &
%         X /\ Y               requires [ X:any, Y:any ] &
%         X \ Y                requires [ X:any, Y:any ] &
%         X or Y               requires [ X:any, Y:any ] &
%         X subset_of Y        requires [ X:any, Y:any ] &
%         X strict_subset_of Y requires [ X:any, Y:any ].
%-------------------------------------------------------------------------------


/*** Set rules ***/

/*** Element of ***/

sets(1):        X in (set A) may_be_deduced_from [ goal(is_in(X,A)) ].
sets(2):        (X not_in A) & (not (X in A)) are_interchangeable.
sets(3):        (X in A) & (not (X not_in A)) are_interchangeable.


/*** Union ***/

sets(4):        X in (A \/ B) may_be_deduced_from [ X in A ].
sets(5):        X in (A \/ B) may_be_deduced_from [ X in B ].
sets(6):        X not_in (A \/ B) may_be_deduced_from
                        [ X not_in A, X not_in B ].
sets(7):        A \/ B may_be_replaced_by A if [ B subset_of A ].
sets(8):        B \/ A may_be_replaced_by A if [ B subset_of A ].
sets(9):        A \/ (set []) may_be_replaced_by A if [].
sets(10):       (set []) \/ A may_be_replaced_by A if [].
sets(11):       (set A) \/ (set B) may_be_replaced_by (set C) if
                        [ goal(set_union(A,B,C)) ].


/*** Intersection ***/

sets(12):       X in (A /\ B) may_be_deduced_from [ X in A, X in B ].
sets(13):       X not_in (A /\ B) may_be_deduced_from [ X not_in A ].
sets(14):       X not_in (A /\ B) may_be_deduced_from [ X not_in B ].
sets(15):       A /\ B may_be_replaced_by A if [ A subset_of B ].
sets(16):       B /\ A may_be_replaced_by A if [ A subset_of B ].
sets(17):       (set []) /\ B may_be_replaced_by (set []) if [].
sets(18):       A /\ (set []) may_be_replaced_by (set []) if [].
sets(19):       ((set A) /\ (set B)) may_be_replaced_by (set C) if
                        [ goal(set_intersect(A,B,C)) ].


/*** 'Lacking' ***/

sets(20):       X in (A \ B) may_be_deduced_from [ X in A, X not_in B ].
sets(21):       X not_in (A \ B) may_be_deduced_from [ X not_in A ].
sets(22):       X not_in (A \ B) may_be_deduced_from [ X in B ].
sets(23):       (A \ B) may_be_replaced_by A if [ B=(set []) ].
sets(24):       (A \ B) may_be_replaced_by A if [ (A /\ B)=(set []) ].
sets(25):       (A \ B) may_be_replaced_by A if [ (B /\ A)=(set []) ].
sets(26):       (set A) \ (set B) may_be_replaced_by (set C) if
                        [ goal(set_lacking(A,B,C)) ].
sets(27):       X=E or X in S may_be_deduced_from
                        [ X in (set U), goal(is_in(E,U),
                          set_lacking(U,[E],S)) ].

/*** Empty set ***/

sets(28):       X not_in (set []) may_be_deduced.


/*** Subset rules ***/

sets(29):       (set []) subset_of A may_be_deduced.
sets(30):       A subset_of (A \/ B) may_be_deduced.
sets(31):       A subset_of (B \/ A) may_be_deduced.
sets(32):       (A /\ B) subset_of A may_be_deduced.
sets(33):       (B /\ A) subset_of A may_be_deduced.
sets(34):       (A \ B) subset_of A may_be_deduced.
sets(35):       A subset_of B may_be_deduced_from [ A strict_subset_of B ].
sets(36):       (set A) subset_of (set B) may_be_deduced_from
                        [ goal(subset(A,B)) ].


/*** Strict subset rule ***/

sets(37):       A strict_subset_of B may_be_deduced_from
                        [ A subset_of B, A <> B ].


/*** Commutativity of /\, \/ ***/

sets(38):       (X \/ Y) may_be_replaced_by (Y \/ X).
sets(39):       (X /\ Y) may_be_replaced_by (Y /\ X).


/*** Associativity of /\, \/ ***/

sets(40):       (X \/ (Y \/ Z)) & ((X \/ Y) \/ Z) are_interchangeable.
sets(41):       (X /\ (Y /\ Z)) & ((X /\ Y) /\ Z) are_interchangeable.


/*** Distributivity of /\, \/ ***/

sets(42):       (X /\ (Y \/ Z)) & ((X /\ Y) \/ (X /\ Z)) are_interchangeable.
sets(43):       (X \/ (Y /\ Z)) & ((X \/ Y) /\ (X \/ Z)) are_interchangeable.


