theory Main_Main
  use        bool.Bool

  (* special private type for private types not in SPARK and hidden extension
  components *)
  type __private

  (* special type for representation of fixed_point types *)
  type __fixed = int

end

theory Integer
  use        int.Int
  use        bool.Bool

  function bool_eq int int : bool
  function bool_ne int int : bool
  function bool_lt int int : bool
  function bool_le int int : bool
  function bool_gt int int : bool
  function bool_ge int int : bool

  axiom bool_eq_axiom:
    forall x:int.
    forall y:int.
      bool_eq x y = True <-> x = y
  meta "remove_unused:dependency" axiom bool_eq_axiom, function bool_eq

  axiom bool_ne_axiom:
    forall x:int.
    forall y:int.
      bool_ne x y = True <-> x <> y
  meta "remove_unused:dependency" axiom bool_ne_axiom, function bool_ne

  axiom bool_lt_axiom:
    forall x:int.
    forall y:int.
      bool_lt x y = True <-> x < y
  meta "remove_unused:dependency" axiom bool_lt_axiom, function bool_lt

  axiom bool_int__le_axiom:
    forall x:int.
    forall y:int.
      bool_le x y = True <-> x <= y
  meta "remove_unused:dependency" axiom bool_int__le_axiom, function bool_le

  axiom bool_gt_axiom:
    forall x:int.
    forall y:int.
        bool_gt x y = True <-> x > y
  meta "remove_unused:dependency" axiom bool_gt_axiom, function bool_gt

  axiom bool_ge_axiom:
    forall x:int.
    forall y:int.
        bool_ge x y = True <-> x >= y
  meta "remove_unused:dependency" axiom bool_ge_axiom, function bool_ge

  function length (x y: int) : int =
    if x <= y then (y-x) + 1 else 0

end

theory Real
  use        real.RealInfix
  use        bool.Bool

  function bool_eq real real : bool
  function bool_ne real real : bool
  function bool_lt real real : bool
  function bool_le real real : bool
  function bool_gt real real : bool
  function bool_ge real real : bool

  axiom bool_eq_axiom:
    forall x:real.
    forall y:real.
      bool_eq x y = True <-> x = y
  meta "remove_unused:dependency" axiom bool_eq_axiom, function bool_eq

  axiom bool_ne_axiom:
    forall x:real.
    forall y:real.
      bool_ne x y = True <-> x <> y
  meta "remove_unused:dependency" axiom bool_ne_axiom, function bool_ne

  axiom bool_lt_axiom:
    forall x:real.
    forall y:real.
      bool_lt x y = True <-> x <. y
  meta "remove_unused:dependency" axiom bool_lt_axiom, function bool_lt

  axiom bool_int__le_axiom:
    forall x:real.
    forall y:real.
      bool_le x y = True <-> x <=. y
  meta "remove_unused:dependency" axiom bool_int__le_axiom, function bool_le

  axiom bool_gt_axiom:
    forall x:real.
    forall y:real.
        bool_gt x y = True <-> x >. y
  meta "remove_unused:dependency" axiom bool_gt_axiom, function bool_gt

  axiom bool_ge_axiom:
    forall x:real.
    forall y:real.
        bool_ge x y = True <-> x >=. y
  meta "remove_unused:dependency" axiom bool_ge_axiom, function bool_ge

end

theory Floating_Func
  use        bool.Bool

  type t

  predicate lt t t
  predicate le t t
  predicate gt t t
  predicate ge t t
  predicate eq t t
  predicate neq (x y : t) = not (eq x y)

  function bool_lt  (x: t) (y: t) : bool = lt x y
  function bool_le  (x: t) (y: t) : bool = le x y
  function bool_gt  (x: t) (y: t) : bool = gt x y
  function bool_ge  (x: t) (y: t) : bool = ge x y
  function bool_eq  (x: t) (y: t) : bool = eq x y
  function bool_neq (x: t) (y: t) : bool = not (eq x y)
end

module Boolean_Func
  use        bool.Bool

  function bool_eq (x : bool) (y : bool) : bool =
    if x = y then True else False

  function to_int (b : bool) : int =
   if b then 1 else 0

  function of_int (i : int) : bool =
   if i = 0 then False else True

end
