sig
  type 'a printer = 'CCFormat.printer
  module Features :
    sig
      type t
      type value =
          Present
        | Absent
        | Mono
        | Poly
        | Eqn_single
        | Eqn_nested
        | Eqn_app
      type key =
          Ty
        | Eqn
        | If_then_else
        | Ind_preds
        | Match
        | Data
        | Codata
        | Fun
        | HOF
        | Prop_args
        | Copy
      val empty : Transform.Features.t
      val full : Transform.Features.t
      val update :
        Transform.Features.key ->
        Transform.Features.value ->
        Transform.Features.t -> Transform.Features.t
      val update_l :
        (Transform.Features.key * Transform.Features.value) list ->
        Transform.Features.t -> Transform.Features.t
      val of_list :
        (Transform.Features.key * Transform.Features.value) list ->
        Transform.Features.t
      type check_res =
          Check_ok
        | Check_fail of Transform.Features.key * Transform.Features.value *
            Transform.Features.value
      val check :
        Transform.Features.t ->
        spec:Transform.Features.t -> Transform.Features.check_res
      val print : Transform.Features.t Transform.printer
    end
  type ('a, 'b, 'c, 'd) t =
      Ex :
        ('a, 'b, 'c, 'd, 'st) Transform.inner -> ('a, 'b, 'c, 'd) Transform.t
  and ('a, 'b, 'c, 'd, 'st) inner = {
    name : string;
    encode : '-> 'b * 'st;
    decode : 'st -> '-> 'd;
    input_spec : Transform.Features.t;
    map_spec : Transform.Features.t -> Transform.Features.t;
    mutable on_input : ('-> unit) list;
    mutable on_encoded : ('-> unit) list;
    mutable on_decoded : ('-> unit) list;
    print_state : (Format.formatter -> 'st -> unit) option;
  }
  type ('a, 'b, 'c, 'd) transformation = ('a, 'b, 'c, 'd) Transform.t
  val make :
    ?print:(Format.formatter -> 'st -> unit) ->
    ?on_input:('-> unit) list ->
    ?on_encoded:('-> unit) list ->
    ?on_decoded:('-> unit) list ->
    ?input_spec:Transform.Features.t ->
    ?map_spec:(Transform.Features.t -> Transform.Features.t) ->
    name:string ->
    encode:('-> 'b * 'st) ->
    decode:('st -> '-> 'd) -> unit -> ('a, 'b, 'c, 'd) Transform.t
  val backward : name:string -> ('-> 'c) -> ('a, 'a, 'b, 'c) Transform.t
  val nop : unit -> ('a, 'a, 'b, 'b) Transform.t
  val on_encoded : ('a, 'b, 'c, 'd) Transform.t -> f:('-> unit) -> unit
  val on_input : ('a, 'b, 'c, 'd) Transform.t -> f:('-> unit) -> unit
  module Pipe :
    sig
      type ('a, 'b, 'c, 'd) t = private
          Id : ('a, 'a, 'c, 'c) Transform.Pipe.t
        | Fail : ('a, 'b, 'c, 'd) Transform.Pipe.t
        | Flatten :
            ('a, 'b list, 'c, 'd) Transform.Pipe.t -> ('a, 'b, 'c, 'd)
                                                      Transform.Pipe.t
        | Close : ('b1 -> ('c1 -> 'd) -> 'b2 * ('c2 -> 'd)) *
            ('a, 'b1, 'c1, 'd) Transform.Pipe.t -> ('a, 'b2, 'c2, 'd)
                                                   Transform.Pipe.t
        | Comp : ('a, 'b, 'e, 'f) Transform.transformation *
            ('b, 'c, 'd, 'e) Transform.Pipe.t -> ('a, 'c, 'd, 'f)
                                                 Transform.Pipe.t
        | Fork : ('a, 'b, 'c, 'd) Transform.Pipe.t *
            ('a, 'b, 'c, 'd) Transform.Pipe.t -> ('a, 'b, 'c, 'd)
                                                 Transform.Pipe.t
      val id : ('a, 'a, 'c, 'c) Transform.Pipe.t
      val fail : ('a, 'b, 'c, 'd) Transform.Pipe.t
      val flatten :
        ('a, 'b list, 'c, 'd) Transform.Pipe.t ->
        ('a, 'b, 'c, 'd) Transform.Pipe.t
      val close :
        f:('b1 -> ('c1 -> 'd) -> 'b2 * ('c2 -> 'd)) ->
        ('a, 'b1, 'c1, 'd) Transform.Pipe.t ->
        ('a, 'b2, 'c2, 'd) Transform.Pipe.t
      val compose :
        ('a, 'b, 'd1, 'e) Transform.transformation ->
        ('b, 'b2, 'c, 'd1) Transform.Pipe.t ->
        ('a, 'b2, 'c, 'e) Transform.Pipe.t
      val ( @@@ ) :
        ('a, 'b, 'd1, 'e) Transform.transformation ->
        ('b, 'b2, 'c, 'd1) Transform.Pipe.t ->
        ('a, 'b2, 'c, 'e) Transform.Pipe.t
      val fork :
        ('a, 'b, 'c, 'd) Transform.Pipe.t ->
        ('a, 'b, 'c, 'd) Transform.Pipe.t ->
        ('a, 'b, 'c, 'd) Transform.Pipe.t
      val fork_l :
        ('a, 'b, 'c, 'd) Transform.Pipe.t list ->
        ('a, 'b, 'c, 'd) Transform.Pipe.t
      val fork_comp :
        ('a, 'b, 'd1, 'e) Transform.transformation list ->
        ('b, 'b2, 'c, 'd1) Transform.Pipe.t ->
        ('a, 'b2, 'c, 'e) Transform.Pipe.t
      val check : ('a, 'b, 'c, 'd) Transform.Pipe.t -> unit
      val print : ('a, 'b, 'c, 'd) Transform.Pipe.t Transform.printer
    end
  val run :
    pipe:('a, 'b, 'c, 'd) Transform.Pipe.t ->
    '-> ('b * ('-> 'd)) Lazy_list.t
end