(** Why3 driver for Colibri (with floating point support) *)

prelude ";; produced by colibri.drv ;;"
prelude "(set-logic ALL)"
prelude "(set-info :smt-lib-version 2.6)"

import "smt-libv2.gen"
printer "smtv2.6par"
import "smt-libv2-bv.gen"
import "cvc4_bv.gen"
import "smt-libv2-floats.gen"
import "smt-libv2-gnatprove.gen"
import "smt-libv2-floats-gnatprove.gen"
import "smt-libv2-floats-int_via_real.gen"
(* import "discrimination.gen" *)

steps "Steps : \\([0-9]+.?[0-9]*\\)" 1
steplimitexceeded "(Step limit reached)"


theory BuiltIn
(* Since quantifiers are all removed we can fully discriminate *)
  meta "select_inst_default" "all"
  meta "select_lskept_default" "all"
  meta "select_lsinst_default" "all"
  meta "select_kept_default" "all"
end

theory bool.Bool
  meta "inline:no" function andb
  meta "inline:no" function orb
  meta "inline:no" function notb
  meta "inline:no" function xorb
  meta "inline:no" function implb
end

theory bool.Ite
   meta "inline:no" function ite
end

theory int.Int
  remove prop CompatOrderMult
end

transformation "remove_unused_keep_constants"
(* Performed introductions depending on whether counterexamples are
   requested, as said by the meta "get_counterexmp". When this meta
   set, this transformation introduces the model variables that are
   still embedded in the goal. When it is not set, it removes all
   these unused-ce-related variables, even in the context.  *)
transformation "counterexamples_dependent_intros"

transformation "monomorphise_goal"
transformation "compile_match"
transformation "inline_trivial"
transformation "simplify_formula"
transformation "eliminate_builtin"
transformation "eliminate_recursion"
transformation "eliminate_inductive"
transformation "eliminate_gnatprove_guard_epsilon"
transformation "eliminate_epsilon"
transformation "eliminate_algebraic"
transformation "eliminate_literal"
transformation "instantiate_predicate"
transformation "introduce_premises"

(** Extra theories supported by COLIBRI *)

theory int.EuclideanDivision
  syntax function div "(div %1 %2)"
  syntax function mod "(mod %1 %2)"
  remove prop Mod_bound
  remove prop Div_mod
  remove prop Mod_1
  remove prop Div_1
end

theory int.ComputerDivision
  syntax function div "(colibri_cdiv %1 %2)"
  syntax function mod "(colibri_crem %1 %2)"
  remove prop Mod_bound
  remove prop Div_mod
  remove prop Mod_1
  remove prop Div_1
end

theory real.Truncate
  syntax function floor "(to_int %1)"
  overriding syntax function truncate "(to_int (colibri_truncate %1))"
  overriding syntax function ceil "(to_int (colibri_ceil %1))"
  remove prop Floor_down
  remove prop Floor_monotonic
end

theory real.FromInt
  syntax function from_int "(to_real %1)"
end

theory real.Abs
  overriding syntax function abs "(colibri_abs_real %1)"
end

theory int.Abs
  syntax function abs "(colibri_abs_int %1)"
end

theory real.PowerInt
  syntax function power "(colibri_pow_real_int %1 %2)"
end

theory int.Power
  syntax function power "(colibri_pow_int_int %1 %2)"
end

theory real.ExpLog
  syntax function exp "(colibri_exp %1)"
  (* syntax function log "(colibri_ln %1)" *)
end

theory real.MinMax
  syntax function min "(colibri_min_real %1 %2)"
  syntax function max "(colibri_max_real %1 %2)"
end

theory int.MinMax
  syntax function min "(colibri_min_int %1 %2)"
  syntax function max "(colibri_max_int %1 %2)"
end


(** TODO *)

(**
- colibri_floor
- colibri_abs_int
- colibri_abs_real
- colibri_truncate
- colibri_pow_real_int
- colibri_max
- colibri_min
- is_int
- to_int
- to_real

*)
