Polymorphic Universe i.Polymorphic Inductive plist : Type@{i} :=
  | pnil
  | pcons : T -> plist -> plist.Polymorphic Inductive plist : Type@{i} :=
  | pnil
  | pcons : T -> plist -> plist.Polymorphic Inductive plist : Type@{i} :=
  | pnil
  | pcons : T -> plist -> plist.Polymorphic Fixpoint length (ls : plist) : nat :=
    match ls with
    | pnil => 0
    | pcons _ ls' => S (length ls')
    end.Polymorphic Fixpoint app (ls ls' : plist) : plist :=
    match ls with
    | pnil => ls'
    | pcons l ls => pcons l (app ls ls')
    end.Polymorphic Definition hd (ls : plist) : poption T :=
    match ls with
    | pnil => pNone
    | pcons x _ => pSome x
    end.Polymorphic Definition tl (ls : plist) : plist :=
    match ls with
    | pnil => ls
    | pcons _ ls => ls
    end.Polymorphic Fixpoint pIn (a : T) (l : plist) : Prop :=
    match l with
    | pnil => False
    | pcons b m => b = a \/ pIn a m
    end.Polymorphic Inductive pNoDup : plist -> Prop :=
    pNoDup_nil : pNoDup pnil
  | pNoDup_cons : forall (x : T) (l : plist),
                 ~ pIn x l -> pNoDup l -> pNoDup (pcons x l).Polymorphic Inductive pNoDup : plist -> Prop :=
    pNoDup_nil : pNoDup pnil
  | pNoDup_cons : forall (x : T) (l : plist),
                 ~ pIn x l -> pNoDup l -> pNoDup (pcons x l).Polymorphic Inductive pNoDup : plist -> Prop :=
    pNoDup_nil : pNoDup pnil
  | pNoDup_cons : forall (x : T) (l : plist),
                 ~ pIn x l -> pNoDup l -> pNoDup (pcons x l).Polymorphic Fixpoint inb {RelDecA : RelDec (@eq T)} (x : T) (lst : plist) :=
    match lst with
    | pnil => false
    | pcons l ls => if x ?[ eq ] l then true else inb x ls
    end.Polymorphic Fixpoint anyb (p : T -> bool) (ls : plist) : bool :=
    match ls with
    | pnil => false
    | pcons l ls0 => if p l then true else anyb p ls0
    end.Polymorphic Fixpoint allb (p : T -> bool) (lst : plist) : bool :=
    match lst with
    | pnil => true
    | pcons l ls => if p l then allb p ls else false
    end.Polymorphic Fixpoint nodup {RelDecA : RelDec (@eq T)} (lst : plist) :=
    match lst with
    | pnil => true
    | pcons l ls => andb (negb (inb l ls)) (nodup ls)
    end.Polymorphic Fixpoint nth_error (ls : plist) (n : nat) : poption T :=
    match n , ls with
    | 0 , pcons l _ => pSome l
    | S n , pcons _ ls => nth_error ls n
    | _ , _ => pNone
    end.Polymorphic Universe j.Polymorphic Fixpoint fold_left (acc : U) (ls : plist) : U :=
      match ls with
      | pnil => acc
      | pcons l ls => fold_left (f l acc) ls
      end.Polymorphic Fixpoint fold_right (ls : plist) (rr : U) : U :=
      match ls with
      | pnil => rr
      | pcons l ls => f l (fold_right ls rr)
      end.Polymorphic Fixpoint split {A B : Type} (lst : plist (pprod A B)) :=
    match lst with
    | pnil => (pnil, pnil)
    | pcons (ppair x y) tl => let (left, right) := split tl in (pcons x left, pcons y right)
    end.

(* Specifications: *)
Lemma pIn_split_l {A B : Type} (lst : plist (pprod A B)) (p : pprod A B) (H : pIn p lst) : (pIn (pfst p) (fst (split lst))).
Lemma pIn_split_r {A B : Type} (lst : plist (pprod A B)) (p : pprod A B) (H : pIn p lst) : (pIn (psnd p) (snd (split lst))).
Lemma pIn_app_iff (A : Type) (l l' : plist A) (a : A) : pIn a (app l l') <-> pIn a l \/ pIn a l'.
Lemma inb_sound (x : A) (lst : plist A) (H : inb x lst = true) : pIn x lst.
Lemma inb_complete (x : A) (lst : plist A) (H : pIn x lst) : inb x lst = true.
Lemma nodup_sound (lst : plist A) (H : nodup lst = true) : pNoDup lst.
Lemma nodup_complete (lst : plist A) (H : pNoDup lst) : nodup lst = true.