sig
  module type Domain =
    sig
      type t
      val lub : Solve.Domain.t -> Solve.Domain.t -> Solve.Domain.t
      val eq : Solve.Domain.t -> Solve.Domain.t -> bool
      val bot : Solve.Domain.t
    end
  module type ItemEq =
    sig type t val eq : Solve.ItemEq.t -> Solve.ItemEq.t -> bool end
  module type Solver =
    sig
      module I : ItemEq
      module D : Domain
      type item
      and domain
      and assign = Solve.Solver.item -> Solve.Solver.domain
      and system =
        Solve.Solver.item -> Solve.Solver.assign -> Solve.Solver.domain
      and equation =
        Solve.Solver.item * (Solve.Solver.assign -> Solve.Solver.domain)
      val solve :
        Solve.Solver.system ->
        Solve.Solver.item list ->
        (Solve.Solver.item, Solve.Solver.domain) Hashtbl.t
    end
  module Make :
    functor (Item : ItemEq->
      functor (Domain : Domain->
        sig
          module I : ItemEq
          module D : Domain
          type item = Item.t
          and domain = Domain.t
          and assign = Solve.Solver.item -> Solve.Solver.domain
          and system =
            Solve.Solver.item -> Solve.Solver.assign -> Solve.Solver.domain
          and equation =
            Solve.Solver.item * (Solve.Solver.assign -> Solve.Solver.domain)
          val solve :
            Solve.Solver.system ->
            Solve.Solver.item list ->
            (Solve.Solver.item, Solve.Solver.domain) Hashtbl.t
        end
end