Skip to content

Commit de671f6

Browse files
authored
Add transposition decomposition for permutations (#1271)
1 parent e31c5fc commit de671f6

File tree

3 files changed

+189
-32
lines changed

3 files changed

+189
-32
lines changed

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,18 @@ New modules
261261
System.Environment.Primitive
262262
```
263263

264+
* Added a module `Data.Fin.Permutation.Transposition.List` which
265+
contains a type `TranspositionList n = List (Fin n × Fin n)` for
266+
representing a list of transpositions (a permutation which switches
267+
two elements). Also added a function `decompose` that decomposes an
268+
arbitrary permutation into a list of transpositions and provided a
269+
proof that this list of transpositions evaluates to the originial
270+
permutation. Note that currently transpositions of the form (i,i)
271+
are allowed as in some literature they are not (in particular the
272+
proof that any two transposition decompositions of a permutation
273+
have lengths that differ by an even number).
274+
```
275+
264276
* Added the following `Show` modules:
265277
```agda
266278
Data.Fin.Show
@@ -314,6 +326,17 @@ Other minor additions
314326
CancellativeCommutativeSemiring c ℓ : Set (suc (c ⊔ ℓ))
315327
```
316328

329+
* Added new relations, functions and proofs to `Data.Fin.Permutation`:
330+
```
331+
_≈_ : Rel (Permutation m n) 0ℓ
332+
lift₀ : Permutation m n → Permutation (suc m) (suc n)
333+
lift₀-remove : π ⟨$⟩ʳ 0F ≡ 0F → ∀ i → lift₀ (remove 0F π) ≈ π
334+
lift₀-id : lift₀ id ⟨$⟩ʳ i ≡ i
335+
lift₀-comp : lift₀ π ∘ₚ lift₀ ρ ≈ lift₀ (π ∘ₚ ρ)
336+
lift₀-cong : π ≈ ρ → lift₀ π ≈ lift₀ ρ
337+
lift₀-transpose : transpose (suc i) (suc j)≈ lift₀ (transpose i j)
338+
```
339+
317340
* Added new definitions to `Algebra.Definitions`:
318341
```agda
319342
AlmostLeftCancellative e _•_ = ∀ {x} y z → ¬ x ≈ e → (x • y) ≈ (x • z) → y ≈ z

src/Data/Fin/Permutation.agda

Lines changed: 95 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,29 @@
88

99
module Data.Fin.Permutation where
1010

11+
open import Data.Bool using (true; false)
1112
open import Data.Empty using (⊥-elim)
1213
open import Data.Fin.Base
14+
open import Data.Fin.Patterns
1315
open import Data.Fin.Properties
1416
import Data.Fin.Permutation.Components as PC
1517
open import Data.Nat.Base using (ℕ; suc; zero)
1618
open import Data.Product using (proj₂)
1719
open import Function.Inverse as Inverse using (_↔_; Inverse; _InverseOf_)
1820
open import Function.Equality using (_⟨$⟩_)
1921
open import Function.Base using (_∘_)
20-
open import Relation.Nullary using (¬_; yes; no)
22+
open import Level using (0ℓ)
23+
open import Relation.Binary using (Rel)
24+
open import Relation.Nullary using (does; ¬_; yes; no)
2125
open import Relation.Nullary.Negation using (contradiction)
2226
open import Relation.Binary.PropositionalEquality as P
2327
using (_≡_; _≢_; refl; trans; sym; →-to-⟶; cong; cong₂)
2428
open P.≡-Reasoning
2529

30+
private
31+
variable
32+
m n o :
33+
2634
------------------------------------------------------------------------
2735
-- Types
2836

@@ -42,48 +50,54 @@ Permutation′ n = Permutation n n
4250
------------------------------------------------------------------------
4351
-- Helper functions
4452

45-
permutation : {m n} (f : Fin m Fin n) (g : Fin n Fin m)
53+
permutation : (f : Fin m Fin n) (g : Fin n Fin m)
4654
(→-to-⟶ g) InverseOf (→-to-⟶ f) Permutation m n
4755
permutation f g inv = record
4856
{ to = →-to-⟶ f
4957
; from = →-to-⟶ g
5058
; inverse-of = inv
5159
}
5260

53-
_⟨$⟩ʳ_ : {m n} Permutation m n Fin m Fin n
61+
infixl 5 _⟨$⟩ʳ_ _⟨$⟩ˡ_
62+
_⟨$⟩ʳ_ : Permutation m n Fin m Fin n
5463
_⟨$⟩ʳ_ = _⟨$⟩_ ∘ Inverse.to
5564

56-
_⟨$⟩ˡ_ : {m n} Permutation m n Fin n Fin m
65+
_⟨$⟩ˡ_ : Permutation m n Fin n Fin m
5766
_⟨$⟩ˡ_ = _⟨$⟩_ ∘ Inverse.from
5867

59-
inverseˡ : {m n} : Permutation m n) {i} π ⟨$⟩ˡ (π ⟨$⟩ʳ i) ≡ i
68+
inverseˡ : : Permutation m n) {i} π ⟨$⟩ˡ (π ⟨$⟩ʳ i) ≡ i
6069
inverseˡ π = Inverse.left-inverse-of π _
6170

62-
inverseʳ : {m n} : Permutation m n) {i} π ⟨$⟩ʳ (π ⟨$⟩ˡ i) ≡ i
71+
inverseʳ : : Permutation m n) {i} π ⟨$⟩ʳ (π ⟨$⟩ˡ i) ≡ i
6372
inverseʳ π = Inverse.right-inverse-of π _
6473

74+
------------------------------------------------------------------------
75+
-- Equality
76+
77+
infix 6 _≈_
78+
_≈_ : Rel (Permutation m n) 0ℓ
79+
π ≈ ρ = i π ⟨$⟩ʳ i ≡ ρ ⟨$⟩ʳ i
80+
6581
------------------------------------------------------------------------
6682
-- Example permutations
6783

6884
-- Identity
6985

70-
id : {n} Permutation′ n
86+
id : Permutation′ n
7187
id = Inverse.id
7288

7389
-- Transpose two indices
7490

75-
transpose : {n} Fin n Fin n Permutation′ n
76-
transpose i j = permutation (PC.transpose i j) (PC.transpose j i)
77-
record
91+
transpose : Fin n Fin n Permutation′ n
92+
transpose i j = permutation (PC.transpose i j) (PC.transpose j i) record
7893
{ left-inverse-of = λ _ PC.transpose-inverse _ _
7994
; right-inverse-of = λ _ PC.transpose-inverse _ _
8095
}
8196

8297
-- Reverse the order of indices
8398

84-
reverse : {n} Permutation′ n
85-
reverse = permutation PC.reverse PC.reverse
86-
record
99+
reverse : Permutation′ n
100+
reverse = permutation PC.reverse PC.reverse record
87101
{ left-inverse-of = PC.reverse-involutive
88102
; right-inverse-of = PC.reverse-involutive
89103
}
@@ -93,12 +107,13 @@ reverse = permutation PC.reverse PC.reverse
93107

94108
-- Composition
95109

96-
_∘ₚ_ : {m n o} Permutation m n Permutation n o Permutation m o
110+
infixr 9 _∘ₚ_
111+
_∘ₚ_ : Permutation m n Permutation n o Permutation m o
97112
π₁ ∘ₚ π₂ = π₂ Inverse.∘ π₁
98113

99114
-- Flip
100115

101-
flip : {m n} Permutation m n Permutation n m
116+
flip : Permutation m n Permutation n m
102117
flip = Inverse.sym
103118

104119
-- Element removal
@@ -107,10 +122,8 @@ flip = Inverse.sym
107122
--
108123
-- [0 ↦ i₀, …, k-1 ↦ iₖ₋₁, k ↦ iₖ₊₁, k+1 ↦ iₖ₊₂, …, n-1 ↦ iₙ]
109124

110-
remove : {m n} Fin (suc m)
111-
Permutation (suc m) (suc n) Permutation m n
112-
remove {m} {n} i π = permutation to from
113-
record
125+
remove : Fin (suc m) Permutation (suc m) (suc n) Permutation m n
126+
remove {m} {n} i π = permutation to from record
114127
{ left-inverse-of = left-inverse-of
115128
; right-inverse-of = right-inverse-of
116129
}
@@ -139,47 +152,97 @@ remove {m} {n} i π = permutation to from
139152
left-inverse-of : j from (to j) ≡ j
140153
left-inverse-of j = begin
141154
from (to j) ≡⟨⟩
142-
punchOut {i = i} {πˡ (punchIn (πʳ i) (punchOut to-punchOut))} _ ≡⟨ punchOut-cong′ i (cong πˡ (punchIn-punchOut {i = πʳ i} _)) ⟩
155+
punchOut {i = i} {πˡ (punchIn (πʳ i) (punchOut to-punchOut))} _ ≡⟨ punchOut-cong′ i (cong πˡ (punchIn-punchOut _)) ⟩
143156
punchOut {i = i} {πˡ (πʳ (punchIn i j))} _ ≡⟨ punchOut-cong i (inverseˡ π) ⟩
144157
punchOut {i = i} {punchIn i j} _ ≡⟨ punchOut-punchIn i ⟩
145158
j ∎
146159

147160
right-inverse-of : j to (from j) ≡ j
148161
right-inverse-of j = begin
149162
to (from j) ≡⟨⟩
150-
punchOut {i = πʳ i} {πʳ (punchIn i (punchOut from-punchOut))} _ ≡⟨ punchOut-cong′ (πʳ i) (cong πʳ (punchIn-punchOut {i = i} _)) ⟩
163+
punchOut {i = πʳ i} {πʳ (punchIn i (punchOut from-punchOut))} _ ≡⟨ punchOut-cong′ (πʳ i) (cong πʳ (punchIn-punchOut _)) ⟩
151164
punchOut {i = πʳ i} {πʳ (πˡ (punchIn (πʳ i) j))} _ ≡⟨ punchOut-cong (πʳ i) (inverseʳ π) ⟩
152165
punchOut {i = πʳ i} {punchIn (πʳ i) j} _ ≡⟨ punchOut-punchIn (πʳ i) ⟩
153166
j ∎
154167

168+
-- lift: takes a permutation m → n and creates a permutation (suc m) → (suc n)
169+
-- by mapping 0 to 0 and applying the input permutation to everything else
170+
lift₀ : Permutation m n Permutation (suc m) (suc n)
171+
lift₀ {m} {n} π = permutation to from record
172+
{ left-inverse-of = left-inverse-of
173+
; right-inverse-of = right-inverse-of
174+
}
175+
where
176+
to : Fin (suc m) Fin (suc n)
177+
to 0F = 0F
178+
to (suc i) = suc (π ⟨$⟩ʳ i)
179+
180+
from : Fin (suc n) Fin (suc m)
181+
from 0F = 0F
182+
from (suc i) = suc (π ⟨$⟩ˡ i)
183+
184+
left-inverse-of : j from (to j) ≡ j
185+
left-inverse-of 0F = refl
186+
left-inverse-of (suc j) = cong suc (inverseˡ π)
187+
188+
right-inverse-of : j to (from j) ≡ j
189+
right-inverse-of 0F = refl
190+
right-inverse-of (suc j) = cong suc (inverseʳ π)
191+
155192
------------------------------------------------------------------------
156193
-- Other properties
157194

158-
module _ {m n} : Permutation (suc m) (suc n)) where
195+
module _: Permutation (suc m) (suc n)) where
159196
private
160197
πʳ = π ⟨$⟩ʳ_
161198
πˡ = π ⟨$⟩ˡ_
162199

163200
punchIn-permute : i j πʳ (punchIn i j) ≡ punchIn (πʳ i) (remove i π ⟨$⟩ʳ j)
164-
punchIn-permute i j = begin
165-
πʳ (punchIn i j) ≡⟨ sym (punchIn-punchOut {i = πʳ i} _) ⟩
166-
punchIn (πʳ i) (punchOut {i = πʳ i} {πʳ (punchIn i j)} _) ≡⟨⟩
167-
punchIn (πʳ i) (remove i π ⟨$⟩ʳ j) ∎
201+
punchIn-permute i j = sym (punchIn-punchOut _)
168202

169203
punchIn-permute′ : i j πʳ (punchIn (πˡ i) j) ≡ punchIn i (remove (πˡ i) π ⟨$⟩ʳ j)
170204
punchIn-permute′ i j = begin
171205
πʳ (punchIn (πˡ i) j) ≡⟨ punchIn-permute _ _ ⟩
172206
punchIn (πʳ (πˡ i)) (remove (πˡ i) π ⟨$⟩ʳ j) ≡⟨ cong₂ punchIn (inverseʳ π) refl ⟩
173207
punchIn i (remove (πˡ i) π ⟨$⟩ʳ j) ∎
174208

175-
↔⇒≡ : {m n} Permutation m n m ≡ n
209+
lift₀-remove : πʳ 0F ≡ 0F lift₀ (remove 0F π) ≈ π
210+
lift₀-remove p 0F = sym p
211+
lift₀-remove p (suc i) = punchOut-zero (πʳ (suc i)) p
212+
where
213+
punchOut-zero : {i} (j : Fin (suc n)) {neq} i ≡ 0F suc (punchOut {i = i} {j} neq) ≡ j
214+
punchOut-zero 0F {neq} p = ⊥-elim (neq p)
215+
punchOut-zero (suc j) refl = refl
216+
217+
↔⇒≡ : Permutation m n m ≡ n
176218
↔⇒≡ {zero} {zero} π = refl
177-
↔⇒≡ {zero} {suc n} π = contradiction (π ⟨$⟩ˡ zero) ¬Fin0
178-
↔⇒≡ {suc m} {zero} π = contradiction (π ⟨$⟩ʳ zero) ¬Fin0
179-
↔⇒≡ {suc m} {suc n} π = cong suc (↔⇒≡ (remove zero π))
219+
↔⇒≡ {zero} {suc n} π = contradiction (π ⟨$⟩ˡ 0F) ¬Fin0
220+
↔⇒≡ {suc m} {zero} π = contradiction (π ⟨$⟩ʳ 0F) ¬Fin0
221+
↔⇒≡ {suc m} {suc n} π = cong suc (↔⇒≡ (remove 0F π))
180222

181-
fromPermutation : {m n} Permutation m n Permutation′ m
223+
fromPermutation : Permutation m n Permutation′ m
182224
fromPermutation π = P.subst (Permutation _) (sym (↔⇒≡ π)) π
183225

184-
refute : {m n} m ≢ n ¬ Permutation m n
226+
refute : m ≢ n ¬ Permutation m n
185227
refute m≢n π = contradiction (↔⇒≡ π) m≢n
228+
229+
lift₀-id : (i : Fin (suc n)) lift₀ id ⟨$⟩ʳ i ≡ i
230+
lift₀-id 0F = refl
231+
lift₀-id (suc i) = refl
232+
233+
lift₀-comp : : Permutation m n) (ρ : Permutation n o)
234+
lift₀ π ∘ₚ lift₀ ρ ≈ lift₀ (π ∘ₚ ρ)
235+
lift₀-comp π ρ 0F = refl
236+
lift₀-comp π ρ (suc i) = refl
237+
238+
lift₀-cong : (π ρ : Permutation m n) π ≈ ρ lift₀ π ≈ lift₀ ρ
239+
lift₀-cong π ρ f 0F = refl
240+
lift₀-cong π ρ f (suc i) = cong suc (f i)
241+
242+
lift₀-transpose : (i j : Fin n) transpose (suc i) (suc j) ≈ lift₀ (transpose i j)
243+
lift₀-transpose i j 0F = refl
244+
lift₀-transpose i j (suc k) with does (k ≟ i)
245+
... | true = refl
246+
... | false with does (k ≟ j)
247+
... | false = refl
248+
... | true = refl
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- Decomposition of permutations into a list of transpositions.
5+
------------------------------------------------------------------------
6+
7+
{-# OPTIONS --without-K --safe #-}
8+
9+
module Data.Fin.Permutation.Transposition.List where
10+
11+
open import Data.Fin.Base
12+
open import Data.Fin.Patterns using (0F)
13+
open import Data.Fin.Permutation as P hiding (lift₀)
14+
import Data.Fin.Permutation.Components as PC
15+
open import Data.List using (List; []; _∷_; map)
16+
open import Data.Nat.Base using (ℕ; suc; zero)
17+
open import Data.Product using (_×_; _,_)
18+
open import Function using (_∘_)
19+
open import Relation.Binary.PropositionalEquality
20+
using (_≡_; sym; cong; module ≡-Reasoning)
21+
open ≡-Reasoning
22+
23+
private
24+
variable
25+
n :
26+
27+
------------------------------------------------------------------------
28+
-- Definition
29+
30+
-- This decomposition is not a unique representation of the original
31+
-- permutation but can be used to simply proofs about permutations (by
32+
-- instead inducting on the list of transpositions).
33+
34+
TranspositionList : Set
35+
TranspositionList n = List (Fin n × Fin n)
36+
37+
------------------------------------------------------------------------
38+
-- Operations on transposition lists
39+
40+
lift₀ : TranspositionList n TranspositionList (suc n)
41+
lift₀ xs = map (λ (i , j) (suc i , suc j)) xs
42+
43+
eval : TranspositionList n Permutation′ n
44+
eval [] = id
45+
eval ((i , j) ∷ xs) = transpose i j ∘ₚ eval xs
46+
47+
decompose : Permutation′ n TranspositionList n
48+
decompose {zero} π = []
49+
decompose {suc n} π = (π ⟨$⟩ˡ 0F , 0F) ∷ lift₀ (decompose (remove 0F ((transpose 0F (π ⟨$⟩ˡ 0F)) ∘ₚ π)))
50+
51+
------------------------------------------------------------------------
52+
-- Properties
53+
54+
eval-lift : (xs : TranspositionList n) eval (lift₀ xs) ≈ P.lift₀ (eval xs)
55+
eval-lift [] = sym ∘ lift₀-id
56+
eval-lift ((i , j) ∷ xs) k = begin
57+
transpose (suc i) (suc j) ∘ₚ eval (lift₀ xs) ⟨$⟩ʳ k ≡⟨ cong (eval (lift₀ xs) ⟨$⟩ʳ_) (lift₀-transpose i j k) ⟩
58+
P.lift₀ (transpose i j) ∘ₚ eval (lift₀ xs) ⟨$⟩ʳ k ≡⟨ eval-lift xs (P.lift₀ (transpose i j) ⟨$⟩ʳ k) ⟩
59+
P.lift₀ (eval xs) ⟨$⟩ʳ (P.lift₀ (transpose i j) ⟨$⟩ʳ k) ≡⟨ lift₀-comp (transpose i j) (eval xs) k ⟩
60+
P.lift₀ (transpose i j ∘ₚ eval xs) ⟨$⟩ʳ k ∎
61+
62+
eval-decompose : : Permutation′ n) eval (decompose π) ≈ π
63+
eval-decompose {suc n} π i = begin
64+
tπ0 ∘ₚ eval (lift₀ (decompose (remove 0F (t0π ∘ₚ π)))) ⟨$⟩ʳ i ≡⟨ eval-lift (decompose (remove 0F (t0π ∘ₚ π))) (tπ0 ⟨$⟩ʳ i) ⟩
65+
tπ0 ∘ₚ P.lift₀ (eval (decompose (remove 0F (t0π ∘ₚ π)))) ⟨$⟩ʳ i ≡⟨ lift₀-cong _ _ (eval-decompose _) (tπ0 ⟨$⟩ʳ i) ⟩
66+
tπ0 ∘ₚ P.lift₀ (remove 0F (t0π ∘ₚ π)) ⟨$⟩ʳ i ≡⟨ lift₀-remove (t0π ∘ₚ π) (inverseʳ π) (tπ0 ⟨$⟩ʳ i) ⟩
67+
tπ0 ∘ₚ t0π ∘ₚ π ⟨$⟩ʳ i ≡⟨ cong (π ⟨$⟩ʳ_) (PC.transpose-inverse 0F (π ⟨$⟩ˡ 0F)) ⟩
68+
π ⟨$⟩ʳ i ∎
69+
where
70+
tπ0 = transpose (π ⟨$⟩ˡ 0F) 0F
71+
t0π = transpose 0F (π ⟨$⟩ˡ 0F)

0 commit comments

Comments
 (0)