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 Permutation SetoidList.
(* Set Universe Polymorphism. *)

Set Implicit Arguments.
Unset Strict Implicit.
Permutations of list modulo a setoid equality.
Contribution by Robbert Krebbers (Nijmegen University).
Section Permutation.
Context {A : Type} (eqA : relation A) (e : Equivalence eqA).

Inductive PermutationA : list A -> list A -> Prop :=
  | permA_nil: PermutationA nil nil
  | permA_skip x₁ x₂ l₁ l₂ :
     eqA x₁ x₂ -> PermutationA l₁ l₂ -> PermutationA (x₁ :: l₁) (x₂ :: l₂)
  | permA_swap x y l : PermutationA (y :: x :: l) (x :: y :: l)
  | permA_trans l₁ l₂ l₃ :
     PermutationA l₁ l₂ -> PermutationA l₂ l₃ -> PermutationA l₁ l₃.
Local Hint Constructors PermutationA : core.

A:Type
eqA:relation A
e:Equivalence eqA

Equivalence PermutationA
A:Type
eqA:relation A
e:Equivalence eqA

Equivalence PermutationA
A:Type
eqA:relation A
e:Equivalence eqA

Reflexive PermutationA
A:Type
eqA:relation A
e:Equivalence eqA
Symmetric PermutationA
A:Type
eqA:relation A
e:Equivalence eqA
Transitive PermutationA
A:Type
eqA:relation A
e:Equivalence eqA

Reflexive PermutationA
A:Type
eqA:relation A
e:Equivalence eqA
l:list A

PermutationA l l
induction l; intuition.
A:Type
eqA:relation A
e:Equivalence eqA

Symmetric PermutationA
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

PermutationA l₁ l₂ -> PermutationA l₂ l₁
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
H0:PermutationA l₁ l₂
IHPermutationA:PermutationA l₂ l₁

PermutationA (x₂ :: l₂) (x₁ :: l₁)
apply permA_skip; intuition.
A:Type
eqA:relation A
e:Equivalence eqA

Transitive PermutationA
exact permA_trans. Qed.
A:Type
eqA:relation A
e:Equivalence eqA

Proper (eqA ==> PermutationA ==> PermutationA) cons
A:Type
eqA:relation A
e:Equivalence eqA

Proper (eqA ==> PermutationA ==> PermutationA) cons
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
H:eqA x y
x0, y0:list A
H0:PermutationA x0 y0

PermutationA (x :: x0) (y :: y0)
now apply permA_skip. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l:list A

PermutationA l₁ l₂ -> PermutationA (l ++ l₁) (l ++ l₂)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l:list A

PermutationA l₁ l₂ -> PermutationA (l ++ l₁) (l ++ l₂)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A
a:A
l:list A
IHl:PermutationA l₁ l₂ -> PermutationA (l ++ l₁) (l ++ l₂)
H:PermutationA l₁ l₂

PermutationA ((a :: l) ++ l₁) ((a :: l) ++ l₂)
apply permA_skip; intuition. Qed.
A:Type
eqA:relation A
e:Equivalence eqA

Proper (PermutationA ==> PermutationA ==> PermutationA) (app (A:=A))
A:Type
eqA:relation A
e:Equivalence eqA

Proper (PermutationA ==> PermutationA ==> PermutationA) (app (A:=A))
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A
Pl:PermutationA l₁ l₂
k₁, k₂:list A
Pk:PermutationA k₁ k₂

PermutationA (l₁ ++ k₁) (l₂ ++ k₂)
A:Type
eqA:relation A
e:Equivalence eqA
k₁, k₂:list A
Pk:PermutationA k₁ k₂

PermutationA (nil ++ k₁) (nil ++ k₂)
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
Pl:PermutationA l₁ l₂
k₁, k₂:list A
Pk:PermutationA k₁ k₂
IHPl:PermutationA (l₁ ++ k₁) (l₂ ++ k₂)
PermutationA ((x₁ :: l₁) ++ k₁) ((x₂ :: l₂) ++ k₂)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, k₁, k₂:list A
Pk:PermutationA k₁ k₂
PermutationA ((y :: x :: l) ++ k₁) ((x :: y :: l) ++ k₂)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
Pl1:PermutationA l₁ l₂
Pl2:PermutationA l₂ l₃
k₁, k₂:list A
Pk:PermutationA k₁ k₂
IHPl1:PermutationA (l₁ ++ k₁) (l₂ ++ k₂)
IHPl2:PermutationA (l₂ ++ k₁) (l₃ ++ k₂)
PermutationA (l₁ ++ k₁) (l₃ ++ k₂)
A:Type
eqA:relation A
e:Equivalence eqA
k₁, k₂:list A
Pk:PermutationA k₁ k₂

PermutationA (nil ++ k₁) (nil ++ k₂)
easy.
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
Pl:PermutationA l₁ l₂
k₁, k₂:list A
Pk:PermutationA k₁ k₂
IHPl:PermutationA (l₁ ++ k₁) (l₂ ++ k₂)

PermutationA ((x₁ :: l₁) ++ k₁) ((x₂ :: l₂) ++ k₂)
now apply permA_skip.
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, k₁, k₂:list A
Pk:PermutationA k₁ k₂

PermutationA ((y :: x :: l) ++ k₁) ((x :: y :: l) ++ k₂)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, k₁, k₂:list A
Pk:PermutationA k₁ k₂

PermutationA ((y :: x :: l) ++ k₁) ?y
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, k₁, k₂:list A
Pk:PermutationA k₁ k₂
PermutationA ?y ((x :: y :: l) ++ k₂)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, k₁, k₂:list A
Pk:PermutationA k₁ k₂

PermutationA ((y :: x :: l) ++ k₁) ?y
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, k₁, k₂:list A
Pk:PermutationA k₁ k₂

PermutationA (y :: x :: l ++ k₁) ?y
now apply permA_swap.
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, k₁, k₂:list A
Pk:PermutationA k₁ k₂

PermutationA (x :: y :: l ++ k₁) ((x :: y :: l) ++ k₂)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, k₁, k₂:list A
Pk:PermutationA k₁ k₂

PermutationA ((x :: y :: l) ++ k₁) ((x :: y :: l) ++ k₂)
now apply PermutationA_app_head.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
Pl1:PermutationA l₁ l₂
Pl2:PermutationA l₂ l₃
k₁, k₂:list A
Pk:PermutationA k₁ k₂
IHPl1:PermutationA (l₁ ++ k₁) (l₂ ++ k₂)
IHPl2:PermutationA (l₂ ++ k₁) (l₃ ++ k₂)

PermutationA (l₁ ++ k₁) (l₃ ++ k₂)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
Pl1:PermutationA l₁ l₂
Pl2:PermutationA l₂ l₃
k₁, k₂:list A
Pk:PermutationA k₁ k₂
IHPl1:PermutationA (l₁ ++ k₁) (l₂ ++ k₂)
IHPl2:PermutationA (l₂ ++ k₁) (l₃ ++ k₂)

PermutationA (l₂ ++ k₂) (l₂ ++ k₁)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
Pl1:PermutationA l₁ l₂
Pl2:PermutationA l₂ l₃
k₁, k₂:list A
Pk:PermutationA k₁ k₂
IHPl1:PermutationA (l₁ ++ k₁) (l₂ ++ k₂)
IHPl2:PermutationA (l₂ ++ k₁) (l₃ ++ k₂)

PermutationA k₂ k₁
now symmetry. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l:list A

PermutationA l₁ l₂ -> PermutationA (l₁ ++ l) (l₂ ++ l)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l:list A

PermutationA l₁ l₂ -> PermutationA (l₁ ++ l) (l₂ ++ l)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l:list A
E:PermutationA l₁ l₂

PermutationA (l₁ ++ l) (l₂ ++ l)
now rewrite E. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l:list A
x:A

PermutationA (x :: l) (l ++ x :: nil)
A:Type
eqA:relation A
e:Equivalence eqA
l:list A
x:A

PermutationA (x :: l) (l ++ x :: nil)
A:Type
eqA:relation A
e:Equivalence eqA
x:A

PermutationA (x :: nil) (nil ++ x :: nil)
A:Type
eqA:relation A
e:Equivalence eqA
a:A
l:list A
x:A
IHl:PermutationA (x :: l) (l ++ x :: nil)
PermutationA (x :: a :: l) ((a :: l) ++ x :: nil)
A:Type
eqA:relation A
e:Equivalence eqA
x:A

PermutationA (x :: nil) (nil ++ x :: nil)
easy.
A:Type
eqA:relation A
e:Equivalence eqA
a:A
l:list A
x:A
IHl:PermutationA (x :: l) (l ++ x :: nil)

PermutationA (x :: a :: l) ((a :: l) ++ x :: nil)
A:Type
eqA:relation A
e:Equivalence eqA
a:A
l:list A
x:A
IHl:PermutationA (x :: l) (l ++ x :: nil)

PermutationA (x :: a :: l) (a :: l ++ x :: nil)
A:Type
eqA:relation A
e:Equivalence eqA
a:A
l:list A
x:A
IHl:PermutationA (x :: l) (l ++ x :: nil)

PermutationA (x :: a :: l) (a :: x :: l)
intuition. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

PermutationA (l₁ ++ l₂) (l₂ ++ l₁)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

PermutationA (l₁ ++ l₂) (l₂ ++ l₁)
A:Type
eqA:relation A
e:Equivalence eqA
l₂:list A

PermutationA (nil ++ l₂) (l₂ ++ nil)
A:Type
eqA:relation A
e:Equivalence eqA
a:A
l₁, l₂:list A
IHl₁:PermutationA (l₁ ++ l₂) (l₂ ++ l₁)
PermutationA ((a :: l₁) ++ l₂) (l₂ ++ a :: l₁)
A:Type
eqA:relation A
e:Equivalence eqA
l₂:list A

PermutationA (nil ++ l₂) (l₂ ++ nil)
now rewrite app_nil_r.
A:Type
eqA:relation A
e:Equivalence eqA
a:A
l₁, l₂:list A
IHl₁:PermutationA (l₁ ++ l₂) (l₂ ++ l₁)

PermutationA ((a :: l₁) ++ l₂) (l₂ ++ a :: l₁)
A:Type
eqA:relation A
e:Equivalence eqA
a:A
l₁, l₂:list A
IHl₁:PermutationA (l₁ ++ l₂) (l₂ ++ l₁)

PermutationA ((a :: l₂) ++ l₁) (l₂ ++ a :: l₁)
now rewrite PermutationA_cons_append, <-app_assoc. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l, l₁, l₂:list A
x:A

PermutationA l (l₁ ++ l₂) -> PermutationA (x :: l) (l₁ ++ x :: l₂)
A:Type
eqA:relation A
e:Equivalence eqA
l, l₁, l₂:list A
x:A

PermutationA l (l₁ ++ l₂) -> PermutationA (x :: l) (l₁ ++ x :: l₂)
A:Type
eqA:relation A
e:Equivalence eqA
l, l₁, l₂:list A
x:A
E:PermutationA l (l₁ ++ l₂)

PermutationA (x :: l) (l₁ ++ x :: l₂)
A:Type
eqA:relation A
e:Equivalence eqA
l, l₁, l₂:list A
x:A
E:PermutationA l (l₁ ++ l₂)

PermutationA (x :: l₁ ++ l₂) (l₁ ++ x :: l₂)
now rewrite app_comm_cons, (PermutationA_cons_append l₁ x), <- app_assoc. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A
x:A

PermutationA (x :: l₁ ++ l₂) (l₁ ++ x :: l₂)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A
x:A

PermutationA (x :: l₁ ++ l₂) (l₁ ++ x :: l₂)
now apply PermutationA_cons_app. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

PermutationA l₁ l₂ -> equivlistA eqA l₁ l₂
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

PermutationA l₁ l₂ -> equivlistA eqA l₁ l₂
A:Type
eqA:relation A
e:Equivalence eqA

equivlistA eqA nil nil
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
H0:PermutationA l₁ l₂
IHPermutationA:equivlistA eqA l₁ l₂
equivlistA eqA (x₁ :: l₁) (x₂ :: l₂)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
equivlistA eqA (y :: x :: l) (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
IHPermutationA1:equivlistA eqA l₁ l₂
IHPermutationA2:equivlistA eqA l₂ l₃
equivlistA eqA l₁ l₃
A:Type
eqA:relation A
e:Equivalence eqA

equivlistA eqA nil nil
reflexivity.
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
H0:PermutationA l₁ l₂
IHPermutationA:equivlistA eqA l₁ l₂

equivlistA eqA (x₁ :: l₁) (x₂ :: l₂)
now apply equivlistA_cons_proper.
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A

equivlistA eqA (y :: x :: l) (x :: y :: l)
now apply equivlistA_permute_heads.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
IHPermutationA1:equivlistA eqA l₁ l₂
IHPermutationA2:equivlistA eqA l₂ l₃

equivlistA eqA l₁ l₃
etransitivity; eassumption. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

NoDupA eqA l₁ -> NoDupA eqA l₂ -> equivlistA eqA l₁ l₂ -> PermutationA l₁ l₂
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

NoDupA eqA l₁ -> NoDupA eqA l₂ -> equivlistA eqA l₁ l₂ -> PermutationA l₁ l₂
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A
Pl₁:NoDupA eqA l₁

NoDupA eqA l₂ -> equivlistA eqA l₁ l₂ -> PermutationA l₁ l₂
A:Type
eqA:relation A
e:Equivalence eqA
l₁:list A
Pl₁:NoDupA eqA l₁

forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA l₁ l₂ -> PermutationA l₁ l₂
A:Type
eqA:relation A
e:Equivalence eqA

forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA nil l₂ -> PermutationA nil l₂
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA l₁ l₂ -> PermutationA l₁ l₂
forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA (x :: l₁) l₂ -> PermutationA (x :: l₁) l₂
A:Type
eqA:relation A
e:Equivalence eqA

forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA nil l₂ -> PermutationA nil l₂
A:Type
eqA:relation A
e:Equivalence eqA
l₂:list A
H₂:equivlistA eqA nil l₂

PermutationA nil l₂
A:Type
eqA:relation A
e:Equivalence eqA
l₂:list A
H₂:equivlistA eqA l₂ nil

PermutationA nil l₂
now rewrite (equivlistA_nil_eq eqA).
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA l₁ l₂ -> PermutationA l₁ l₂

forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA (x :: l₁) l₂ -> PermutationA (x :: l₁) l₂
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂0 : list A, NoDupA eqA l₂0 -> equivlistA eqA l₁ l₂0 -> PermutationA l₁ l₂0
l₂:list A
Pl₂:NoDupA eqA l₂
E2:equivlistA eqA (x :: l₁) l₂

PermutationA (x :: l₁) l₂
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂0 : list A, NoDupA eqA l₂0 -> equivlistA eqA l₁ l₂0 -> PermutationA l₁ l₂0
l₂:list A
Pl₂:NoDupA eqA l₂
E2:equivlistA eqA (x :: l₁) l₂

InA eqA x l₂
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂0 : list A, NoDupA eqA l₂0 -> equivlistA eqA l₁ l₂0 -> PermutationA l₁ l₂0
l₂:list A
Pl₂:NoDupA eqA l₂
E2:equivlistA eqA (x :: l₁) l₂
l₂h:list A
y:A
l₂t:list A
E3:eqA x y
H:l₂ = l₂h ++ y :: l₂t
PermutationA (x :: l₁) l₂
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂0 : list A, NoDupA eqA l₂0 -> equivlistA eqA l₁ l₂0 -> PermutationA l₁ l₂0
l₂:list A
Pl₂:NoDupA eqA l₂
E2:equivlistA eqA (x :: l₁) l₂

InA eqA x l₂
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂0 : list A, NoDupA eqA l₂0 -> equivlistA eqA l₁ l₂0 -> PermutationA l₁ l₂0
l₂:list A
Pl₂:NoDupA eqA l₂
E2:equivlistA eqA (x :: l₁) l₂

InA eqA x (x :: l₁)
intuition.
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂0 : list A, NoDupA eqA l₂0 -> equivlistA eqA l₁ l₂0 -> PermutationA l₁ l₂0
l₂:list A
Pl₂:NoDupA eqA l₂
E2:equivlistA eqA (x :: l₁) l₂
l₂h:list A
y:A
l₂t:list A
E3:eqA x y
H:l₂ = l₂h ++ y :: l₂t

PermutationA (x :: l₁) l₂
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA l₁ l₂ -> PermutationA l₁ l₂
l₂h:list A
y:A
l₂t:list A
E2:equivlistA eqA (x :: l₁) (l₂h ++ y :: l₂t)
Pl₂:NoDupA eqA (l₂h ++ y :: l₂t)
E3:eqA x y

PermutationA (x :: l₁) (l₂h ++ y :: l₂t)
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA l₁ l₂ -> PermutationA l₁ l₂
l₂h:list A
y:A
l₂t:list A
E2:equivlistA eqA (x :: l₁) (l₂h ++ y :: l₂t)
Pl₂:NoDupA eqA (l₂h ++ y :: l₂t)
E3:eqA x y

PermutationA (y :: l₁) (l₂h ++ y :: l₂t)
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA l₁ l₂ -> PermutationA l₁ l₂
l₂h:list A
y:A
l₂t:list A
E2:equivlistA eqA (x :: l₁) (l₂h ++ y :: l₂t)
Pl₂:NoDupA eqA (l₂h ++ y :: l₂t)
E3:eqA x y

NoDupA eqA (l₂h ++ l₂t)
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA l₁ l₂ -> PermutationA l₁ l₂
l₂h:list A
y:A
l₂t:list A
E2:equivlistA eqA (x :: l₁) (l₂h ++ y :: l₂t)
Pl₂:NoDupA eqA (l₂h ++ y :: l₂t)
E3:eqA x y
equivlistA eqA l₁ (l₂h ++ l₂t)
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l₁:list A
E1:~ InA eqA x l₁
Pl₁:NoDupA eqA l₁
IHPl₁:forall l₂ : list A, NoDupA eqA l₂ -> equivlistA eqA l₁ l₂ -> PermutationA l₁ l₂
l₂h:list A
y:A
l₂t:list A
E2:equivlistA eqA (x :: l₁) (l₂h ++ y :: l₂t)
Pl₂:NoDupA eqA (l₂h ++ y :: l₂t)
E3:eqA x y

equivlistA eqA l₁ (l₂h ++ l₂t)
apply equivlistA_NoDupA_split with x y; intuition. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A

eqlistA eqA l₁ l₂ -> Permutation l₂ l₃ -> exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' l₃
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A

eqlistA eqA l₁ l₂ -> Permutation l₂ l₃ -> exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' l₃
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
E:eqlistA eqA l₁ l₂
P:Permutation l₂ l₃

exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' l₃
A:Type
eqA:relation A
e:Equivalence eqA
l₂, l₃:list A
P:Permutation l₂ l₃

forall l₁ : list A, eqlistA eqA l₁ l₂ -> exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' l₃
A:Type
eqA:relation A
e:Equivalence eqA
l₁:list A
E:eqlistA eqA l₁ nil

exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' nil
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l, l':list A
P:Permutation l l'
IHP:forall l₁0 : list A, eqlistA eqA l₁0 l -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l'
l₁:list A
E:eqlistA eqA l₁ (x :: l)
exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' (x :: l')
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, l₁:list A
E:eqlistA eqA l₁ (y :: x :: l)
exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
l, l', l'':list A
P1:Permutation l l'
P2:Permutation l' l''
IHP1:forall l₁0 : list A, eqlistA eqA l₁0 l -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l'
IHP2:forall l₁0 : list A, eqlistA eqA l₁0 l' -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l''
l₁:list A
E:eqlistA eqA l₁ l
exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' l''
A:Type
eqA:relation A
e:Equivalence eqA
l₁:list A
E:eqlistA eqA l₁ nil

exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' nil
A:Type
eqA:relation A
e:Equivalence eqA
l₁:list A

exists l₂' : list A, Permutation nil l₂' /\ eqlistA eqA l₂' nil
now exists nil.
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l, l':list A
P:Permutation l l'
IHP:forall l₁0 : list A, eqlistA eqA l₁0 l -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l'
l₁:list A
E:eqlistA eqA l₁ (x :: l)

exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' (x :: l')
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l, l':list A
P:Permutation l l'
IHP:forall l₁0 : list A, eqlistA eqA l₁0 l -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l'
l₁:list A
x0:A
l0:list A
H:eqA x0 x
H0:eqlistA eqA l0 l

exists l₂' : list A, Permutation (x0 :: l0) l₂' /\ eqlistA eqA l₂' (x :: l')
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l, l':list A
P:Permutation l l'
IHP:forall l₁0 : list A, eqlistA eqA l₁0 l -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l'
l₁:list A
x0:A
l0:list A
H:eqA x0 x
H0:eqlistA eqA l0 l
l0':list A
P':Permutation l0 l0'
E':eqlistA eqA l0' l'

exists l₂' : list A, Permutation (x0 :: l0) l₂' /\ eqlistA eqA l₂' (x :: l')
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l, l':list A
P:Permutation l l'
l₁:list A
x0:A
l0:list A
H:eqA x0 x
H0:eqlistA eqA l0 l
l0':list A
P':Permutation l0 l0'
E':eqlistA eqA l0' l'

exists l₂' : list A, Permutation (x0 :: l0) l₂' /\ eqlistA eqA l₂' (x :: l')
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l, l':list A
P:Permutation l l'
l₁:list A
x0:A
l0:list A
H:eqA x0 x
H0:eqlistA eqA l0 l
l0':list A
P':Permutation l0 l0'
E':eqlistA eqA l0' l'

Permutation (x0 :: l0) (x0 :: l0') /\ eqlistA eqA (x0 :: l0') (x :: l')
split; auto.
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, l₁:list A
E:eqlistA eqA l₁ (y :: x :: l)

exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, l₁:list A
x0:A
l0:list A
H:eqA x0 y
H0:eqlistA eqA l0 (x :: l)

exists l₂' : list A, Permutation (x0 :: l0) l₂' /\ eqlistA eqA l₂' (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, l₁:list A
x0:A
l0:list A
H:eqA x0 y
x1:A
l1:list A
H1:eqA x1 x
H2:eqlistA eqA l1 l

exists l₂' : list A, Permutation (x0 :: x1 :: l1) l₂' /\ eqlistA eqA l₂' (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l, l₁:list A
x0:A
l0:list A
H:eqA x0 y
x1:A
l1:list A
H1:eqA x1 x
H2:eqlistA eqA l1 l

Permutation (x0 :: x1 :: l1) (x1 :: x0 :: l1) /\ eqlistA eqA (x1 :: x0 :: l1) (x :: y :: l)
now repeat constructor.
A:Type
eqA:relation A
e:Equivalence eqA
l, l', l'':list A
P1:Permutation l l'
P2:Permutation l' l''
IHP1:forall l₁0 : list A, eqlistA eqA l₁0 l -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l'
IHP2:forall l₁0 : list A, eqlistA eqA l₁0 l' -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l''
l₁:list A
E:eqlistA eqA l₁ l

exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' l''
A:Type
eqA:relation A
e:Equivalence eqA
l, l', l'':list A
IHP1:forall l₁0 : list A, eqlistA eqA l₁0 l -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l'
IHP2:forall l₁0 : list A, eqlistA eqA l₁0 l' -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l''
l₁:list A
E:eqlistA eqA l₁ l

exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' l''
A:Type
eqA:relation A
e:Equivalence eqA
l, l', l'':list A
IHP1:forall l₁0 : list A, eqlistA eqA l₁0 l -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l'
IHP2:forall l₁0 : list A, eqlistA eqA l₁0 l' -> exists l₂' : list A, Permutation l₁0 l₂' /\ eqlistA eqA l₂' l''
l₁:list A
E:eqlistA eqA l₁ l
l₁':list A
P₁:Permutation l₁ l₁'
E₁:eqlistA eqA l₁' l'

exists l₂' : list A, Permutation l₁ l₂' /\ eqlistA eqA l₂' l''
A:Type
eqA:relation A
e:Equivalence eqA
l, l', l'':list A
IHP1:forall l₁0 : list A, eqlistA eqA l₁0 l -> exists l₂'0 : list A, Permutation l₁0 l₂'0 /\ eqlistA eqA l₂'0 l'
IHP2:forall l₁0 : list A, eqlistA eqA l₁0 l' -> exists l₂'0 : list A, Permutation l₁0 l₂'0 /\ eqlistA eqA l₂'0 l''
l₁:list A
E:eqlistA eqA l₁ l
l₁':list A
P₁:Permutation l₁ l₁'
E₁:eqlistA eqA l₁' l'
l₂':list A
P₂:Permutation l₁' l₂'
E₂:eqlistA eqA l₂' l''

exists l₂'0 : list A, Permutation l₁ l₂'0 /\ eqlistA eqA l₂'0 l''
A:Type
eqA:relation A
e:Equivalence eqA
l, l', l'':list A
IHP1:forall l₁0 : list A, eqlistA eqA l₁0 l -> exists l₂'0 : list A, Permutation l₁0 l₂'0 /\ eqlistA eqA l₂'0 l'
IHP2:forall l₁0 : list A, eqlistA eqA l₁0 l' -> exists l₂'0 : list A, Permutation l₁0 l₂'0 /\ eqlistA eqA l₂'0 l''
l₁:list A
E:eqlistA eqA l₁ l
l₁':list A
P₁:Permutation l₁ l₁'
E₁:eqlistA eqA l₁' l'
l₂':list A
P₂:Permutation l₁' l₂'
E₂:eqlistA eqA l₂' l''

Permutation l₁ l₂' /\ eqlistA eqA l₂' l''
A:Type
eqA:relation A
e:Equivalence eqA
l, l', l'':list A
IHP1:forall l₁0 : list A, eqlistA eqA l₁0 l -> exists l₂'0 : list A, Permutation l₁0 l₂'0 /\ eqlistA eqA l₂'0 l'
IHP2:forall l₁0 : list A, eqlistA eqA l₁0 l' -> exists l₂'0 : list A, Permutation l₁0 l₂'0 /\ eqlistA eqA l₂'0 l''
l₁:list A
E:eqlistA eqA l₁ l
l₁':list A
P₁:Permutation l₁ l₁'
E₁:eqlistA eqA l₁' l'
l₂':list A
P₂:Permutation l₁' l₂'
E₂:eqlistA eqA l₂' l''

Permutation l₁ l₂'
econstructor; eauto. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

PermutationA l₁ l₂ -> exists l : list A, Permutation l₁ l /\ eqlistA eqA l l₂
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

PermutationA l₁ l₂ -> exists l : list A, Permutation l₁ l /\ eqlistA eqA l l₂
A:Type
eqA:relation A
e:Equivalence eqA

exists l : list A, Permutation nil l /\ eqlistA eqA l nil
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
H0:PermutationA l₁ l₂
IHPermutationA:exists l : list A, Permutation l₁ l /\ eqlistA eqA l l₂
exists l : list A, Permutation (x₁ :: l₁) l /\ eqlistA eqA l (x₂ :: l₂)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
exists l0 : list A, Permutation (y :: x :: l) l0 /\ eqlistA eqA l0 (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
IHPermutationA1:exists l : list A, Permutation l₁ l /\ eqlistA eqA l l₂
IHPermutationA2:exists l : list A, Permutation l₂ l /\ eqlistA eqA l l₃
exists l : list A, Permutation l₁ l /\ eqlistA eqA l l₃
A:Type
eqA:relation A
e:Equivalence eqA

exists l : list A, Permutation nil l /\ eqlistA eqA l nil
now exists nil.
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
H0:PermutationA l₁ l₂
IHPermutationA:exists l : list A, Permutation l₁ l /\ eqlistA eqA l l₂

exists l : list A, Permutation (x₁ :: l₁) l /\ eqlistA eqA l (x₂ :: l₂)
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
H0:PermutationA l₁ l₂
l:list A
P:Permutation l₁ l
E:eqlistA eqA l l₂

exists l0 : list A, Permutation (x₁ :: l₁) l0 /\ eqlistA eqA l0 (x₂ :: l₂)
exists (x₁::l); auto.
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A

exists l0 : list A, Permutation (y :: x :: l) l0 /\ eqlistA eqA l0 (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A

Permutation (y :: x :: l) (x :: y :: l) /\ eqlistA eqA (x :: y :: l) (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A

Permutation (y :: x :: l) (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
eqlistA eqA (x :: y :: l) (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A

eqlistA eqA (x :: y :: l) (x :: y :: l)
reflexivity.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
IHPermutationA1:exists l : list A, Permutation l₁ l /\ eqlistA eqA l l₂
IHPermutationA2:exists l : list A, Permutation l₂ l /\ eqlistA eqA l l₃

exists l : list A, Permutation l₁ l /\ eqlistA eqA l l₃
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
l₁':list A
P:Permutation l₁ l₁'
E:eqlistA eqA l₁' l₂
IHPermutationA2:exists l : list A, Permutation l₂ l /\ eqlistA eqA l l₃

exists l : list A, Permutation l₁ l /\ eqlistA eqA l l₃
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
l₁':list A
P:Permutation l₁ l₁'
E:eqlistA eqA l₁' l₂
l₂':list A
P':Permutation l₂ l₂'
E':eqlistA eqA l₂' l₃

exists l : list A, Permutation l₁ l /\ eqlistA eqA l l₃
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
l₁':list A
P:Permutation l₁ l₁'
E:eqlistA eqA l₁' l₂
l₂':list A
P':Permutation l₂ l₂'
E':eqlistA eqA l₂' l₃
l₁'':list A
P'':Permutation l₁' l₁''
E'':eqlistA eqA l₁'' l₂'

exists l : list A, Permutation l₁ l /\ eqlistA eqA l l₃
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
l₁':list A
P:Permutation l₁ l₁'
E:eqlistA eqA l₁' l₂
l₂':list A
P':Permutation l₂ l₂'
E':eqlistA eqA l₂' l₃
l₁'':list A
P'':Permutation l₁' l₁''
E'':eqlistA eqA l₁'' l₂'

Permutation l₁ l₁'' /\ eqlistA eqA l₁'' l₃
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
l₁':list A
P:Permutation l₁ l₁'
E:eqlistA eqA l₁' l₂
l₂':list A
P':Permutation l₂ l₂'
E':eqlistA eqA l₂' l₃
l₁'':list A
P'':Permutation l₁' l₁''
E'':eqlistA eqA l₁'' l₂'

Permutation l₁ l₁''
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
l₁':list A
P:Permutation l₁ l₁'
E:eqlistA eqA l₁' l₂
l₂':list A
P':Permutation l₂ l₂'
E':eqlistA eqA l₂' l₃
l₁'':list A
P'':Permutation l₁' l₁''
E'':eqlistA eqA l₁'' l₂'
eqlistA eqA l₁'' l₃
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
l₁':list A
P:Permutation l₁ l₁'
E:eqlistA eqA l₁' l₂
l₂':list A
P':Permutation l₂ l₂'
E':eqlistA eqA l₂' l₃
l₁'':list A
P'':Permutation l₁' l₁''
E'':eqlistA eqA l₁'' l₂'

eqlistA eqA l₁'' l₃
now transitivity l₂'. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

Permutation l₁ l₂ -> PermutationA l₁ l₂
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

Permutation l₁ l₂ -> PermutationA l₁ l₂
A:Type
eqA:relation A
e:Equivalence eqA

PermutationA nil nil
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l, l':list A
H:Permutation l l'
IHPermutation:PermutationA l l'
PermutationA (x :: l) (x :: l')
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
PermutationA (y :: x :: l) (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
l, l', l'':list A
H:Permutation l l'
H0:Permutation l' l''
IHPermutation1:PermutationA l l'
IHPermutation2:PermutationA l' l''
PermutationA l l''
A:Type
eqA:relation A
e:Equivalence eqA

PermutationA nil nil
constructor.
A:Type
eqA:relation A
e:Equivalence eqA
x:A
l, l':list A
H:Permutation l l'
IHPermutation:PermutationA l l'

PermutationA (x :: l) (x :: l')
now constructor.
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A

PermutationA (y :: x :: l) (x :: y :: l)
apply permA_swap.
A:Type
eqA:relation A
e:Equivalence eqA
l, l', l'':list A
H:Permutation l l'
H0:Permutation l' l''
IHPermutation1:PermutationA l l'
IHPermutation2:PermutationA l' l''

PermutationA l l''
econstructor; eauto. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

eqlistA eqA l₁ l₂ -> PermutationA l₁ l₂
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

eqlistA eqA l₁ l₂ -> PermutationA l₁ l₂
induction 1; now constructor. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l1, l2:list A

NoDupA eqA l1 -> NoDupA eqA l2 -> equivlistA eqA l1 l2 -> exists l : list A, Permutation l1 l /\ eqlistA eqA l l2
A:Type
eqA:relation A
e:Equivalence eqA
l1, l2:list A

NoDupA eqA l1 -> NoDupA eqA l2 -> equivlistA eqA l1 l2 -> exists l : list A, Permutation l1 l /\ eqlistA eqA l l2
A:Type
eqA:relation A
e:Equivalence eqA
l1, l2:list A
H:NoDupA eqA l1
H0:NoDupA eqA l2
H1:equivlistA eqA l1 l2

exists l : list A, Permutation l1 l /\ eqlistA eqA l l2
A:Type
eqA:relation A
e:Equivalence eqA
l1, l2:list A
H:NoDupA eqA l1
H0:NoDupA eqA l2
H1:equivlistA eqA l1 l2

PermutationA l1 l2
now apply NoDupA_equivlistA_PermutationA. Qed.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

PermutationA l₁ l₂ -> NoDupA eqA l₁ -> NoDupA eqA l₂
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂:list A

PermutationA l₁ l₂ -> NoDupA eqA l₁ -> NoDupA eqA l₂
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
H0:PermutationA l₁ l₂
IHPermutationA:NoDupA eqA l₁ -> NoDupA eqA l₂

NoDupA eqA (x₁ :: l₁) -> NoDupA eqA (x₂ :: l₂)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
NoDupA eqA (y :: x :: l) -> NoDupA eqA (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
IHPermutationA1:NoDupA eqA l₁ -> NoDupA eqA l₂
IHPermutationA2:NoDupA eqA l₂ -> NoDupA eqA l₃
NoDupA eqA l₁ -> NoDupA eqA l₃
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
H0:PermutationA l₁ l₂
IHPermutationA:NoDupA eqA l₁ -> NoDupA eqA l₂

NoDupA eqA (x₁ :: l₁) -> NoDupA eqA (x₂ :: l₂)
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
H0:PermutationA l₁ l₂
IHPermutationA:NoDupA eqA l₁ -> NoDupA eqA l₂
H2:~ InA eqA x₁ l₁
H3:NoDupA eqA l₁

~ InA eqA x₂ l₂
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
H0:equivlistA eqA l₁ l₂
IHPermutationA:NoDupA eqA l₁ -> NoDupA eqA l₂
H2:~ InA eqA x₁ l₁
H3:NoDupA eqA l₁

~ InA eqA x₂ l₂
A:Type
eqA:relation A
e:Equivalence eqA
x₁, x₂:A
l₁, l₂:list A
H:eqA x₁ x₂
H0:equivlistA eqA l₁ l₂
IHPermutationA:NoDupA eqA l₁ -> NoDupA eqA l₂
H3:NoDupA eqA l₁
H2:InA eqA x₂ l₂

InA eqA x₁ l₁
now rewrite H, H0.
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A

NoDupA eqA (y :: x :: l) -> NoDupA eqA (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
H0:~ InA eqA y (x :: l)
H1:NoDupA eqA (x :: l)

NoDupA eqA (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
H0:~ InA eqA y (x :: l)
H:~ InA eqA x l
H2:NoDupA eqA l

NoDupA eqA (x :: y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
H0:~ InA eqA y (x :: l)
H:~ InA eqA x l
H2:NoDupA eqA l

~ InA eqA x (y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
H0:~ InA eqA y (x :: l)
H:~ InA eqA x l
H2:NoDupA eqA l
NoDupA eqA (y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
H0:~ InA eqA y (x :: l)
H:~ InA eqA x l
H2:NoDupA eqA l

~ InA eqA x (y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
H0:~ InA eqA y (x :: l)
H2:NoDupA eqA l
H:InA eqA x (y :: l)

InA eqA x l
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
H0:~ InA eqA y (x :: l)
H2:NoDupA eqA l
H1:eqA x y

InA eqA x l
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
H0:~ InA eqA y (x :: l)
H2:NoDupA eqA l
H1:eqA x y

InA eqA y (x :: l)
now constructor.
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
H0:~ InA eqA y (x :: l)
H:~ InA eqA x l
H2:NoDupA eqA l

NoDupA eqA (y :: l)
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
H0:~ InA eqA y (x :: l)
H:~ InA eqA x l
H2:NoDupA eqA l

~ InA eqA y l
A:Type
eqA:relation A
e:Equivalence eqA
x, y:A
l:list A
H:~ InA eqA x l
H2:NoDupA eqA l
H0:InA eqA y l

InA eqA y (x :: l)
now apply InA_cons_tl.
A:Type
eqA:relation A
e:Equivalence eqA
l₁, l₂, l₃:list A
H:PermutationA l₁ l₂
H0:PermutationA l₂ l₃
IHPermutationA1:NoDupA eqA l₁ -> NoDupA eqA l₂
IHPermutationA2:NoDupA eqA l₂ -> NoDupA eqA l₃

NoDupA eqA l₁ -> NoDupA eqA l₃
eauto. Qed. End Permutation.