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


/* VAR   */  _X iss V :- var(V), !, fail.

/* +INT  */  A iss A :- integer(A), A>=0, !.

/* -INT  */  X iss A :-
                integer(A),
                A<0,
                !,
                A1 is -A,
                X=(-A1),
                !.

/* DMIN  */  X iss -(-A) :- X iss A, !.

/* UMIN  */  X iss -(A) :-
                P iss A,
                !,
                (
                   P=0, X=0
                ;
                   integer(P), P>0,
                   X=(-P)
                ;
                   P=(-X), X>0
                ), !.

/* PLUS  */  X iss A+B :-
                P iss A,
                Q iss B,
                !,
                X1 is P+Q,
                (
                   X1>=0,
                   X=X1
                ;
                   X1<0,
                   X2 is -X1,
                   X=(-X2)
                ), !.

/* MINUS */  X iss A-B :- X iss A+(-B), !.

/* MULT  */  X iss A*B :-
                P iss A,
                Q iss B,
                !,
                X1 is P*Q,
                (
                   X1>=0,
                   X=X1
                ;
                   X1<0,
                   X2 is -X1,
                   X=(-X2)
                ), !.

/* DIV   */  X iss A div B :-
                P iss A,
                Q iss B,
                !,
                Q\=0,
                eval_div(P, Q, X1),
                (
                   X1>=0,
                   X=X1
                ;
                   X1<0,
                   X2 is -X1,
                   X=(-X2)
                ), !.

/* MOD 1 */  X iss A mod B :-
                spark_enabled,          /* SPARK definition */
                !,
                P iss A,
                Q iss B,
                !,
                Q \= 0,
                eval_div(P, Q, X1),
                Remainder iss P - (X1 * Q),
                (
                   Remainder = 0,
                   X = 0
                ;
                   signed_integer(P),
                   signed_integer(Q),
                   (
                      (
                         P >= 0,
                         Q > 0
                      ;
                         P =< 0,
                         Q < 0
                      ),
                      X = Remainder
                   ;
                      (
                         P >= 0,
                         Q < 0
                      ;
                         P =< 0,
                         Q > 0
                      ),
                      X iss Remainder + Q
                   )
                ;
                   X = (P mod Q)
                ),
                !.
/* MOD 2 */  X iss A mod B :-
                \+ spark_enabled,       /* Non-SPARK definition */
                !,
                P iss A,
                Q iss B,
                !,
                Q \= 0,
                eval_div(P, Q, X1),
                Remainder iss P - (X1 * Q),
                (
                   Remainder = 0,
                   X = 0
                ;
                   Q = 1,
                   X = 0
                ;
                   X = (P mod Q)
                ),
                !.

/* POWER */  X iss A**B :-                                      /* CFR038 */
                _P iss A,                                       /* CFR038 */
                _Q iss B,                                       /* CFR038 */
                !,                                              /* CFR038 */
                (                                               /* CFR038 */
                   B = 0,                                       /* CFR038 */
                   X = 1                                        /* CFR038 */
                ;                                               /* CFR038 */
                   integer(B),                                  /* CFR038 */
                   B > 0,                                       /* CFR038 */
                   B1 is B - 1,                                 /* CFR038 */
                   !,                                           /* CFR038 */
                   A1 iss A**B1,                                /* CFR038 */
                   !,                                           /* CFR038 */
                   X iss A * A1                                 /* CFR038 */
                ),                                              /* CFR038 */
                !.                                              /* CFR038 */
%###############################################################################
%END-OF-FILE
