sig
  type tau =
      Integer
    | Real
    | Boolean
    | Pointer of Formula.tau
    | Set of Formula.tau
    | Record of Cil_types.compinfo
    | Array of Ctypes.arrayinfo
    | ADT of string * Formula.tau list
  type kind =
      Model of Formula.tau
    | Acsl of Formula.tau * Cil_types.logic_type
  type m_boolean
  type m_integer
  type m_real
  type m_abstract
  type m_name
  type m_pointer
  type m_array
  type m_record
  type m_urecord
  type m_set
  type m_zone
  type int_op = Iadd | Isub | Imul | Idiv | Imod
  type real_op = Radd | Rsub | Rmul | Rdiv
  type cmp_op = Ceq | Cneq | Clt | Cleq
  type section =
      S_Type
    | S_Cons
    | S_Logic_Sig
    | S_Logic_Def
    | S_Logic_Prop
    | S_Model_Sig
    | S_Model_Def
    | S_Model_Prop
    | S_User_Sig
    | S_User_Prop
  type ('a, 'b, 'c) item =
      Type of int
    | Cons of int
    | Function of Formula.tau list * Formula.tau
    | Predicate of Formula.tau list
    | FunctionDef of 'a list * Formula.tau * 'b
    | PredicateDef of 'a list * 'c
    | Axiom of 'c
    | Trecord of Cil_types.compinfo
  type ('a, 'b, 'c) declaration = {
    d_section : Formula.section;
    d_name : string;
    d_title : Format.formatter -> unit;
    d_descr : Format.formatter -> unit;
    d_source : Lexing.position option;
    d_item : ('a, 'b, 'c) Formula.item;
  }
  module type S =
    sig
      type var
      type 'a term
      type pred
      type abstract = Formula.m_abstract Formula.S.term
      type integer = Formula.m_integer Formula.S.term
      type real = Formula.m_real Formula.S.term
      type boolean = Formula.m_boolean Formula.S.term
      type record = Formula.m_record Formula.S.term
      type urecord = Formula.m_array Formula.S.term
      type array = Formula.m_array Formula.S.term
      type set = Formula.m_set Formula.S.term
      type name = Formula.m_integer Formula.S.term
      type decl =
          (Formula.S.var, Formula.S.abstract, Formula.S.pred)
          Formula.declaration
      val e_int : int -> Formula.S.integer
      val e_call : string -> Formula.S.abstract list -> Formula.S.abstract
      val p_call : string -> Formula.S.abstract list -> Formula.S.pred
      val wrap : 'Formula.S.term -> Formula.S.abstract
      val unwrap : Formula.S.abstract -> 'Formula.S.term
      val clear : unit -> unit
      val on_clear : (unit -> unit) -> unit
      val fresh_name : string -> string -> string
      val add_declaration : Formula.S.decl -> unit
      val has_declaration : string -> bool
      val iter_all : (string -> unit) -> (Formula.S.decl -> unit) -> unit
      module type Identifiable =
        sig
          type t
          module H : Hashtbl.S
          val index : Formula.S.Identifiable.t -> H.key
          val prefix : string
          val basename : Formula.S.Identifiable.t -> string
          val location : Formula.S.Identifiable.t -> Lexing.position option
          val pp_title : Format.formatter -> Formula.S.Identifiable.t -> unit
          val pp_descr : Format.formatter -> Formula.S.Identifiable.t -> unit
        end
      module type Registry =
        sig
          type t
          val define : Formula.S.Registry.t -> unit
          val get_definition : Formula.S.Registry.t -> Formula.S.decl
          val on_definition :
            (Formula.S.Registry.t -> Formula.S.decl -> unit) -> unit
        end
      module type Declarator =
        sig
          type t
          module H : Hashtbl.S
          val index : t -> H.key
          val prefix : string
          val basename : t -> string
          val location : t -> Lexing.position option
          val pp_title : Format.formatter -> t -> unit
          val pp_descr : Format.formatter -> t -> unit
          val clear : unit -> unit
          val section : Formula.section
          val declare :
            t ->
            string ->
            (Formula.S.var, Formula.S.abstract, Formula.S.pred) Formula.item
        end
      module DRegister :
        functor (D : Declarator->
          sig
            type t = D.t
            val define : t -> unit
            val get_definition : t -> decl
            val on_definition : (t -> decl -> unit) -> unit
          end
      module Varinfo :
        sig
          type t = Cil_types.varinfo
          module H : Hashtbl.S
          val index : t -> H.key
          val prefix : string
          val basename : t -> string
          val location : t -> Lexing.position option
          val pp_title : Format.formatter -> t -> unit
          val pp_descr : Format.formatter -> t -> unit
        end
      module Varaddr :
        sig
          type t = Cil_types.varinfo
          module H : Hashtbl.S
          val index : t -> H.key
          val prefix : string
          val basename : t -> string
          val location : t -> Lexing.position option
          val pp_title : Format.formatter -> t -> unit
          val pp_descr : Format.formatter -> t -> unit
        end
      module Fieldinfo :
        sig
          type t = Cil_types.fieldinfo
          module H : Hashtbl.S
          val index : t -> H.key
          val prefix : string
          val basename : t -> string
          val location : t -> Lexing.position option
          val pp_title : Format.formatter -> t -> unit
          val pp_descr : Format.formatter -> t -> unit
        end
      module Compinfo :
        sig
          type t = Cil_types.compinfo
          module H : Hashtbl.S
          val index : t -> H.key
          val prefix : string
          val basename : t -> string
          val location : t -> Lexing.position option
          val pp_title : Format.formatter -> t -> unit
          val pp_descr : Format.formatter -> t -> unit
        end
      module Arrayinfo :
        sig
          type t = Ctypes.arrayinfo
          module H : Hashtbl.S
          val index : t -> H.key
          val prefix : string
          val basename : t -> string
          val location : t -> Lexing.position option
          val pp_title : Format.formatter -> t -> unit
          val pp_descr : Format.formatter -> t -> unit
        end
      module Logicvar :
        sig
          type t = Cil_types.logic_var
          module H : Hashtbl.S
          val index : t -> H.key
          val prefix : string
          val basename : t -> string
          val location : t -> Lexing.position option
          val pp_title : Format.formatter -> t -> unit
          val pp_descr : Format.formatter -> t -> unit
        end
      module LTypeinfo :
        sig
          type t = Cil_types.logic_type
          module H : Hashtbl.S
          val index : t -> H.key
          val prefix : string
          val basename : t -> string
          val location : t -> Lexing.position option
          val pp_title : Format.formatter -> t -> unit
          val pp_descr : Format.formatter -> t -> unit
        end
      module Cobject :
        sig
          type t = Ctypes.c_object
          module H : Hashtbl.S
          val index : t -> H.key
          val prefix : string
          val basename : t -> string
          val location : t -> Lexing.position option
          val pp_title : Format.formatter -> t -> unit
          val pp_descr : Format.formatter -> t -> unit
        end
      module ArrayDim :
        sig
          type t = Ctypes.c_object * int
          module H : Hashtbl.S
          val index : t -> H.key
          val prefix : string
          val basename : t -> string
          val location : t -> Lexing.position option
          val pp_title : Format.formatter -> t -> unit
          val pp_descr : Format.formatter -> t -> unit
        end
      val adt_decl : Cil_types.logic_type_info -> string
      val pp_tau : Format.formatter -> Formula.tau -> unit
      val e_true : Formula.S.boolean
      val e_false : Formula.S.boolean
      val e_float : float -> Formula.S.real
      val e_icst : string -> Formula.S.integer
      val e_rcst : string -> Formula.S.real
      val e_int64 : int64 -> Formula.S.integer
      val e_ineg : Formula.S.integer -> Formula.S.integer
      val e_rneg : Formula.S.real -> Formula.S.real
      val e_iop :
        Formula.int_op ->
        Formula.S.integer -> Formula.S.integer -> Formula.S.integer
      val e_rop :
        Formula.real_op -> Formula.S.real -> Formula.S.real -> Formula.S.real
      val e_icmp :
        Formula.cmp_op ->
        Formula.S.integer -> Formula.S.integer -> Formula.S.boolean
      val e_rcmp :
        Formula.cmp_op ->
        Formula.S.real -> Formula.S.real -> Formula.S.boolean
      val p_icmp :
        Formula.cmp_op ->
        Formula.S.integer -> Formula.S.integer -> Formula.S.pred
      val p_rcmp :
        Formula.cmp_op -> Formula.S.real -> Formula.S.real -> Formula.S.pred
      val e_bnot : Formula.S.integer -> Formula.S.integer
      val e_band :
        Formula.S.integer -> Formula.S.integer -> Formula.S.integer
      val e_bor : Formula.S.integer -> Formula.S.integer -> Formula.S.integer
      val e_bxor :
        Formula.S.integer -> Formula.S.integer -> Formula.S.integer
      val e_lshift :
        Formula.S.integer -> Formula.S.integer -> Formula.S.integer
      val e_rshift :
        Formula.S.integer -> Formula.S.integer -> Formula.S.integer
      val integer_of_real : Formula.S.real -> Formula.S.integer
      val real_of_integer : Formula.S.integer -> Formula.S.real
      val e_bool : Formula.S.boolean -> Formula.S.integer
      val e_not : Formula.S.boolean -> Formula.S.boolean
      val e_and : Formula.S.boolean -> Formula.S.boolean -> Formula.S.boolean
      val e_or : Formula.S.boolean -> Formula.S.boolean -> Formula.S.boolean
      val e_cond :
        Formula.S.boolean ->
        'Formula.S.term -> 'Formula.S.term -> 'Formula.S.term
      val p_cond :
        Formula.S.boolean ->
        Formula.S.pred -> Formula.S.pred -> Formula.S.pred
      val e_getfield :
        Cil_types.fieldinfo -> Formula.S.record -> Formula.S.abstract
      val e_setfield :
        Cil_types.fieldinfo ->
        Formula.S.record -> Formula.S.abstract -> Formula.S.record
      val e_access :
        Formula.S.array -> Formula.S.integer -> Formula.S.abstract
      val e_update :
        Formula.S.array ->
        Formula.S.integer -> Formula.S.abstract -> Formula.S.array
      val p_true : Formula.S.pred
      val p_false : Formula.S.pred
      val p_bool : Formula.S.boolean -> Formula.S.pred
      val p_and : Formula.S.pred -> Formula.S.pred -> Formula.S.pred
      val p_or : Formula.S.pred -> Formula.S.pred -> Formula.S.pred
      val p_xor : Formula.S.pred -> Formula.S.pred -> Formula.S.pred
      val p_not : Formula.S.pred -> Formula.S.pred
      val p_implies : Formula.S.pred -> Formula.S.pred -> Formula.S.pred
      val p_iff : Formula.S.pred -> Formula.S.pred -> Formula.S.pred
      val p_eq : 'Formula.S.term -> 'Formula.S.term -> Formula.S.pred
      val p_neq : 'Formula.S.term -> 'Formula.S.term -> Formula.S.pred
      val p_conj : Formula.S.pred list -> Formula.S.pred
      val p_disj : Formula.S.pred list -> Formula.S.pred
      val p_named : string -> Formula.S.pred -> Formula.S.pred
      val is_true : Formula.S.pred -> bool
      val is_false : Formula.S.pred -> bool
      val huge_term : int -> 'Formula.S.term -> bool
      val huge_pred : int -> Formula.S.pred -> bool
      type pool
      val pool : unit -> Formula.S.pool
      val p_fresh : Formula.S.pool -> string -> Formula.kind -> Formula.S.var
      val p_freshen : Formula.S.pool -> Formula.S.var -> Formula.S.var
      val var : Formula.S.var -> 'Formula.S.term
      val eq_var : Formula.S.var -> Formula.S.var -> bool
      val name_of_var : Formula.S.var -> string
      val basename_of_var : Formula.S.var -> string
      val tau_of_var : Formula.S.var -> Formula.tau
      val kind_of_var : Formula.S.var -> Formula.kind
      val term_has_var : Formula.S.var list -> 'Formula.S.term -> bool
      val pred_has_var : Formula.S.var list -> Formula.S.pred -> bool
      val term_calls : string -> 'Formula.S.term -> bool
      val pred_calls : string -> Formula.S.pred -> bool
      val term_closed : 'Formula.S.term -> bool
      val pred_closed : Formula.S.pred -> bool
      val freevars : Formula.S.pred -> Formula.S.var list
      val p_forall : Formula.S.var list -> Formula.S.pred -> Formula.S.pred
      val p_exists : Formula.S.var list -> Formula.S.pred -> Formula.S.pred
      val p_subst :
        (Formula.S.var -> Formula.S.var option) ->
        Formula.S.var ->
        'Formula.S.term -> Formula.S.pred -> Formula.S.pred
      val e_subst :
        (Formula.S.var -> Formula.S.var option) ->
        Formula.S.var ->
        'Formula.S.term -> 'Formula.S.term -> 'Formula.S.term
      val e_rename :
        (Formula.S.var * Formula.S.var) list ->
        'Formula.S.term -> 'Formula.S.term
      val equal_terms : 'Formula.S.term -> 'Formula.S.term -> bool
      type alpha
      val empty_alpha : Formula.S.alpha
      val fold_alpha :
        (Formula.S.var -> Formula.S.var -> '-> 'a) ->
        Formula.S.alpha -> '-> 'a
      val p_more_alpha_cv :
        Formula.S.alpha -> Formula.S.pred -> Formula.S.alpha * Formula.S.pred
      val p_alpha_cv : Formula.S.pred -> Formula.S.var list * Formula.S.pred
      val pp_var : Format.formatter -> Formula.S.var -> unit
      val pp_section : Format.formatter -> string -> unit
      val pp_term : Format.formatter -> 'Formula.S.term -> unit
      val pp_pred : Format.formatter -> Formula.S.pred -> unit
      val pp_decl : Format.formatter -> Formula.S.decl -> unit
      val pp_goal : Format.formatter -> string -> Formula.S.pred -> unit
      val pp_vkind : Format.formatter -> Formula.kind -> unit
      val e_app0 : string -> 'Formula.S.term
      val e_app1 : string -> 'Formula.S.term -> 'Formula.S.term
      val e_app2 :
        string -> 'Formula.S.term -> 'Formula.S.term -> 'Formula.S.term
      val e_app3 :
        string ->
        'Formula.S.term ->
        'Formula.S.term -> 'Formula.S.term -> 'Formula.S.term
      val e_app4 :
        string ->
        'Formula.S.term ->
        'Formula.S.term ->
        'Formula.S.term -> 'Formula.S.term -> 'Formula.S.term
      val e_app5 :
        string ->
        'Formula.S.term ->
        'Formula.S.term ->
        'Formula.S.term ->
        'Formula.S.term -> 'Formula.S.term -> 'Formula.S.term
      val p_app0 : string -> Formula.S.pred
      val p_app1 : string -> 'Formula.S.term -> Formula.S.pred
      val p_app2 :
        string -> 'Formula.S.term -> 'Formula.S.term -> Formula.S.pred
      val p_app3 :
        string ->
        'Formula.S.term ->
        'Formula.S.term -> 'Formula.S.term -> Formula.S.pred
      val p_app4 :
        string ->
        'Formula.S.term ->
        'Formula.S.term ->
        'Formula.S.term -> 'Formula.S.term -> Formula.S.pred
      val p_app5 :
        string ->
        'Formula.S.term ->
        'Formula.S.term ->
        'Formula.S.term ->
        'Formula.S.term -> 'Formula.S.term -> Formula.S.pred
      val dummy : unit -> Formula.S.pred
      val i_zero : Formula.S.integer
      val r_zero : Formula.S.real
      val i_one : Formula.S.integer
      val i_add : Formula.S.integer -> Formula.S.integer -> Formula.S.integer
      val i_mult :
        Formula.S.integer -> Formula.S.integer -> Formula.S.integer
      val i_sub : Formula.S.integer -> Formula.S.integer -> Formula.S.integer
      val guard : Ctypes.c_int -> Formula.S.integer -> Formula.S.pred
      val modulo : Ctypes.c_int -> Formula.S.integer -> Formula.S.integer
      val i_convert :
        Ctypes.c_int ->
        Ctypes.c_int -> Formula.S.integer -> Formula.S.integer
      type interval = {
        inf : Formula.S.integer option;
        sup : Formula.S.integer option;
      }
      type 'a assigned =
          Aloc of Ctypes.c_object * 'a
        | Arange of Ctypes.c_object * 'a * Formula.S.interval
      type havoc =
          Fresh of Formula.S.var
        | Update of Formula.S.var *
            ((Formula.S.var * Formula.S.var) list -> Formula.S.abstract)
      val pp_interval : Format.formatter -> Formula.S.interval -> unit
      val set_range_index :
        Formula.S.array -> Formula.S.interval -> Formula.S.array
      val empty : Formula.S.set
      val singleton : Formula.S.abstract -> Formula.S.set
      val union : Formula.S.set -> Formula.S.set -> Formula.S.set
      val unions : Formula.S.set list -> Formula.S.set
      val inter : Formula.S.set -> Formula.S.set -> Formula.S.set
      val remove : Formula.S.set -> Formula.S.set -> Formula.S.set
      val set_of_list : Formula.S.abstract list -> Formula.S.set
      val add_set : Formula.S.set -> Formula.S.set -> Formula.S.set
      val mult_set : Formula.S.set -> Formula.S.set -> Formula.S.set
      val neg_set : Formula.S.set -> Formula.S.set
      val interval : Formula.S.interval -> Formula.S.set
      val acc_field :
        Formula.S.record -> Cil_types.fieldinfo -> Formula.S.abstract
      val upd_field :
        Formula.S.record ->
        Cil_types.fieldinfo -> Formula.S.abstract -> Formula.S.record
      val acc_index :
        Formula.S.array -> Formula.S.integer -> Formula.S.abstract
      val upd_index :
        Formula.S.array ->
        Formula.S.integer -> Formula.S.abstract -> Formula.S.array
      module type Indexed =
        sig
          type t
          val define : t -> unit
          val get_definition : t -> decl
          val on_definition : (t -> decl -> unit) -> unit
          val get_ind : t -> Formula.S.integer
          val has_ind : t -> Formula.S.pred -> bool
        end
      module Dindex :
        functor (I : Identifiable->
          sig
            type t = I.t
            val define : t -> unit
            val get_definition : t -> decl
            val on_definition : (t -> decl -> unit) -> unit
            val get_ind : t -> integer
            val has_ind : t -> pred -> bool
          end
      module Findex :
        sig
          type t = Cil_types.fieldinfo
          val define : t -> unit
          val get_definition : t -> decl
          val on_definition : (t -> decl -> unit) -> unit
          val get_ind : t -> integer
          val has_ind : t -> pred -> bool
        end
      module Xindex :
        sig
          type t = Cil_types.varinfo
          val define : t -> unit
          val get_definition : t -> decl
          val on_definition : (t -> decl -> unit) -> unit
          val get_ind : t -> integer
          val has_ind : t -> pred -> bool
        end
      module Aindex :
        sig
          type t = Cil_types.varinfo
          val define : t -> unit
          val get_definition : t -> decl
          val on_definition : (t -> decl -> unit) -> unit
          val get_ind : t -> integer
          val has_ind : t -> pred -> bool
        end
      module Tindex :
        sig
          type t = Cil_types.compinfo
          val define : t -> unit
          val get_definition : t -> decl
          val on_definition : (t -> decl -> unit) -> unit
          val get_ind : t -> integer
          val has_ind : t -> pred -> bool
        end
      module LTindex :
        sig
          type t = Cil_types.logic_type
          val define : t -> unit
          val get_definition : t -> decl
          val on_definition : (t -> decl -> unit) -> unit
          val get_ind : t -> integer
          val has_ind : t -> pred -> bool
        end
    end
  module type Logic =
    sig
      module F : S
      type context
      type bindings
      val closed : Formula.Logic.bindings
      val close : Formula.Logic.bindings -> F.pred -> F.pred
      val push :
        string -> F.pool -> Formula.Logic.bindings -> Formula.Logic.context
      val pop : string -> Formula.Logic.context -> Formula.Logic.bindings
      val kill : string -> Formula.Logic.context -> unit
      val flush : string -> Formula.Logic.context -> F.pred -> F.pred
      val term_such_that : Formula.tau -> ('F.term -> F.pred) -> 'F.term
      val forall : F.var list -> F.pred -> F.pred
      val exists : F.var list -> F.pred -> F.pred
      val subst : F.var -> 'F.term -> F.pred -> F.pred
      val fresh : string -> Formula.kind -> F.var
      val alpha : F.var -> F.var option
      val pool : unit -> F.pool
      val vkind_of_var : F.var -> Formula.kind
      val has_context_vars : F.var list -> F.pred -> bool
      val has_type : F.abstract -> Cil_types.logic_type -> F.pred
      val is_comp : Cil_types.compinfo -> F.abstract -> F.pred
      val is_array : Ctypes.arrayinfo -> F.abstract -> F.pred
      val apply : (F.var * F.var) list -> 'F.term -> 'F.term
      val havoc_static : F.havoc list -> F.pred -> F.pred
      val havoc_inductive : F.havoc list -> F.pred -> F.pred
    end
end