Ltac InvAdd := repeat (match goal with
| H: Add ?x _ (_ :: _) |- _ => inversion H; clear H; subst
end).
Ltac finish_basic_perms H :=
try constructor; try rewrite perm_swap; try constructor; trivial;
(rewrite <- H; now apply Permutation_Add) ||
(rewrite H; symmetry; now apply Permutation_Add).

(* Specifications: *)
Theorem Permutation_Add_inv a l1 l2 :
Permutation l1 l2 -> forall l1' l2', Add a l1' l1 -> Add a l2' l2 ->
Permutation l1' l2'.
Theorem Permutation_app_inv (l1 l2 l3 l4:list A) a :
Permutation (l1++a::l2) (l3++a::l4) -> Permutation (l1++l2) (l3 ++ l4).
Theorem Permutation_cons_inv l l' a :
Permutation (a::l) (a::l') -> Permutation l l'.
Theorem Permutation_cons_app_inv l l1 l2 a :
Permutation (a :: l) (l1 ++ a :: l2) -> Permutation l (l1 ++ l2).
Theorem Permutation_app_inv_l : forall l l1 l2,
Permutation (l ++ l1) (l ++ l2) -> Permutation l1 l2.
Theorem Permutation_app_inv_r l l1 l2 :
Permutation (l1 ++ l) (l2 ++ l) -> Permutation l1 l2.
Lemma Permutation_app_inv_m l l1 l2 l3 l4 :
Permutation (l1 ++ l ++ l2) (l3 ++ l ++ l4) ->
Permutation (l1 ++ l2) (l3 ++ l4).
Lemma Permutation_length_1_inv: forall a l, Permutation [a] l -> l = [a].
Lemma Permutation_length_1: forall a b, Permutation [a] [b] -> a = b.
Lemma Permutation_length_2_inv :
forall a1 a2 l, Permutation [a1;a2] l -> l = [a1;a2] \/ l = [a2;a1].
Lemma Permutation_length_2 :
forall a1 a2 b1 b2, Permutation [a1;a2] [b1;b2] ->
a1 = b1 /\ a2 = b2 \/ a1 = b2 /\ a2 = b1.
Lemma Permutation_vs_elt_inv : forall l l1 l2 a,
Permutation l (l1 ++ a :: l2) -> exists l' l'', l = l' ++ a :: l''.
Lemma Permutation_vs_cons_inv : forall l l1 a,
Permutation l (a :: l1) -> exists l' l'', l = l' ++ a :: l''.
Lemma Permutation_vs_cons_cons_inv : forall l l' a b,
Permutation l (a :: b :: l') ->
exists l1 l2 l3, l = l1 ++ a :: l2 ++ b :: l3 \/ l = l1 ++ b :: l2 ++ a :: l3.
Lemma NoDup_Permutation l l' : NoDup l -> NoDup l' ->
(forall x:A, In x l <-> In x l') -> Permutation l l'.
Lemma NoDup_Permutation_bis l l' : NoDup l ->
length l' <= length l -> incl l l' -> Permutation l l'.
Lemma Permutation_NoDup l l' : Permutation l l' -> NoDup l -> NoDup l'.
Global Instance Permutation_NoDup' :
Proper (@Permutation A ==> iff) (@NoDup A).
Lemma Permutation_repeat x n l :
Permutation l (repeat x n) -> l = repeat x n.
Lemma Permutation_incl_cons_inv_r (l1 l2 : list A) a : incl l1 (a :: l2) ->
exists n l3, Permutation l1 (repeat a n ++ l3) /\ incl l3 l2.
Lemma Permutation_pigeonhole l1 l2 : incl l1 l2 -> length l2 < length l1 ->
exists a l3, Permutation l1 (a :: a :: l3).
Lemma Permutation_pigeonhole_rel (R : B -> A -> Prop) (l1 : list B) l2 :
Forall (fun b => Exists (R b) l2) l1 ->
length l2 < length l1 ->
exists b b' (l3 : list B), Permutation l1 (b :: b' :: l3) /\ exists a, In a l2 /\ R b a /\ R b' a.