Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) Require Import Omega Relations Multiset SetoidList.
This file is deprecated, use Permutation.v instead.
Indeed, this file defines a notion of permutation based on
multisets (there exists a permutation between two lists iff every
elements have the same multiplicity in the two lists) which
requires a more complex apparatus (the equipment of the domain
with a decidable equality) than Permutation in Permutation.v.
The relation between the two relations are in lemma
permutation_Permutation.
File Permutation concerns Leibniz equality : it shows in particular
that List.Permutation and permutation are equivalent in this context.
Set Implicit Arguments. Local Notation "[ ]" := nil. Local Notation "[ a ; .. ; b ]" := (a :: .. (b :: []) ..). Section Permut.
Variable A : Type. Variable eqA : relation A. Hypothesis eqA_equiv : Equivalence eqA. Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}. Let emptyBag := EmptyBag A. Let singletonBag := SingletonBag _ eqA_dec.
contents of a list
Fixpoint list_contents (l:list A) : multiset A := match l with | [] => emptyBag | a :: l => munion (singletonBag a) (list_contents l) end.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l m : list A, meq (list_contents (l ++ m)) (munion (list_contents l) (list_contents m))A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l m : list A, meq (list_contents (l ++ m)) (munion (list_contents l) (list_contents m))A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al:list Aforall (a : A) (l0 : list A), (forall m : list A, meq (list_contents (l0 ++ m)) (munion (list_contents l0) (list_contents m))) -> forall m : list A, meq (munion (singletonBag a) (list_contents (l0 ++ m))) (munion (munion (singletonBag a) (list_contents l0)) (list_contents m))apply meq_trans with (munion (singletonBag a) (munion (list_contents l0) (list_contents m))); auto with datatypes. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al:list Aa:Al0:list AH:forall m0 : list A, meq (list_contents (l0 ++ m0)) (munion (list_contents l0) (list_contents m0))m:list Ameq (munion (singletonBag a) (list_contents (l0 ++ m))) (munion (munion (singletonBag a) (list_contents l0)) (list_contents m))
Definition permutation (l m:list A) := meq (list_contents l) (list_contents m).A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l : list A, permutation l lunfold permutation; auto with datatypes. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l : list A, permutation l lA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l1 l2 : list A, permutation l1 l2 -> permutation l2 l1unfold permutation, meq; intros; symmetry; trivial. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l1 l2 : list A, permutation l1 l2 -> permutation l2 l1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l m n : list A, permutation l m -> permutation m n -> permutation l nA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l m n : list A, permutation l m -> permutation m n -> permutation l napply meq_trans with (list_contents m); auto with datatypes. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, m, n:list AH:meq (list_contents l) (list_contents m)H0:meq (list_contents m) (list_contents n)meq (list_contents l) (list_contents n)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l m : list A, permutation l m -> forall a a' : A, eqA a a' -> permutation (a :: l) (a' :: m)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l m : list A, permutation l m -> forall a a' : A, eqA a a' -> permutation (a :: l) (a' :: m)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, m:list AH:meq (list_contents l) (list_contents m)a, a':AH0:eqA a a'meq (munion (singletonBag a) (list_contents l)) (munion (singletonBag a') (list_contents m))A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, m:list AH:meq (list_contents l) (list_contents m)a, a':AH0:eqA a a'meq (munion (singletonBag a) (list_contents l)) (munion (singletonBag a') (list_contents l))A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, m:list AH:meq (list_contents l) (list_contents m)a, a':AH0:eqA a a'meq (munion (singletonBag a') (list_contents l)) (munion (singletonBag a') (list_contents m))auto with datatypes. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, m:list AH:meq (list_contents l) (list_contents m)a, a':AH0:eqA a a'meq (munion (singletonBag a') (list_contents l)) (munion (singletonBag a') (list_contents m))A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l m : list A, permutation l m -> forall a : A, permutation (a :: l) (a :: m)unfold permutation; simpl; auto with datatypes. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l m : list A, permutation l m -> forall a : A, permutation (a :: l) (a :: m)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l l' m m' : list A, permutation l l' -> permutation m m' -> permutation (l ++ m) (l' ++ m')A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l l' m m' : list A, permutation l l' -> permutation m m' -> permutation (l ++ m) (l' ++ m')A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l', m, m':list AH:meq (list_contents l) (list_contents l')H0:meq (list_contents m) (list_contents m')meq (list_contents (l ++ m)) (list_contents (l' ++ m'))A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l', m, m':list AH:meq (list_contents l) (list_contents l')H0:meq (list_contents m) (list_contents m')meq (munion (list_contents l) (list_contents m)) (list_contents (l' ++ m'))apply meq_trans with (munion (list_contents l') (list_contents m)); auto using permut_cons, list_contents_app with datatypes. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l', m, m':list AH:meq (list_contents l) (list_contents l')H0:meq (list_contents m) (list_contents m')meq (munion (list_contents l) (list_contents m)) (munion (list_contents l') (list_contents m'))A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a a' : A) (l1 l2 l3 l4 : list A), eqA a a' -> permutation (l1 ++ l2) (l3 ++ l4) -> permutation (l1 ++ a :: l2) (l3 ++ a' :: l4)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a a' : A) (l1 l2 l3 l4 : list A), eqA a a' -> permutation (l1 ++ l2) (l3 ++ l4) -> permutation (l1 ++ a :: l2) (l3 ++ a' :: l4)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa, a':Al1, l2, l3, l4:list AH:eqA a a'H0:forall a1 : A, multiplicity (list_contents (l1 ++ l2)) a1 = multiplicity (list_contents (l3 ++ l4)) a1a0:Amultiplicity (list_contents (l1 ++ a :: l2)) a0 = multiplicity (list_contents (l3 ++ a' :: l4)) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa, a':Al1, l2, l3, l4:list AH:eqA a a'a0:AH0:multiplicity (list_contents (l1 ++ l2)) a0 = multiplicity (list_contents (l3 ++ l4)) a0multiplicity (list_contents (l1 ++ a :: l2)) a0 = multiplicity (list_contents (l3 ++ a' :: l4)) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa, a':Al1, l2, l3, l4:list AH:eqA a a'a0:AH0:multiplicity (list_contents l1) a0 + multiplicity (list_contents l2) a0 = multiplicity (list_contents l3) a0 + multiplicity (list_contents l4) a0multiplicity (list_contents l1) a0 + ((if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l2) a0) = multiplicity (list_contents l3) a0 + ((if eqA_dec a' a0 then 1 else 0) + multiplicity (list_contents l4) a0)do 2 rewrite <- plus_n_Sm; f_equal; auto. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa, a':Al1, l2, l3, l4:list AH:eqA a a'a0:AH0:multiplicity (list_contents l1) a0 + multiplicity (list_contents l2) a0 = multiplicity (list_contents l3) a0 + multiplicity (list_contents l4) a0Ha:eqA a' a0multiplicity (list_contents l1) a0 + S (multiplicity (list_contents l2) a0) = multiplicity (list_contents l3) a0 + S (multiplicity (list_contents l4) a0)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a : A) (l1 l2 l3 l4 : list A), permutation (l1 ++ l2) (l3 ++ l4) -> permutation (l1 ++ a :: l2) (l3 ++ a :: l4)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a : A) (l1 l2 l3 l4 : list A), permutation (l1 ++ l2) (l3 ++ l4) -> permutation (l1 ++ a :: l2) (l3 ++ a :: l4)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1, l2, l3, l4:list AH:forall a1 : A, multiplicity (list_contents (l1 ++ l2)) a1 = multiplicity (list_contents (l3 ++ l4)) a1a0:Amultiplicity (list_contents (l1 ++ a :: l2)) a0 = multiplicity (list_contents (l3 ++ a :: l4)) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1, l2, l3, l4:list Aa0:Amultiplicity (list_contents (l1 ++ l2)) a0 = multiplicity (list_contents (l3 ++ l4)) a0 -> multiplicity (list_contents (l1 ++ a :: l2)) a0 = multiplicity (list_contents (l3 ++ a :: l4)) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1, l2, l3, l4:list Aa0:Amultiplicity (munion (list_contents l1) (list_contents l2)) a0 = multiplicity (munion (list_contents l3) (list_contents l4)) a0 -> multiplicity (munion (list_contents l1) (list_contents (a :: l2))) a0 = multiplicity (munion (list_contents l3) (list_contents (a :: l4))) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1, l2, l3, l4:list Aa0:Amultiplicity (list_contents l1) a0 + multiplicity (list_contents l2) a0 = multiplicity (list_contents l3) a0 + multiplicity (list_contents l4) a0 -> multiplicity (list_contents l1) a0 + ((if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l2) a0) = multiplicity (list_contents l3) a0 + ((if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l4) a0)do 2 rewrite <- plus_n_Sm; f_equal; auto. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1, l2, l3, l4:list Aa0:Ae:eqA a a0multiplicity (list_contents l1) a0 + multiplicity (list_contents l2) a0 = multiplicity (list_contents l3) a0 + multiplicity (list_contents l4) a0 -> multiplicity (list_contents l1) a0 + S (multiplicity (list_contents l2) a0) = multiplicity (list_contents l3) a0 + S (multiplicity (list_contents l4) a0)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a a' : A) (l l1 l2 : list A), eqA a a' -> permutation l (l1 ++ l2) -> permutation (a :: l) (l1 ++ a' :: l2)intros; replace (a :: l) with ([] ++ a :: l); trivial; apply permut_add_inside_eq; trivial. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a a' : A) (l l1 l2 : list A), eqA a a' -> permutation l (l1 ++ l2) -> permutation (a :: l) (l1 ++ a' :: l2)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a : A) (l l1 l2 : list A), permutation l (l1 ++ l2) -> permutation (a :: l) (l1 ++ a :: l2)intros; replace (a :: l) with ([] ++ a :: l); trivial; apply permut_add_inside; trivial. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a : A) (l l1 l2 : list A), permutation l (l1 ++ l2) -> permutation (a :: l) (l1 ++ a :: l2)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l m : list A) (a : A), permutation (a :: l ++ m) (l ++ a :: m)intros; apply permut_add_cons_inside; auto using permut_sym, permut_refl. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l m : list A) (a : A), permutation (a :: l ++ m) (l ++ a :: m)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l1 l2 : list A, permutation (l1 ++ l2) (l2 ++ l1)intros l1 l2; unfold permutation, meq; intro a; do 2 rewrite list_contents_app; simpl; auto with arith. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l1 l2 : list A, permutation (l1 ++ l2) (l2 ++ l1)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l : list A, permutation l (rev l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l : list A, permutation l (rev l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Apermutation [ ] (rev [ ])A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:permutation l (rev l)permutation (a :: l) (rev (a :: l))A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:permutation l (rev l)permutation (a :: l) (rev (a :: l))A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:permutation l (rev l)permutation (a :: l) (rev l ++ [a])A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:permutation l (rev l)permutation l (rev l ++ [ ])trivial. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:permutation l (rev l)permutation l (rev l)
A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (e : A) (l1 l2 : list A), permutation (e :: l1) (e :: l2) -> permutation l1 l2intros e l1 l2; unfold permutation, meq; simpl; intros H a; generalize (H a); apply plus_reg_l. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (e : A) (l1 l2 : list A), permutation (e :: l1) (e :: l2) -> permutation l1 l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l l1 l2 : list A, permutation (l1 ++ l) (l2 ++ l) -> permutation l1 l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l l1 l2 : list A, permutation (l1 ++ l) (l2 ++ l) -> permutation l1 l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa:Amultiplicity (list_contents (l1 ++ l)) a = multiplicity (list_contents (l2 ++ l)) a -> multiplicity (list_contents l1) a = multiplicity (list_contents l2) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa:Amultiplicity (munion (list_contents l1) (list_contents l)) a = multiplicity (munion (list_contents l2) (list_contents l)) a -> multiplicity (list_contents l1) a = multiplicity (list_contents l2) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa:Amultiplicity (list_contents l1) a + multiplicity (list_contents l) a = multiplicity (list_contents l2) a + multiplicity (list_contents l) a -> multiplicity (list_contents l1) a = multiplicity (list_contents l2) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa:AH:multiplicity (list_contents l1) a + multiplicity (list_contents l) a = multiplicity (list_contents l2) a + multiplicity (list_contents l) amultiplicity (list_contents l) a + multiplicity (list_contents l1) a = multiplicity (list_contents l) a + multiplicity (list_contents l2) atrivial. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa:AH:multiplicity (list_contents l1) a + multiplicity (list_contents l) a = multiplicity (list_contents l2) a + multiplicity (list_contents l) amultiplicity (list_contents l) a + multiplicity (list_contents l2) a = multiplicity (list_contents l) a + multiplicity (list_contents l2) a
we can use multiplicity to define InA and NoDupA.
A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a a' : A) (B : Type) (b b' : B), eqA a a' -> (if eqA_dec a a' then b else b') = bA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a a' : A) (B : Type) (b b' : B), eqA a a' -> (if eqA_dec a a' then b else b') = bA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa, a':AB:Typeb, b':BH:eqA a a'(if eqA_dec a a' then b else b') = bcontradict NEQ; auto. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa, a':AB:Typeb, b':BH:eqA a a'NEQ:~ eqA a a'b' = bA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l l1 l2 : list A, permutation (l ++ l1) (l ++ l2) -> permutation l1 l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l l1 l2 : list A, permutation (l ++ l1) (l ++ l2) -> permutation l1 l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa:Amultiplicity (list_contents (l ++ l1)) a = multiplicity (list_contents (l ++ l2)) a -> multiplicity (list_contents l1) a = multiplicity (list_contents l2) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa:Amultiplicity (munion (list_contents l) (list_contents l1)) a = multiplicity (munion (list_contents l) (list_contents l2)) a -> multiplicity (list_contents l1) a = multiplicity (list_contents l2) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa:Amultiplicity (list_contents l) a + multiplicity (list_contents l1) a = multiplicity (list_contents l) a + multiplicity (list_contents l2) a -> multiplicity (list_contents l1) a = multiplicity (list_contents l2) atrivial. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa:AH:multiplicity (list_contents l) a + multiplicity (list_contents l1) a = multiplicity (list_contents l) a + multiplicity (list_contents l2) amultiplicity (list_contents l) a + multiplicity (list_contents l1) a = multiplicity (list_contents l) a + multiplicity (list_contents l2) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l l1 l2 : list A) (a b : A), eqA a b -> permutation (a :: l) (l1 ++ b :: l2) -> permutation l (l1 ++ l2)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l l1 l2 : list A) (a b : A), eqA a b -> permutation (a :: l) (l1 ++ b :: l2) -> permutation l (l1 ++ l2)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa, b:AHeq:eqA a bH:forall a1 : A, (if eqA_dec a a1 then 1 else 0) + multiplicity (list_contents l) a1 = multiplicity (list_contents (l1 ++ b :: l2)) a1a0:Amultiplicity (list_contents l) a0 = multiplicity (list_contents (l1 ++ l2)) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa, b:AHeq:eqA a ba0:AH:(if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 = multiplicity (list_contents (l1 ++ b :: l2)) a0multiplicity (list_contents l) a0 = multiplicity (list_contents (l1 ++ l2)) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa, b:AHeq:eqA a ba0:AH:(if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 = multiplicity (list_contents l1) a0 + ((if eqA_dec b a0 then 1 else 0) + multiplicity (list_contents l2) a0)multiplicity (list_contents l) a0 = multiplicity (list_contents l1) a0 + multiplicity (list_contents l2) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa, b:AHeq:eqA a ba0:AH:(if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 = multiplicity (list_contents l1) a0 + ((if eqA_dec b a0 then 1 else 0) + multiplicity (list_contents l2) a0)(if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 = (if eqA_dec a a0 then 1 else 0) + (multiplicity (list_contents l1) a0 + multiplicity (list_contents l2) a0)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa, b:AHeq:eqA a ba0:Amultiplicity (list_contents l1) a0 + ((if eqA_dec b a0 then 1 else 0) + multiplicity (list_contents l2) a0) = (if eqA_dec a a0 then 1 else 0) + (multiplicity (list_contents l1) a0 + multiplicity (list_contents l2) a0)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa, b:AHeq:eqA a ba0:Amultiplicity (list_contents l2) a0 + (if eqA_dec a a0 then 1 else 0) = (if eqA_dec b a0 then 1 else 0) + multiplicity (list_contents l2) a0destruct (eqA_dec a a0) as [Ha|Ha]; rewrite Heq in Ha; decide (eqA_dec b a0) with Ha; reflexivity. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l1, l2:list Aa, b:AHeq:eqA a ba0:A(if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l2) a0 = (if eqA_dec b a0 then 1 else 0) + multiplicity (list_contents l2) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l l1 l2 : list A) (a : A), permutation (a :: l) (l1 ++ a :: l2) -> permutation l (l1 ++ l2)eauto using permut_remove_hd_eq, Equivalence_Reflexive. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l l1 l2 : list A) (a : A), permutation (a :: l) (l1 ++ a :: l2) -> permutation l (l1 ++ l2)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a a' : A) (B : Type) (b b' : B), ~ eqA a a' -> (if eqA_dec a a' then b else b') = b'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a a' : A) (B : Type) (b b' : B), ~ eqA a a' -> (if eqA_dec a a' then b else b') = b'decide (eqA_dec a a') with H; auto. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa, a':AB:Typeb, b':BH:~ eqA a a'(if eqA_dec a a' then b else b') = b'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a : A) (B : Type) (b b' : B), (if eqA_dec a a then b else b') = bintros; apply (decide_left (eqA_dec a a)); auto with *. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a : A) (B : Type) (b b' : B), (if eqA_dec a a then b else b') = b
PL: Inutilisable dans un rewrite sans un change prealable.
A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset AB:Typeb, b':BProper (eqA ==> eqA ==> eq) (fun x y : A => if eqA_dec x y then b else b')A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset AB:Typeb, b':BProper (eqA ==> eqA ==> eq) (fun x y : A => if eqA_dec x y then b else b')A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset AB:Typeb, b':Bx, x':AHxx':eqA x x'y, y':AHyy':eqA y y'(if eqA_dec x y then b else b') = (if eqA_dec x' y' then b else b')A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset AB:Typeb, b':Bx, x':AHxx':eqA x x'y, y':AHyy':eqA y y'H:eqA x yH':~ eqA x' y'b = b'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset AB:Typeb, b':Bx, x':AHxx':eqA x x'y, y':AHyy':eqA y y'H:~ eqA x yH':eqA x' y'b' = bcontradict H; transitivity x'; auto with *; transitivity y'; auto with *. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset AB:Typeb, b':Bx, x':AHxx':eqA x x'y, y':AHyy':eqA y y'H:~ eqA x yH':eqA x' y'b' = bA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a1 a1' a2 : A) (B : Type) (b b' : B), eqA a1 a1' -> (if eqA_dec a1 a2 then b else b') = (if eqA_dec a1' a2 then b else b')A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a1 a1' a2 : A) (B : Type) (b b' : B), eqA a1 a1' -> (if eqA_dec a1 a2 then b else b') = (if eqA_dec a1' a2 then b else b')A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, a1', a2:AB:Typeb, b':BH:eqA a1 a1'A1:eqA a1 a2A1':~ eqA a1' a2b = b'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, a1', a2:AB:Typeb, b':BH:eqA a1 a1'A1:~ eqA a1 a2A1':eqA a1' a2b' = bcontradict A1; transitivity a1'; eauto with *. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, a1', a2:AB:Typeb, b':BH:eqA a1 a1'A1:~ eqA a1 a2A1':eqA a1' a2b' = bA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a1 a2 a2' : A) (B : Type) (b b' : B), eqA a2 a2' -> (if eqA_dec a1 a2 then b else b') = (if eqA_dec a1 a2' then b else b')A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (a1 a2 a2' : A) (B : Type) (b b' : B), eqA a2 a2' -> (if eqA_dec a1 a2 then b else b') = (if eqA_dec a1 a2' then b else b')A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, a2, a2':AB:Typeb, b':BH:eqA a2 a2'A2:eqA a1 a2A2':~ eqA a1 a2'b = b'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, a2, a2':AB:Typeb, b':BH:eqA a2 a2'A2:~ eqA a1 a2A2':eqA a1 a2'b' = bcontradict A2; transitivity a2'; eauto with *. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, a2, a2':AB:Typeb, b':BH:eqA a2 a2'A2:~ eqA a1 a2A2':eqA a1 a2'b' = bA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al:list AProper (eqA ==> eq) (multiplicity (list_contents l))A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al:list AProper (eqA ==> eq) (multiplicity (list_contents l))A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al:list Ax, x':AHxx':eqA x x'multiplicity (list_contents l) x = multiplicity (list_contents l) x'rewrite (@if_eqA_rewrite_r y x x'); auto. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Ay:Al:list Ax, x':AHxx':eqA x x'Hl:multiplicity (list_contents l) x = multiplicity (list_contents l) x'(if eqA_dec y x then 1 else 0) + multiplicity (list_contents l) x = (if eqA_dec y x' then 1 else 0) + multiplicity (list_contents l) x'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l : list A) (a : A), InA eqA a l <-> 0 < multiplicity (list_contents l) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l : list A) (a : A), InA eqA a l <-> 0 < multiplicity (list_contents l) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall a : A, InA eqA a [ ] <-> 0 < multiplicity (list_contents [ ]) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0forall a0 : A, InA eqA a0 (a :: l) <-> 0 < multiplicity (list_contents (a :: l)) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall a : A, InA eqA a [ ] <-> 0 < 0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0forall a0 : A, InA eqA a0 (a :: l) <-> 0 < multiplicity (list_contents (a :: l)) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0forall a0 : A, InA eqA a0 (a :: l) <-> 0 < multiplicity (list_contents (a :: l)) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0forall a0 : A, InA eqA a0 (a :: l) <-> 0 < (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':AH:InA eqA a' (a :: l)0 < (if eqA_dec a a' then 1 else 0) + multiplicity (list_contents l) a'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':AH:0 < (if eqA_dec a a' then 1 else 0) + multiplicity (list_contents l) a'InA eqA a' (a :: l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':AH0:eqA a' a0 < (if eqA_dec a a' then 1 else 0) + multiplicity (list_contents l) a'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':AH0:InA eqA a' l0 < (if eqA_dec a a' then 1 else 0) + multiplicity (list_contents l) a'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':AH:0 < (if eqA_dec a a' then 1 else 0) + multiplicity (list_contents l) a'InA eqA a' (a :: l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':AH0:InA eqA a' l0 < (if eqA_dec a a' then 1 else 0) + multiplicity (list_contents l) a'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':AH:0 < (if eqA_dec a a' then 1 else 0) + multiplicity (list_contents l) a'InA eqA a' (a :: l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':AH0:InA eqA a' ln:~ eqA a a'0 < 0 + multiplicity (list_contents l) a'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':AH:0 < (if eqA_dec a a' then 1 else 0) + multiplicity (list_contents l) a'InA eqA a' (a :: l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':AH:0 < (if eqA_dec a a' then 1 else 0) + multiplicity (list_contents l) a'InA eqA a' (a :: l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':An:~ eqA a a'H:0 < 0 + multiplicity (list_contents l) a'InA eqA a' (a :: l)rewrite IHl; auto. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:forall a0 : A, InA eqA a0 l <-> 0 < multiplicity (list_contents l) a0a':An:~ eqA a a'H:0 < 0 + multiplicity (list_contents l) a'InA eqA a' lA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l : list A) (a : A), ~ InA eqA a l -> multiplicity (list_contents l) a = 0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l : list A) (a : A), ~ InA eqA a l -> multiplicity (list_contents l) a = 0destruct 1; auto with arith. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al:list Aa:An:nat~ 0 < S n -> S n = 0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l : list A) (a : A), InA eqA a l -> multiplicity (list_contents l) a >= 1intros l a; rewrite multiplicity_InA; auto with arith. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l : list A) (a : A), InA eqA a l -> multiplicity (list_contents l) a >= 1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l : list A, NoDupA eqA l <-> (forall a : A, multiplicity (list_contents l) a <= 1)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l : list A, NoDupA eqA l <-> (forall a : A, multiplicity (list_contents l) a <= 1)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset ANoDupA eqA [ ] <-> (forall a : A, multiplicity (list_contents [ ]) a <= 1)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)NoDupA eqA (a :: l) <-> (forall a0 : A, multiplicity (list_contents (a :: l)) a0 <= 1)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset ANoDupA eqA [ ] <-> (A -> 0 <= 1)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)NoDupA eqA (a :: l) <-> (forall a0 : A, multiplicity (list_contents (a :: l)) a0 <= 1)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)NoDupA eqA (a :: l) <-> (forall a0 : A, multiplicity (list_contents (a :: l)) a0 <= 1)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)NoDupA eqA (a :: l) -> forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDupA eqA (a :: l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H0:~ InA eqA a lH1:NoDupA eqA lforall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDupA eqA (a :: l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H0:~ InA eqA a lH1:forall a0 : A, multiplicity (list_contents l) a0 <= 1forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDupA eqA (a :: l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a1 : A, multiplicity (list_contents l) a1 <= 1)H0:~ InA eqA a lH1:forall a1 : A, multiplicity (list_contents l) a1 <= 1a0:AEQ:eqA a a0S (multiplicity (list_contents l) a0) <= 1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDupA eqA (a :: l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a1 : A, multiplicity (list_contents l) a1 <= 1)H0:~ InA eqA a lH1:forall a1 : A, multiplicity (list_contents l) a1 <= 1a0:AEQ:eqA a a0S (multiplicity (list_contents l) a) <= 1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDupA eqA (a :: l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDupA eqA (a :: l)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1~ InA eqA a lA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDupA eqA lA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1~ 0 < multiplicity (list_contents l) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDupA eqA lA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:(if eqA_dec a a then 1 else 0) + multiplicity (list_contents l) a <= 1~ 0 < multiplicity (list_contents l) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDupA eqA lA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:1 + multiplicity (list_contents l) a <= 1~ 0 < multiplicity (list_contents l) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDupA eqA lA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDupA eqA lA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a1 : A, multiplicity (list_contents l) a1 <= 1)H:forall a1 : A, (if eqA_dec a a1 then 1 else 0) + multiplicity (list_contents l) a1 <= 1a0:Amultiplicity (list_contents l) a0 <= 1omega. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al:list AIHl:NoDupA eqA l <-> (forall a1 : A, multiplicity (list_contents l) a1 <= 1)a0:AH:(if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1multiplicity (list_contents l) a0 <= 1
Permutation is compatible with InA.
A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l1 l2 : list A) (e : A), permutation l1 l2 -> InA eqA e l1 -> InA eqA e l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l1 l2 : list A) (e : A), permutation l1 l2 -> InA eqA e l1 -> InA eqA e l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al1, l2:list Ae:Apermutation l1 l2 -> InA eqA e l1 -> InA eqA e l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al1, l2:list Ae:Apermutation l1 l2 -> 0 < multiplicity (list_contents l1) e -> 0 < multiplicity (list_contents l2) eintros H;rewrite H; auto. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al1, l2:list Ae:A(forall a : A, multiplicity (list_contents l1) a = multiplicity (list_contents l2) a) -> 0 < multiplicity (list_contents l1) e -> 0 < multiplicity (list_contents l2) eA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l1 l2 : list A) (e : A), permutation (e :: l1) l2 -> InA eqA e l2intros; apply (permut_InA_InA (e:=e) H); auto with *. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall (l1 l2 : list A) (e : A), permutation (e :: l1) l2 -> InA eqA e l2
Permutation of an empty list.
A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l : list A, permutation l [ ] -> l = [ ]A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l : list A, permutation l [ ] -> l = [ ]A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Ae:Al:list Apermutation (e :: l) [ ] -> e :: l = [ ]A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Ae:Al:list AH:InA eqA e (e :: l)permutation (e :: l) [ ] -> e :: l = [ ]inversion 1. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Ae:Al:list AH:InA eqA e (e :: l)Abs:permutation (e :: l) [ ]InA eqA e [ ] -> e :: l = [ ]
Permutation for short lists.
A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall a b : A, permutation [a] [b] -> eqA a bA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall a b : A, permutation [a] [b] -> eqA a bA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa, b:A(forall a0 : A, multiplicity (list_contents [a]) a0 = multiplicity (list_contents [b]) a0) -> eqA a bA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa, b:AP:(if eqA_dec a b then 1 else 0) + 0 = (if eqA_dec b b then 1 else 0) + 0eqA a bdestruct (eqA_dec a b); simpl; auto; discriminate. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa, b:AP:(if eqA_dec a b then 1 else 0) + 0 = 1 + 0eqA a bA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall a1 b1 a2 b2 : A, permutation [a1; b1] [a2; b2] -> eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall a1 b1 a2 b2 : A, permutation [a1; b1] [a2; b2] -> eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H:InA eqA a1 [a2; b2]eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:eqA a1 a2eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:InA eqA a1 [b2]eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:eqA a1 a2eqA b1 b2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:InA eqA a1 [b2]eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:eqA a1 a2permutation [b1] [b2]A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:InA eqA a1 [b2]eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:eqA a1 a2a:Amultiplicity (list_contents [b1]) a = multiplicity (list_contents [b2]) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:InA eqA a1 [b2]eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2, a:AP:multiplicity (list_contents [a1; b1]) a = multiplicity (list_contents [a2; b2]) aH0:eqA a1 a2multiplicity (list_contents [b1]) a = multiplicity (list_contents [b2]) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:InA eqA a1 [b2]eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2, a:AP:(if eqA_dec a1 a then 1 else 0) + ((if eqA_dec b1 a then 1 else 0) + 0) = (if eqA_dec a2 a then 1 else 0) + ((if eqA_dec b2 a then 1 else 0) + 0)H0:eqA a1 a2(if eqA_dec b1 a then 1 else 0) + 0 = (if eqA_dec b2 a then 1 else 0) + 0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:InA eqA a1 [b2]eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2, a:AP:(if eqA_dec a2 a then 1 else 0) + ((if eqA_dec b1 a then 1 else 0) + 0) = (if eqA_dec a2 a then 1 else 0) + ((if eqA_dec b2 a then 1 else 0) + 0)H0:eqA a1 a2(if eqA_dec b1 a then 1 else 0) + 0 = (if eqA_dec b2 a then 1 else 0) + 0A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:InA eqA a1 [b2]eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:InA eqA a1 [b2]eqA a1 a2 /\ eqA b1 b2 \/ eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H0:InA eqA a1 [b2]eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H:eqA a1 b2eqA a1 b2 /\ eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H:eqA a1 b2eqA a2 b1A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H:eqA a1 b2permutation [a2] [b1]A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2:AP:permutation [a1; b1] [a2; b2]H:eqA a1 b2a:Amultiplicity (list_contents [a2]) a = multiplicity (list_contents [b1]) aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2, a:AP:(if eqA_dec a1 a then 1 else 0) + ((if eqA_dec b1 a then 1 else 0) + 0) = (if eqA_dec a2 a then 1 else 0) + ((if eqA_dec b2 a then 1 else 0) + 0)H:eqA a1 b2(if eqA_dec a2 a then 1 else 0) + 0 = (if eqA_dec b1 a then 1 else 0) + 0omega. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa1, b1, a2, b2, a:AP:(if eqA_dec b2 a then 1 else 0) + ((if eqA_dec b1 a then 1 else 0) + 0) = (if eqA_dec a2 a then 1 else 0) + ((if eqA_dec b2 a then 1 else 0) + 0)H:eqA a1 b2(if eqA_dec a2 a then 1 else 0) + 0 = (if eqA_dec b1 a then 1 else 0) + 0
Permutation is compatible with length.
A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l1 l2 : list A, permutation l1 l2 -> length l1 = length l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l1 l2 : list A, permutation l1 l2 -> length l1 = length l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al2:list AH:permutation [ ] l2length [ ] = length l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l0 : list A, permutation l1 l0 -> length l1 = length l0l2:list AH:permutation (a :: l1) l2length (a :: l1) = length l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l0 : list A, permutation l1 l0 -> length l1 = length l0l2:list AH:permutation (a :: l1) l2length (a :: l1) = length l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l0 : list A, permutation l1 l0 -> length l1 = length l0l2:list AH:permutation (a :: l1) l2H0:InA eqA a l2length (a :: l1) = length l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l0 : list A, permutation l1 l0 -> length l1 = length l0l2:list AH:permutation (a :: l1) l2H0:InA eqA a l2h2:list Ab:At2:list AH1:eqA a bH2:l2 = h2 ++ b :: t2length (a :: l1) = length l2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)H:permutation (a :: l1) (h2 ++ b :: t2)H1:eqA a blength (a :: l1) = length (h2 ++ b :: t2)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)H:permutation (a :: l1) (h2 ++ b :: t2)H1:eqA a blength (a :: l1) = length h2 + length (b :: t2)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)H:permutation (a :: l1) (h2 ++ b :: t2)H1:eqA a blength l1 = length h2 + length t2A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)H:permutation (a :: l1) (h2 ++ b :: t2)H1:eqA a blength l1 = length (h2 ++ t2)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)H:permutation (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation l1 (h2 ++ t2)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)H:permutation (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation (b :: l1) (h2 ++ b :: t2)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)H:permutation (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation (b :: l1) (a :: l1)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)H:permutation (a :: l1) (h2 ++ b :: t2)eqA a b -> forall a0 : A, (if eqA_dec b a0 then 1 else 0) + multiplicity (list_contents l1) a0 = (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents l1) a0rewrite (@if_eqA_rewrite_l a b a0); auto. Qed.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aa:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)H:permutation (a :: l1) (h2 ++ b :: t2)H1:eqA a ba0:A(if eqA_dec b a0 then 1 else 0) = (if eqA_dec a a0 then 1 else 0)A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l l' : list A, NoDupA eqA l -> NoDupA eqA l' -> equivlistA eqA l l' -> permutation l l'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Aforall l l' : list A, NoDupA eqA l -> NoDupA eqA l' -> equivlistA eqA l l' -> permutation l l'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l':list AH:NoDupA eqA lH0:NoDupA eqA l'H1:equivlistA eqA l l'permutation l l'A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l':list AH:NoDupA eqA lH0:NoDupA eqA l'H1:equivlistA eqA l l'a:Amultiplicity (list_contents l) a = multiplicity (list_contents l') aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l':list AH:forall a0 : A, multiplicity (list_contents l) a0 <= 1H0:forall a0 : A, multiplicity (list_contents l') a0 <= 1H1:equivlistA eqA l l'a:Amultiplicity (list_contents l) a = multiplicity (list_contents l') aA:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l':list Aa:Amultiplicity (list_contents l) a <= 1 -> multiplicity (list_contents l') a <= 1 -> InA eqA a l <-> InA eqA a l' -> multiplicity (list_contents l) a = multiplicity (list_contents l') adestruct 3; omega. Qed. End Permut. Section Permut_map. Variables A B : Type. Variable eqA : relation A. Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}. Hypothesis eqA_equiv : Equivalence eqA. Variable eqB : B->B->Prop. Hypothesis eqB_dec : forall x y:B, { eqB x y }+{ ~eqB x y }. Hypothesis eqB_trans : Transitive eqB.A:TypeeqA:relation AeqA_equiv:Equivalence eqAeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}emptyBag:=EmptyBag A:multiset AsingletonBag:=SingletonBag eqA eqA_dec:A -> multiset Al, l':list Aa:Amultiplicity (list_contents l) a <= 1 -> multiplicity (list_contents l') a <= 1 -> 0 < multiplicity (list_contents l) a <-> 0 < multiplicity (list_contents l') a -> multiplicity (list_contents l) a = multiplicity (list_contents l') a
Permutation is compatible with map.
A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBforall f : A -> B, Proper (eqA ==> eqB) f -> forall l1 l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBforall f : A -> B, Proper (eqA ==> eqB) f -> forall l1 l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fforall l2 : list A, permutation eqA eqA_dec [ ] l2 -> permutation eqB eqB_dec (map f [ ]) (map f l2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)forall l2 : list A, permutation eqA eqA_dec (a :: l1) l2 -> permutation eqB eqB_dec (map f (a :: l1)) (map f l2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)forall l2 : list A, permutation eqA eqA_dec (a :: l1) l2 -> permutation eqB eqB_dec (map f (a :: l1)) (map f l2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l0 : list A, permutation eqA eqA_dec l1 l0 -> permutation eqB eqB_dec (map f l1) (map f l0)l2:list AP:permutation eqA eqA_dec (a :: l1) l2permutation eqB eqB_dec (map f (a :: l1)) (map f l2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l0 : list A, permutation eqA eqA_dec l1 l0 -> permutation eqB eqB_dec (map f l1) (map f l0)l2:list AP:permutation eqA eqA_dec (a :: l1) l2permutation eqB eqB_dec (f a :: map f l1) (map f l2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l0 : list A, permutation eqA eqA_dec l1 l0 -> permutation eqB eqB_dec (map f l1) (map f l0)l2:list AP:permutation eqA eqA_dec (a :: l1) l2H0:InA eqA a l2permutation eqB eqB_dec (f a :: map f l1) (map f l2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l0 : list A, permutation eqA eqA_dec l1 l0 -> permutation eqB eqB_dec (map f l1) (map f l0)l2:list AP:permutation eqA eqA_dec (a :: l1) l2H0:InA eqA a l2h2:list Ab:At2:list AH1:eqA a bH2:l2 = h2 ++ b :: t2permutation eqB eqB_dec (f a :: map f l1) (map f l2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (f a :: map f l1) (map f (h2 ++ b :: t2))A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (f a :: map f l1) (map f h2 ++ map f (b :: t2))A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (f a :: map f l1) (map f h2 ++ f b :: map f t2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (f a :: map f l1) (f b :: map f l1)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (f b :: map f l1) (map f h2 ++ f b :: map f t2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)eqA a b -> forall a0 : B, (if eqB_dec (f a) a0 then 1 else 0) + multiplicity (list_contents eqB eqB_dec (map f l1)) a0 = (if eqB_dec (f b) a0 then 1 else 0) + multiplicity (list_contents eqB eqB_dec (map f l1)) a0A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (f b :: map f l1) (map f h2 ++ f b :: map f t2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a ba0:B(if eqB_dec (f a) a0 then 1 else 0) = (if eqB_dec (f b) a0 then 1 else 0)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (f b :: map f l1) (map f h2 ++ f b :: map f t2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a ba0:BH2:eqB (f b) a0H3:~ eqB (f a) a00 = 1A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a ba0:BH2:~ eqB (f b) a0H3:eqB (f a) a01 = 0A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (f b :: map f l1) (map f h2 ++ f b :: map f t2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a ba0:BH2:~ eqB (f b) a0H3:eqB (f a) a01 = 0A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (f b :: map f l1) (map f h2 ++ f b :: map f t2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (f b :: map f l1) (map f h2 ++ f b :: map f t2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (map f l1) (map f h2 ++ map f t2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqB eqB_dec (map f l1) (map f (h2 ++ t2))A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqA eqA_dec l1 (h2 ++ t2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqA eqA_dec (b :: l1) (h2 ++ b :: t2)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a bpermutation eqA eqA_dec (b :: l1) (a :: l1)A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)eqA a b -> forall a0 : A, (if eqA_dec b a0 then 1 else 0) + multiplicity (list_contents eqA eqA_dec l1) a0 = (if eqA_dec a a0 then 1 else 0) + multiplicity (list_contents eqA eqA_dec l1) a0rewrite (@if_eqA_rewrite_l _ _ eqA_equiv eqA_dec a b a0); auto. Qed. End Permut_map. Require Import Permutation. Section Permut_permut. Variable A : Type. Variable eqA : relation A. Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}. Hypothesis eqA_equiv : Equivalence eqA.A, B:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAeqB:B -> B -> PropeqB_dec:forall x y : B, {eqB x y} + {~ eqB x y}eqB_trans:Transitive eqBf:A -> BH:Proper (eqA ==> eqB) fa:Al1:list AIHl1:forall l2 : list A, permutation eqA eqA_dec l1 l2 -> permutation eqB eqB_dec (map f l1) (map f l2)h2:list Ab:At2:list AH0:InA eqA a (h2 ++ b :: t2)P:permutation eqA eqA_dec (a :: l1) (h2 ++ b :: t2)H1:eqA a ba0:A(if eqA_dec b a0 then 1 else 0) = (if eqA_dec a a0 then 1 else 0)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAforall l l' : list A, Permutation l l' -> permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAforall l l' : list A, Permutation l l' -> permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqApermutation eqA eqA_dec [ ] [ ]A:TypeeqA:relation AeqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}eqA_equiv:Equivalence eqAx:Al, l':list AH:Permutation l l'IHPermutation:permutation eqA eqA_dec l l'permutation eqA eqA_dec (x :: l) (x :: l')A:TypeeqA:relation AeqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}eqA_equiv:Equivalence eqAx, y:Al:list Apermutation eqA eqA_dec (y :: x :: l) (x :: y :: l)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:permutation eqA eqA_dec l l'IHPermutation2:permutation eqA eqA_dec l' l''permutation eqA eqA_dec l l''A:TypeeqA:relation AeqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}eqA_equiv:Equivalence eqAx:Al, l':list AH:Permutation l l'IHPermutation:permutation eqA eqA_dec l l'permutation eqA eqA_dec (x :: l) (x :: l')A:TypeeqA:relation AeqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}eqA_equiv:Equivalence eqAx, y:Al:list Apermutation eqA eqA_dec (y :: x :: l) (x :: y :: l)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:permutation eqA eqA_dec l l'IHPermutation2:permutation eqA eqA_dec l' l''permutation eqA eqA_dec l l''A:TypeeqA:relation AeqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}eqA_equiv:Equivalence eqAx, y:Al:list Apermutation eqA eqA_dec (y :: x :: l) (x :: y :: l)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:permutation eqA eqA_dec l l'IHPermutation2:permutation eqA eqA_dec l' l''permutation eqA eqA_dec l l''apply permut_trans with l'; trivial. Qed.A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:permutation eqA eqA_dec l l'IHPermutation2:permutation eqA eqA_dec l' l''permutation eqA eqA_dec l l''A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAforall l l' : list A, Forall2 eqA l l' -> permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAforall l l' : list A, Forall2 eqA l l' -> permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqApermutation eqA eqA_dec [ ] [ ]A:TypeeqA:relation AeqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}eqA_equiv:Equivalence eqAx, y:Al, l':list AH:eqA x yH0:Forall2 eqA l l'IHForall2:permutation eqA eqA_dec l l'permutation eqA eqA_dec (x :: l) (y :: l')apply permut_cons_eq; trivial. Qed.A:TypeeqA:relation AeqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}eqA_equiv:Equivalence eqAx, y:Al, l':list AH:eqA x yH0:Forall2 eqA l l'IHForall2:permutation eqA eqA_dec l l'permutation eqA eqA_dec (x :: l) (y :: l')A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAforall l l' : list A, permutation eqA eqA_dec l l' <-> (exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l')A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAforall l l' : list A, permutation eqA eqA_dec l l' <-> (exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l')(* -> *)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l':list AH:permutation eqA eqA_dec l l'exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l':list AH:exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl':list AH:permutation eqA eqA_dec [ ] l'exists l'' : list A, Permutation [ ] l'' /\ Forall2 eqA l'' l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAa:Al, l':list AH:permutation eqA eqA_dec (a :: l) l'IHl:forall l'0 : list A, permutation eqA eqA_dec l l'0 -> exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'0exists l'' : list A, Permutation (a :: l) l'' /\ Forall2 eqA l'' l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l':list AH:exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAa:Al, l':list AH:permutation eqA eqA_dec (a :: l) l'IHl:forall l'0 : list A, permutation eqA eqA_dec l l'0 -> exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'0exists l'' : list A, Permutation (a :: l) l'' /\ Forall2 eqA l'' l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l':list AH:exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAa:Al, l':list AH:permutation eqA eqA_dec (a :: l) l'IHl:forall l'0 : list A, permutation eqA eqA_dec l l'0 -> exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'0H':permutation eqA eqA_dec (a :: l) l'exists l'' : list A, Permutation (a :: l) l'' /\ Forall2 eqA l'' l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l':list AH:exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y0 : A, {eqA x y0} + {~ eqA x y0}eqA_equiv:Equivalence eqAa:Al, l1:list Ay:Al2:list AHeq:eqA a yIHl:forall l' : list A, permutation eqA eqA_dec l l' -> exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'H':permutation eqA eqA_dec (a :: l) (l1 ++ y :: l2)exists l'' : list A, Permutation (a :: l) l'' /\ Forall2 eqA l'' (l1 ++ y :: l2)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l':list AH:exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y0 : A, {eqA x y0} + {~ eqA x y0}eqA_equiv:Equivalence eqAa:Al, l1:list Ay:Al2:list AHeq:eqA a yl'':list AIHP:Permutation l l''IHA:Forall2 eqA l'' (l1 ++ l2)exists l''0 : list A, Permutation (a :: l) l''0 /\ Forall2 eqA l''0 (l1 ++ y :: l2)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l':list AH:exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y0 : A, {eqA x y0} + {~ eqA x y0}eqA_equiv:Equivalence eqAa:Al, l1:list Ay:Al2:list AHeq:eqA a yl1'', l2'':list AIHP:Permutation l (l1'' ++ l2'')Hl1:Forall2 eqA l1'' l1Hl2:Forall2 eqA l2'' l2exists l'' : list A, Permutation (a :: l) l'' /\ Forall2 eqA l'' (l1 ++ y :: l2)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l':list AH:exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y0 : A, {eqA x y0} + {~ eqA x y0}eqA_equiv:Equivalence eqAa:Al, l1:list Ay:Al2:list AHeq:eqA a yl1'', l2'':list AIHP:Permutation l (l1'' ++ l2'')Hl1:Forall2 eqA l1'' l1Hl2:Forall2 eqA l2'' l2Permutation (a :: l) (l1'' ++ a :: l2'')A:TypeeqA:relation AeqA_dec:forall x y0 : A, {eqA x y0} + {~ eqA x y0}eqA_equiv:Equivalence eqAa:Al, l1:list Ay:Al2:list AHeq:eqA a yl1'', l2'':list AIHP:Permutation l (l1'' ++ l2'')Hl1:Forall2 eqA l1'' l1Hl2:Forall2 eqA l2'' l2Forall2 eqA (l1'' ++ a :: l2'') (l1 ++ y :: l2)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l':list AH:exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y0 : A, {eqA x y0} + {~ eqA x y0}eqA_equiv:Equivalence eqAa:Al, l1:list Ay:Al2:list AHeq:eqA a yl1'', l2'':list AIHP:Permutation l (l1'' ++ l2'')Hl1:Forall2 eqA l1'' l1Hl2:Forall2 eqA l2'' l2Forall2 eqA (l1'' ++ a :: l2'') (l1 ++ y :: l2)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l':list AH:exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'permutation eqA eqA_dec l l'(* <- *)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l':list AH:exists l'' : list A, Permutation l l'' /\ Forall2 eqA l'' l'permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l', l'':list AH:Permutation l l''Heq:Forall2 eqA l'' l'permutation eqA eqA_dec l l'A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l', l'':list AH:Permutation l l''Heq:Forall2 eqA l'' l'permutation eqA eqA_dec l l''A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l', l'':list AH:Permutation l l''Heq:Forall2 eqA l'' l'permutation eqA eqA_dec l'' l'apply permut_eqA; trivial. Qed. End Permut_permut. (* begin hide *)A:TypeeqA:relation AeqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}eqA_equiv:Equivalence eqAl, l', l'':list AH:Permutation l l''Heq:Forall2 eqA l'' l'permutation eqA eqA_dec l'' l'
For compatibility
Notation permut_right := permut_cons (only parsing). Notation permut_tran := permut_trans (only parsing). (* end hide *)