sig
  type t
  val of_schs_and_cstr : cstr:Constraint.t -> schs:Schema.t list -> Block.t
  val schs_of : Block.t -> Schema.t list
  val cstr_of : Block.t -> Constraint.t
  val is_empty : Block.t -> bool
  val to_string : Block.t -> string
  val equal : Block.t -> Block.t -> bool
  val contains_iterations : Block.t -> bool
  val max_bound : Block.t -> Indexes.t option
  val dedup : Block.t -> Block.t
  val normalize : Block.t -> Block.t
  type branch_update =
      Replace_with_schema of Schema.t
    | Replace_with_schemas of Schema.t * Schema.t
    | Replace_with_schema_add_constraint of Schema.t * Constraint.t
    | Add_constraint of Constraint.t
  type branching =
      Go_on
    | Close
    | Update of Block.branch_update
    | Branch of Block.branch_update * Block.branch_update
  val apply_rules_with_closure :
    Block.t ->
    rules:(sch:Schema.t -> cstr:Constraint.t -> Block.branching) ->
    k:(Block.t -> Satisfiability.t) -> Satisfiability.t
  val apply_rules :
    Block.t ->
    rules:(sch:Schema.t -> cstr:Constraint.t -> Block.branching) ->
    k:(Block.t -> Satisfiability.t) -> Satisfiability.t
  type purable = t
  val purity_add :
    purable -> ?range:Purity.range option -> pur:Purity.t -> Purity.t
  val purify :
    purable -> cstr:Constraint.t -> pur:Purity.t -> Modified.t * purable
  val purity : Block.t -> Purity.t
  module LoopingMap :
    sig
      type loopable = t
      type 'a t
      val empty : 'a t
      val add : 'a t -> key:loopable -> data:'-> 'a t
      val find : 'a t -> key:loopable -> 'a option
    end
end