sig
  type 'a or_bottom = [ `Bottom | `Value of 'a ]
  type 'a or_top = [ `Top | `Value of 'a ]
  type 'a or_top_bottom = [ `Bottom | `Top | `Value of 'a ]
  module Bottom :
    sig
      type 'a t = 'a Lattice_bounds.or_bottom
      module Operators :
        sig
          val ( >>- ) :
            [< 'a Lattice_bounds.Bottom.t ] ->
            ('a -> ([> 'b Lattice_bounds.Bottom.t ] as 'c)) -> 'c
          val ( >>-: ) :
            [< 'a Lattice_bounds.Bottom.t ] ->
            ('a -> 'b) -> [> 'b Lattice_bounds.Bottom.t ]
          val ( let+ ) :
            [< 'a Lattice_bounds.Bottom.t ] ->
            ('a -> 'b) -> [> 'b Lattice_bounds.Bottom.t ]
          val ( and+ ) :
            [< 'a Lattice_bounds.Bottom.t ] ->
            [< 'b Lattice_bounds.Bottom.t ] ->
            [> ('a * 'b) Lattice_bounds.Bottom.t ]
          val ( let* ) :
            [< 'a Lattice_bounds.Bottom.t ] ->
            ('a -> ([> 'b Lattice_bounds.Bottom.t ] as 'c)) -> 'c
          val ( and* ) :
            [< 'a Lattice_bounds.Bottom.t ] ->
            [< 'b Lattice_bounds.Bottom.t ] ->
            [> ('a * 'b) Lattice_bounds.Bottom.t ]
        end
      module Make_Datatype :
        functor (Domain : Datatype.S) ->
          sig
            type t = Domain.t or_bottom
            val ty : t Type.t
            val name : string
            val descr : t Descr.t
            val packed_descr : Structural_descr.pack
            val reprs : t list
            val equal : t -> t -> bool
            val compare : t -> t -> int
            val hash : t -> int
            val pretty_code : Format.formatter -> t -> unit
            val internal_pretty_code :
              Type.precedence -> Format.formatter -> t -> unit
            val pretty : Format.formatter -> t -> unit
            val varname : t -> string
            val mem_project : (Project_skeleton.t -> bool) -> t -> bool
            val copy : t -> t
          end
      module Bound_Lattice :
        functor (Lattice : Lattice_type.Join_Semi_Lattice) ->
          sig
            type t = Lattice.t or_bottom
            val ty : t Type.t
            val name : string
            val descr : t Descr.t
            val packed_descr : Structural_descr.pack
            val reprs : t list
            val equal : t -> t -> bool
            val compare : t -> t -> int
            val hash : t -> int
            val pretty_code : Format.formatter -> t -> unit
            val internal_pretty_code :
              Type.precedence -> Format.formatter -> t -> unit
            val pretty : Format.formatter -> t -> unit
            val varname : t -> string
            val mem_project : (Project_skeleton.t -> bool) -> t -> bool
            val copy : t -> t
            val join : t -> t -> t
            val is_included : t -> t -> bool
            val bottom : t
          end
      val is_bottom : 'a Lattice_bounds.Bottom.t -> bool
      val non_bottom : 'a Lattice_bounds.Bottom.t -> 'a
      val value : bottom:'a -> 'a Lattice_bounds.Bottom.t -> 'a
      val hash : ('a -> int) -> 'a Lattice_bounds.Bottom.t -> int
      val equal :
        ('a -> 'a -> bool) ->
        'a Lattice_bounds.Bottom.t -> 'a Lattice_bounds.Bottom.t -> bool
      val compare :
        ('a -> 'a -> int) ->
        'a Lattice_bounds.Bottom.t -> 'a Lattice_bounds.Bottom.t -> int
      val pretty_bottom : Stdlib.Format.formatter -> unit
      val pretty :
        (Stdlib.Format.formatter -> 'a -> unit) ->
        Stdlib.Format.formatter -> 'a Lattice_bounds.Bottom.t -> unit
      val is_included :
        ('a -> 'b -> bool) ->
        'a Lattice_bounds.Bottom.t -> 'b Lattice_bounds.Bottom.t -> bool
      val join :
        ('a -> 'a -> 'a) ->
        'a Lattice_bounds.Bottom.t ->
        'a Lattice_bounds.Bottom.t -> 'a Lattice_bounds.Bottom.t
      val join_list :
        ('a -> 'a -> 'a) ->
        'a Lattice_bounds.Bottom.t list -> 'a Lattice_bounds.Bottom.t
      val narrow :
        ('a -> 'a -> 'a Lattice_bounds.Bottom.t) ->
        'a Lattice_bounds.Bottom.t ->
        'a Lattice_bounds.Bottom.t -> 'a Lattice_bounds.Bottom.t
      val iter : ('a -> unit) -> 'a Lattice_bounds.Bottom.t -> unit
      val fold : bottom:'b -> ('a -> 'b) -> 'a Lattice_bounds.Bottom.t -> 'b
      val map :
        ('a -> 'b) ->
        'a Lattice_bounds.Bottom.t -> 'b Lattice_bounds.Bottom.t
      val zip :
        'a Lattice_bounds.Bottom.t ->
        'b Lattice_bounds.Bottom.t -> ('a * 'b) Lattice_bounds.Bottom.t
      val to_option : 'a Lattice_bounds.Bottom.t -> 'a option
      val of_option : 'a option -> 'a Lattice_bounds.Bottom.t
      val to_list : 'a Lattice_bounds.Bottom.t -> 'a list
      val bot_of_list : 'a list -> 'a list Lattice_bounds.Bottom.t
      val list_of_bot : 'a list Lattice_bounds.Bottom.t -> 'a list
      val list_values : 'a Lattice_bounds.Bottom.t list -> 'a list
      val add_to_list : 'a Lattice_bounds.Bottom.t -> 'a list -> 'a list
    end
  module Top :
    sig
      type 'a t = 'a Lattice_bounds.or_top
      module Operators :
        sig
          val ( >>- ) :
            [< 'a Lattice_bounds.Top.t ] ->
            ('a -> ([> 'b Lattice_bounds.Top.t ] as 'c)) -> 'c
          val ( >>-: ) :
            [< 'a Lattice_bounds.Top.t ] ->
            ('a -> 'b) -> [> 'b Lattice_bounds.Top.t ]
          val ( let+ ) :
            [< 'a Lattice_bounds.Top.t ] ->
            ('a -> 'b) -> [> 'b Lattice_bounds.Top.t ]
          val ( and+ ) :
            [< 'a Lattice_bounds.Top.t ] ->
            [< 'b Lattice_bounds.Top.t ] ->
            [> ('a * 'b) Lattice_bounds.Top.t ]
          val ( let* ) :
            [< 'a Lattice_bounds.Top.t ] ->
            ('a -> ([> 'b Lattice_bounds.Top.t ] as 'c)) -> 'c
          val ( and* ) :
            [< 'a Lattice_bounds.Top.t ] ->
            [< 'b Lattice_bounds.Top.t ] ->
            [> ('a * 'b) Lattice_bounds.Top.t ]
        end
      val is_top : 'a Lattice_bounds.Top.t -> bool
      val non_top : 'a Lattice_bounds.Top.t -> 'a
      val value : top:'a -> 'a Lattice_bounds.Top.t -> 'a
      val hash : ('a -> int) -> 'a Lattice_bounds.Top.t -> int
      val equal :
        ('a -> 'a -> bool) ->
        'a Lattice_bounds.Top.t -> 'a Lattice_bounds.Top.t -> bool
      val compare :
        ('a -> 'a -> int) ->
        'a Lattice_bounds.Top.t -> 'a Lattice_bounds.Top.t -> int
      val pretty_top : Stdlib.Format.formatter -> unit
      val pretty :
        (Stdlib.Format.formatter -> 'a -> unit) ->
        Stdlib.Format.formatter -> 'a Lattice_bounds.Top.t -> unit
      val join :
        ('a -> 'a -> 'a Lattice_bounds.Top.t) ->
        'a Lattice_bounds.Top.t ->
        'a Lattice_bounds.Top.t -> 'a Lattice_bounds.Top.t
      val narrow :
        ('a -> 'a -> 'a) ->
        'a Lattice_bounds.Top.t ->
        'a Lattice_bounds.Top.t -> 'a Lattice_bounds.Top.t
      val zip :
        'a Lattice_bounds.Top.t ->
        'b Lattice_bounds.Top.t -> ('a * 'b) Lattice_bounds.Top.t
      val to_option : 'a Lattice_bounds.Top.t -> 'a option
      val of_option : 'a option -> 'a Lattice_bounds.Top.t
    end
  module TopBottom :
    sig
      type 'a t = 'a Lattice_bounds.or_top_bottom
      module Operators :
        sig
          val ( >>- ) :
            [< 'a Lattice_bounds.TopBottom.t ] ->
            ('a -> ([> 'b Lattice_bounds.TopBottom.t ] as 'c)) -> 'c
          val ( >>-: ) :
            [< 'a Lattice_bounds.TopBottom.t ] ->
            ('a -> 'b) -> [> 'b Lattice_bounds.TopBottom.t ]
          val ( let+ ) :
            [< 'a Lattice_bounds.TopBottom.t ] ->
            ('a -> 'b) -> [> 'b Lattice_bounds.TopBottom.t ]
          val ( and+ ) :
            [< 'a Lattice_bounds.TopBottom.t ] ->
            [< 'b Lattice_bounds.TopBottom.t ] ->
            [> ('a * 'b) Lattice_bounds.TopBottom.t ]
          val ( let* ) :
            [< 'a Lattice_bounds.TopBottom.t ] ->
            ('a -> ([> 'b Lattice_bounds.TopBottom.t ] as 'c)) -> 'c
          val ( and* ) :
            [< 'a Lattice_bounds.TopBottom.t ] ->
            [< 'b Lattice_bounds.TopBottom.t ] ->
            [> ('a * 'b) Lattice_bounds.TopBottom.t ]
        end
      val hash : ('a -> int) -> 'a Lattice_bounds.TopBottom.t -> int
      val equal :
        ('a -> 'a -> bool) ->
        'a Lattice_bounds.TopBottom.t ->
        'a Lattice_bounds.TopBottom.t -> bool
      val compare :
        ('a -> 'a -> int) ->
        'a Lattice_bounds.TopBottom.t -> 'a Lattice_bounds.TopBottom.t -> int
      val pretty :
        (Stdlib.Format.formatter -> 'a -> unit) ->
        Stdlib.Format.formatter -> 'a Lattice_bounds.TopBottom.t -> unit
      val join :
        ('a -> 'a -> [< 'a Lattice_bounds.TopBottom.t ]) ->
        'a Lattice_bounds.TopBottom.t ->
        'a Lattice_bounds.TopBottom.t -> 'a Lattice_bounds.TopBottom.t
      val narrow :
        ('a -> 'a -> [< 'a Lattice_bounds.TopBottom.t ]) ->
        'a Lattice_bounds.TopBottom.t ->
        'a Lattice_bounds.TopBottom.t -> 'a Lattice_bounds.TopBottom.t
    end
end