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 Relations Setoid SetoidList List Multiset PermutSetoid Permutation Omega. Set Implicit Arguments.
This file is similar to PermutSetoid, except that the equality used here
is Coq usual one instead of a setoid equality. In particular, we can then
prove the equivalence between Permutation.Permutation and
PermutSetoid.permutation.
Section Perm. Variable A : Type. Hypothesis eq_dec : forall x y:A, {x=y} + {~ x=y}. Notation permutation := (permutation _ eq_dec). Notation list_contents := (list_contents _ eq_dec).
we can use multiplicity to define In and NoDup.
A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall (l : list A) (a : A), In a l <-> 0 < multiplicity (list_contents l) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall (l : list A) (a : A), In a l <-> 0 < multiplicity (list_contents l) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l:list Aa:AH:In a l0 < multiplicity (list_contents l) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l:list Aa:AH:0 < multiplicity (list_contents l) aIn a leapply multiplicity_InA, InA_alt in H as (y & -> & H); eauto with typeclass_instances. Qed.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l:list Aa:AH:0 < multiplicity (list_contents l) aIn a lA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall (l : list A) (a : A), ~ In a l -> multiplicity (list_contents l) a = 0A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall (l : list A) (a : A), ~ In a l -> multiplicity (list_contents l) a = 0destruct 1; auto with arith. Qed.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l:list Aa:An:nat~ 0 < S n -> S n = 0A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall (l : list A) (a : A), In a l -> multiplicity (list_contents l) a >= 1intros l a; rewrite multiplicity_In; auto. Qed.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall (l : list A) (a : A), In a l -> multiplicity (list_contents l) a >= 1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall l : list A, NoDup l <-> (forall a : A, multiplicity (list_contents l) a <= 1)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall l : list A, NoDup l <-> (forall a : A, multiplicity (list_contents l) a <= 1)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}NoDup nil <-> (forall a : A, multiplicity (list_contents nil) a <= 1)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)NoDup (a :: l) <-> (forall a0 : A, multiplicity (list_contents (a :: l)) a0 <= 1)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}NoDup nil <-> (A -> 0 <= 1)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)NoDup (a :: l) <-> (forall a0 : A, multiplicity (list_contents (a :: l)) a0 <= 1)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}(A -> 0 <= 1) -> NoDup nilA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)NoDup (a :: l) <-> (forall a0 : A, multiplicity (list_contents (a :: l)) a0 <= 1)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)NoDup (a :: l) <-> (forall a0 : A, multiplicity (list_contents (a :: l)) a0 <= 1)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)NoDup (a :: l) -> forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDup (a :: l)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H0:~ In a lH1:NoDup lforall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDup (a :: l)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H0:~ In a lH1:forall a0 : A, multiplicity (list_contents l) a0 <= 1forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDup (a :: l)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a1 : A, multiplicity (list_contents l) a1 <= 1)H0:~ In a lH1:forall a1 : A, multiplicity (list_contents l) a1 <= 1a0:AH2:a = a0S (multiplicity (list_contents l) a0) <= 1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDup (a :: l)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H0:~ In a lH1:forall a0 : A, multiplicity (list_contents l) a0 <= 1S (multiplicity (list_contents l) a) <= 1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDup (a :: l)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)(forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1) -> NoDup (a :: l)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1~ In a lA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDup lA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1~ 0 < multiplicity (list_contents l) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDup lA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1(if eq_dec a a then 1 else 0) + multiplicity (list_contents l) a <= 1 -> ~ 0 < multiplicity (list_contents l) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDup lA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1H0:a = a1 + multiplicity (list_contents l) a <= 1 -> ~ 0 < multiplicity (list_contents l) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1H0:a <> a0 + multiplicity (list_contents l) a <= 1 -> ~ 0 < multiplicity (list_contents l) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDup lA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1H0:a = an:nat1 + S n <= 1 -> ~ 0 < S nA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1H0:a <> a0 + multiplicity (list_contents l) a <= 1 -> ~ 0 < multiplicity (list_contents l) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDup lA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1H0:a = an:natH1:S (S n) <= 1m:natH3:S (S n) <= 0H2:m = 0~ 0 < S nA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1H0:a <> a0 + multiplicity (list_contents l) a <= 1 -> ~ 0 < multiplicity (list_contents l) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDup lA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1H0:a <> a0 + multiplicity (list_contents l) a <= 1 -> ~ 0 < multiplicity (list_contents l) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDup lA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)H:forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1NoDup lA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a1 : A, multiplicity (list_contents l) a1 <= 1)H:forall a1 : A, (if eq_dec a a1 then 1 else 0) + multiplicity (list_contents l) a1 <= 1a0:Amultiplicity (list_contents l) a0 <= 1destruct (eq_dec a a0); simpl; auto with arith. Qed.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:NoDup l <-> (forall a1 : A, multiplicity (list_contents l) a1 <= 1)H:forall a1 : A, (if eq_dec a a1 then 1 else 0) + multiplicity (list_contents l) a1 <= 1a0:A(if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1 -> multiplicity (list_contents l) a0 <= 1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall l l' : list A, NoDup l -> NoDup l' -> (forall x : A, In x l <-> In x l') -> permutation l l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall l l' : list A, NoDup l -> NoDup l' -> (forall x : A, In x l <-> In x l') -> permutation l l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list AH:NoDup lH0:NoDup l'H1:forall x : A, In x l <-> In x l'permutation l l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list AH:NoDup lH0:NoDup l'H1:forall x : A, In x l <-> In x l'a:Amultiplicity (list_contents l) a = multiplicity (list_contents l') aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list AH:forall a0 : A, multiplicity (list_contents l) a0 <= 1H0:forall a0 : A, multiplicity (list_contents l') a0 <= 1H1:forall x : A, In x l <-> In x l'a:Amultiplicity (list_contents l) a = multiplicity (list_contents l') aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list Aa:Amultiplicity (list_contents l) a <= 1 -> multiplicity (list_contents l') a <= 1 -> In a l <-> In a l' -> multiplicity (list_contents l) a = multiplicity (list_contents l') adestruct 3; omega. Qed.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, 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 In.
A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall (l1 l2 : list A) (e : A), permutation l1 l2 -> In e l1 -> In e l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall (l1 l2 : list A) (e : A), permutation l1 l2 -> In e l1 -> In e l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l1, l2:list Ae:AP:forall a : A, multiplicity (list_contents l1) a = multiplicity (list_contents l2) aIN:In e l1In e l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l1, l2:list Ae:AIN:In e l1multiplicity (list_contents l1) e = multiplicity (list_contents l2) e -> In e l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l1, l2:list Ae:AIN:In e l1H:~ In e l2multiplicity (list_contents l1) e = multiplicity (list_contents l2) e -> In e l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l1, l2:list Ae:AIN:In e l1H:~ In e l2multiplicity (list_contents l1) e = 0 -> In e l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l1, l2:list Ae:AIN:In e l1H:~ In e l2H0:multiplicity (list_contents l1) e = 0In e l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l1, l2:list Ae:AIN:In e l1H:~ In e l2H0:multiplicity (list_contents l1) e = 0multiplicity (list_contents l1) e >= 1 -> In e l2inversion 1. Qed.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l1, l2:list Ae:AIN:In e l1H:~ In e l2H0:multiplicity (list_contents l1) e = 00 >= 1 -> In e l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall (l1 l2 : list A) (e : A), permutation (e :: l1) l2 -> In e l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall (l1 l2 : list A) (e : A), permutation (e :: l1) l2 -> In e l2red; auto. Qed.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l1, l2:list Ae:AH:permutation (e :: l1) l2In e (e :: l1)
Permutation of an empty list.
A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall l : list A, permutation l nil -> l = nilA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall l : list A, permutation l nil -> l = nilA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}e:Al:list Apermutation (e :: l) nil -> e :: l = nilA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}e:Al:list AH:In e (e :: l)permutation (e :: l) nil -> e :: l = nilinversion 1. Qed.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}e:Al:list AH:In e (e :: l)Abs:permutation (e :: l) nilIn e nil -> e :: l = nil
When used with eq, this permutation notion is equivalent to
the one defined in List.v.
A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall l l' : list A, Permutation l l' <-> permutation l l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall l l' : list A, Permutation l l' <-> permutation l l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list APermutation l l' -> permutation l l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list Apermutation l l' -> Permutation l l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}permutation nil nilA:Typeeq_dec:forall x0 y : A, {x0 = y} + {x0 <> y}x:Al, l':list AH:Permutation l l'IHPermutation:permutation l l'permutation (x :: l) (x :: l')A:Typeeq_dec:forall x0 y0 : A, {x0 = y0} + {x0 <> y0}x, y:Al:list Apermutation (y :: x :: l) (x :: y :: l)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:permutation l l'IHPermutation2:permutation l' l''permutation l l''A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list Apermutation l l' -> Permutation l l'A:Typeeq_dec:forall x0 y : A, {x0 = y} + {x0 <> y}x:Al, l':list AH:Permutation l l'IHPermutation:permutation l l'permutation (x :: l) (x :: l')A:Typeeq_dec:forall x0 y0 : A, {x0 = y0} + {x0 <> y0}x, y:Al:list Apermutation (y :: x :: l) (x :: y :: l)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:permutation l l'IHPermutation2:permutation l' l''permutation l l''A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list Apermutation l l' -> Permutation l l'A:Typeeq_dec:forall x0 y0 : A, {x0 = y0} + {x0 <> y0}x, y:Al:list Apermutation (y :: x :: l) (x :: y :: l)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:permutation l l'IHPermutation2:permutation l' l''permutation l l''A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list Apermutation l l' -> Permutation l l'A:Typeeq_dec:forall x0 y0 : A, {x0 = y0} + {x0 <> y0}x, y:Al:list Apermutation (y :: x :: l) ((x :: nil) ++ y :: l)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:permutation l l'IHPermutation2:permutation l' l''permutation l l''A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list Apermutation l l' -> Permutation l l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:permutation l l'IHPermutation2:permutation l' l''permutation l l''A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list Apermutation l l' -> Permutation l l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l, l':list Apermutation l l' -> Permutation l l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l:list Aforall l' : list A, permutation l l' -> Permutation l l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall l' : list A, permutation nil l' -> Permutation nil l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:forall l' : list A, permutation l l' -> Permutation l l'forall l' : list A, permutation (a :: l) l' -> Permutation (a :: l) l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l':list AH:permutation nil l'Permutation nil l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:forall l' : list A, permutation l l' -> Permutation l l'forall l' : list A, permutation (a :: l) l' -> Permutation (a :: l) l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l':list AH:permutation nil l'Permutation nil nilA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:forall l' : list A, permutation l l' -> Permutation l l'forall l' : list A, permutation (a :: l) l' -> Permutation (a :: l) l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:forall l' : list A, permutation l l' -> Permutation l l'forall l' : list A, permutation (a :: l) l' -> Permutation (a :: l) l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:forall l'0 : list A, permutation l l'0 -> Permutation l l'0l':list AH:permutation (a :: l) l'Permutation (a :: l) l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:forall l'0 : list A, permutation l l'0 -> Permutation l l'0l':list AH:permutation (a :: l) l'h2, t2:list AH1:l' = h2 ++ a :: t2Permutation (a :: l) l'A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:forall l' : list A, permutation l l' -> Permutation l l'h2, t2:list AH:permutation (a :: l) (h2 ++ a :: t2)Permutation (a :: l) (h2 ++ a :: t2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:forall l' : list A, permutation l l' -> Permutation l l'h2, t2:list AH:permutation (a :: l) (h2 ++ a :: t2)Permutation l (h2 ++ t2)apply permut_remove_hd with a; auto with typeclass_instances. Qed.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al:list AIHl:forall l' : list A, permutation l l' -> Permutation l l'h2, t2:list AH:permutation (a :: l) (h2 ++ a :: t2)permutation l (h2 ++ t2)
Permutation for short lists.
A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall a b : A, permutation (a :: nil) (b :: nil) -> a = bA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall a b : A, permutation (a :: nil) (b :: nil) -> a = bA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a, b:A(if eq_dec a b then 1 else 0) + 0 = (if eq_dec b b then 1 else 0) + 0 -> a = bdestruct (eq_dec a b); simpl; auto; intros; discriminate. Qed.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a, b:AH:b = b(if eq_dec a b then 1 else 0) + 0 = 1 + 0 -> a = bA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall a1 b1 a2 b2 : A, permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil) -> a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall a1 b1 a2 b2 : A, permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil) -> a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H:In a1 (a2 :: b2 :: nil)a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:a2 = a1a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:In a1 (b2 :: nil)a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:a2 = a1b1 = b2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:In a1 (b2 :: nil)a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:a2 = a1permutation (b1 :: nil) (b2 :: nil)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:In a1 (b2 :: nil)a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:a2 = a1a:Amultiplicity (list_contents (b1 :: nil)) a = multiplicity (list_contents (b2 :: nil)) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:In a1 (b2 :: nil)a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AH0:a2 = a1a:A(if eq_dec a1 a then 1 else 0) + ((if eq_dec b1 a then 1 else 0) + 0) = (if eq_dec a2 a then 1 else 0) + ((if eq_dec b2 a then 1 else 0) + 0) -> (if eq_dec b1 a then 1 else 0) + 0 = (if eq_dec b2 a then 1 else 0) + 0A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:In a1 (b2 :: nil)a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AH0:a2 = a1a:AH2:a1 = aH3:a2 <> a1 + ((if eq_dec b1 a then 1 else 0) + 0) = 0 + ((if eq_dec b2 a then 1 else 0) + 0) -> (if eq_dec b1 a then 1 else 0) + 0 = (if eq_dec b2 a then 1 else 0) + 0A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AH0:a2 = a1a:AH2:a1 <> aH3:a2 = a0 + ((if eq_dec b1 a then 1 else 0) + 0) = 1 + ((if eq_dec b2 a then 1 else 0) + 0) -> (if eq_dec b1 a then 1 else 0) + 0 = (if eq_dec b2 a then 1 else 0) + 0A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:In a1 (b2 :: nil)a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AH0:a2 = a1a:AH2:a1 <> aH3:a2 = a0 + ((if eq_dec b1 a then 1 else 0) + 0) = 1 + ((if eq_dec b2 a then 1 else 0) + 0) -> (if eq_dec b1 a then 1 else 0) + 0 = (if eq_dec b2 a then 1 else 0) + 0A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:In a1 (b2 :: nil)a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:In a1 (b2 :: nil)a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H0:In a1 (b2 :: nil)a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H:b2 = a1a1 = b2 /\ a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H:b2 = a1a2 = b1A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H:b2 = a1permutation (a2 :: nil) (b1 :: nil)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AP:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)H:b2 = a1a:Amultiplicity (list_contents (a2 :: nil)) a = multiplicity (list_contents (b1 :: nil)) aA:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AH:b2 = a1a:A(if eq_dec a1 a then 1 else 0) + ((if eq_dec b1 a then 1 else 0) + 0) = (if eq_dec a2 a then 1 else 0) + ((if eq_dec b2 a then 1 else 0) + 0) -> (if eq_dec a2 a then 1 else 0) + 0 = (if eq_dec b1 a then 1 else 0) + 0A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AH:b2 = a1a:AH2:a1 = aH3:b2 = a1 + ((if eq_dec b1 a then 1 else 0) + 0) = (if eq_dec a2 a then 1 else 0) + (1 + 0) -> (if eq_dec a2 a then 1 else 0) + 0 = (if eq_dec b1 a then 1 else 0) + 0A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AH:b2 = a1a:AH2:a1 = aH3:b2 <> a1 + ((if eq_dec b1 a then 1 else 0) + 0) = (if eq_dec a2 a then 1 else 0) + (0 + 0) -> (if eq_dec a2 a then 1 else 0) + 0 = (if eq_dec b1 a then 1 else 0) + 0A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AH:b2 = a1a:AH2:a1 <> aH3:b2 = a0 + ((if eq_dec b1 a then 1 else 0) + 0) = (if eq_dec a2 a then 1 else 0) + (1 + 0) -> (if eq_dec a2 a then 1 else 0) + 0 = (if eq_dec b1 a then 1 else 0) + 0A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AH:b2 = a1a:AH2:a1 = aH3:b2 <> a1 + ((if eq_dec b1 a then 1 else 0) + 0) = (if eq_dec a2 a then 1 else 0) + (0 + 0) -> (if eq_dec a2 a then 1 else 0) + 0 = (if eq_dec b1 a then 1 else 0) + 0A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AH:b2 = a1a:AH2:a1 <> aH3:b2 = a0 + ((if eq_dec b1 a then 1 else 0) + 0) = (if eq_dec a2 a then 1 else 0) + (1 + 0) -> (if eq_dec a2 a then 1 else 0) + 0 = (if eq_dec b1 a then 1 else 0) + 0destruct H2; transitivity b2; auto. Qed.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a1, b1, a2, b2:AH:b2 = a1a:AH2:a1 <> aH3:b2 = a0 + ((if eq_dec b1 a then 1 else 0) + 0) = (if eq_dec a2 a then 1 else 0) + (1 + 0) -> (if eq_dec a2 a then 1 else 0) + 0 = (if eq_dec b1 a then 1 else 0) + 0
Permutation is compatible with length.
A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall l1 l2 : list A, permutation l1 l2 -> length l1 = length l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}forall l1 l2 : list A, permutation l1 l2 -> length l1 = length l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}l2:list AH:permutation nil l2length nil = length l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al1:list AIHl1:forall l0 : list A, permutation l1 l0 -> length l1 = length l0l2:list AH:permutation (a :: l1) l2length (a :: l1) = length l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al1:list AIHl1:forall l0 : list A, permutation l1 l0 -> length l1 = length l0l2:list AH:permutation (a :: l1) l2length (a :: l1) = length l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al1:list AIHl1:forall l0 : list A, permutation l1 l0 -> length l1 = length l0l2:list AH:permutation (a :: l1) l2h2, t2:list AH1:l2 = h2 ++ a :: t2length (a :: l1) = length l2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2, t2:list AH:permutation (a :: l1) (h2 ++ a :: t2)length (a :: l1) = length (h2 ++ a :: t2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2, t2:list AH:permutation (a :: l1) (h2 ++ a :: t2)length (a :: l1) = length h2 + length (a :: t2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2, t2:list AH:permutation (a :: l1) (h2 ++ a :: t2)length l1 = length h2 + length t2A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2, t2:list AH:permutation (a :: l1) (h2 ++ a :: t2)length l1 = length (h2 ++ t2)apply permut_remove_hd with a; auto with typeclass_instances. Qed. Variable B : Type. Variable eqB_dec : forall x y:B, { x=y }+{ ~x=y }.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}a:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2h2, t2:list AH:permutation (a :: l1) (h2 ++ a :: t2)permutation l1 (h2 ++ t2)
Permutation is compatible with map.
A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}forall (f : A -> B) (l1 l2 : list A), permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}forall (f : A -> B) (l1 l2 : list A), permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Bforall l2 : list A, permutation nil l2 -> PermutSetoid.permutation eq eqB_dec (map f nil) (map f l2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Ba:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)forall l2 : list A, permutation (a :: l1) l2 -> PermutSetoid.permutation eq eqB_dec (map f (a :: l1)) (map f l2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Ba:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)forall l2 : list A, permutation (a :: l1) l2 -> PermutSetoid.permutation eq eqB_dec (map f (a :: l1)) (map f l2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Ba:Al1:list AIHl1:forall l0 : list A, permutation l1 l0 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l0)l2:list AP:permutation (a :: l1) l2PermutSetoid.permutation eq eqB_dec (map f (a :: l1)) (map f l2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Ba:Al1:list AIHl1:forall l0 : list A, permutation l1 l0 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l0)l2:list AP:permutation (a :: l1) l2PermutSetoid.permutation eq eqB_dec (f a :: map f l1) (map f l2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Ba:Al1:list AIHl1:forall l0 : list A, permutation l1 l0 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l0)l2:list AP:permutation (a :: l1) l2h2, t2:list AH1:l2 = h2 ++ a :: t2PermutSetoid.permutation eq eqB_dec (f a :: map f l1) (map f l2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Ba:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)h2, t2:list AP:permutation (a :: l1) (h2 ++ a :: t2)PermutSetoid.permutation eq eqB_dec (f a :: map f l1) (map f (h2 ++ a :: t2))A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Ba:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)h2, t2:list AP:permutation (a :: l1) (h2 ++ a :: t2)PermutSetoid.permutation eq eqB_dec (f a :: map f l1) (map f h2 ++ map f (a :: t2))A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Ba:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)h2, t2:list AP:permutation (a :: l1) (h2 ++ a :: t2)PermutSetoid.permutation eq eqB_dec (f a :: map f l1) (map f h2 ++ f a :: map f t2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Ba:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)h2, t2:list AP:permutation (a :: l1) (h2 ++ a :: t2)PermutSetoid.permutation eq eqB_dec (map f l1) (map f h2 ++ map f t2)A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Ba:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)h2, t2:list AP:permutation (a :: l1) (h2 ++ a :: t2)PermutSetoid.permutation eq eqB_dec (map f l1) (map f (h2 ++ t2))apply permut_remove_hd with a; auto with typeclass_instances. Qed. End Perm.A:Typeeq_dec:forall x y : A, {x = y} + {x <> y}B:TypeeqB_dec:forall x y : B, {x = y} + {x <> y}f:A -> Ba:Al1:list AIHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)h2, t2:list AP:permutation (a :: l1) (h2 ++ a :: t2)permutation l1 (h2 ++ t2)