(* Why driver for SMT2 syntax *)

prelude ";;; this is a prelude for MathSAT5"
prelude "(set-logic AUFNIRA)"

printer "smtv2"
filename "%f-%t-%g.smt2"

valid "^unsat"
unknown "^\\(unknown\\|sat\\|Fail\\)" ""
outofmemory "(error \".*out of memory\")\\|Cannot allocate memory"
time "why3cpulimit time : %s s"


transformation "inline_trivial"
transformation "eliminate_builtin"
transformation "eliminate_definition"
transformation "eliminate_inductive"
transformation "eliminate_epsilon"
transformation "eliminate_algebraic"
transformation "eliminate_literal"

transformation "simplify_formula"
(*transformation "simplify_trivial_quantification"*)

transformation "discriminate"
transformation "encoding_smt"

theory BuiltIn
  syntax type int   "Int"
  syntax type real  "Real"
  syntax predicate (=)  "(= %1 %2)"

  meta "encoding:kept" type int
end

theory int.Int

  prelude ";;; this is a prelude for Z3 integer arithmetic"

  syntax function zero "0"
  syntax function one  "1"

  syntax function (+)  "(+ %1 %2)"
  syntax function (-)  "(- %1 %2)"
  syntax function (*)  "(* %1 %2)"
  syntax function (-_) "(- %1)"

  syntax predicate (<=) "(<= %1 %2)"
  syntax predicate (<)  "(< %1 %2)"
  syntax predicate (>=) "(>= %1 %2)"
  syntax predicate (>)  "(> %1 %2)"

  remove prop MulComm.Comm
  remove prop MulAssoc.Assoc
  remove prop Unit_def_l
  remove prop Unit_def_r
  remove prop Inv_def_l
  remove prop Inv_def_r
  remove prop Assoc
  remove prop Mul_distr_l
  remove prop Mul_distr_r
  remove prop Comm
  remove prop Unitary
  remove prop Refl
  remove prop Trans
  remove prop Antisymm
  remove prop Total
  remove prop NonTrivialRing
  remove prop CompatOrderAdd
  remove prop ZeroLessOne

end


theory real.Real

  prelude ";;; this is a prelude for Z3 real arithmetic"

  syntax function zero "0.0"
  syntax function one  "1.0"

  syntax function (+)  "(+ %1 %2)"
  syntax function (-)  "(- %1 %2)"
  syntax function (*)  "(* %1 %2)"
  syntax function (/)  "(/ %1 %2)"
  syntax function (-_) "(- %1)"
  syntax function inv  "(/ 1.0 %1)"

  syntax predicate (<=) "(<= %1 %2)"
  syntax predicate (<)  "(< %1 %2)"
  syntax predicate (>=) "(>= %1 %2)"
  syntax predicate (>)  "(> %1 %2)"

  remove prop MulComm.Comm
  remove prop MulAssoc.Assoc
  remove prop Unit_def_l
  remove prop Unit_def_r
  remove prop Inv_def_l
  remove prop Inv_def_r
  remove prop Assoc
  remove prop Mul_distr_l
  remove prop Mul_distr_r
  remove prop Comm
  remove prop Unitary
  remove prop Inverse
  remove prop Refl
  remove prop Trans
  remove prop Antisymm
  remove prop Total
  remove prop NonTrivialRing
  remove prop CompatOrderAdd
  remove prop ZeroLessOne

  meta "encoding:kept" type real

end

theory Bool
  syntax type     bool  "Bool"
  syntax function True  "true"
  syntax function False "false"
  meta "encoding:kept" type bool
end

theory bool.Bool
  syntax function andb  "(and %1 %2)"
  syntax function orb   "(or %1 %2)"
  syntax function xorb  "(xor %1 %2)"
  syntax function notb  "(not %1)"
  syntax function implb "(=> %1 %2)"
end

theory bool.Ite
  syntax function ite "(ite %1 %2 %3)"
  meta "encoding:lskept" function ite
end

(* needs to be checked
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 real.FromInt
  syntax function from_int "(to_real %1)"
  remove prop Zero
  remove prop One
  remove prop Add
  remove prop Sub
  remove prop Mul
  remove prop Neg
end

(*
theory real.Truncate
  syntax function floor "(to_int %1)"
  remove prop Floor_down
  remove prop Floor_monotonic
end
*)

theory HighOrd
  syntax type     (->) "(Array %1 %2)"
  syntax function (@) "(select %1 %2)"

  meta "encoding:lskept" function (@)
end

theory map.Map
  syntax function get "(select %1 %2)"
  syntax function set "(store %1 %2 %3)"

  meta "encoding:lskept" function get
  meta "encoding:lskept" function set
end

theory map.Const
  meta "encoding:lskept" function const
(*  syntax function const "(const[%t0] %1)" *)
end
