% -----------------------------------------------------------------------------
%  (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 :-
%
% enum         : properties of enumerated types (pred & succ etc.)
% enum_cases   : list of cases for enumerations of size 2..25 elements
%-------------------------------------------------------------------------------
% MODEL DECLARATIONS FOR THIS FILE :-
%
% rule_family enum:
%         X = Y   requires [ X:e,   Y:e   ] &
%         X <= Y  requires [ X:e,   Y:e   ] &
%         X < Y   requires [ X:e,   Y:e   ] &
%         X >= Y  requires [ X:e,   Y:e   ] &
%         X > Y   requires [ X:e,   Y:e   ] &
%         X <> Y  requires [ X:e,   Y:e   ] &
%         X or Y  requires [ X:any, Y:any ] &
%         succ(X) requires [ X:e          ] &
%         pred(X) requires [ X:e          ].
%
% rule_family enum_cases:
%         X or Y requires [ X:any, Y:any ].
%-------------------------------------------------------------------------------


/*** Enumerated type rules ***/

enum(1):        pred(succ(X))=X may_be_deduced_from
                        [ goal(enumeration_list(X,L)),
                          goal(\+ last(L,X)) ].
enum(2):        X=pred(succ(X)) may_be_deduced_from
                        [ goal(enumeration_list(X,L)),
                          goal(\+ last(L,X)) ].
enum(3):        succ(pred(X))=X may_be_deduced_from
                        [ goal(enumeration_list(X,L)),
                          goal(L\=[X|_]) ].
enum(4):        X=succ(pred(X)) may_be_deduced_from
                        [ goal(enumeration_list(X,L)),
                          goal(L\=[X|_]) ].
enum(5):        X <= Y may_be_deduced_from
                        [ goal(enumeration_list(X,L)),
                          goal(in_order(X,Y,L)) ].
enum(6):        X < Y may_be_deduced_from
                        [ goal(enumeration_list(X,L)),
                          goal(in_order(X,Y,L)), goal(X\=Y) ].
enum(7):        Y >= X may_be_deduced_from
                        [ goal(enumeration_list(X,L)),
                          goal(in_order(X,Y,L)) ].
enum(8):        Y > X may_be_deduced_from
                        [ goal(enumeration_list(X,L)),
                          goal(in_order(X,Y,L)), goal(X\=Y) ].
enum(9):        X<>Y may_be_deduced_from
                        [ goal(enumeration_list(X,L)), goal(is_in(X,L)),
                          goal(is_in(Y,L)), goal(X\=Y) ].
enum(10):       X=E may_be_deduced_from
                        [ X<=E, goal(enumeration_list(E,[E|_])) ].
enum(11):       X=E may_be_deduced_from
                        [ X<F, goal(enumeration_list(F,[E,F|_])) ].
enum(12):       X=E may_be_deduced_from
                        [ X>=E, goal(enumeration_list(E,L)), goal(last(L,E)) ].
enum(13):       X=E may_be_deduced_from
                        [ X>F, goal(enumeration_list(E,L)), goal(last(L,E)),
                          goal(strict_sublist([F,E],L)) ].
enum(14):       X=E1 or X>=E2 may_be_deduced_from
                        [ X>=E1, goal(enumeration_list(E1,L)),
                          goal(strict_sublist([E1,E2],L)) ].
enum(15):       X=E or REST may_be_deduced_from
                        [ goal(atom(E)), goal(enumeration_list(E,L)),
                          goal(build_other_cases(X,E,L,REST)),
                          goal(REST\=false) ].
enum(16):       X=E may_be_deduced_from
                        [ goal(atom(E)), goal(enumeration_list(E,L)),
                          goal(build_other_cases(X,E,L,false)) ].
enum(17):       succ(Y) may_be_replaced_by X if
                        [ goal(enumeration_list(Y,L)),
                          goal(strict_sublist([Y,X],L)) ].
enum(18):       pred(X) may_be_replaced_by Y if
                        [ goal(enumeration_list(X,L)),
                          goal(strict_sublist([Y,X],L)) ].


enum_cases(2):  X=A or X=B may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B])) ].
enum_cases(3):  X=A or X=B or X=C may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C])) ].
enum_cases(4):  X=A or X=B or X=C or X=D may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D])) ].
enum_cases(5):  X=A or X=B or X=C or X=D or X=E may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E])) ].
enum_cases(6):  X=A or X=B or X=C or X=D or X=E or X=F may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F])) ].
enum_cases(7):  X=A or X=B or X=C or X=D or X=E or X=F or X=G may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G])) ].
enum_cases(8):  X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H])) ].
enum_cases(9):  X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I])) ].
enum_cases(10): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J])) ].
enum_cases(11): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K])) ].
enum_cases(12): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L])) ].
enum_cases(13): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M])) ].
enum_cases(14): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N])) ].
enum_cases(15): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N or X=O may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O])) ].
enum_cases(16): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N or X=O or X=P may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,
                                                P])) ].
enum_cases(17): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N or X=O or X=P or X=Q may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,
                                                P,Q])) ].
enum_cases(18): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N or X=O or X=P or X=Q or X=R may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,
                                                P,Q,R])) ].
enum_cases(19): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N or X=O or X=P or X=Q or X=R or
                X=S may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,
                                                P,Q,R,S])) ].
enum_cases(20): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N or X=O or X=P or X=Q or X=R or
                X=S or X=T may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,
                                                P,Q,R,S,T])) ].
enum_cases(21): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N or X=O or X=P or X=Q or X=R or
                X=S or X=T or X=U may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,
                                               P,Q,R,S,T,U])) ].
enum_cases(22): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N or X=O or X=P or X=Q or X=R or
                X=S or X=T or X=U or X=V may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,
                                               P,Q,R,S,T,U,V])) ].
enum_cases(23): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N or X=O or X=P or X=Q or X=R or
                X=S or X=T or X=U or X=V or X=W may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,
                                               P,Q,R,S,T,U,V,W])) ].
enum_cases(24): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N or X=O or X=P or X=Q or X=R or
                X=S or X=T or X=U or X=V or X=W or X=Y may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,
                                               P,Q,R,S,T,U,V,W,Y])) ].
enum_cases(25): X=A or X=B or X=C or X=D or X=E or X=F or X=G or X=H or X=I or
                X=J or X=K or X=L or X=M or X=N or X=O or X=P or X=Q or X=R or
                X=S or X=T or X=U or X=V or X=W or X=Y or X=Z may_be_deduced_from
                       [ goal(atom(X)),
                         goal(checktype(X,TYPE)),
                         goal(type(TYPE,enumerated)),
                         goal(enumeration(TYPE,[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,
                                               P,Q,R,S,T,U,V,W,Y,Z])) ].
