sig
  module type VARS =
    sig
      module TVar :
        sig
          type obs
          type t
          val create : unit -> t
          val compare : t -> t -> int
          val total_ord : t -> t -> int
          val add_alias : t -> t -> unit
          val do_normalize : t -> unit
          val add_observer : obs -> t -> unit
          val remove_observer : obs -> t -> unit
          val string_of : t -> string
          val reset : unit -> unit
          val get_all_ts : unit -> t list
          type img
          type elm
          val set_lower : elm -> t -> unit
          val set_upper : elm -> t -> unit
          val set_eq : elm -> t -> unit
          val subset : t -> t -> unit
          val get_lower : t -> elm option
          val get_upper : t -> elm option
          val string_of_img : t -> string
          val get_exact : t -> elm option
          val string_of_with_img : t -> string
          val do_on_exact :
            ?nothing:(unit -> unit) -> ?something:(elm -> unit) -> t -> unit
          val do_on_lower :
            ?nothing:(unit -> unit) -> ?something:(elm -> unit) -> t -> unit
          val do_on_upper :
            ?nothing:(unit -> unit) -> ?something:(elm -> unit) -> t -> unit
        end
      module LSVar :
        sig
          type obs
          type t
          val create : unit -> t
          val compare : t -> t -> int
          val total_ord : t -> t -> int
          val add_alias : t -> t -> unit
          val do_normalize : t -> unit
          val add_observer : obs -> t -> unit
          val remove_observer : obs -> t -> unit
          val string_of : t -> string
          val reset : unit -> unit
          val get_all_ts : unit -> t list
          type img
          type elm = Location.LSet.t
          val set_lower : elm -> t -> unit
          val set_upper : elm -> t -> unit
          val set_eq : elm -> t -> unit
          val subset : t -> t -> unit
          val get_lower : t -> elm option
          val get_upper : t -> elm option
          val string_of_img : t -> string
          val get_exact : t -> elm option
          val string_of_with_img : t -> string
          val set_neg : elm -> t -> unit
          val disjoint : t -> t -> unit
          val get_neg : t -> elm option
          val lower_one_element :
            ?nothing:(unit -> unit) ->
            ?exact:(Location.Loc.t -> unit) ->
            ?tomuch:(unit -> unit) -> t -> unit
          val lower_iter : (Location.Loc.t -> unit) -> t -> unit
          val upper_iter : (Location.Loc.t -> unit) -> t -> unit
          val is_one_possible : t -> bool
          val equal_possible : t -> t -> bool
          val equal_possible_lset : t -> Location.LSet.t -> bool
          val subset_possible : t -> t -> bool
          val subset_possible_lset : t -> Location.LSet.t -> bool
          val choose_lower : t -> Location.Loc.t option
          val set_upper_for_all : Location.LSet.t -> unit
        end
      module PrVar :
        sig
          type obs
          type t
          val create : unit -> t
          val compare : t -> t -> int
          val total_ord : t -> t -> int
          val add_alias : t -> t -> unit
          val do_normalize : t -> unit
          val add_observer : obs -> t -> unit
          val remove_observer : obs -> t -> unit
          val string_of : t -> string
          val reset : unit -> unit
          val get_all_ts : unit -> t list
          type img
          type elm
          val set_lower : elm -> t -> unit
          val set_upper : elm -> t -> unit
          val set_eq : elm -> t -> unit
          val subset : t -> t -> unit
          val get_lower : t -> elm option
          val get_upper : t -> elm option
          val string_of_img : t -> string
          val get_exact : t -> elm option
          val string_of_with_img : t -> string
          val do_on_lower :
            ?nothing:(unit -> unit) ->
            ?exact:(unit -> unit) ->
            ?inexact:(unit -> unit) -> ?nv:(NoValue.nv -> unit) -> t -> unit
          val do_on_upper :
            ?nothing:(unit -> unit) ->
            ?exact:(unit -> unit) ->
            ?inexact:(unit -> unit) -> ?nv:(NoValue.nv -> unit) -> t -> unit
        end
      module ObjectType :
        sig type t type key = Syntax.label type img = Gvars.VARS.TVar.t end
      module OTVar :
        sig
          type obs
          type t
          val create : unit -> t
          val compare : t -> t -> int
          val total_ord : t -> t -> int
          val add_alias : t -> t -> unit
          val do_normalize : t -> unit
          val add_observer : obs -> t -> unit
          val remove_observer : obs -> t -> unit
          val string_of : t -> string
          val reset : unit -> unit
          val get_all_ts : unit -> t list
          type img
          module I : sig type key = Syntax.label type img = TVar.t end
          val domain : t -> I.key list
          val find' : I.key -> t -> I.img option
          val find_or_add :
            create:(unit -> I.img) -> key:I.key -> map:t -> I.img
          val iter : (I.key -> I.img -> unit) -> t -> unit
          val fold : (I.key -> I.img -> '-> 'a) -> t -> '-> 'a
          val make_write_equal :
            (I.key -> I.key -> int) ->
            (I.img -> I.img -> unit) -> t -> t -> I.key -> unit
          val string_of_map : t -> string
          val string_of_with_img : t -> string
          type domain_var
          val get_domain_var : t -> domain_var
        end
      module LEVar :
        sig
          type obs
          type t
          val create : unit -> t
          val compare : t -> t -> int
          val total_ord : t -> t -> int
          val add_alias : t -> t -> unit
          val do_normalize : t -> unit
          val add_observer : obs -> t -> unit
          val remove_observer : obs -> t -> unit
          val string_of : t -> string
          val reset : unit -> unit
          val get_all_ts : unit -> t list
          type img
          module I : sig type key = Location.Loc.t type img = OTVar.t end
          val domain : t -> I.key list
          val find' : I.key -> t -> I.img option
          val find_or_add :
            create:(unit -> I.img) -> key:I.key -> map:t -> I.img
          val iter : (I.key -> I.img -> unit) -> t -> unit
          val fold : (I.key -> I.img -> '-> 'a) -> t -> '-> 'a
          val make_write_equal :
            (I.key -> I.key -> int) ->
            (I.img -> I.img -> unit) -> t -> t -> I.key -> unit
          val string_of_map : t -> string
          val string_of_with_img : t -> string
          type domain_var = LSVar.t
          val get_domain_var : t -> domain_var
          val synchronize : t -> unit
        end
    end
  module type TYPE =
    sig
      type t
      val is_empty : t -> bool
      val subset : t -> t -> bool option
      val inter : t -> t -> t
      val union : t -> t -> t
      val compare : t -> t -> int
      val string_of : t -> string
      val normalize : t -> t
      val make_eq_lower : t -> t -> bool * t
      val make_eq_upper : t -> t -> bool * t
      val make_eq_eq : t -> t -> bool * t
      type obs
    end
  module Make :
    functor (Obs : GenVars.OBSERVER->
      functor
        (Type : sig
                  type t
                  val is_empty : t -> bool
                  val subset : t -> t -> bool option
                  val inter : t -> t -> t
                  val union : t -> t -> t
                  val compare : t -> t -> int
                  val string_of : t -> string
                  val normalize : t -> t
                  val make_eq_lower : t -> t -> bool * t
                  val make_eq_upper : t -> t -> bool * t
                  val make_eq_eq : t -> t -> bool * t
                  type obs = Obs.t
                end->
        functor
          (State : sig type obs = Obs.t val add_wl : obs -> unit end->
          sig
            module TVar :
              sig
                type obs = Obs.t
                type t
                val create : unit -> t
                val compare : t -> t -> int
                val total_ord : t -> t -> int
                val add_alias : t -> t -> unit
                val do_normalize : t -> unit
                val add_observer : obs -> t -> unit
                val remove_observer : obs -> t -> unit
                val string_of : t -> string
                val reset : unit -> unit
                val get_all_ts : unit -> t list
                type img
                type elm = Type.t
                val set_lower : elm -> t -> unit
                val set_upper : elm -> t -> unit
                val set_eq : elm -> t -> unit
                val subset : t -> t -> unit
                val get_lower : t -> elm option
                val get_upper : t -> elm option
                val string_of_img : t -> string
                val get_exact : t -> elm option
                val string_of_with_img : t -> string
                val do_on_exact :
                  ?nothing:(unit -> unit) ->
                  ?something:(elm -> unit) -> t -> unit
                val do_on_lower :
                  ?nothing:(unit -> unit) ->
                  ?something:(elm -> unit) -> t -> unit
                val do_on_upper :
                  ?nothing:(unit -> unit) ->
                  ?something:(elm -> unit) -> t -> unit
              end
            module LSVar :
              sig
                type obs = Obs.t
                type t
                val create : unit -> t
                val compare : t -> t -> int
                val total_ord : t -> t -> int
                val add_alias : t -> t -> unit
                val do_normalize : t -> unit
                val add_observer : obs -> t -> unit
                val remove_observer : obs -> t -> unit
                val string_of : t -> string
                val reset : unit -> unit
                val get_all_ts : unit -> t list
                type img
                type elm = Location.LSet.t
                val set_lower : elm -> t -> unit
                val set_upper : elm -> t -> unit
                val set_eq : elm -> t -> unit
                val subset : t -> t -> unit
                val get_lower : t -> elm option
                val get_upper : t -> elm option
                val string_of_img : t -> string
                val get_exact : t -> elm option
                val string_of_with_img : t -> string
                val set_neg : elm -> t -> unit
                val disjoint : t -> t -> unit
                val get_neg : t -> elm option
                val lower_one_element :
                  ?nothing:(unit -> unit) ->
                  ?exact:(Location.Loc.t -> unit) ->
                  ?tomuch:(unit -> unit) -> t -> unit
                val lower_iter : (Location.Loc.t -> unit) -> t -> unit
                val upper_iter : (Location.Loc.t -> unit) -> t -> unit
                val is_one_possible : t -> bool
                val equal_possible : t -> t -> bool
                val equal_possible_lset : t -> Location.LSet.t -> bool
                val subset_possible : t -> t -> bool
                val subset_possible_lset : t -> Location.LSet.t -> bool
                val choose_lower : t -> Location.Loc.t option
                val set_upper_for_all : Location.LSet.t -> unit
              end
            module PrVar :
              sig
                type obs = Obs.t
                type t
                val create : unit -> t
                val compare : t -> t -> int
                val total_ord : t -> t -> int
                val add_alias : t -> t -> unit
                val do_normalize : t -> unit
                val add_observer : obs -> t -> unit
                val remove_observer : obs -> t -> unit
                val string_of : t -> string
                val reset : unit -> unit
                val get_all_ts : unit -> t list
                type img
                type elm = Pre.t
                val set_lower : elm -> t -> unit
                val set_upper : elm -> t -> unit
                val set_eq : elm -> t -> unit
                val subset : t -> t -> unit
                val get_lower : t -> elm option
                val get_upper : t -> elm option
                val string_of_img : t -> string
                val get_exact : t -> elm option
                val string_of_with_img : t -> string
                val do_on_lower :
                  ?nothing:(unit -> unit) ->
                  ?exact:(unit -> unit) ->
                  ?inexact:(unit -> unit) ->
                  ?nv:(NoValue.nv -> unit) -> t -> unit
                val do_on_upper :
                  ?nothing:(unit -> unit) ->
                  ?exact:(unit -> unit) ->
                  ?inexact:(unit -> unit) ->
                  ?nv:(NoValue.nv -> unit) -> t -> unit
              end
            module ObjectType :
              sig type t type key = Syntax.label type img = TVar.t end
            module OTVar :
              sig
                type obs = Obs.t
                type t
                val create : unit -> t
                val compare : t -> t -> int
                val total_ord : t -> t -> int
                val add_alias : t -> t -> unit
                val do_normalize : t -> unit
                val add_observer : obs -> t -> unit
                val remove_observer : obs -> t -> unit
                val string_of : t -> string
                val reset : unit -> unit
                val get_all_ts : unit -> t list
                type img
                module I : sig type key = Syntax.label type img = TVar.t end
                val domain : t -> I.key list
                val find' : I.key -> t -> I.img option
                val find_or_add :
                  create:(unit -> I.img) -> key:I.key -> map:t -> I.img
                val iter : (I.key -> I.img -> unit) -> t -> unit
                val fold : (I.key -> I.img -> '-> 'a) -> t -> '-> 'a
                val make_write_equal :
                  (I.key -> I.key -> int) ->
                  (I.img -> I.img -> unit) -> t -> t -> I.key -> unit
                val string_of_map : t -> string
                val string_of_with_img : t -> string
                type domain_var
                val get_domain_var : t -> domain_var
              end
            module LEVar :
              sig
                type obs = Obs.t
                type t
                val create : unit -> t
                val compare : t -> t -> int
                val total_ord : t -> t -> int
                val add_alias : t -> t -> unit
                val do_normalize : t -> unit
                val add_observer : obs -> t -> unit
                val remove_observer : obs -> t -> unit
                val string_of : t -> string
                val reset : unit -> unit
                val get_all_ts : unit -> t list
                type img
                module I :
                  sig type key = Location.Loc.t type img = OTVar.t end
                val domain : t -> I.key list
                val find' : I.key -> t -> I.img option
                val find_or_add :
                  create:(unit -> I.img) -> key:I.key -> map:t -> I.img
                val iter : (I.key -> I.img -> unit) -> t -> unit
                val fold : (I.key -> I.img -> '-> 'a) -> t -> '-> 'a
                val make_write_equal :
                  (I.key -> I.key -> int) ->
                  (I.img -> I.img -> unit) -> t -> t -> I.key -> unit
                val string_of_map : t -> string
                val string_of_with_img : t -> string
                type domain_var = LSVar.t
                val get_domain_var : t -> domain_var
                val synchronize : t -> unit
              end
          end
end