Skip to content

Commit f5e4c2b

Browse files
Some preparatory proofs for proving sorting+permutation is equality #2724 (#2725)
* Some preparatory proofs for proving sorting+permutation is equality * Minor tweaks * Addressed feedback * Fix bugs * Update src/Data/List/Relation/Binary/Permutation/Setoid/Properties.agda Co-authored-by: jamesmckinna <[email protected]> * Addressed James feedback * fix: `2+` pattern plus `onIndices-lookup` in `CHANGELOG` --------- Co-authored-by: jamesmckinna <[email protected]> Co-authored-by: jamesmckinna <[email protected]>
1 parent 9fca9dc commit f5e4c2b

File tree

9 files changed

+184
-63
lines changed

9 files changed

+184
-63
lines changed

CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,23 @@ Additions to existing modules
239239
∙-cong-∣ : x ∣ y → a ∣ b → x ∙ a ∣ y ∙ b
240240
```
241241

242+
* In `Data.Fin.Base`:
243+
```agda
244+
_≰_ : Rel (Fin n) 0ℓ
245+
_≮_ : Rel (Fin n) 0ℓ
246+
```
247+
248+
* In `Data.Fin.Permutation`:
249+
```agda
250+
cast-id : .(m ≡ n) → Permutation m n
251+
swap : Permutation m n → Permutation (suc (suc m)) (suc (suc n))
252+
```
253+
254+
* In `Data.Fin.Properties`:
255+
```agda
256+
cast-involutive : .(eq₁ : m ≡ n) .(eq₂ : n ≡ m) → ∀ k → cast eq₁ (cast eq₂ k) ≡ k
257+
```
258+
242259
* In `Data.Fin.Subset`:
243260
```agda
244261
_⊇_ : Subset n → Subset n → Set
@@ -275,14 +292,31 @@ Additions to existing modules
275292
map-downFrom : ∀ (f : ℕ → A) n → map f (downFrom n) ≡ applyDownFrom f n
276293
```
277294

295+
* In `Data.List.Relation.Binary.Permutation.Homogeneous`:
296+
```agda
297+
onIndices : Permutation R xs ys → Fin.Permutation (length xs) (length ys)
298+
```
299+
278300
* In `Data.List.Relation.Binary.Permutation.Propositional`:
279301
```agda
280302
↭⇒↭ₛ′ : IsEquivalence _≈_ → _↭_ ⇒ _↭ₛ′_
281303
```
282304

305+
* In `Data.List.Relation.Binary.Permutation.Setoid.Properties`:
306+
```agda
307+
xs↭ys⇒|xs|≡|ys| : xs ↭ ys → length xs ≡ length ys
308+
¬x∷xs↭[] : ¬ (x ∷ xs ↭ [])
309+
onIndices-lookup : ∀ i → lookup xs i ≈ lookup ys (Inverse.to (onIndices xs↭ys) i)
310+
```
311+
283312
* In `Data.List.Relation.Binary.Permutation.Propositional.Properties`:
284313
```agda
285314
filter-↭ : ∀ (P? : Pred.Decidable P) → xs ↭ ys → filter P? xs ↭ filter P? ys
315+
```
316+
317+
* In `Data.List.Relation.Binary.Pointwise.Properties`:
318+
```agda
319+
lookup-cast : Pointwise R xs ys → .(∣xs∣≡∣ys∣ : length xs ≡ length ys) → ∀ i → R (lookup xs i) (lookup ys (cast ∣xs∣≡∣ys∣ i))
286320
```
287321

288322
* In `Data.List.NonEmpty.Properties`:

src/Data/Fin/Base.agda

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ open import Level using (0ℓ)
1919
open import Relation.Binary.Core using (Rel)
2020
open import Relation.Binary.PropositionalEquality.Core using (_≡_; _≢_; refl; cong)
2121
open import Relation.Binary.Indexed.Heterogeneous.Core using (IRel)
22-
open import Relation.Nullary.Negation.Core using (contradiction)
22+
open import Relation.Nullary.Negation.Core using (¬_; contradiction)
2323

2424
private
2525
variable
@@ -271,7 +271,7 @@ pinch {suc n} (suc i) (suc j) = suc (pinch i j)
271271
------------------------------------------------------------------------
272272
-- Order relations
273273

274-
infix 4 _≤_ _≥_ _<_ _>_
274+
infix 4 _≤_ _≥_ _<_ _>_ _≰_ _≮_
275275

276276
_≤_ : IRel Fin 0ℓ
277277
i ≤ j = toℕ i ℕ.≤ toℕ j
@@ -285,6 +285,11 @@ i < j = toℕ i ℕ.< toℕ j
285285
_>_ : IRel Fin 0ℓ
286286
i > j = toℕ i ℕ.> toℕ j
287287

288+
_≰_ : {n} Rel (Fin n) 0ℓ
289+
i ≰ j = ¬ (i ≤ j)
290+
291+
_≮_ : {n} Rel (Fin n) 0ℓ
292+
i ≮ j = ¬ (i < j)
288293

289294
------------------------------------------------------------------------
290295
-- An ordering view.

src/Data/Fin/Permutation.agda

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
module Data.Fin.Permutation where
1010

1111
open import Data.Bool.Base using (true; false)
12-
open import Data.Fin.Base using (Fin; suc; opposite; punchIn; punchOut)
13-
open import Data.Fin.Patterns using (0F)
12+
open import Data.Fin.Base using (Fin; suc; cast; opposite; punchIn; punchOut)
13+
open import Data.Fin.Patterns using (0F; 1F)
1414
open import Data.Fin.Properties using (punchInᵢ≢i; punchOut-punchIn;
15-
punchOut-cong; punchOut-cong′; punchIn-punchOut; _≟_; ¬Fin0)
15+
punchOut-cong; punchOut-cong′; punchIn-punchOut; _≟_; ¬Fin0; cast-involutive)
1616
import Data.Fin.Permutation.Components as PC
1717
open import Data.Nat.Base using (ℕ; suc; zero)
1818
open import Data.Product.Base using (_,_; proj₂)
@@ -22,7 +22,7 @@ open import Function.Construct.Identity using (↔-id)
2222
open import Function.Construct.Symmetry using (↔-sym)
2323
open import Function.Definitions using (StrictlyInverseˡ; StrictlyInverseʳ)
2424
open import Function.Properties.Inverse using (↔⇒↣)
25-
open import Function.Base using (_∘_)
25+
open import Function.Base using (_∘_; _∘′_)
2626
open import Level using (0ℓ)
2727
open import Relation.Binary.Core using (Rel)
2828
open import Relation.Nullary using (does; ¬_; yes; no)
@@ -57,11 +57,15 @@ Permutation′ n = Permutation n n
5757
------------------------------------------------------------------------
5858
-- Helper functions
5959

60-
permutation : (f : Fin m Fin n) (g : Fin n Fin m)
61-
StrictlyInverseˡ _≡_ f g StrictlyInverseʳ _≡_ f g Permutation m n
60+
permutation : (f : Fin m Fin n)
61+
(g : Fin n Fin m)
62+
StrictlyInverseˡ _≡_ f g
63+
StrictlyInverseʳ _≡_ f g
64+
Permutation m n
6265
permutation = mk↔ₛ′
6366

6467
infixl 5 _⟨$⟩ʳ_ _⟨$⟩ˡ_
68+
6569
_⟨$⟩ʳ_ : Permutation m n Fin m Fin n
6670
_⟨$⟩ʳ_ = Inverse.to
6771

@@ -75,44 +79,61 @@ inverseʳ : ∀ (π : Permutation m n) {i} → π ⟨$⟩ʳ (π ⟨$⟩ˡ i) ≡
7579
inverseʳ π = Inverse.inverseˡ π refl
7680

7781
------------------------------------------------------------------------
78-
-- Equality
82+
-- Equality over permutations
7983

8084
infix 6 _≈_
85+
8186
_≈_ : Rel (Permutation m n) 0ℓ
8287
π ≈ ρ = i π ⟨$⟩ʳ i ≡ ρ ⟨$⟩ʳ i
8388

8489
------------------------------------------------------------------------
85-
-- Example permutations
90+
-- Permutation properties
8691

87-
-- Identity
88-
89-
id : Permutation′ n
92+
id : Permutation n n
9093
id = ↔-id _
9194

92-
-- Transpose two indices
93-
94-
transpose : Fin n Fin n Permutation′ n
95-
transpose i j = permutation (PC.transpose i j) (PC.transpose j i) (λ _ PC.transpose-inverse _ _) (λ _ PC.transpose-inverse _ _)
95+
flip : Permutation m n Permutation n m
96+
flip = ↔-sym
9697

97-
-- Reverse the order of indices
98+
infixr 9 _∘ₚ_
9899

99-
reverse : Permutation′ n
100-
reverse = permutation opposite opposite PC.reverse-involutive PC.reverse-involutive
100+
_∘ₚ_ : Permutation m n Permutation n o Permutation m o
101+
π₁ ∘ₚ π₂ = π₂ ↔-∘ π₁
101102

102103
------------------------------------------------------------------------
103-
-- Operations
104+
-- Non-trivial identity
104105

105-
-- Composition
106+
cast-id : .(m ≡ n) Permutation m n
107+
cast-id m≡n = permutation
108+
(cast m≡n)
109+
(cast (sym m≡n))
110+
(cast-involutive m≡n (sym m≡n))
111+
(cast-involutive (sym m≡n) m≡n)
106112

107-
infixr 9 _∘ₚ_
108-
_∘ₚ_ : Permutation m n Permutation n o Permutation m o
109-
π₁ ∘ₚ π₂ = π₂ ↔-∘ π₁
113+
------------------------------------------------------------------------
114+
-- Transposition
110115

111-
-- Flip
116+
-- Transposes two elements in the permutation, keeping the remainder
117+
-- of the permutation the same
118+
transpose : Fin n Fin n Permutation n n
119+
transpose i j = permutation
120+
(PC.transpose i j)
121+
(PC.transpose j i)
122+
(λ _ PC.transpose-inverse _ _)
123+
(λ _ PC.transpose-inverse _ _)
112124

113-
flip : Permutation m n Permutation n m
114-
flip = ↔-sym
125+
------------------------------------------------------------------------
126+
-- Reverse
115127

128+
-- Reverses a permutation
129+
reverse : Permutation n n
130+
reverse = permutation
131+
opposite
132+
opposite
133+
PC.reverse-involutive
134+
PC.reverse-involutive
135+
136+
------------------------------------------------------------------------
116137
-- Element removal
117138
--
118139
-- `remove k [0 ↦ i₀, …, k ↦ iₖ, …, n ↦ iₙ]` yields
@@ -159,8 +180,14 @@ remove {m} {n} i π = permutation to from inverseˡ′ inverseʳ′
159180
punchOut {i = πʳ i} {punchIn (πʳ i) j} _ ≡⟨ punchOut-punchIn (πʳ i) ⟩
160181
j ∎
161182

162-
-- lift: takes a permutation m → n and creates a permutation (suc m) → (suc n)
183+
------------------------------------------------------------------------
184+
-- Lifting
185+
186+
-- Takes a permutation m → n and creates a permutation (suc m) → (suc n)
163187
-- by mapping 0 to 0 and applying the input permutation to everything else
188+
--
189+
-- Note: should be refactored as a special-case when we add the
190+
-- concatenation of two permutations
164191
lift₀ : Permutation m n Permutation (suc m) (suc n)
165192
lift₀ {m} {n} π = permutation to from inverseˡ′ inverseʳ′
166193
where
@@ -180,6 +207,9 @@ lift₀ {m} {n} π = permutation to from inverseˡ′ inverseʳ′
180207
inverseˡ′ 0F = refl
181208
inverseˡ′ (suc j) = cong suc (inverseʳ π)
182209

210+
------------------------------------------------------------------------
211+
-- Insertion
212+
183213
-- insert i j π is the permutation that maps i to j and otherwise looks like π
184214
-- it's roughly an inverse of remove
185215
insert : {m n} Fin (suc m) Fin (suc n) Permutation m n Permutation (suc m) (suc n)
@@ -221,6 +251,18 @@ insert {m} {n} i j π = permutation to from inverseˡ′ inverseʳ′
221251
punchIn j (punchOut j≢k) ≡⟨ punchIn-punchOut j≢k ⟩
222252
k ∎
223253

254+
------------------------------------------------------------------------
255+
-- Swapping
256+
257+
-- Takes a permutation m → n and creates a permutation
258+
-- suc (suc m) → suc (suc n) by mapping 0 to 1 and 1 to 0 and
259+
-- then applying the input permutation to everything else
260+
--
261+
-- Note: should be refactored as a special-case when we add the
262+
-- concatenation of two permutations
263+
swap : Permutation m n Permutation (suc (suc m)) (suc (suc n))
264+
swap π = transpose 0F 1F ∘ₚ lift₀ (lift₀ π)
265+
224266
------------------------------------------------------------------------
225267
-- Other properties
226268

src/Data/Fin/Properties.agda

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,10 @@ cast-trans {m = suc _} {n = suc _} {o = suc _} eq₁ eq₂ zero = refl
279279
cast-trans {m = suc _} {n = suc _} {o = suc _} eq₁ eq₂ (suc k) =
280280
cong suc (cast-trans (ℕ.suc-injective eq₁) (ℕ.suc-injective eq₂) k)
281281

282+
cast-involutive : .(eq₁ : m ≡ n) .(eq₂ : n ≡ m)
283+
k cast eq₁ (cast eq₂ k) ≡ k
284+
cast-involutive eq₁ eq₂ k = trans (cast-trans eq₂ eq₁ k) (cast-is-id refl k)
285+
282286
------------------------------------------------------------------------
283287
-- Properties of _≤_
284288
------------------------------------------------------------------------

src/Data/List/Relation/Binary/Permutation/Homogeneous.agda

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@
88

99
module Data.List.Relation.Binary.Permutation.Homogeneous where
1010

11-
open import Data.List.Base using (List; _∷_)
11+
open import Data.List.Base using (List; _∷_; length)
1212
open import Data.List.Relation.Binary.Pointwise.Base as Pointwise
1313
using (Pointwise)
1414
import Data.List.Relation.Binary.Pointwise.Properties as Pointwise
1515
open import Data.Nat.Base using (ℕ; suc; _+_)
16+
open import Data.Fin.Base using (Fin; zero; suc; cast)
17+
import Data.Fin.Permutation as Fin
1618
open import Level using (Level; _⊔_)
19+
open import Function.Base using (_∘_)
1720
open import Relation.Binary.Core using (Rel; _⇒_)
1821
open import Relation.Binary.Bundles using (Setoid)
1922
open import Relation.Binary.Structures using (IsEquivalence)
@@ -23,6 +26,7 @@ private
2326
variable
2427
a r s : Level
2528
A : Set a
29+
R S : Rel A r
2630

2731
data Permutation {A : Set a} (R : Rel A r) : Rel (List A) (a ⊔ r) where
2832
refl : {xs ys} Pointwise R xs ys Permutation R xs ys
@@ -33,37 +37,39 @@ data Permutation {A : Set a} (R : Rel A r) : Rel (List A) (a ⊔ r) where
3337
------------------------------------------------------------------------
3438
-- The Permutation relation is an equivalence
3539

36-
module _ {R : Rel A r} where
40+
sym : Symmetric R Symmetric (Permutation R)
41+
sym R-sym (refl xs∼ys) = refl (Pointwise.symmetric R-sym xs∼ys)
42+
sym R-sym (prep x∼x′ xs↭ys) = prep (R-sym x∼x′) (sym R-sym xs↭ys)
43+
sym R-sym (swap x∼x′ y∼y′ xs↭ys) = swap (R-sym y∼y′) (R-sym x∼x′) (sym R-sym xs↭ys)
44+
sym R-sym (trans xs↭ys ys↭zs) = trans (sym R-sym ys↭zs) (sym R-sym xs↭ys)
3745

38-
sym : Symmetric R Symmetric (Permutation R)
39-
sym R-sym (refl xs∼ys) = refl (Pointwise.symmetric R-sym xs∼ys)
40-
sym R-sym (prep x∼x′ xs↭ys) = prep (R-sym x∼x′) (sym R-sym xs↭ys)
41-
sym R-sym (swap x∼x′ y∼y′ xs↭ys) = swap (R-sym y∼y′) (R-sym x∼x′) (sym R-sym xs↭ys)
42-
sym R-sym (trans xs↭ys ys↭zs) = trans (sym R-sym ys↭zs) (sym R-sym xs↭ys)
46+
isEquivalence : Reflexive R Symmetric R IsEquivalence (Permutation R)
47+
isEquivalence R-refl R-sym = record
48+
{ refl = refl (Pointwise.refl R-refl)
49+
; sym = sym R-sym
50+
; trans = trans
51+
}
4352

44-
isEquivalence : Reflexive R Symmetric R IsEquivalence (Permutation R)
45-
isEquivalence R-refl R-sym = record
46-
{ refl = refl (Pointwise.refl R-refl)
47-
; sym = sym R-sym
48-
; trans = trans
49-
}
53+
setoid : Reflexive R Symmetric R Setoid _ _
54+
setoid {R = R} R-refl R-sym = record
55+
{ isEquivalence = isEquivalence {R = R} R-refl R-sym
56+
}
5057

51-
setoid : Reflexive R Symmetric R Setoid _ _
52-
setoid R-refl R-sym = record
53-
{ isEquivalence = isEquivalence R-refl R-sym
54-
}
55-
56-
map : {R : Rel A r} {S : Rel A s}
57-
(R ⇒ S) (Permutation R ⇒ Permutation S)
58+
map : (R ⇒ S) (Permutation R ⇒ Permutation S)
5859
map R⇒S (refl xs∼ys) = refl (Pointwise.map R⇒S xs∼ys)
5960
map R⇒S (prep e xs∼ys) = prep (R⇒S e) (map R⇒S xs∼ys)
6061
map R⇒S (swap e₁ e₂ xs∼ys) = swap (R⇒S e₁) (R⇒S e₂) (map R⇒S xs∼ys)
6162
map R⇒S (trans xs∼ys ys∼zs) = trans (map R⇒S xs∼ys) (map R⇒S ys∼zs)
6263

6364
-- Measures the number of constructors, can be useful for termination proofs
64-
65-
steps : {R : Rel A r} {xs ys} Permutation R xs ys
65+
steps : {xs ys} Permutation R xs ys
6666
steps (refl _) = 1
6767
steps (prep _ xs↭ys) = suc (steps xs↭ys)
6868
steps (swap _ _ xs↭ys) = suc (steps xs↭ys)
6969
steps (trans xs↭ys ys↭zs) = steps xs↭ys + steps ys↭zs
70+
71+
onIndices : {xs ys} Permutation R xs ys Fin.Permutation (length xs) (length ys)
72+
onIndices (refl ≋) = Fin.cast-id (Pointwise.Pointwise-length ≋)
73+
onIndices (prep e xs↭ys) = Fin.lift₀ (onIndices xs↭ys)
74+
onIndices (swap e f xs↭ys) = Fin.swap (onIndices xs↭ys)
75+
onIndices (trans ↭₁ ↭₂) = onIndices ↭₁ Fin.∘ₚ onIndices ↭₂

src/Data/List/Relation/Binary/Permutation/Setoid.agda

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ open ≋ S using (_≋_; _∷_; ≋-refl; ≋-sym; ≋-trans)
3131
-- Definition, based on `Homogeneous`
3232

3333
open Homogeneous public
34-
using (refl; prep; swap; trans)
34+
using (refl; prep; swap; trans; onIndices)
3535

3636
infix 3 _↭_
3737

0 commit comments

Comments
 (0)