|
| 1 | +------------------------------------------------------------------------------- |
| 2 | +-- The Agda standard library |
| 3 | +-- |
| 4 | +-- A alternative definition for the permutation relation using setoid equality |
| 5 | +-- Based on Choudhury and Fiore, "Free Commutative Monoids in HoTT" (MFPS, 2022) |
| 6 | +-- Constructor `_⋎_` below is rule (3), directly after the proof of Theorem 6.3, |
| 7 | +-- and appears as rule `commrel` of their earlier presentation at (HoTT, 2019), |
| 8 | +-- "The finite-multiset construction in HoTT". |
| 9 | +-- |
| 10 | +-- `Algorithmic` ⊆ `Data.List.Relation.Binary.Permutation.Declarative` |
| 11 | +-- but enjoys a much smaller space of derivations, without being so (over-) |
| 12 | +-- deterministic as to being inductively defined as the relation generated |
| 13 | +-- by swapping the top two elements (the relational analogue of bubble-sort). |
| 14 | + |
| 15 | +-- In particular, transitivity, `↭-trans` below, is an admissible property. |
| 16 | +-- |
| 17 | +-- So this relation is 'better' for proving properties of `_↭_`, while at the |
| 18 | +-- same time also being a better fit, via `_⋎_`, for the operational features |
| 19 | +-- of e.g. sorting algorithms which transpose at arbitary positions. |
| 20 | +------------------------------------------------------------------------------- |
| 21 | + |
| 22 | +{-# OPTIONS --cubical-compatible --safe #-} |
| 23 | + |
| 24 | +open import Relation.Binary.Bundles using (Setoid) |
| 25 | + |
| 26 | +module Data.List.Relation.Binary.Permutation.Algorithmic |
| 27 | + {s ℓ} (S : Setoid s ℓ) where |
| 28 | + |
| 29 | +open import Data.List.Base using (List; []; _∷_; length) |
| 30 | +open import Data.List.Properties using (++-identityʳ) |
| 31 | +open import Data.Nat.Base using (ℕ; suc) |
| 32 | +open import Data.Nat.Properties using (suc-injective) |
| 33 | +open import Level using (_⊔_) |
| 34 | +open import Relation.Binary.PropositionalEquality as ≡ using (_≡_) |
| 35 | + |
| 36 | +open import Data.List.Relation.Binary.Equality.Setoid S as ≋ |
| 37 | + using (_≋_; []; _∷_; ≋-refl) |
| 38 | + |
| 39 | +open Setoid S |
| 40 | + renaming (Carrier to A; refl to ≈-refl; sym to ≈-sym; trans to ≈-trans) |
| 41 | + |
| 42 | +private |
| 43 | + variable |
| 44 | + a b c d : A |
| 45 | + as bs cs ds : List A |
| 46 | + n : ℕ |
| 47 | + |
| 48 | + |
| 49 | +------------------------------------------------------------------------------- |
| 50 | +-- Definition |
| 51 | + |
| 52 | +infix 4 _↭_ |
| 53 | +infix 5 _⋎_ _⋎[_]_ |
| 54 | + |
| 55 | +data _↭_ : List A → List A → Set (s ⊔ ℓ) where |
| 56 | + [] : [] ↭ [] |
| 57 | + _∷_ : a ≈ b → as ↭ bs → a ∷ as ↭ b ∷ bs |
| 58 | + _⋎_ : as ↭ b ∷ cs → a ∷ cs ↭ bs → a ∷ as ↭ b ∷ bs |
| 59 | + |
| 60 | +-- smart constructor for prefix congruence |
| 61 | + |
| 62 | +_≡∷_ : ∀ c → as ↭ bs → c ∷ as ↭ c ∷ bs |
| 63 | +_≡∷_ c = ≈-refl ∷_ |
| 64 | + |
| 65 | +-- pattern synonym to allow naming the 'middle' term |
| 66 | +pattern _⋎[_]_ {as} {b} {a} {bs} as↭b∷cs cs a∷cs↭bs |
| 67 | + = _⋎_ {as} {b} {cs = cs} {a} {bs} as↭b∷cs a∷cs↭bs |
| 68 | + |
| 69 | +------------------------------------------------------------------------------- |
| 70 | +-- Properties |
| 71 | + |
| 72 | +↭-reflexive : as ≋ bs → as ↭ bs |
| 73 | +↭-reflexive [] = [] |
| 74 | +↭-reflexive (a≈b ∷ as↭bs) = a≈b ∷ ↭-reflexive as↭bs |
| 75 | + |
| 76 | +↭-refl : ∀ as → as ↭ as |
| 77 | +↭-refl _ = ↭-reflexive ≋-refl |
| 78 | + |
| 79 | +↭-sym : as ↭ bs → bs ↭ as |
| 80 | +↭-sym [] = [] |
| 81 | +↭-sym (a≈b ∷ as↭bs) = ≈-sym a≈b ∷ ↭-sym as↭bs |
| 82 | +↭-sym (as↭b∷cs ⋎ a∷cs↭bs) = ↭-sym a∷cs↭bs ⋎ ↭-sym as↭b∷cs |
| 83 | + |
| 84 | +≋∘↭⇒↭ : as ≋ bs → bs ↭ cs → as ↭ cs |
| 85 | +≋∘↭⇒↭ [] [] = [] |
| 86 | +≋∘↭⇒↭ (a≈b ∷ as≋bs) (b≈c ∷ bs↭cs) = ≈-trans a≈b b≈c ∷ ≋∘↭⇒↭ as≋bs bs↭cs |
| 87 | +≋∘↭⇒↭ (a≈b ∷ as≋bs) (bs↭c∷ds ⋎ b∷ds↭cs) = |
| 88 | + ≋∘↭⇒↭ as≋bs bs↭c∷ds ⋎ ≋∘↭⇒↭ (a≈b ∷ ≋-refl) b∷ds↭cs |
| 89 | + |
| 90 | +↭∘≋⇒↭ : as ↭ bs → bs ≋ cs → as ↭ cs |
| 91 | +↭∘≋⇒↭ [] [] = [] |
| 92 | +↭∘≋⇒↭ (a≈b ∷ as↭bs) (b≈c ∷ bs≋cs) = ≈-trans a≈b b≈c ∷ ↭∘≋⇒↭ as↭bs bs≋cs |
| 93 | +↭∘≋⇒↭ (as↭b∷cs ⋎ a∷cs↭bs) (b≈d ∷ bs≋ds) = |
| 94 | + ↭∘≋⇒↭ as↭b∷cs (b≈d ∷ ≋-refl) ⋎ ↭∘≋⇒↭ a∷cs↭bs bs≋ds |
| 95 | + |
| 96 | +↭-length : as ↭ bs → length as ≡ length bs |
| 97 | +↭-length [] = ≡.refl |
| 98 | +↭-length (a≈b ∷ as↭bs) = ≡.cong suc (↭-length as↭bs) |
| 99 | +↭-length (as↭b∷cs ⋎ a∷cs↭bs) = ≡.cong suc (≡.trans (↭-length as↭b∷cs) (↭-length a∷cs↭bs)) |
| 100 | + |
| 101 | +↭-trans : as ↭ bs → bs ↭ cs → as ↭ cs |
| 102 | +↭-trans = lemma ≡.refl |
| 103 | + where |
| 104 | + lemma : n ≡ length bs → as ↭ bs → bs ↭ cs → as ↭ cs |
| 105 | + |
| 106 | +-- easy base case for bs = [], eq: 0 ≡ 0 |
| 107 | + lemma _ [] [] = [] |
| 108 | + |
| 109 | +-- fiddly step case for bs = b ∷ bs, where eq : suc n ≡ suc (length bs) |
| 110 | +-- hence suc-injective eq : n ≡ length bs |
| 111 | + |
| 112 | + lemma {n = suc n} eq (a≈b ∷ as↭bs) (b≈c ∷ bs↭cs) |
| 113 | + = ≈-trans a≈b b≈c ∷ lemma (suc-injective eq) as↭bs bs↭cs |
| 114 | + |
| 115 | + lemma {n = suc n} eq (a≈b ∷ as↭bs) (bs↭c∷ys ⋎ b∷ys↭cs) |
| 116 | + = ≋∘↭⇒↭ (a≈b ∷ ≋-refl) (lemma (suc-injective eq) as↭bs bs↭c∷ys ⋎ b∷ys↭cs) |
| 117 | + |
| 118 | + lemma {n = suc n} eq (as↭b∷xs ⋎ a∷xs↭bs) (a≈b ∷ bs↭cs) |
| 119 | + = ↭∘≋⇒↭ (as↭b∷xs ⋎ lemma (suc-injective eq) a∷xs↭bs bs↭cs) (a≈b ∷ ≋-refl) |
| 120 | + |
| 121 | + lemma {n = suc n} {bs = b ∷ bs} {as = a ∷ as} {cs = c ∷ cs} eq |
| 122 | + (as↭b∷xs ⋎[ xs ] a∷xs↭bs) (bs↭c∷ys ⋎[ ys ] b∷ys↭cs) = a∷as↭c∷cs |
| 123 | + where |
| 124 | + n≡∣bs∣ : n ≡ length bs |
| 125 | + n≡∣bs∣ = suc-injective eq |
| 126 | + |
| 127 | + n≡∣b∷xs∣ : n ≡ length (b ∷ xs) |
| 128 | + n≡∣b∷xs∣ = ≡.trans n≡∣bs∣ (≡.sym (↭-length a∷xs↭bs)) |
| 129 | + |
| 130 | + n≡∣b∷ys∣ : n ≡ length (b ∷ ys) |
| 131 | + n≡∣b∷ys∣ = ≡.trans n≡∣bs∣ (↭-length bs↭c∷ys) |
| 132 | + |
| 133 | + a∷as↭c∷cs : a ∷ as ↭ c ∷ cs |
| 134 | + a∷as↭c∷cs with lemma n≡∣bs∣ a∷xs↭bs bs↭c∷ys |
| 135 | + ... | a≈c ∷ xs↭ys = a≈c ∷ as↭cs |
| 136 | + where |
| 137 | + as↭cs : as ↭ cs |
| 138 | + as↭cs = lemma n≡∣b∷xs∣ as↭b∷xs |
| 139 | + (lemma n≡∣b∷ys∣ (b ≡∷ xs↭ys) b∷ys↭cs) |
| 140 | + ... | xs↭c∷zs ⋎[ zs ] a∷zs↭ys |
| 141 | + = lemma n≡∣b∷xs∣ as↭b∷xs b∷xs↭c∷b∷zs |
| 142 | + ⋎[ b ∷ zs ] |
| 143 | + lemma n≡∣b∷ys∣ a∷b∷zs↭b∷ys b∷ys↭cs |
| 144 | + where |
| 145 | + b∷zs↭b∷zs : b ∷ zs ↭ b ∷ zs |
| 146 | + b∷zs↭b∷zs = ↭-refl (b ∷ zs) |
| 147 | + b∷xs↭c∷b∷zs : b ∷ xs ↭ c ∷ (b ∷ zs) |
| 148 | + b∷xs↭c∷b∷zs = xs↭c∷zs ⋎[ zs ] b∷zs↭b∷zs |
| 149 | + a∷b∷zs↭b∷ys : a ∷ (b ∷ zs) ↭ b ∷ ys |
| 150 | + a∷b∷zs↭b∷ys = b∷zs↭b∷zs ⋎[ zs ] a∷zs↭ys |
0 commit comments