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