diff --git a/CHANGELOG.md b/CHANGELOG.md index 381bd0eb9c..0459c45466 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -243,17 +243,23 @@ Additions to existing modules ```agda _≰_ : Rel (Fin n) 0ℓ _≮_ : Rel (Fin n) 0ℓ + lower : ∀ (i : Fin m) → .(toℕ i ℕ.< n) → Fin n ``` * In `Data.Fin.Permutation`: ```agda cast-id : .(m ≡ n) → Permutation m n - swap : Permutation m n → Permutation (suc (suc m)) (suc (suc n)) + inject!-injective : swap : Permutation m n → Permutation (suc (suc m)) (suc (suc n)) ``` * In `Data.Fin.Properties`: ```agda - cast-involutive : .(eq₁ : m ≡ n) .(eq₂ : n ≡ m) → ∀ k → cast eq₁ (cast eq₂ k) ≡ k + cast-involutive : .(eq₁ : m ≡ n) .(eq₂ : n ≡ m) → ∀ k → cast eq₁ (cast eq₂ k) ≡ k + inject!-injective : Injective _≡_ _≡_ inject! + inject!-< : (k : Fin′ i) → inject! k < i + lower-injective : lower i i i≰fj + ------------------------------------------------------------------------ -- Effectful ------------------------------------------------------------------------ diff --git a/src/Data/List/Relation/Unary/Linked.agda b/src/Data/List/Relation/Unary/Linked.agda index dc1b7fb87d..6717adebd0 100644 --- a/src/Data/List/Relation/Unary/Linked.agda +++ b/src/Data/List/Relation/Unary/Linked.agda @@ -11,6 +11,7 @@ module Data.List.Relation.Unary.Linked {a} {A : Set a} where open import Data.List.Base as List using (List; []; _∷_) open import Data.List.Relation.Unary.All as All using (All; []; _∷_) open import Data.Product.Base as Prod using (_,_; _×_; uncurry; <_,_>) +open import Data.Fin.Base using (zero; suc) open import Data.Maybe.Base using (just) open import Data.Maybe.Relation.Binary.Connected using (Connected; just; just-nothing) @@ -26,6 +27,7 @@ open import Relation.Nullary.Decidable using (yes; no; map′; _×-dec_) private variable p q r ℓ : Level + R : Rel A ℓ ------------------------------------------------------------------------ -- Definition @@ -92,6 +94,14 @@ module _ {P : Rel A p} {Q : Rel A q} where unzip : Linked (P ∩ᵇ Q) ⊆ Linked P ∩ᵘ Linked Q unzip = unzipWith id +lookup : ∀ {x xs} → Transitive R → Linked R xs → + Connected R (just x) (List.head xs) → + ∀ i → R x (List.lookup xs i) +lookup trans [-] (just Rvx) zero = Rvx +lookup trans (x ∷ xs↗) (just Rvx) zero = Rvx +lookup trans (x ∷ xs↗) (just Rvx) (suc i) = + lookup trans xs↗ (just (trans Rvx x)) i + ------------------------------------------------------------------------ -- Properties of predicates preserved by Linked diff --git a/src/Data/List/Relation/Unary/Sorted/TotalOrder/Properties.agda b/src/Data/List/Relation/Unary/Sorted/TotalOrder/Properties.agda index c8c4210ed6..916bcba823 100644 --- a/src/Data/List/Relation/Unary/Sorted/TotalOrder/Properties.agda +++ b/src/Data/List/Relation/Unary/Sorted/TotalOrder/Properties.agda @@ -14,20 +14,34 @@ open import Data.List.Relation.Unary.AllPairs using (AllPairs) open import Data.List.Relation.Unary.Linked as Linked using (Linked; []; [-]; _∷_; _∷′_; head′; tail) import Data.List.Relation.Unary.Linked.Properties as Linked +import Data.List.Relation.Binary.Equality.Setoid as Equality import Data.List.Relation.Binary.Sublist.Setoid as Sublist import Data.List.Relation.Binary.Sublist.Setoid.Properties as SublistProperties -open import Data.List.Relation.Unary.Sorted.TotalOrder hiding (head) - +import Data.List.Relation.Binary.Permutation.Setoid as Permutation +import Data.List.Relation.Binary.Permutation.Setoid.Properties as PermutationProperties +import Data.List.Relation.Binary.Pointwise as Pointwise +open import Data.List.Relation.Unary.Sorted.TotalOrder as Sorted hiding (head) + +open import Data.Fin.Base as Fin hiding (_<_; _≤_) +import Data.Fin.Properties as Fin +open import Data.Fin.Permutation +open import Data.Product using (_,_) open import Data.Maybe.Base using (just; nothing) open import Data.Maybe.Relation.Binary.Connected using (Connected; just) -open import Data.Nat.Base using (ℕ; zero; suc; _<_) - +open import Data.Nat.Base as ℕ using (ℕ; z≤n; s≤s; zero; suc) +import Data.Nat.Properties as ℕ +open import Function.Base using (_∘_; const) +open import Function.Bundles using (Inverse) +open import Function.Consequences.Propositional using (inverseʳ⇒injective) open import Level using (Level) -open import Relation.Binary.Core using (_Preserves_⟶_) +open import Relation.Binary.Core using (_Preserves_⟶_; Rel) open import Relation.Binary.Bundles using (TotalOrder; DecTotalOrder; Preorder) import Relation.Binary.Properties.TotalOrder as TotalOrderProperties +import Relation.Binary.Reasoning.PartialOrder as PosetReasoning open import Relation.Unary using (Pred; Decidable) +open import Relation.Nullary using (contradiction) open import Relation.Nullary.Decidable using (yes; no) +open import Relation.Binary.PropositionalEquality as P using (_≡_) private variable @@ -80,7 +94,7 @@ module _ (O : TotalOrder a ℓ₁ ℓ₂) where module _ (O : TotalOrder a ℓ₁ ℓ₂) where open TotalOrder O - applyUpTo⁺₁ : ∀ f n → (∀ {i} → suc i < n → f i ≤ f (suc i)) → + applyUpTo⁺₁ : ∀ f n → (∀ {i} → suc i ℕ.< n → f i ≤ f (suc i)) → Sorted O (applyUpTo f n) applyUpTo⁺₁ = Linked.applyUpTo⁺₁ @@ -94,7 +108,7 @@ module _ (O : TotalOrder a ℓ₁ ℓ₂) where module _ (O : TotalOrder a ℓ₁ ℓ₂) where open TotalOrder O - applyDownFrom⁺₁ : ∀ f n → (∀ {i} → suc i < n → f (suc i) ≤ f i) → + applyDownFrom⁺₁ : ∀ f n → (∀ {i} → suc i ℕ.< n → f (suc i) ≤ f i) → Sorted O (applyDownFrom f n) applyDownFrom⁺₁ = Linked.applyDownFrom⁺₁ @@ -150,3 +164,48 @@ module _ (O : TotalOrder a ℓ₁ ℓ₂) {P : Pred _ p} (P? : Decidable P) wher filter⁺ : ∀ {xs} → Sorted O xs → Sorted O (filter P? xs) filter⁺ = Linked.filter⁺ P? trans + +------------------------------------------------------------------------ +-- lookup + +module _ (O : TotalOrder a ℓ₁ ℓ₂) where + open TotalOrder O + + lookup-mono-≤ : ∀ {xs} → Sorted O xs → + ∀ {i j} → i Fin.≤ j → lookup xs i ≤ lookup xs j + lookup-mono-≤ {x ∷ xs} xs↗ {zero} {zero} z≤n = refl + lookup-mono-≤ {x ∷ xs} xs↗ {zero} {suc j} z≤n = Linked.lookup trans xs↗ (just refl) (suc j) + lookup-mono-≤ {x ∷ xs} xs↗ {suc i} {suc j} (s≤s i≤j) = lookup-mono-≤ (Sorted.tail O {y = x} xs↗) i≤j + +------------------------------------------------------------------------ +-- Relationship to binary relations +------------------------------------------------------------------------ + +module _ (O : TotalOrder a ℓ₁ ℓ₂) where + open TotalOrder O + open Equality Eq.setoid + open Permutation Eq.setoid hiding (refl; trans) + open PermutationProperties Eq.setoid + open PosetReasoning poset + + -- Proof that any two sorted lists that are a permutation of each + -- other are pointwise equal + ↗↭↗⇒≋ : ∀ {xs ys} → Sorted O xs → Sorted O ys → xs ↭ ys → xs ≋ ys + ↗↭↗⇒≋ {xs} {ys} xs↗ ys↗ xs↭ys = Pointwise.lookup⁻ + (xs↭ys⇒|xs|≡|ys| xs↭ys) + (λ i≡j → antisym + (↗↭↗⇒≤ (↭-sym xs↭ys) ys↗ xs↗ (P.sym i≡j)) + (↗↭↗⇒≤ xs↭ys xs↗ ys↗ i≡j)) + where + ↗↭↗⇒≤ : ∀ {xs ys} + (xs↭ys : xs ↭ ys) → + Sorted O xs → Sorted O ys → + ∀ {i j} → toℕ i ≡ toℕ j → + lookup ys j ≤ lookup xs i + ↗↭↗⇒≤ {xs} {ys} xs↭ys xs↗ ys↗ {i} {j} i≡j + with Fin.injective⇒existsPivot _ (inverseʳ⇒injective _ (Inverse.inverseʳ (toFin xs↭ys))) i + ... | (k , k≤i , i≤π[k]) = begin + lookup ys j ≤⟨ lookup-mono-≤ O ys↗ (P.subst (ℕ._≤ _) i≡j i≤π[k]) ⟩ + lookup ys (toFin xs↭ys ⟨$⟩ʳ k) ≈⟨ toFin-lookup xs↭ys k ⟨ + lookup xs k ≤⟨ lookup-mono-≤ O xs↗ k≤i ⟩ + lookup xs i ∎ diff --git a/src/Data/List/Sort/Base.agda b/src/Data/List/Sort/Base.agda index 018f93fd2e..1c0438207e 100644 --- a/src/Data/List/Sort/Base.agda +++ b/src/Data/List/Sort/Base.agda @@ -13,11 +13,14 @@ module Data.List.Sort.Base where open import Data.List.Base using (List) -open import Data.List.Relation.Binary.Permutation.Propositional using (_↭_) +open import Data.List.Relation.Binary.Permutation.Propositional + using (_↭_; ↭⇒↭ₛ) +import Data.List.Relation.Binary.Permutation.Homogeneous as Homo open import Level using (_⊔_) open TotalOrder totalOrder renaming (Carrier to A) open import Data.List.Relation.Unary.Sorted.TotalOrder totalOrder +import Data.List.Relation.Binary.Permutation.Setoid Eq.setoid as S ------------------------------------------------------------------------ -- Definition of a sorting algorithm @@ -26,8 +29,17 @@ record SortingAlgorithm : Set (a ⊔ ℓ₁ ⊔ ℓ₂) where field sort : List A → List A - -- The output of `sort` is a permutation of the input + -- The output of `sort` is a propositional permutation of the input. + -- Note that the choice of using a propositional equality here + -- is very deliberate. A sorting algorithm should only be capable + -- of altering the order of the elements of the list, and should not + -- be capable of altering the elements themselves in any way. sort-↭ : ∀ xs → sort xs ↭ xs -- The output of `sort` is sorted. sort-↗ : ∀ xs → Sorted (sort xs) + + -- Lists are also permutations under the setoid versions of + -- permutation. + sort-↭ₛ : ∀ xs → sort xs S.↭ xs + sort-↭ₛ xs = Homo.map Eq.reflexive (↭⇒↭ₛ (sort-↭ xs))