open Prims
type 'a clist =
  | CNil 
  | CCons of 'a * 'a clist 
  | CCat of 'a clist * 'a clist 
let uu___is_CNil (projectee : 'a clist) : Prims.bool=
  match projectee with | CNil -> true | uu___ -> false
let uu___is_CCons (projectee : 'a clist) : Prims.bool=
  match projectee with | CCons (_0, _1) -> true | uu___ -> false
let __proj__CCons__item___0 (projectee : 'a clist) : 'a=
  match projectee with | CCons (_0, _1) -> _0
let __proj__CCons__item___1 (projectee : 'a clist) : 'a clist=
  match projectee with | CCons (_0, _1) -> _1
let uu___is_CCat (projectee : 'a clist) : Prims.bool=
  match projectee with | CCat (_0, _1) -> true | uu___ -> false
let __proj__CCat__item___0 (projectee : 'a clist) : 'a clist=
  match projectee with | CCat (_0, _1) -> _0
let __proj__CCat__item___1 (projectee : 'a clist) : 'a clist=
  match projectee with | CCat (_0, _1) -> _1
type 'a t = 'a clist
let ccat (xs : 'a clist) (ys : 'a clist) : 'a clist=
  match (xs, ys) with
  | (CNil, uu___) -> ys
  | (uu___, CNil) -> xs
  | uu___ -> CCat (xs, ys)
let rec view : 'a . 'a clist -> ('a, 'a clist) FStarC_Class_Listlike.view_t =
  fun l ->
    match l with
    | CNil -> FStarC_Class_Listlike.VNil
    | CCons (x, xs) -> FStarC_Class_Listlike.VCons (x, xs)
    | CCat (CCat (xs, ys), zs) -> view (CCat (xs, (CCat (ys, zs))))
    | CCat (xs, ys) ->
        (match view xs with
         | FStarC_Class_Listlike.VNil -> view ys
         | FStarC_Class_Listlike.VCons (x, xs') ->
             FStarC_Class_Listlike.VCons (x, (CCat (xs', ys))))
let listlike_clist (uu___ : unit) :
  ('a, 'a t) FStarC_Class_Listlike.listlike=
  {
    FStarC_Class_Listlike.empty = CNil;
    FStarC_Class_Listlike.cons =
      (fun uu___1 uu___2 -> CCons (uu___1, uu___2));
    FStarC_Class_Listlike.view = view
  }
let monoid_clist (uu___ : unit) : 'a t FStarC_Class_Monoid.monoid=
  { FStarC_Class_Monoid.mzero = CNil; FStarC_Class_Monoid.mplus = ccat }
let showable_clist (uu___ : 'a FStarC_Class_Show.showable) :
  'a t FStarC_Class_Show.showable=
  {
    FStarC_Class_Show.show =
      (fun l ->
         let uu___1 = FStarC_Class_Listlike.to_list (listlike_clist ()) l in
         FStarC_Class_Show.show (FStarC_Class_Show.show_list uu___) uu___1)
  }
let eq_clist (d : 'a FStarC_Class_Deq.deq) : 'a t FStarC_Class_Deq.deq=
  {
    FStarC_Class_Deq.op_Equals_Question =
      (fun l1 l2 ->
         let uu___ = FStarC_Class_Listlike.to_list (listlike_clist ()) l1 in
         let uu___1 = FStarC_Class_Listlike.to_list (listlike_clist ()) l2 in
         FStarC_Class_Deq.op_Equals_Question (FStarC_Class_Deq.deq_list d)
           uu___ uu___1)
  }
let ord_clist (d : 'a FStarC_Class_Ord.ord) : 'a t FStarC_Class_Ord.ord=
  {
    FStarC_Class_Ord.super = (eq_clist (FStarC_Class_Ord.ord_eq d));
    FStarC_Class_Ord.cmp =
      (fun l1 l2 ->
         let uu___ = FStarC_Class_Listlike.to_list (listlike_clist ()) l1 in
         let uu___1 = FStarC_Class_Listlike.to_list (listlike_clist ()) l2 in
         FStarC_Class_Ord.cmp (FStarC_Class_Ord.ord_list d) uu___ uu___1)
  }
let rec map : 'a 'b . ('a -> 'b) -> 'a clist -> 'b clist =
  fun f l ->
    match l with
    | CNil -> CNil
    | CCons (x, xs) ->
        let uu___ = f x in let uu___1 = map f xs in CCons (uu___, uu___1)
    | CCat (xs, ys) ->
        let uu___ = map f xs in let uu___1 = map f ys in ccat uu___ uu___1
let rec existsb : 'a . ('a -> Prims.bool) -> 'a clist -> Prims.bool =
  fun p l ->
    match l with
    | CNil -> false
    | CCons (x, xs) -> (p x) || (existsb p xs)
    | CCat (xs, ys) -> (existsb p xs) || (existsb p ys)
let rec for_all : 'a . ('a -> Prims.bool) -> 'a clist -> Prims.bool =
  fun p l ->
    match l with
    | CNil -> true
    | CCons (x, xs) -> (p x) && (for_all p xs)
    | CCat (xs, ys) -> (for_all p xs) && (for_all p ys)
let rec partition :
  'a . ('a -> Prims.bool) -> 'a clist -> ('a clist * 'a clist) =
  fun p l ->
    match l with
    | CNil -> (CNil, CNil)
    | CCons (x, xs) ->
        let uu___ = partition p xs in
        (match uu___ with
         | (ys, zs) ->
             let uu___1 = p x in
             if uu___1 then ((CCons (x, ys)), zs) else (ys, (CCons (x, zs))))
    | CCat (xs, ys) ->
        let uu___ = partition p xs in
        (match uu___ with
         | (ys1, zs) ->
             let uu___1 = partition p ys1 in
             (match uu___1 with
              | (us, vs) ->
                  let uu___2 = ccat ys1 us in
                  let uu___3 = ccat zs vs in (uu___2, uu___3)))
let rec collect : 'a 'b . ('a -> 'b clist) -> 'a clist -> 'b clist =
  fun f l ->
    match l with
    | CNil -> CNil
    | CCons (x, xs) ->
        let uu___ = f x in let uu___1 = collect f xs in ccat uu___ uu___1
    | CCat (xs, ys) ->
        let uu___ = collect f xs in
        let uu___1 = collect f ys in ccat uu___ uu___1
