(* Equality up to permutation *)
Section PermSeq.
Variable T : eqType.
Implicit Type s : seq T.
Definition perm_eq s1 s2 :=
all [pred x | count_mem x s1 == count_mem x s2] (s1 ++ s2).

(* Specifications: *)
Lemma perm_eqP s1 s2 : reflect (count^~ s1 =1 count^~ s2) (perm_eq s1 s2).
Lemma perm_eq_refl s : perm_eq s s.
Lemma perm_eqrP s1 s2 : reflect (perm_eqr s1 s2) (perm_eq s1 s2).
Lemma perm_catC s1 s2 : perm_eql (s1 ++ s2) (s2 ++ s1).
Lemma perm_cons x s1 s2 : perm_eq (x :: s1) (x :: s2) = perm_eq s1 s2.
Lemma perm_filterC a s : perm_eql (filter a s ++ filter (predC a) s) s.
Lemma perm_eq_mem s1 s2 : perm_eq s1 s2 -> s1 =i s2.
Lemma uniq_leq_size s1 s2 : uniq s1 -> {subset s1 <= s2} -> size s1 <= size s2.
Lemma leq_size_uniq s1 s2 :
uniq s1 -> {subset s1 <= s2} -> size s2 <= size s1 -> uniq s2.
Lemma uniq_size_uniq s1 s2 :
uniq s1 -> s1 =i s2 -> uniq s2 = (size s2 == size s1).
Lemma leq_size_perm s1 s2 :
uniq s1 -> {subset s1 <= s2} -> size s2 <= size s1 ->
s1 =i s2 /\ size s1 = size s2.
Lemma perm_uniq s1 s2 : s1 =i s2 -> size s1 = size s2 -> uniq s1 = uniq s2.
Lemma perm_eq_uniq s1 s2 : perm_eq s1 s2 -> uniq s1 = uniq s2.
Lemma uniq_perm_eq s1 s2 : uniq s1 -> uniq s2 -> s1 =i s2 -> perm_eq s1 s2.
Lemma count_mem_uniq s : (forall x, count_mem x s = (x \in s)) -> uniq s.
Lemma catCA_perm_ind P :
(forall s1 s2 s3, P (s1 ++ s2 ++ s3) -> P (s2 ++ s1 ++ s3)) ->
(forall s1 s2, perm_eq s1 s2 -> P s1 -> P s2).
Lemma catCA_perm_subst R F :
(forall s1 s2 s3, F (s1 ++ s2 ++ s3) = F (s2 ++ s1 ++ s3) :> R) ->
(forall s1 s2, perm_eq s1 s2 -> F s1 = F s2).