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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall (l : list A) (a : A), In a l <-> 0 < multiplicity (list_contents l) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall (l : list A) (a : A), In a l <-> 0 < multiplicity (list_contents l) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l:list A
a:A
H:In a l

0 < multiplicity (list_contents l) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l:list A
a:A
H:0 < multiplicity (list_contents l) a
In a l
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l:list A
a:A
H:0 < multiplicity (list_contents l) a

In a l
eapply multiplicity_InA, InA_alt in H as (y & -> & H); eauto with typeclass_instances. Qed.
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall (l : list A) (a : A), ~ In a l -> multiplicity (list_contents l) a = 0
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall (l : list A) (a : A), ~ In a l -> multiplicity (list_contents l) a = 0
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l:list A
a:A
n:nat

~ 0 < S n -> S n = 0
destruct 1; auto with arith. Qed.
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall (l : list A) (a : A), In a l -> multiplicity (list_contents l) a >= 1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall (l : list A) (a : A), In a l -> multiplicity (list_contents l) a >= 1
intros l a; rewrite multiplicity_In; auto. Qed.
A:Type
eq_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:Type
eq_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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

NoDup nil <-> (forall a : A, multiplicity (list_contents nil) a <= 1)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

NoDup nil <-> (A -> 0 <= 1)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

(A -> 0 <= 1) -> NoDup nil
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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 <= 1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)
H0:~ In a l
H1:NoDup l

forall a0 : A, (if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)
H0:~ In a l
H1: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
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:NoDup l <-> (forall a1 : A, multiplicity (list_contents l) a1 <= 1)
H0:~ In a l
H1:forall a1 : A, multiplicity (list_contents l) a1 <= 1
a0:A
H2:a = a0

S (multiplicity (list_contents l) a0) <= 1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:NoDup l <-> (forall a0 : A, multiplicity (list_contents l) a0 <= 1)
H0:~ In a l
H1:forall a0 : A, multiplicity (list_contents l) a0 <= 1

S (multiplicity (list_contents l) a) <= 1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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 l
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
NoDup l
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
NoDup l
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
NoDup l
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
H0:a = a

1 + multiplicity (list_contents l) a <= 1 -> ~ 0 < multiplicity (list_contents l) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
H0:a <> a
0 + multiplicity (list_contents l) a <= 1 -> ~ 0 < multiplicity (list_contents l) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
NoDup l
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
H0:a = a
n:nat

1 + S n <= 1 -> ~ 0 < S n
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
H0:a <> a
0 + multiplicity (list_contents l) a <= 1 -> ~ 0 < multiplicity (list_contents l) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
NoDup l
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
H0:a = a
n:nat
H1:S (S n) <= 1
m:nat
H3:S (S n) <= 0
H2:m = 0

~ 0 < S n
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
H0:a <> a
0 + multiplicity (list_contents l) a <= 1 -> ~ 0 < multiplicity (list_contents l) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
NoDup l
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
H0:a <> a

0 + multiplicity (list_contents l) a <= 1 -> ~ 0 < multiplicity (list_contents l) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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
NoDup l
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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

NoDup l
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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 <= 1
a0:A

multiplicity (list_contents l) a0 <= 1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl: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 <= 1
a0:A

(if eq_dec a a0 then 1 else 0) + multiplicity (list_contents l) a0 <= 1 -> multiplicity (list_contents l) a0 <= 1
destruct (eq_dec a a0); simpl; auto with arith. Qed.
A:Type
eq_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:Type
eq_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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A
H:NoDup l
H0:NoDup l'
H1:forall x : A, In x l <-> In x l'

permutation l l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A
H:NoDup l
H0:NoDup l'
H1:forall x : A, In x l <-> In x l'
a:A

multiplicity (list_contents l) a = multiplicity (list_contents l') a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A
H:forall a0 : A, multiplicity (list_contents l) a0 <= 1
H0:forall a0 : A, multiplicity (list_contents l') a0 <= 1
H1:forall x : A, In x l <-> In x l'
a:A

multiplicity (list_contents l) a = multiplicity (list_contents l') a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A
a:A

multiplicity (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') a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A
a:A

multiplicity (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
destruct 3; omega. Qed.
Permutation is compatible with In.
  
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall (l1 l2 : list A) (e : A), permutation l1 l2 -> In e l1 -> In e l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall (l1 l2 : list A) (e : A), permutation l1 l2 -> In e l1 -> In e l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l1, l2:list A
e:A
P:forall a : A, multiplicity (list_contents l1) a = multiplicity (list_contents l2) a
IN:In e l1

In e l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l1, l2:list A
e:A
IN:In e l1

multiplicity (list_contents l1) e = multiplicity (list_contents l2) e -> In e l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l1, l2:list A
e:A
IN:In e l1
H:~ In e l2

multiplicity (list_contents l1) e = multiplicity (list_contents l2) e -> In e l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l1, l2:list A
e:A
IN:In e l1
H:~ In e l2

multiplicity (list_contents l1) e = 0 -> In e l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l1, l2:list A
e:A
IN:In e l1
H:~ In e l2
H0:multiplicity (list_contents l1) e = 0

In e l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l1, l2:list A
e:A
IN:In e l1
H:~ In e l2
H0:multiplicity (list_contents l1) e = 0

multiplicity (list_contents l1) e >= 1 -> In e l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l1, l2:list A
e:A
IN:In e l1
H:~ In e l2
H0:multiplicity (list_contents l1) e = 0

0 >= 1 -> In e l2
inversion 1. Qed.
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall (l1 l2 : list A) (e : A), permutation (e :: l1) l2 -> In e l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall (l1 l2 : list A) (e : A), permutation (e :: l1) l2 -> In e l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l1, l2:list A
e:A
H:permutation (e :: l1) l2

In e (e :: l1)
red; auto. Qed.
Permutation of an empty list.
  
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall l : list A, permutation l nil -> l = nil
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall l : list A, permutation l nil -> l = nil
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
e:A
l:list A

permutation (e :: l) nil -> e :: l = nil
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
e:A
l:list A
H:In e (e :: l)

permutation (e :: l) nil -> e :: l = nil
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
e:A
l:list A
H:In e (e :: l)
Abs:permutation (e :: l) nil

In e nil -> e :: l = nil
inversion 1. Qed.
When used with eq, this permutation notion is equivalent to the one defined in List.v.
  
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall l l' : list A, Permutation l l' <-> permutation l l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall l l' : list A, Permutation l l' <-> permutation l l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A

Permutation l l' -> permutation l l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A
permutation l l' -> Permutation l l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

permutation nil nil
A:Type
eq_dec:forall x0 y : A, {x0 = y} + {x0 <> y}
x:A
l, l':list A
H:Permutation l l'
IHPermutation:permutation l l'
permutation (x :: l) (x :: l')
A:Type
eq_dec:forall x0 y0 : A, {x0 = y0} + {x0 <> y0}
x, y:A
l:list A
permutation (y :: x :: l) (x :: y :: l)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l', l'':list A
H:Permutation l l'
H0:Permutation l' l''
IHPermutation1:permutation l l'
IHPermutation2:permutation l' l''
permutation l l''
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A
permutation l l' -> Permutation l l'
A:Type
eq_dec:forall x0 y : A, {x0 = y} + {x0 <> y}
x:A
l, l':list A
H:Permutation l l'
IHPermutation:permutation l l'

permutation (x :: l) (x :: l')
A:Type
eq_dec:forall x0 y0 : A, {x0 = y0} + {x0 <> y0}
x, y:A
l:list A
permutation (y :: x :: l) (x :: y :: l)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l', l'':list A
H:Permutation l l'
H0:Permutation l' l''
IHPermutation1:permutation l l'
IHPermutation2:permutation l' l''
permutation l l''
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A
permutation l l' -> Permutation l l'
A:Type
eq_dec:forall x0 y0 : A, {x0 = y0} + {x0 <> y0}
x, y:A
l:list A

permutation (y :: x :: l) (x :: y :: l)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l', l'':list A
H:Permutation l l'
H0:Permutation l' l''
IHPermutation1:permutation l l'
IHPermutation2:permutation l' l''
permutation l l''
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A
permutation l l' -> Permutation l l'
A:Type
eq_dec:forall x0 y0 : A, {x0 = y0} + {x0 <> y0}
x, y:A
l:list A

permutation (y :: x :: l) ((x :: nil) ++ y :: l)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l', l'':list A
H:Permutation l l'
H0:Permutation l' l''
IHPermutation1:permutation l l'
IHPermutation2:permutation l' l''
permutation l l''
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A
permutation l l' -> Permutation l l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l', l'':list A
H:Permutation l l'
H0:Permutation l' l''
IHPermutation1:permutation l l'
IHPermutation2:permutation l' l''

permutation l l''
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A
permutation l l' -> Permutation l l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l, l':list A

permutation l l' -> Permutation l l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l:list A

forall l' : list A, permutation l l' -> Permutation l l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall l' : list A, permutation nil l' -> Permutation nil l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:forall l' : list A, permutation l l' -> Permutation l l'
forall l' : list A, permutation (a :: l) l' -> Permutation (a :: l) l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l':list A
H:permutation nil l'

Permutation nil l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:forall l' : list A, permutation l l' -> Permutation l l'
forall l' : list A, permutation (a :: l) l' -> Permutation (a :: l) l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l':list A
H:permutation nil l'

Permutation nil nil
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:forall l' : list A, permutation l l' -> Permutation l l'
forall l' : list A, permutation (a :: l) l' -> Permutation (a :: l) l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:forall l' : list A, permutation l l' -> Permutation l l'

forall l' : list A, permutation (a :: l) l' -> Permutation (a :: l) l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:forall l'0 : list A, permutation l l'0 -> Permutation l l'0
l':list A
H:permutation (a :: l) l'

Permutation (a :: l) l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:forall l'0 : list A, permutation l l'0 -> Permutation l l'0
l':list A
H:permutation (a :: l) l'
h2, t2:list A
H1:l' = h2 ++ a :: t2

Permutation (a :: l) l'
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:forall l' : list A, permutation l l' -> Permutation l l'
h2, t2:list A
H:permutation (a :: l) (h2 ++ a :: t2)

Permutation (a :: l) (h2 ++ a :: t2)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:forall l' : list A, permutation l l' -> Permutation l l'
h2, t2:list A
H:permutation (a :: l) (h2 ++ a :: t2)

Permutation l (h2 ++ t2)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l:list A
IHl:forall l' : list A, permutation l l' -> Permutation l l'
h2, t2:list A
H:permutation (a :: l) (h2 ++ a :: t2)

permutation l (h2 ++ t2)
apply permut_remove_hd with a; auto with typeclass_instances. Qed.
Permutation for short lists.
  
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall a b : A, permutation (a :: nil) (b :: nil) -> a = b
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall a b : A, permutation (a :: nil) (b :: nil) -> a = b
A:Type
eq_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 = b
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a, b:A
H:b = b

(if eq_dec a b then 1 else 0) + 0 = 1 + 0 -> a = b
destruct (eq_dec a b); simpl; auto; intros; discriminate. Qed.
A:Type
eq_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 = b1
A:Type
eq_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 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)

a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H:In a1 (a2 :: b2 :: nil)

a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:a2 = a1

a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:In a1 (b2 :: nil)
a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:a2 = a1

b1 = b2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:In a1 (b2 :: nil)
a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:a2 = a1

permutation (b1 :: nil) (b2 :: nil)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:In a1 (b2 :: nil)
a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:a2 = a1
a:A

multiplicity (list_contents (b1 :: nil)) a = multiplicity (list_contents (b2 :: nil)) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:In a1 (b2 :: nil)
a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
H0:a2 = a1
a: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) + 0
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:In a1 (b2 :: nil)
a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
H0:a2 = a1
a:A
H2:a1 = a
H3:a2 <> a

1 + ((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) + 0
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
H0:a2 = a1
a:A
H2:a1 <> a
H3:a2 = a
0 + ((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) + 0
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:In a1 (b2 :: nil)
a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
H0:a2 = a1
a:A
H2:a1 <> a
H3:a2 = a

0 + ((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) + 0
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:In a1 (b2 :: nil)
a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:In a1 (b2 :: nil)

a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H0:In a1 (b2 :: nil)

a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H:b2 = a1

a1 = b2 /\ a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H:b2 = a1

a2 = b1
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H:b2 = a1

permutation (a2 :: nil) (b1 :: nil)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
P:permutation (a1 :: b1 :: nil) (a2 :: b2 :: nil)
H:b2 = a1
a:A

multiplicity (list_contents (a2 :: nil)) a = multiplicity (list_contents (b1 :: nil)) a
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
H:b2 = a1
a: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) + 0
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
H:b2 = a1
a:A
H2:a1 = a
H3:b2 = a

1 + ((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
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
H:b2 = a1
a:A
H2:a1 = a
H3:b2 <> a
1 + ((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) + 0
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
H:b2 = a1
a:A
H2:a1 <> a
H3:b2 = a
0 + ((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
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
H:b2 = a1
a:A
H2:a1 = a
H3:b2 <> a

1 + ((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) + 0
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
H:b2 = a1
a:A
H2:a1 <> a
H3:b2 = a
0 + ((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
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a1, b1, a2, b2:A
H:b2 = a1
a:A
H2:a1 <> a
H3:b2 = a

0 + ((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
destruct H2; transitivity b2; auto. Qed.
Permutation is compatible with length.
  
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall l1 l2 : list A, permutation l1 l2 -> length l1 = length l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}

forall l1 l2 : list A, permutation l1 l2 -> length l1 = length l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
l2:list A
H:permutation nil l2

length nil = length l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l1:list A
IHl1:forall l0 : list A, permutation l1 l0 -> length l1 = length l0
l2:list A
H:permutation (a :: l1) l2
length (a :: l1) = length l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l1:list A
IHl1:forall l0 : list A, permutation l1 l0 -> length l1 = length l0
l2:list A
H:permutation (a :: l1) l2

length (a :: l1) = length l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l1:list A
IHl1:forall l0 : list A, permutation l1 l0 -> length l1 = length l0
l2:list A
H:permutation (a :: l1) l2
h2, t2:list A
H1:l2 = h2 ++ a :: t2

length (a :: l1) = length l2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l1:list A
IHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2
h2, t2:list A
H:permutation (a :: l1) (h2 ++ a :: t2)

length (a :: l1) = length (h2 ++ a :: t2)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l1:list A
IHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2
h2, t2:list A
H:permutation (a :: l1) (h2 ++ a :: t2)

length (a :: l1) = length h2 + length (a :: t2)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l1:list A
IHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2
h2, t2:list A
H:permutation (a :: l1) (h2 ++ a :: t2)

length l1 = length h2 + length t2
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l1:list A
IHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2
h2, t2:list A
H:permutation (a :: l1) (h2 ++ a :: t2)

length l1 = length (h2 ++ t2)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
a:A
l1:list A
IHl1:forall l2 : list A, permutation l1 l2 -> length l1 = length l2
h2, t2:list A
H:permutation (a :: l1) (h2 ++ a :: t2)

permutation l1 (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 }.
Permutation is compatible with map.
  
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B

forall l2 : list A, permutation nil l2 -> PermutSetoid.permutation eq eqB_dec (map f nil) (map f l2)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B
a:A
l1:list A
IHl1: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B
a:A
l1:list A
IHl1: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B
a:A
l1:list A
IHl1:forall l0 : list A, permutation l1 l0 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l0)
l2:list A
P:permutation (a :: l1) l2

PermutSetoid.permutation eq eqB_dec (map f (a :: l1)) (map f l2)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B
a:A
l1:list A
IHl1:forall l0 : list A, permutation l1 l0 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l0)
l2:list A
P:permutation (a :: l1) l2

PermutSetoid.permutation eq eqB_dec (f a :: map f l1) (map f l2)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B
a:A
l1:list A
IHl1:forall l0 : list A, permutation l1 l0 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l0)
l2:list A
P:permutation (a :: l1) l2
h2, t2:list A
H1:l2 = h2 ++ a :: t2

PermutSetoid.permutation eq eqB_dec (f a :: map f l1) (map f l2)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B
a:A
l1:list A
IHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)
h2, t2:list A
P:permutation (a :: l1) (h2 ++ a :: t2)

PermutSetoid.permutation eq eqB_dec (f a :: map f l1) (map f (h2 ++ a :: t2))
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B
a:A
l1:list A
IHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)
h2, t2:list A
P:permutation (a :: l1) (h2 ++ a :: t2)

PermutSetoid.permutation eq eqB_dec (f a :: map f l1) (map f h2 ++ map f (a :: t2))
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B
a:A
l1:list A
IHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)
h2, t2:list A
P: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:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B
a:A
l1:list A
IHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)
h2, t2:list A
P:permutation (a :: l1) (h2 ++ a :: t2)

PermutSetoid.permutation eq eqB_dec (map f l1) (map f h2 ++ map f t2)
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B
a:A
l1:list A
IHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)
h2, t2:list A
P:permutation (a :: l1) (h2 ++ a :: t2)

PermutSetoid.permutation eq eqB_dec (map f l1) (map f (h2 ++ t2))
A:Type
eq_dec:forall x y : A, {x = y} + {x <> y}
B:Type
eqB_dec:forall x y : B, {x = y} + {x <> y}
f:A -> B
a:A
l1:list A
IHl1:forall l2 : list A, permutation l1 l2 -> PermutSetoid.permutation eq eqB_dec (map f l1) (map f l2)
h2, t2:list A
P:permutation (a :: l1) (h2 ++ a :: t2)

permutation l1 (h2 ++ t2)
apply permut_remove_hd with a; auto with typeclass_instances. Qed. End Perm.