sig
  type z3_context = Z3.context
  type z3_expr = Z3.Expr.expr
  type z3_func_decl = Z3.FuncDecl.func_decl
  type 'a open_expr =
      [ `Add of 'a list
      | `And of 'a list
      | `App of SrkZ3.z3_func_decl * 'a list
      | `Atom of [ `Eq | `Leq | `Lt ] * 'a * 'a
      | `Binop of [ `Div | `Mod ] * 'a * 'a
      | `Fls
      | `Ite of 'a * 'a * 'a
      | `Mul of 'a list
      | `Not of 'a
      | `Or of 'a list
      | `Quantify of [ `Exists | `Forall ] * string * Syntax.typ_fo * 'a
      | `Real of QQ.t
      | `Tru
      | `Unop of [ `Floor | `Neg ] * 'a
      | `Var of int * Syntax.typ_fo ]
  val z3_of_term :
    'Syntax.context -> SrkZ3.z3_context -> 'Syntax.term -> SrkZ3.z3_expr
  val z3_of_formula :
    'Syntax.context ->
    SrkZ3.z3_context -> 'Syntax.formula -> SrkZ3.z3_expr
  val z3_of_expr :
    'Syntax.context ->
    SrkZ3.z3_context -> ('a, Syntax.typ_fo) Syntax.expr -> SrkZ3.z3_expr
  val term_of_z3 : 'Syntax.context -> SrkZ3.z3_expr -> 'Syntax.term
  val formula_of_z3 : 'Syntax.context -> SrkZ3.z3_expr -> 'Syntax.formula
  val expr_of_z3 :
    'Syntax.context -> SrkZ3.z3_expr -> ('a, Syntax.typ_fo) Syntax.expr
  module Solver :
    sig
      type 'a t
      val add : 'SrkZ3.Solver.t -> 'Syntax.formula list -> unit
      val push : 'SrkZ3.Solver.t -> unit
      val pop : 'SrkZ3.Solver.t -> int -> unit
      val reset : 'SrkZ3.Solver.t -> unit
      val check :
        'SrkZ3.Solver.t ->
        'Syntax.formula list -> [ `Sat | `Unknown | `Unsat ]
      val to_string : 'SrkZ3.Solver.t -> string
      val get_model :
        ?symbols:Syntax.symbol list ->
        'SrkZ3.Solver.t ->
        [ `Sat of 'Interpretation.interpretation | `Unknown | `Unsat ]
      val get_concrete_model :
        'SrkZ3.Solver.t ->
        Syntax.symbol list ->
        [ `Sat of 'Interpretation.interpretation | `Unknown | `Unsat ]
      val get_unsat_core :
        'SrkZ3.Solver.t ->
        'Syntax.formula list ->
        [ `Sat | `Unknown | `Unsat of 'Syntax.formula list ]
    end
  val mk_solver :
    ?context:SrkZ3.z3_context ->
    ?theory:string -> 'Syntax.context -> 'SrkZ3.Solver.t
  val optimize_box :
    ?context:SrkZ3.z3_context ->
    'Syntax.context ->
    'Syntax.formula ->
    'Syntax.term list -> [ `Sat of Interval.t list | `Unknown | `Unsat ]
  val qe :
    ?context:SrkZ3.z3_context ->
    'Syntax.context -> 'Syntax.formula -> 'Syntax.formula
  val load_smtlib2 :
    ?context:SrkZ3.z3_context ->
    'Syntax.context -> string -> 'Syntax.formula
  val interpolate_seq :
    ?context:SrkZ3.z3_context ->
    'Syntax.context ->
    'Syntax.formula list ->
    [ `Sat of 'Interpretation.interpretation
    | `Unknown
    | `Unsat of 'Syntax.formula list ]
  module CHC :
    sig
      type 'a solver
      val mk_solver :
        ?context:SrkZ3.z3_context -> 'Syntax.context -> 'SrkZ3.CHC.solver
      val register_relation : 'SrkZ3.CHC.solver -> Syntax.symbol -> unit
      val add_rule :
        'SrkZ3.CHC.solver -> 'Syntax.formula -> 'Syntax.formula -> unit
      val add : 'SrkZ3.CHC.solver -> 'Syntax.formula list -> unit
      val check :
        'SrkZ3.CHC.solver ->
        'Syntax.formula list -> [ `Sat | `Unknown | `Unsat ]
      val get_solution :
        'SrkZ3.CHC.solver -> Syntax.symbol -> 'Syntax.formula
      val to_string : 'SrkZ3.CHC.solver -> string
      val push : 'SrkZ3.CHC.solver -> unit
      val pop : 'SrkZ3.CHC.solver -> unit
    end
end