(********************************************************************)
(*                                                                  *)
(*  boolean.s7i   Boolean support library                           *)
(*  Copyright (C) 1989 - 2011  Thomas Mertes                        *)
(*                                                                  *)
(*  This file is part of the Seed7 Runtime Library.                 *)
(*                                                                  *)
(*  The Seed7 Runtime Library is free software; you can             *)
(*  redistribute it and/or modify it under the terms of the GNU     *)
(*  Lesser General Public License as published by the Free Software *)
(*  Foundation; either version 2.1 of the License, or (at your      *)
(*  option) any later version.                                      *)
(*                                                                  *)
(*  The Seed7 Runtime Library 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 Lesser General Public License for more    *)
(*  details.                                                        *)
(*                                                                  *)
(*  You should have received a copy of the GNU Lesser General       *)
(*  Public License along with this program; if not, write to the    *)
(*  Free Software Foundation, Inc., 51 Franklin Street,             *)
(*  Fifth Floor, Boston, MA  02110-1301, USA.                       *)
(*                                                                  *)
(********************************************************************)


(**
 *  Logical type, which consists of the two truth values TRUE and FALSE.
 *)
const type: boolean is subtype ENUMERATION;


IN_PARAM_IS_VALUE(boolean);

const proc: (ref boolean: dest) ::= (in boolean: source)   is action "BLN_CREATE";
const proc: destroy (ref boolean: aValue)                  is action "GEN_DESTR";
const proc: (inout boolean: dest) := (in boolean: source)  is action "BLN_CPY";


(**
 *  ''FALSE'' is one of the two ''Boolean'' truth values.
 *  The negation of ''FALSE'' is ''TRUE''.
 *)
const boolean: FALSE is enumlit;


(**
 *  ''TRUE'' is one of the two ''Boolean'' truth values.
 *  The negation of ''TRUE'' is ''FALSE''.
 *)
const boolean: TRUE is enumlit;


$ system "true" is TRUE;
$ system "false" is FALSE;


(**
 *  Default value of ''boolean'' (FALSE).
 *)
const boolean: (attr boolean) . value is FALSE;


(**
 *  Minimum value of ''boolean'' (FALSE).
 *)
const boolean: (attr boolean) . first is FALSE;


(**
 *  Maximum value of ''boolean'' (TRUE).
 *)
const boolean: (attr boolean) . last  is TRUE;


(**
 *  Negate a boolean value.
 *  @return TRUE if boolValue is FALSE,
 *          FALSE otherwise.
 *)
const func boolean: not (in boolean: boolValue)                          is action "BLN_NOT";


(**
 *  Logical ''and'' for two boolean values.
 *  The logical ''and'' operator works strictly left to right.
 *  If the result can be determined after the evaluation of
 *  ''boolValue1'' the right operand (''boolValue2'') is not evaluated.
 *  @return TRUE if boolValue1 is TRUE and boolValue2 is TRUE,
 *          FALSE otherwise.
 *)
const func boolean: (in boolean: boolValue1) and (ref func boolean: boolValue2)    is action "BLN_AND";
const func boolean: (in boolean: boolValue1) and (ref varfunc boolean: boolValue2) is action "BLN_AND";
const func boolean: (in boolean: boolValue1) and (in boolean: boolValue2)          is action "BLN_AND";


(**
 *  Inclusive logical ''or'' for two boolean values.
 *  The logical ''or'' operator works strictly left to right.
 *  If the result can be determined after the evaluation of
 *  ''boolValue1'' the right operand (''boolValue2'') is not evaluated.
 *  @return TRUE if boolValue1 is TRUE or boolValue2 is TRUE (or both are true),
 *          FALSE otherwise.
 *)
const func boolean: (in boolean: boolValue1) or (ref func boolean: boolValue2)     is action "BLN_OR";
const func boolean: (in boolean: boolValue1) or (ref varfunc boolean: boolValue2)  is action "BLN_OR";
const func boolean: (in boolean: boolValue1) or (in boolean: boolValue2)           is action "BLN_OR";


(**
 *  Check if two boolean values are equal.
 *  @return TRUE if the two boolean values are equal,
 *          FALSE otherwise.
 *)
const func boolean: (in boolean: boolValue1) = (in boolean: boolValue2)  is action "BLN_EQ";


(**
 *  Check if two boolean values are not equal.
 *  @return FALSE if the two boolean values are equal,
 *          TRUE otherwise.
 *)
const func boolean: (in boolean: boolValue1) <> (in boolean: boolValue2) is action "BLN_NE";


(**
 *  Check if boolValue1 is less than boolValue2.
 *  @return TRUE if boolValue1 is FALSE and boolValue2 is TRUE,
 *          FALSE otherwise.
 *)
const func boolean: (in boolean: boolValue1) < (in boolean: boolValue2)  is action "BLN_LT";


(**
 *  Check if boolValue1 is greater than boolValue2.
 *  @return TRUE if boolValue1 is TRUE and boolValue2 is FALSE,
 *          FALSE otherwise.
 *)
const func boolean: (in boolean: boolValue1) > (in boolean: boolValue2)  is action "BLN_GT";


(**
 *  Check if boolValue1 is less than or equal to boolValue2.
 *  @return TRUE if boolValue1 is FALSE or boolValue2 is TRUE,
 *          FALSE otherwise.
 *)
const func boolean: (in boolean: boolValue1) <= (in boolean: boolValue2) is action "BLN_LE";


(**
 *  Check if boolValue1 is greater than or equal to boolValue2.
 *  @return TRUE if boolValue1 is TRUE or boolValue2 is FALSE,
 *          FALSE otherwise.
 *)
const func boolean: (in boolean: boolValue1) >= (in boolean: boolValue2) is action "BLN_GE";


(**
 *  Compare two boolean values..
 *  @return -1, 0 or 1 if the first argument is considered to be
 *          respectively less than, equal to, or greater than the
 *          second.
 *)
const func integer: compare (in boolean: aBoolean1, in boolean: aBoolean2) is forward;


(**
 *  Compute the hash value of a boolean value.
 *  @return the hash value.
 *)
const func integer: hashCode (in boolean: aBoolean)                      is action "BLN_ORD";


(**
 *  Convert to [[integer]].
 *  @return 0 if boolValue is FALSE and
 *          1 if boolValue is TRUE.
 *)
const func integer: ord (in boolean: boolValue)                          is action "BLN_ORD";


(**
 *  Convert to [[integer]].
 *  @return 0 if boolValue is FALSE and
 *          1 if boolValue is TRUE.
 *)
const func integer: integer (in boolean: boolValue)                      is action "BLN_ORD";


(**
 *  Conversion from boolean to [[integer]].
 *  @return 0 if boolValue is FALSE and
 *          1 if boolValue is TRUE.
 *)
const func integer: (attr integer) conv (in boolean: boolValue) is forward;


(**
 *  Convert an [[integer]] to a boolean value.
 *  @return FALSE if number is 0,
 *          TRUE if number is 1.
 *  @exception RANGE_ERROR If number is neither 0 nor 1.
 *)
const func boolean: boolean (in integer: number)                         is action "BLN_ICONV1";


(**
 *  Convert an [[integer]] to a boolean value.
 *  @return FALSE if number is 0,
 *          TRUE if number is 1.
 *  @exception RANGE_ERROR If number is neither 0 nor 1.
 *)
const func boolean: (attr boolean) conv (in integer: number)             is action "BLN_ICONV3";


const varfunc boolean: (attr boolean) varConv (inout integer: number)    is action "TYP_VARCONV";


# const boolean: succ (FALSE) is TRUE;
# const boolean: pred (TRUE) is  FALSE;


(**
 *  Successor of a boolean value.
 *   succ(FALSE)  returns  TRUE
 *   succ(TRUE)   raises   RANGE_ERROR
 *  @return TRUE, if the boolean value is FALSE.
 *  @exception RANGE_ERROR If the boolean value is TRUE.
 *)
const func boolean: succ (ref boolean: boolValue)                        is action "BLN_SUCC";


(**
 *  Predecessor of a boolean value.
 *   pred(FALSE)  raises    RANGE_ERROR
 *   pred(TRUE)   returns   FALSE
 *  @return FALSE, if the boolean value is TRUE.
 *  @exception RANGE_ERROR If the boolean value is FALSE.
 *)
const func boolean: pred (ref boolean: boolValue)                        is action "BLN_PRED";


(**
 *  Increment a boolean value.
 *)
const proc: incr (inout boolean: boolValue) is func
  begin
    boolValue := succ(boolValue);
  end func;


(**
 *  Decrement a boolean value.
 *)
const proc: decr (inout boolean: boolValue) is func
  begin
    boolValue := pred(boolValue);
  end func;


(**
 *  Convert a boolean value to a [[string]].
 *  The boolean value is converted to the string "TRUE" or "FALSE.
 *  @return "TRUE" if aBool is TRUE,
 *          "FALSE" otherwise.
 *  @exception MEMORY_ERROR Not enough memory to represent the result.
 *)
const func string: str (in boolean: aBool)                               is action "ENU_LIT";


(**
 *  Convert a boolean value to a boolean literal.
 *  The boolean value is converted to the string "TRUE" or "FALSE.
 *  @return "TRUE" if aBool is TRUE,
 *          "FALSE" otherwise.
 *  @exception MEMORY_ERROR Not enough memory to represent the result.
 *)
const func string: literal (in boolean: aBool)                           is action "ENU_LIT";


(**
 *  Convert a [[string]] to a boolean value.
 *  @return the boolean result of the conversion.
 *  @exception RANGE_ERROR If the string is not equal to
 *             "TRUE" or "FALSE".
 *)
const func boolean: (attr boolean) parse (in string: stri) is forward;


(**
 *  Convert a [[string]] to a boolean value.
 *  @return the boolean result of the conversion.
 *  @exception RANGE_ERROR If the string is not equal to
 *             "TRUE" or "FALSE".
 *)
const func boolean: boolean (in string: stri) is
    return boolean parse stri;


(**
 *  Compute pseudo-random boolean value in the range [low, high].
 *  The random values are uniform distributed.
 *  @return a random value such that low <= rand(low, high) and
 *          rand(low, high) <= high holds.
 *  @exception RANGE_ERROR The range is empty (low > high holds).
 *)
const func boolean: rand (in boolean: low, in boolean: high) is forward;


const proc: DECLARE_TERNARY (in type: aType) is func
  begin

    (**
     *  Ternary operator ''condition'' ? ''thenValue'' : ''elseValue''
     *  @return ''thenValue'' if ''condition'' is TRUE, and
     *          ''elseValue'' if ''condition'' is FALSE.
     *)
    const func aType: (in boolean: condition) ? (ref func aType: thenValue) : (ref func aType: elseValue) is action "BLN_TERNARY";

    const func aType: (in boolean: condition) ? (ref func aType: thenValue) : (in aType: elseValue)       is action "BLN_TERNARY";

    const func aType: (in boolean: condition) ? (in aType: thenValue) : (ref func aType: elseValue)       is action "BLN_TERNARY";

    const func aType: (in boolean: condition) ? (in aType: thenValue) : (in aType: elseValue)             is action "BLN_TERNARY";

  end func;


DECLARE_TERNARY(boolean);


(*
const func boolean: not (attr TRUE) is          FALSE;
const func boolean: not (attr FALSE) is         TRUE;

const func boolean: (attr FALSE) and (func boolean) is FALSE;
const func boolean: (attr FALSE) and boolean is        FALSE;
const func boolean: (attr FALSE) or (attr FALSE) is    FALSE;
const func boolean: (attr FALSE) or (attr TRUE) is     TRUE;
const func boolean: (attr FALSE) = (attr FALSE) is     TRUE;
const func boolean: (attr FALSE) = (attr TRUE) is      FALSE;
const func boolean: (attr FALSE) < (attr FALSE) is     FALSE;
const func boolean: (attr FALSE) < (attr TRUE) is      TRUE;
const func boolean: (attr FALSE) > boolean is          FALSE;
const func boolean: (attr FALSE) <= boolean is         TRUE;
const func boolean: (attr FALSE) >= (attr FALSE) is    TRUE;
const func boolean: (attr FALSE) >= (attr TRUE) is     FALSE;
const func boolean: (attr FALSE) <> (attr FALSE) is    FALSE;
const func boolean: (attr FALSE) <> (attr TRUE) is     TRUE;

const integer: ord (attr FALSE) is       0;
const func boolean: succ (attr FALSE) is TRUE;
const EXCEPTION: pred (attr FALSE) is    RANGE_ERROR;
const string: str (attr FALSE) is        "FALSE";

const func boolean: (attr TRUE) and (attr FALSE) is    FALSE;
const func boolean: (attr TRUE) and (attr TRUE) is     TRUE;
const func boolean: (attr TRUE) or (func boolean) is   TRUE;
const func boolean: (attr TRUE) or boolean is          TRUE;
const func boolean: (attr TRUE) = (attr FALSE) is      FALSE;
const func boolean: (attr TRUE) = (attr TRUE) is       TRUE;
const func boolean: (attr TRUE) < boolean is           FALSE;
const func boolean: (attr TRUE) > (attr FALSE) is      TRUE;
const func boolean: (attr TRUE) > (attr TRUE) is       FALSE;
const func boolean: (attr TRUE) <= (attr FALSE) is     FALSE;
const func boolean: (attr TRUE) <= (attr TRUE) is      TRUE;
const func boolean: (attr TRUE) >= boolean is          TRUE;
const func boolean: (attr TRUE) <> (attr FALSE) is     TRUE;
const func boolean: (attr TRUE) <> (attr TRUE) is      FALSE;

const integer: ord (attr TRUE) is        1;
const EXCEPTION: succ (attr TRUE) is     RANGE_ERROR;
const func boolean: pred (attr TRUE) is  FALSE;
const string: str (attr TRUE) is         "TRUE";
*)