sig
  type 'a io = 'Lwt.t
  type chan_endpoint = Lwt_io.input_channel * Lwt_io.output_channel
  type ('a, 'b) session constraint 'a = [>  ] constraint 'b = [>  ]
  type ('a, 'b, 'c) process
  val send :
    '->
    (unit,
     ([ `Send of 'a * ([>  ] as 'b) ], [ `Recv of 'a * ([>  ] as 'c) ])
     session, ('b, 'c) session)
    process
  val recv :
    unit ->
    ('a,
     ([ `Recv of 'a * ([>  ] as 'b) ], [ `Send of 'a * ([>  ] as 'c) ])
     session, ('b, 'c) session)
    process
  val offer :
    ('e, ([>  ] as 'a, [>  ] as 'b) session, 'f) process ->
    ('e, ([>  ] as 'c, [>  ] as 'd) session, 'f) process ->
    ('e,
     ([ `Offer of ('a, 'b) session * ('c, 'd) session ],
      [ `Choice of ('b, 'a) session * ('d, 'c) session ])
     session, 'f)
    process
  val choose_left :
    ('e, ([>  ] as 'a, [>  ] as 'b) session, 'f) process ->
    ('e,
     ([ `Choice of ('a, 'b) session * ([>  ] as 'c, [>  ] as 'd) session ],
      [ `Offer of ('b, 'a) session * ('d, 'c) session ])
     session, 'f)
    process
  val choose_right :
    ('e, ([>  ] as 'a, [>  ] as 'b) session, 'f) process ->
    ('e,
     ([ `Choice of ([>  ] as 'c, [>  ] as 'd) session * ('a, 'b) session ],
      [ `Offer of ('d, 'c) session * ('b, 'a) session ])
     session, 'f)
    process
  val stop : '-> ('a, ([ `Stop ], [ `Stop ]) session, unit) process
  val lift_io : 'a io -> ('a, 'b, 'b) process
  val return : '-> ('a, 'b, 'b) process
  val ( >>= ) :
    ('a, 'b, 'c) process ->
    ('-> ('d, 'c, 'e) process) -> ('d, 'b, 'e) process
  val run_processes :
    ('a, ([>  ] as 'b, [>  ] as 'c) session, unit) process ->
    ('d, ('c, 'b) session, unit) process ->
    ((unit -> 'a io) * (unit -> 'd io)) io
end