From 2268a4b1feab1b3cd3aa219cd3a1ab442d19cabd Mon Sep 17 00:00:00 2001 From: Calin Tataru Date: Thu, 18 Jun 2020 19:17:08 +0100 Subject: [PATCH 1/6] Add more operations to Data.Vec.Functional --- src/Data/Fin/Base.agda | 15 ++++++++++ src/Data/Vec/Functional.agda | 56 ++++++++++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/Data/Fin/Base.agda b/src/Data/Fin/Base.agda index a660ef658b..81130fd427 100644 --- a/src/Data/Fin/Base.agda +++ b/src/Data/Fin/Base.agda @@ -15,6 +15,7 @@ module Data.Fin.Base where open import Data.Empty using (⊥-elim) open import Data.Nat.Base as ℕ using (ℕ; zero; suc; z≤n; s≤s) open import Data.Nat.Properties.Core using (≤-pred) +open import Data.Product as Product using (_×_; _,_) open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂) open import Function.Base using (id; _∘_; _on_) open import Level using () renaming (zero to ℓ₀) @@ -130,6 +131,14 @@ splitAt zero i = inj₂ i splitAt (suc m) zero = inj₁ zero splitAt (suc m) (suc i) = Sum.map suc id (splitAt m i) +-- group n k "i" = "i / k" , "i % k" +-- This is dual to group from Data.Vec. + +group : ∀ n k → Fin (n ℕ.* k) → Fin k × Fin n +group (suc n) k i with splitAt k i +... | inj₁ j = j , zero +... | inj₂ j = Product.map id suc (group n k j) + ------------------------------------------------------------------------ -- Operations @@ -195,6 +204,12 @@ pred : ∀ {n} → Fin n → Fin n pred zero = zero pred (suc i) = inject₁ i +-- opposite "i" = "n - i" (i.e. the additive inverse). + +opposite : ∀ {n} → Fin n → Fin n +opposite {suc n} zero = fromℕ n +opposite {suc n} (suc i) = inject₁ (opposite i) + -- The function f(i,j) = if j>i then j-1 else j -- This is a variant of the thick function from Conor -- McBride's "First-order unification by structural recursion". diff --git a/src/Data/Vec/Functional.agda b/src/Data/Vec/Functional.agda index 1bc0eef9f5..d1ef04a067 100644 --- a/src/Data/Vec/Functional.agda +++ b/src/Data/Vec/Functional.agda @@ -15,10 +15,10 @@ module Data.Vec.Functional where -open import Data.Fin.Base using (Fin; zero; suc; splitAt; punchIn) +open import Data.Fin.Base open import Data.List.Base as L using (List) -open import Data.Nat.Base using (ℕ; zero; suc; _+_) -open import Data.Product using (Σ; ∃; _×_; _,_; proj₁; proj₂) +open import Data.Nat.Base as ℕ using (ℕ; zero; suc) +open import Data.Product using (Σ; ∃; _×_; _,_; proj₁; proj₂; uncurry) open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_]) open import Data.Vec.Base as V using (Vec) open import Function @@ -26,6 +26,7 @@ open import Level using (Level) infixr 5 _∷_ _++_ infixl 4 _⊛_ +infixl 1 _>>=_ private variable @@ -56,7 +57,7 @@ fromList : ∀ (xs : List A) → Vector A (L.length xs) fromList = L.lookup ------------------------------------------------------------------------ --- Construction and deconstruction +-- Basic operations [] : Vector A zero [] () @@ -65,6 +66,9 @@ _∷_ : ∀ {n} → A → Vector A n → Vector A (suc n) (x ∷ xs) zero = x (x ∷ xs) (suc i) = xs i +length : ∀ {n} → Vector A n → ℕ +length {n = n} _ = n + head : ∀ {n} → Vector A (suc n) → A head xs = xs zero @@ -77,18 +81,33 @@ uncons xs = head xs , tail xs replicate : ∀ {n} → A → Vector A n replicate = const +insert : ∀ {n} → Vector A n → Fin (suc n) → A → Vector A (suc n) +insert {n = n} xs zero v zero = v +insert {n = n} xs zero v (suc j) = xs j +insert {n = suc n} xs (suc i) v zero = head xs +insert {n = suc n} xs (suc i) v (suc j) = insert (tail xs) i v j + remove : ∀ {n} → Fin (suc n) → Vector A (suc n) → Vector A n remove i t = t ∘ punchIn i +updateAt : ∀ {n} → Fin n → (A → A) → Vector A n → Vector A n +updateAt {n = suc n} zero f xs zero = f (head xs) +updateAt {n = suc n} zero f xs (suc j) = xs (suc j) +updateAt {n = suc n} (suc i) f xs zero = head xs +updateAt {n = suc n} (suc i) f xs (suc j) = updateAt i f (tail xs) j + ------------------------------------------------------------------------ -- Transformations map : (A → B) → ∀ {n} → Vector A n → Vector B n map f xs = f ∘ xs -_++_ : ∀ {m n} → Vector A m → Vector A n → Vector A (m + n) +_++_ : ∀ {m n} → Vector A m → Vector A n → Vector A (m ℕ.+ n) _++_ {m = m} xs ys i = [ xs , ys ] (splitAt m i) +concat : ∀ {m n} → Vector (Vector A m) n → Vector A (n ℕ.* m) +concat {m = m} {n = n} xss = uncurry (flip xss) ∘ group n m + foldr : (A → B → B) → B → ∀ {n} → Vector A n → B foldr f z {n = zero} xs = z foldr f z {n = suc n} xs = f (head xs) (foldr f z (tail xs)) @@ -103,8 +122,35 @@ rearrange r xs = xs ∘ r _⊛_ : ∀ {n} → Vector (A → B) n → Vector A n → Vector B n _⊛_ = _ˢ_ +_>>=_ : ∀ {m n} → Vector A m → (A → Vector B n) → Vector B (m ℕ.* n) +xs >>= f = concat (map f xs) + zipWith : (A → B → C) → ∀ {n} → Vector A n → Vector B n → Vector C n zipWith f xs ys i = f (xs i) (ys i) +unzipWith : ∀ {n} → (A → B × C) → Vector A n → Vector B n × Vector C n +unzipWith f xs = proj₁ ∘ f ∘ xs , proj₂ ∘ f ∘ xs + zip : ∀ {n} → Vector A n → Vector B n → Vector (A × B) n zip = zipWith _,_ + +unzip : ∀ {n} → Vector (A × B) n → Vector A n × Vector B n +unzip = unzipWith id + +take : ∀ m {n} → Vector A (m ℕ.+ n) → Vector A m +take _ {n = n} xs = xs ∘ inject+ n + +drop : ∀ m {n} → Vector A (m ℕ.+ n) → Vector A n +drop m xs = xs ∘ raise m + +reverse : ∀ {n} → Vector A n → Vector A n +reverse xs = xs ∘ opposite + +init : ∀ {n} → Vector A (suc n) → Vector A n +init xs = xs ∘ inject₁ + +last : ∀ {n} → Vector A (suc n) → A +last {n = n} xs = xs (fromℕ n) + +transpose : ∀ {m n} → Vector (Vector A n) m → Vector (Vector A m) n +transpose = flip From ce35aea36b06d98170ae7ec9074e2d38c067bfc6 Mon Sep 17 00:00:00 2001 From: Calin Tataru Date: Fri, 19 Jun 2020 15:31:48 +0100 Subject: [PATCH 2/6] Add Data.Vec.Functional.Properties --- src/Data/Fin/Properties.agda | 13 +- src/Data/Vec/Functional/Properties.agda | 265 ++++++++++++++++++++++++ 2 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 src/Data/Vec/Functional/Properties.agda diff --git a/src/Data/Fin/Properties.agda b/src/Data/Fin/Properties.agda index 96d64ef6d3..6ba04d604d 100644 --- a/src/Data/Fin/Properties.agda +++ b/src/Data/Fin/Properties.agda @@ -19,7 +19,7 @@ open import Data.Nat.Base as ℕ using (ℕ; zero; suc; s≤s; z≤n; _∸_) import Data.Nat.Properties as ℕₚ open import Data.Unit using (tt) open import Data.Product using (∃; ∃₂; ∄; _×_; _,_; map; proj₁; uncurry; <_,_>) -open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_]) +open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]) open import Data.Sum.Properties using ([,]-map-commute; [,]-∘-distr) open import Function.Base using (_∘_; id; _$_) open import Function.Equivalence using (_⇔_; equivalence) @@ -436,6 +436,17 @@ inject+-raise-splitAt (suc m) n (suc i) = begin suc i ∎ where open ≡-Reasoning +-- splitAt "m" "i" ≡ inj₁ "i" if i < m + +splitAt-< : ∀ m {n} i → (i Date: Fri, 19 Jun 2020 15:43:50 +0100 Subject: [PATCH 3/6] Update changelog --- CHANGELOG.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08d4aaab36..9051f92521 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -148,12 +148,18 @@ New modules ```agda Function.Properties.Inverse Function.Properties.Equivalence + ``` * Indexed nullary relations/sets: ``` Relation.Nullary.Indexed ``` +* Properties for functional vectors: + ``` + Data.Vec.Functional.Properties + ``` + Other major changes ------------------- @@ -378,6 +384,36 @@ Other minor additions _⇔_ : REL A B ℓ₁ → REL A B ℓ₂ → Set _ ``` +* Added new functions to `Data.Fin.Base`: + ```agda + group : ∀ n k → Fin (n ℕ.* k) → Fin k × Fin n + opposite : ∀ {n} → Fin n → Fin n + ``` + +* Added new proofs to `Data.Fin.Properties`: + ```agda + splitAt-< : ∀ m {n} i → (i>=_ : ∀ {m n} → Vector A m → (A → Vector B n) → Vector B (m ℕ.* n) + unzipWith : ∀ {n} → (A → B × C) → Vector A n → Vector B n × Vector C n + unzip : ∀ {n} → Vector (A × B) n → Vector A n × Vector B n + take : ∀ m {n} → Vector A (m ℕ.+ n) → Vector A m + drop : ∀ m {n} → Vector A (m ℕ.+ n) → Vector A n + reverse : ∀ {n} → Vector A n → Vector A n + init : ∀ {n} → Vector A (suc n) → Vector A n + last : ∀ {n} → Vector A (suc n) → A + transpose : ∀ {m n} → Vector (Vector A n) m → Vector (Vector A m) n + ``` + Refactorings ------------ From d144c1edb34877ff23a1a5563e05b6e642382404 Mon Sep 17 00:00:00 2001 From: Calin Tataru Date: Sun, 21 Jun 2020 19:06:54 +0100 Subject: [PATCH 4/6] Rename `group` to `quotRem` --- CHANGELOG.md | 2 +- src/Data/Fin/Base.agda | 8 ++++---- src/Data/Vec/Functional.agda | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9051f92521..4c73edc510 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -386,7 +386,7 @@ Other minor additions * Added new functions to `Data.Fin.Base`: ```agda - group : ∀ n k → Fin (n ℕ.* k) → Fin k × Fin n + quotRem : ∀ {n} k → Fin (n ℕ.* k) → Fin k × Fin n opposite : ∀ {n} → Fin n → Fin n ``` diff --git a/src/Data/Fin/Base.agda b/src/Data/Fin/Base.agda index 81130fd427..142179ddce 100644 --- a/src/Data/Fin/Base.agda +++ b/src/Data/Fin/Base.agda @@ -131,13 +131,13 @@ splitAt zero i = inj₂ i splitAt (suc m) zero = inj₁ zero splitAt (suc m) (suc i) = Sum.map suc id (splitAt m i) --- group n k "i" = "i / k" , "i % k" +-- quotRem k "i" = "i % k" , "i / k" -- This is dual to group from Data.Vec. -group : ∀ n k → Fin (n ℕ.* k) → Fin k × Fin n -group (suc n) k i with splitAt k i +quotRem : ∀ {n} k → Fin (n ℕ.* k) → Fin k × Fin n +quotRem {suc n} k i with splitAt k i ... | inj₁ j = j , zero -... | inj₂ j = Product.map id suc (group n k j) +... | inj₂ j = Product.map id suc (quotRem {n} k j) ------------------------------------------------------------------------ -- Operations diff --git a/src/Data/Vec/Functional.agda b/src/Data/Vec/Functional.agda index d1ef04a067..b0398c1fa3 100644 --- a/src/Data/Vec/Functional.agda +++ b/src/Data/Vec/Functional.agda @@ -106,7 +106,7 @@ _++_ : ∀ {m n} → Vector A m → Vector A n → Vector A (m ℕ.+ n) _++_ {m = m} xs ys i = [ xs , ys ] (splitAt m i) concat : ∀ {m n} → Vector (Vector A m) n → Vector A (n ℕ.* m) -concat {m = m} {n = n} xss = uncurry (flip xss) ∘ group n m +concat {m = m} xss i = uncurry (flip xss) (quotRem m i) foldr : (A → B → B) → B → ∀ {n} → Vector A n → B foldr f z {n = zero} xs = z From 0f0cbca023ab9ec57e19c3ac86fd5811239409f5 Mon Sep 17 00:00:00 2001 From: Calin Tataru Date: Sun, 21 Jun 2020 19:08:57 +0100 Subject: [PATCH 5/6] =?UTF-8?q?Use=20Data.Product.map=E2=82=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Data/Fin/Base.agda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Fin/Base.agda b/src/Data/Fin/Base.agda index 142179ddce..681a8b8463 100644 --- a/src/Data/Fin/Base.agda +++ b/src/Data/Fin/Base.agda @@ -137,7 +137,7 @@ splitAt (suc m) (suc i) = Sum.map suc id (splitAt m i) quotRem : ∀ {n} k → Fin (n ℕ.* k) → Fin k × Fin n quotRem {suc n} k i with splitAt k i ... | inj₁ j = j , zero -... | inj₂ j = Product.map id suc (quotRem {n} k j) +... | inj₂ j = Product.map₂ suc (quotRem {n} k j) ------------------------------------------------------------------------ -- Operations From c075326ad6e94bf07174bb7740749adcd083588d Mon Sep 17 00:00:00 2001 From: Calin Tataru Date: Mon, 22 Jun 2020 17:48:46 +0100 Subject: [PATCH 6/6] Address comments --- src/Data/Vec/Functional/Properties.agda | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Data/Vec/Functional/Properties.agda b/src/Data/Vec/Functional/Properties.agda index 707beb5f21..a868739fe9 100644 --- a/src/Data/Vec/Functional/Properties.agda +++ b/src/Data/Vec/Functional/Properties.agda @@ -40,18 +40,18 @@ private module _ {n} {xs ys : Vector A (suc n)} where - ∷-cong : head xs ≡ head ys × tail xs ≗ tail ys → xs ≗ ys - ∷-cong (eq , _) zero = eq - ∷-cong (_ , eq) (suc i) = eq i + ∷-cong : head xs ≡ head ys → tail xs ≗ tail ys → xs ≗ ys + ∷-cong eq _ zero = eq + ∷-cong _ eq (suc i) = eq i ∷-injective : xs ≗ ys → head xs ≡ head ys × tail xs ≗ tail ys ∷-injective eq = eq zero , eq ∘ suc -≗-dec : B.Decidable {A = A} _≡_ → +≗-dec : B.DecidableEquality A → ∀ {n} → B.Decidable {A = Vector A n} _≗_ ≗-dec _≟_ {zero} xs ys = yes λ () ≗-dec _≟_ {suc n} xs ys = - map′ ∷-cong ∷-injective + map′ (Product.uncurry ∷-cong) ∷-injective (head xs ≟ head ys ×-dec ≗-dec _≟_ (tail xs) (tail ys)) ------------------------------------------------------------------------