functor
  (Elem : sig
            type t
            val equal : Retype.t -> Retype.t -> bool
            val prefer : Retype.t -> Retype.t -> int
          end->
  functor
    (ElemSet : sig
                 type elt = Elem.t
                 type t
                 val empty : t
                 val is_empty : t -> bool
                 val mem : elt -> t -> bool
                 val add : elt -> t -> t
                 val singleton : elt -> t
                 val remove : elt -> t -> t
                 val union : t -> t -> t
                 val inter : t -> t -> t
                 val diff : t -> t -> t
                 val compare : t -> t -> int
                 val equal : t -> t -> bool
                 val subset : t -> t -> bool
                 val iter : (elt -> unit) -> t -> unit
                 val fold : (elt -> '-> 'a) -> t -> '-> 'a
                 val for_all : (elt -> bool) -> t -> bool
                 val exists : (elt -> bool) -> t -> bool
                 val filter : (elt -> bool) -> t -> t
                 val partition : (elt -> bool) -> t -> t * t
                 val cardinal : t -> int
                 val elements : t -> elt list
                 val min_elt : t -> elt
                 val max_elt : t -> elt
                 val choose : t -> elt
                 val split : elt -> t -> t * bool * t
               end->
    functor
      (ElemTable : sig
                     type key = Elem.t
                     type 'a t
                     val create : int -> 'a t
                     val clear : 'a t -> unit
                     val copy : 'a t -> 'a t
                     val add : 'a t -> key -> '-> unit
                     val remove : 'a t -> key -> unit
                     val find : 'a t -> key -> 'a
                     val find_all : 'a t -> key -> 'a list
                     val replace : 'a t -> key -> '-> unit
                     val mem : 'a t -> key -> bool
                     val iter : (key -> '-> unit) -> 'a t -> unit
                     val fold : (key -> '-> '-> 'b) -> 'a t -> '-> 'b
                     val length : 'a t -> int
                   end->
      sig
        val table : ElemTable.key ElemTable.t
        val ranks : int ElemTable.t
        val repr : ElemTable.key -> ElemTable.key
        val rank : ElemTable.key -> int
        val unify : ElemTable.key -> ElemTable.key -> unit
        val classes : unit -> ElemSet.t list
        val one_class : ElemTable.key -> ElemTable.key list
        val same_class : ElemTable.key -> ElemTable.key -> bool
      end