Fixpoint subseq {A} (xs ys : list A) : Prop :=
  match xs, ys with
    | [], _ => True
    | x :: xs', y :: ys' => (x = y /\ subseq xs' ys') \/ subseq xs ys'
    | _, _ => False
  end.

(* Specifications: *)
Lemma subseq_refl : forall (l : list A), subseq l l.
Lemma subseq_trans : forall (zs xs ys : list A), subseq xs ys -> subseq ys zs -> subseq xs zs.
Lemma subseq_In : forall (ys xs : list A) x, subseq xs ys -> In x xs -> In x ys.
Theorem subseq_NoDup : forall (ys xs : list A), subseq xs ys -> NoDup ys -> NoDup xs.
Lemma subseq_remove : forall (x : A) xs, subseq (remove A_eq_dec x xs) xs.
Lemma subseq_map : forall (f : A -> B) ys xs, subseq xs ys -> subseq (map f xs) (map f ys).
Lemma subseq_cons_drop : forall xs ys (a : A), subseq (a :: xs) ys -> subseq xs ys.
Lemma subseq_length : forall (ys xs : list A), subseq xs ys -> length xs <= length ys.
Lemma subseq_subseq_eq : forall (xs ys : list A), subseq xs ys -> subseq ys xs -> xs = ys.
Lemma subseq_filter : forall (f : A -> bool) xs, subseq (filter f xs) xs.
Lemma subseq_nil : forall xs, subseq (A:=A) [] xs.
Lemma subseq_skip : forall a xs ys, subseq(A:=A) xs ys -> subseq xs (a :: ys).
Lemma subseq_filterMap : forall (f : B -> option A) ys xs, subseq xs ys -> subseq (filterMap f xs) (filterMap f ys).
Lemma subseq_app_r : forall xs ys, subseq (A:=A) ys (xs ++ ys).
Lemma subseq_app_tail : forall ys xs zs, subseq (A:=A) xs ys -> subseq (xs ++ zs) (ys ++ zs).
Lemma subseq_app_head : forall xs ys zs, subseq (A:=A) ys zs -> subseq (A:=A) (xs ++ ys) (xs ++ zs).
Lemma subseq_2_3 : forall xs ys zs x y, subseq(A:=A) (xs ++ ys ++ zs) (xs ++ x :: ys ++ y :: zs).
Lemma subseq_middle : forall xs y zs, subseq (A:=A) (xs ++ zs) (xs ++ y :: zs).
Lemma subseq_remove_all : forall (ds l l' : list A), subseq l l' -> subseq (remove_all A_eq_dec ds l) l'.