|
| 1 | +------------------------------------------------------------------------ |
| 2 | +-- The Agda standard library |
| 3 | +-- |
| 4 | +-- Lexicographic ordering of same-length vectors |
| 5 | +------------------------------------------------------------------------ |
| 6 | + |
| 7 | +{-# OPTIONS --without-K --safe #-} |
| 8 | + |
| 9 | +module Data.Vec.Relation.Binary.Lex.Core {a} {A : Set a} where |
| 10 | + |
| 11 | +open import Data.Empty |
| 12 | +open import Data.Nat using (ℕ; suc) |
| 13 | +import Data.Nat.Properties as ℕ |
| 14 | +open import Data.Product using (_×_; _,_; proj₁; proj₂; uncurry) |
| 15 | +open import Data.Sum using (_⊎_; inj₁; inj₂; [_,_]) |
| 16 | +open import Data.Vec using (Vec; []; _∷_) |
| 17 | +open import Data.Vec.Relation.Binary.Pointwise.Inductive using (Pointwise; []; _∷_) |
| 18 | +open import Function.Base using (flip) |
| 19 | +open import Function.Equivalence using (_⇔_; equivalence) |
| 20 | +open import Relation.Binary hiding (_⇔_) |
| 21 | +open import Relation.Binary.PropositionalEquality as P |
| 22 | + using (_≡_; refl; cong) |
| 23 | +open import Relation.Nullary as Nullary hiding (Irrelevant) |
| 24 | +import Relation.Nullary.Decidable as Dec |
| 25 | +open import Relation.Nullary.Product using (_×-dec_) |
| 26 | +open import Relation.Nullary.Sum using (_⊎-dec_) |
| 27 | +open import Relation.Nullary.Negation |
| 28 | +open import Level using (Level; _⊔_) |
| 29 | + |
| 30 | +private |
| 31 | + variable |
| 32 | + ℓ₁ ℓ₂ : Level |
| 33 | + |
| 34 | +------------------------------------------------------------------------ |
| 35 | +-- Definition |
| 36 | + |
| 37 | +-- The lexicographic ordering itself can be either strict or non-strict, |
| 38 | +-- depending on whether type P is inhabited. |
| 39 | + |
| 40 | +data Lex {A : Set a} (P : Set) (_≈_ : Rel A ℓ₁) (_≺_ : Rel A ℓ₂) |
| 41 | + : ∀ {m n} → REL (Vec A m) (Vec A n) (a ⊔ ℓ₁ ⊔ ℓ₂) where |
| 42 | + base : (p : P) → Lex P _≈_ _≺_ [] [] |
| 43 | + this : ∀ {x y m n} {xs : Vec A m} {ys : Vec A n} |
| 44 | + (x≺y : x ≺ y) (m≡n : m ≡ n) → Lex P _≈_ _≺_ (x ∷ xs) (y ∷ ys) |
| 45 | + next : ∀ {x y m n} {xs : Vec A m} {ys : Vec A n} |
| 46 | + (x≈y : x ≈ y) (xs<ys : Lex P _≈_ _≺_ xs ys) → Lex P _≈_ _≺_ (x ∷ xs) (y ∷ ys) |
| 47 | + |
| 48 | +------------------------------------------------------------------------ |
| 49 | +-- Operations |
| 50 | + |
| 51 | +map-P : ∀ {_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂} {P₁ P₂ : Set} → (P₁ → P₂) → |
| 52 | + ∀ {m n} {xs : Vec A m} {ys : Vec A n} → |
| 53 | + Lex P₁ _≈_ _≺_ xs ys → Lex P₂ _≈_ _≺_ xs ys |
| 54 | +map-P f (base p) = base (f p) |
| 55 | +map-P f (this x≺y m≡n) = this x≺y m≡n |
| 56 | +map-P f (next x≈y xs<ys) = next x≈y (map-P f xs<ys) |
| 57 | + |
| 58 | +------------------------------------------------------------------------ |
| 59 | +-- Properties |
| 60 | + |
| 61 | +module _ {P : Set} {_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂} where |
| 62 | + |
| 63 | + length-equal : ∀ {m n} {xs : Vec A m} {ys : Vec A n} → |
| 64 | + Lex P _≈_ _≺_ xs ys → m ≡ n |
| 65 | + length-equal (base _) = refl |
| 66 | + length-equal (this x≺y m≡n) = cong suc m≡n |
| 67 | + length-equal (next x≈y xs<ys) = cong suc (length-equal xs<ys) |
| 68 | + |
| 69 | +module _ {P : Set} {_≈_ : Rel A ℓ₁} {_≺_ : Rel A ℓ₂} where |
| 70 | + |
| 71 | + private |
| 72 | + _≋_ = Pointwise _≈_ |
| 73 | + _<ₗₑₓ_ = Lex P _≈_ _≺_ |
| 74 | + |
| 75 | + ≰-this : ∀ {x y m n} {xs : Vec A m} {ys : Vec A n} → |
| 76 | + ¬ (x ≈ y) → ¬ (x ≺ y) → ¬ (x ∷ xs) <ₗₑₓ (y ∷ ys) |
| 77 | + ≰-this x≉y x≮y (this x≺y m≡n) = contradiction x≺y x≮y |
| 78 | + ≰-this x≉y x≮y (next x≈y xs<ys) = contradiction x≈y x≉y |
| 79 | + |
| 80 | + ≰-next : ∀ {x y m n} {xs : Vec A m} {ys : Vec A n} → |
| 81 | + ¬ (x ≺ y) → ¬ (xs <ₗₑₓ ys) → ¬ (x ∷ xs) <ₗₑₓ (y ∷ ys) |
| 82 | + ≰-next x≮y xs≮ys (this x≺y m≡n) = contradiction x≺y x≮y |
| 83 | + ≰-next x≮y xs≮ys (next x≈y xs<ys) = contradiction xs<ys xs≮ys |
| 84 | + |
| 85 | + P⇔[]<[] : P ⇔ [] <ₗₑₓ [] |
| 86 | + P⇔[]<[] = equivalence base (λ { (base p) → p }) |
| 87 | + |
| 88 | + toSum : ∀ {x y n} {xs ys : Vec A n} → (x ∷ xs) <ₗₑₓ (y ∷ ys) → (x ≺ y ⊎ (x ≈ y × xs <ₗₑₓ ys)) |
| 89 | + toSum (this x≺y m≡n) = inj₁ x≺y |
| 90 | + toSum (next x≈y xs<ys) = inj₂ (x≈y , xs<ys) |
| 91 | + |
| 92 | + ∷<∷-⇔ : ∀ {x y n} {xs ys : Vec A n} → (x ≺ y ⊎ (x ≈ y × xs <ₗₑₓ ys)) ⇔ (x ∷ xs) <ₗₑₓ (y ∷ ys) |
| 93 | + ∷<∷-⇔ = equivalence [ flip this refl , uncurry next ] toSum |
| 94 | + |
| 95 | + module _ (≈-equiv : IsPartialEquivalence _≈_) |
| 96 | + ((≺-respʳ-≈ , ≺-respˡ-≈) : _≺_ Respects₂ _≈_) |
| 97 | + (≺-trans : Transitive _≺_) |
| 98 | + (open IsPartialEquivalence ≈-equiv) |
| 99 | + where |
| 100 | + |
| 101 | + transitive′ : ∀ {m n o P₂} → Trans (Lex P _≈_ _≺_ {m} {n}) (Lex P₂ _≈_ _≺_ {n} {o}) (Lex (P × P₂) _≈_ _≺_) |
| 102 | + transitive′ (base p₁) (base p₂) = base (p₁ , p₂) |
| 103 | + transitive′ (this x≺y m≡n) (this y≺z n≡o) = this (≺-trans x≺y y≺z) (P.trans m≡n n≡o) |
| 104 | + transitive′ (this x≺y m≡n) (next y≈z ys<zs) = this (≺-respʳ-≈ y≈z x≺y) (P.trans m≡n (length-equal ys<zs)) |
| 105 | + transitive′ (next x≈y xs<ys) (this y≺z n≡o) = this (≺-respˡ-≈ (sym x≈y) y≺z) (P.trans (length-equal xs<ys) n≡o) |
| 106 | + transitive′ (next x≈y xs<ys) (next y≈z ys<zs) = next (trans x≈y y≈z) (transitive′ xs<ys ys<zs) |
| 107 | + |
| 108 | + transitive : ∀ {m n o} → Trans (_<ₗₑₓ_ {m} {n}) (_<ₗₑₓ_ {n} {o}) _<ₗₑₓ_ |
| 109 | + transitive xs<ys ys<zs = map-P proj₁ (transitive′ xs<ys ys<zs) |
| 110 | + |
| 111 | + module _ (≈-sym : Symmetric _≈_) (≺-irrefl : Irreflexive _≈_ _≺_) (≺-asym : Asymmetric _≺_) where |
| 112 | + |
| 113 | + antisym : ∀ {n} → Antisymmetric (_≋_ {n}) (_<ₗₑₓ_) |
| 114 | + antisym (base _) (base _) = [] |
| 115 | + antisym (this x≺y m≡n) (this y≺x n≡m) = ⊥-elim (≺-asym x≺y y≺x) |
| 116 | + antisym (this x≺y m≡n) (next y≈x ys<xs) = ⊥-elim (≺-irrefl (≈-sym y≈x) x≺y) |
| 117 | + antisym (next x≈y xs<ys) (this y≺x m≡n) = ⊥-elim (≺-irrefl (≈-sym x≈y) y≺x) |
| 118 | + antisym (next x≈y xs<ys) (next y≈x ys<xs) = x≈y ∷ (antisym xs<ys ys<xs) |
| 119 | + |
| 120 | + module _ (≈-equiv : IsPartialEquivalence _≈_) (open IsPartialEquivalence ≈-equiv) where |
| 121 | + |
| 122 | + respectsˡ : _≺_ Respectsˡ _≈_ → ∀ {m n} → (_<ₗₑₓ_ {m} {n}) Respectsˡ _≋_ |
| 123 | + respectsˡ resp [] (base p) = base p |
| 124 | + respectsˡ resp (x≈y ∷ xs≋ys) (this x≺z m≡n) = this (resp x≈y x≺z) m≡n |
| 125 | + respectsˡ resp (x≈y ∷ xs≋ys) (next x≈z xs<zs) = next (trans (sym x≈y) x≈z) (respectsˡ resp xs≋ys xs<zs) |
| 126 | + |
| 127 | + respectsʳ : _≺_ Respectsʳ _≈_ → ∀ {m n} → (_<ₗₑₓ_ {m} {n}) Respectsʳ _≋_ |
| 128 | + respectsʳ resp [] (base p) = base p |
| 129 | + respectsʳ resp (x≈y ∷ xs≋ys) (this x≺z m≡n) = this (resp x≈y x≺z) m≡n |
| 130 | + respectsʳ resp (x≈y ∷ xs≋ys) (next x≈z xs<zs) = next (trans x≈z x≈y) (respectsʳ resp xs≋ys xs<zs) |
| 131 | + |
| 132 | + respects₂ : _≺_ Respects₂ _≈_ → ∀ {n} → (_<ₗₑₓ_ {n} {n}) Respects₂ _≋_ |
| 133 | + respects₂ (≺-resp-≈ʳ , ≺-resp-≈ˡ) = respectsʳ ≺-resp-≈ʳ , respectsˡ ≺-resp-≈ˡ |
| 134 | + |
| 135 | + module _ (P? : Dec P) (_≈?_ : Decidable _≈_) (_≺?_ : Decidable _≺_) where |
| 136 | + |
| 137 | + decidable : ∀ {m n} → Decidable (_<ₗₑₓ_ {m} {n}) |
| 138 | + decidable {m} {n} xs ys with m Data.Nat.≟ n |
| 139 | + decidable {_} {_} [] [] | yes refl = Dec.map P⇔[]<[] P? |
| 140 | + decidable {_} {_} (x ∷ xs) (y ∷ ys) | yes refl = Dec.map ∷<∷-⇔ ((x ≺? y) ⊎-dec (x ≈? y) ×-dec (decidable xs ys)) |
| 141 | + decidable {_} {_} _ _ | no m≢n = no (λ xs<ys → contradiction (length-equal xs<ys) m≢n) |
| 142 | + |
| 143 | + module _ (P-irrel : Nullary.Irrelevant P) |
| 144 | + (≈-irrel : Irrelevant _≈_) |
| 145 | + (≺-irrel : Irrelevant _≺_) |
| 146 | + (≺-irrefl : Irreflexive _≈_ _≺_) |
| 147 | + where |
| 148 | + |
| 149 | + irrelevant : ∀ {m n} → Irrelevant (_<ₗₑₓ_ {m} {n}) |
| 150 | + irrelevant (base p₁) (base p₂) rewrite P-irrel p₁ p₂ = refl |
| 151 | + irrelevant (this x≺y₁ m≡n₁) (this x≺y₂ m≡n₂) rewrite ≺-irrel x≺y₁ x≺y₂ | ℕ.≡-irrelevant m≡n₁ m≡n₂ = refl |
| 152 | + irrelevant (this x≺y m≡n) (next x≈y xs<ys₂) = contradiction x≺y (≺-irrefl x≈y) |
| 153 | + irrelevant (next x≈y xs<ys₁) (this x≺y m≡n) = contradiction x≺y (≺-irrefl x≈y) |
| 154 | + irrelevant (next x≈y₁ xs<ys₁) (next x≈y₂ xs<ys₂) rewrite ≈-irrel x≈y₁ x≈y₂ | irrelevant xs<ys₁ xs<ys₂ = refl |
| 155 | + |
0 commit comments