(* Definition Injective {A B} (f : A->B) := *)
(*  forall x y, f x = f y -> x = y. *)
(* Section fix_X. *)
(*   Variable X:Type. *)
(*   Implicit Types (A B: list X) (a b c: X).  *)
(*   Lemma last_app_eq A B a b : *)
(*     A++[a] = B++[b] -> A = B /\ a = b. *)
(*   Proof. *)
(*     intros H%(f_equal (@rev X)). rewrite !rev_app_distr in H. split. *)
(*     - inv H. apply (f_equal (@rev X)) in H2. now rewrite !rev_involutive in H2. *)
(*     - now inv H. *)
(*   Qed. *)
(*   Lemma rev_eq A B: *)
(*     List.rev A = List.rev B <-> A = B. *)
(*   Proof. *)
(*     split. *)
(*     - intros H%(f_equal (@rev X)). now rewrite !rev_involutive in H. *)
(*     - now intros <-. *)
(*   Qed. *)
(*   Lemma rev_nil A: *)
(*     rev A = [] -> A = []. *)
(*   Proof. *)
(*     destruct A. auto. now intros H%symmetry%app_cons_not_nil. *)
(*   Qed. *)
(*   Lemma map_inj (Y:Type) A B (f: X -> Y) : *)
(*     Injective f -> map f A = map f B <-> A = B. *)
(*   Proof. *)
(*     intros inj. split. *)
(*     - revert B. induction A; intros B H; cbn in *; destruct B; auto; cbn in H; inv H. *)
(*       rewrite (inj a x H1). specialize (IHA B H2). now subst. *)
(*     - now intros <-. *)
(*   Qed. *)
(* End fix_X. *)

(* Specifications: *)
Lemma app_incl_l X (A B C : list X) :
A ++ B <<= C -> A <<= C.
Lemma app_incl_R X (A B C : list X) :
A ++ B <<= C -> B <<= C.
Lemma cons_incl X (a : X) (A B : list X) : a :: A <<= B -> A <<= B.
Lemma incl_sing X (a : X) A : a el A -> [a] <<= A.
Hint Resolve app_incl_l app_incl_R cons_incl incl_sing.