(** Why3 driver for Z3 >= 4.4 *)

prelude ";; produced by z3_gnatprove.drv ;;"
(* no set-logic for Z3 *)
prelude "(set-info :smt-lib-version 2.5)"
prelude "(set-info :source |VC generated by SPARK 2014|)"
prelude "(set-info :category industrial)"
prelude "(set-info :status unknown)"

import "smt-libv2.gen"
import "smt-libv2-bv.gen"
import "z3_bv.gen"
import "smt-libv2-floats.gen"
import "smt-libv2-gnatprove.gen"
import "smt-libv2-floats-gnatprove.gen"
import "smt-libv2-floats-int_via_bv.gen"
import "discrimination.gen"
printer "smtv2"

(* Counterexamples: set model parser *)
model_parser "smtv2"

transformation "inline_trivial"
transformation "eliminate_builtin"
transformation "remove_unused_keep_constants"
transformation "detect_polymorphism"
transformation "eliminate_inductive"
transformation "eliminate_algebraic_if_poly"
transformation "eliminate_literal"
transformation "eliminate_gnatprove_guard_epsilon"
transformation "eliminate_epsilon"

(* remove pointless quantifiers from the goal *)
transformation "introduce_premises"

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

transformation "discriminate_if_poly"
transformation "encoding_smt_if_poly"

(** Error messages specific to Z3 *)

outofmemory "(error \".*out of memory\")\\|Cannot allocate memory\\|Maximal allocation counts .* have been exceeded\\|(error \".*number of configured allocations exceeded\")"
timeout "interrupted by timeout"
steps ":rlimit-count *\\([0-9]+\\)" 1

theory int.EuclideanDivision
  syntax function div "(div %1 %2)"
  syntax function mod "(mod %1 %2)"

  remove allprops
end

theory int.ComputerDivision
  prelude "(define-fun __cdiv ((x Int) (y Int)) Int (ite (>= x 0) (div x y) (- (div (- x) y))))"
  prelude "(define-fun __cmod ((x Int) (y Int)) Int (ite (>= x 0) (mod x y) (- (mod (- x) y))))"

  syntax function div "(__cdiv %1 %2)"
  syntax function mod "(__cmod %1 %2)"

  remove allprops
end

theory int.MinMax
  remove allprops
end
