Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port reverse lemmas to Data.Vec (fixes #942) #1668

Merged
merged 33 commits into from
Jan 1, 2022
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
045c907
fixing issue 942
jamesmckinna Dec 23, 2021
469f59b
removed some 'using' lemmas
jamesmckinna Dec 23, 2021
f3335f3
Merge branch 'master' of https://github.com/agda/agda-stdlib into iss…
jamesmckinna Dec 23, 2021
c5ddfb7
updated CHANGELOG
jamesmckinna Dec 23, 2021
6b68630
horrendous proofs of heterogeneous Vec equalities
jamesmckinna Dec 27, 2021
85b190f
change argument order/implicit status
jamesmckinna Dec 28, 2021
073ebb0
streamline imports
jamesmckinna Dec 28, 2021
65e7a32
new syntax for equational reasoning; reworked almost all proofs
jamesmckinna Dec 28, 2021
034c787
tidying
jamesmckinna Dec 28, 2021
3ff93b6
updated CHANGELOG; added deprecation warning
jamesmckinna Dec 29, 2021
6f01fde
going through comments on PR#1668
jamesmckinna Dec 29, 2021
7181c79
more going through comments on PR#1668
jamesmckinna Dec 29, 2021
c85745f
adding type synonyms for Vec foldr/l auxiliary functions
jamesmckinna Dec 29, 2021
48e5eb5
fixed many of @MatthewDaggit 's points about PR #1668
jamesmckinna Dec 29, 2021
c7975e7
making argument explicit in
jamesmckinna Dec 29, 2021
971703e
knock-on changes from making argument explicit in
jamesmckinna Dec 29, 2021
2c1bfd7
Foldl/FoldrOp change
jamesmckinna Dec 30, 2021
6632ae5
Foldl/FoldrOp change
jamesmckinna Dec 30, 2021
7e551bd
*-++-commute ↦ *-++
jamesmckinna Dec 30, 2021
b9b537d
regularising names of map-* commutation properties
jamesmckinna Dec 30, 2021
06ada23
fix whitespace
jamesmckinna Dec 30, 2021
469bf1f
fix whitespace
jamesmckinna Dec 30, 2021
8cc0f1b
regularising names of reverse-* commutation properties
jamesmckinna Dec 30, 2021
cab8782
removed `Heterogeneous` for the time being
jamesmckinna Dec 30, 2021
599ab48
implicit argument tweaks
jamesmckinna Dec 30, 2021
fff90e8
misc. tidying up
jamesmckinna Dec 30, 2021
3898aba
added new types and operations in `Vec.Base`
jamesmckinna Dec 30, 2021
8519888
added some of the new lemmas in `Vec.Properties`
jamesmckinna Dec 30, 2021
6ab612d
added the last of the new lemmas in `Vec.Properties`
jamesmckinna Dec 30, 2021
c2734b7
added deprecation warnings in `Vec.Properties`
jamesmckinna Dec 30, 2021
796a412
changed name/deprecation as per issue #465
jamesmckinna Dec 31, 2021
1ab0e0a
some additional properties from `Data.List`
jamesmckinna Dec 31, 2021
40a2260
Renamed foldr0 and foldl0 and minor tidy-up
MatthewDaggitt Jan 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 83 additions & 22 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,31 @@ Deprecated names
zipWith-identityʳ ↦ zipWith-zeroʳ
```

* In `Data.Fin.Base`:
two new, hopefully more memorable, names `↑ˡ` `↑ʳ` for the 'left', resp. 'right' injection of a Fin m into a 'larger' type, `Fin (m + n)`, resp. `Fin (n + m)`, with argument order to reflect the position of the Fin m argument.
```
inject+ ↦ flip _↑ˡ_
raise ↦ _↑ʳ_
```

* In `Data.Fin.Properties`:
```
toℕ-raise ↦ toℕ-↑ʳ
toℕ-inject+ n i ↦ sym (toℕ-↑ˡ i n)
splitAt-inject+ m n i ↦ splitAt-↑ˡ m i n
splitAt-raise ↦ splitAt-↑ʳ
Fin0↔⊥ ↦ 0↔⊥
```

* In `Data.Vec.Properties`:

```
[]≔-++-inject+ ↦ []≔-++-↑ˡ
idIsFold ↦ id-is-foldr
sum-++-commute ↦ sum-++
```
Additionally, `[]≔-++-↑ʳ`, by analogy.

* In `Function.Construct.Composition`:
```
_∘-⟶_ ↦ _⟶-∘_
Expand Down Expand Up @@ -465,28 +490,6 @@ Deprecated names
sym-↔ ↦ ↔-sym
```

* In `Data.Fin.Base`:
two new, hopefully more memorable, names `↑ˡ` `↑ʳ` for the 'left', resp. 'right' injection of a Fin m into a 'larger' type, `Fin (m + n)`, resp. `Fin (n + m)`, with argument order to reflect the position of the Fin m argument.
```
inject+ ↦ flip _↑ˡ_
raise ↦ _↑ʳ_
```

* In `Data.Fin.Properties`:
```
toℕ-raise ↦ toℕ-↑ʳ
toℕ-inject+ n i ↦ sym (toℕ-↑ˡ i n)
splitAt-inject+ m n i ↦ splitAt-↑ˡ m i n
splitAt-raise ↦ splitAt-↑ʳ
Fin0↔⊥ ↦ 0↔⊥
```

* In `Data.Vec.Properties`:
```
[]≔-++-inject+ ↦ []≔-++-↑ˡ
```
Additionally, `[]≔-++-↑ʳ`, by analogy.

* In `Foreign.Haskell.Either` and `Foreign.Haskell.Pair`:
```
toForeign ↦ Foreign.Haskell.Coerce.coerce
Expand Down Expand Up @@ -527,6 +530,11 @@ New modules
Data.Vec.Reflection
```

* A small library for heterogenous equational reasoning on vectors:
```
Data.Vec.Properties.Heterogeneous
```

* Show module for unnormalised rationals:
```
Data.Rational.Unnormalised.Show
Expand Down Expand Up @@ -829,6 +837,9 @@ Other minor changes
```agda
diagonal : ∀ {n} → Vec (Vec A n) n → Vec A n
DiagonalBind._>>=_ : ∀ {n} → Vec A n → (A → Vec B n) → Vec B n
FoldrOp : {a b} (A : Set a) (B : ℕ → Set b) → Set (a ⊔ b)
FoldlOp : {a b} (A : Set a) (B : ℕ → Set b) → Set (a ⊔ b)
_ʳ++_ : ∀ {m n} → Vec A m → Vec A n → Vec A (m + n)
```

* Added new instance in `Data.Vec.Categorical`:
Expand All @@ -843,6 +854,56 @@ Other minor changes
⊛-is->>= : ∀ {n} (fs : Vec (A → B) n) (xs : Vec A n) → (fs ⊛ xs) ≡ (fs DiagonalBind.>>= flip map xs)
transpose-replicate : ∀ {m n} (xs : Vec A m) → transpose (replicate {n = n} xs) ≡ map replicate xs
[]≔-++-↑ʳ : ∀ {m n y} (xs : Vec A m) (ys : Vec A n) i → (xs ++ ys) [ m ↑ʳ i ]≔ y ≡ xs ++ (ys [ i ]≔ y)
map-++ : ∀ (f : A → B) {m} {n} (xs : Vec A m) (ys : Vec A n) →
map f (xs ++ ys) ≡ map f xs ++ map f ys
foldl-universal : ∀ {A : Set a} (B : ℕ → Set b)
(f : FoldlOp A B) {e}
(h : ∀ {c} (C : ℕ → Set c) (g : FoldlOp A C) (e : C zero) →
∀ {n} → Vec A n → C n) →
(∀ {c} {C} {g : FoldlOp A C} e → h {c} C g e [] ≡ e) →
(∀ {c} {C} {g : FoldlOp A C} e → ∀ {n} x →
(h {c} C g e {suc n}) ∘ (x ∷_) ≗ h (C ∘ suc) (λ {n} → g {suc n}) (g e x)) →
∀ {n} → h B f e ≗ foldl B {n} f e
foldl-fusion : ∀ {A : Set a} {B : ℕ → Set b} {C : ℕ → Set c}
(h : ∀ {n} → B n → C n) →
{f : FoldlOp A B} {d : B zero} →
{g : FoldlOp A C} {e : C zero} →
(h d ≡ e) →
(∀ {n} b x → h (f {n} b x) ≡ g (h b) x) →
∀ {n} → h ∘ foldl B {n} f d ≗ foldl C g e
unfold-reverse : ∀ {n} (x : A) xs → reverse (x ∷ xs) ≡ reverse {n = n} xs ∷ʳ x
unfold-ʳ++ : ∀ {m n} {xs : Vec A m} {ys : Vec A n} → xs ʳ++ ys ≡ reverse xs ++ ys
foldl-∷ʳ : ∀ {A : Set a} (B : ℕ → Set b) (f : FoldrOp A B) {e} →
∀ {n} y (ys : Vec A n) → foldl B f e (ys ∷ʳ y) ≡ f (foldl B f e ys) y
foldl-[] : ∀ {A : Set a} (B : ℕ → Set b) (f : FoldlOp A B) {e} → foldl B f e [] ≡ e
foldl-reverse : ∀ {B : ℕ → Set b} {n} (f : FoldlOp A B) e →
foldl B {n} f e ∘ reverse ≗ foldr B (λ {n} → flip (f {n})) e
foldr-[] : ∀ {A : Set a} (B : ℕ → Set b) (f : FoldrOp A B) {e} → foldr B f e [] ≡ e
foldr-++ : ∀ {A : Set a} (B : ℕ → Set b) (f : FoldrOp A B) {e} →
∀ {m n} (xs : Vec A m) {ys : Vec A n} →
foldr B f e (xs ++ ys) ≡ foldr (B ∘ (_+ n)) f (foldr B f e ys) xs
foldr-∷ʳ : ∀ {A : Set a} (B : ℕ → Set b) (f : FoldrOp A B) {e} →
∀ {n} y (ys : Vec A n) → foldr B f e (ys ∷ʳ y) ≡ foldr (B ∘ suc) f (f y e) ys
foldr-ʳ++ : ∀ (B : ℕ → Set b) (f : FoldrOp A B) {e} →
∀ {m} {n} b (xs : Vec A m) {ys : Vec A n} →
foldr B f e (xs ʳ++ ys)
foldl (B ∘ (_+ n)) ((λ {m} → flip (f {m + n}))) (foldr B f e ys) xs
foldr-reverse : ∀ {B : ℕ → Set b} (f : FoldrOp A B) {e} {n} →
foldr B {n} f e ∘ reverse ≗ foldl B (λ {n} → flip (f {n})) e
++-is-foldr : ∀ {m n} (xs : Vec A m) {ys : Vec A n} →
xs ++ ys ≡ foldr ((Vec A) ∘ (_+ n)) _∷_ ys xs
∷ʳ-injective : ∀ {n} (xs ys : Vec A n) → xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys × x ≡ y
∷ʳ-injectiveˡ : ∀ {n} (xs ys : Vec A n) → xs ∷ʳ x ≡ ys ∷ʳ y → xs ≡ ys
∷ʳ-injectiveʳ : ∀ {n} (xs ys : Vec A n) → xs ∷ʳ x ≡ ys ∷ʳ y → x ≡ y
map-is-foldr : (f : A → B) → ∀ {n} → map {n = n} f ≗ foldr (Vec B) (λ x ys → f x ∷ ys) []
map-∷ʳ : (f : A → B) → ∀ {n} x (xs : Vec A n) → map f (xs ∷ʳ x) ≡ (map f xs) ∷ʳ (f x)
map-reverse : (f : A → B) → ∀ {n} (xs : Vec A n) → map f (reverse xs) ≡ reverse (map f xs)
map-ʳ++ : ∀ (f : A → B) {m n} (xs : Vec A m) {ys : Vec A n} →
map f (xs ʳ++ ys) ≡ map f xs ʳ++ map f ys
reverse-involutive : ∀ {n} → Involutive {A = Vec A n} _≡_ reverse
reverse-reverse : ∀ {n} {xs ys : Vec A n} → reverse xs ≡ ys → reverse ys ≡ xs
reverse-injective : ∀ {n} {xs ys : Vec A n} → reverse xs ≡ reverse ys → xs ≡ ys
```

* Added new proofs in `Function.Construct.Symmetry`:
Expand Down
12 changes: 6 additions & 6 deletions README/Tactic/Rewrite.agda
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ open import Tactic.Rewrite using (cong!)
-- Usage
----------------------------------------------------------------------

-- When performing large equational reasoning proofs, it's quite
-- When performing large equational reasoning proofs, it's quite
-- common to have to construct sophisticated lambdas to pass
-- into 'cong'. This can be extremely tedious, and can bog down
-- large proofs in piles of boilerplate. The 'cong!' tactic
Expand Down Expand Up @@ -79,13 +79,13 @@ module LiteralTests

test₁ : 40 + 2 ≡ 42
test₁ = cong! refl

test₂ : 48 ≡ 42 → 42 ≡ 48
test₂ eq = cong! (sym eq)
test₃ : (f : ℕ → ℕ) → f 48 ≡ f 42

test₃ : (f : ℕ → ℕ) → f 48 ≡ f 42
test₃ f = cong! assumption

test₄ : (f : ℕ → ℕ → ℕ) → f 48 48 ≡ f 42 42
test₄ f = cong! assumption

Expand All @@ -111,7 +111,7 @@ module HigherOrderTests

test₂ : f ≡ g → ∀ n → f (f (f n)) ≡ g (g (g n))
test₂ eq n = cong! eq

module EquationalReasoningTests where

test₁ : ∀ m n → m ≡ n → suc (suc (m + 0)) + m ≡ suc (suc n) + (n + 0)
Expand Down
51 changes: 38 additions & 13 deletions src/Data/Vec/Base.agda
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module Data.Vec.Base where

open import Data.Bool.Base
open import Data.Nat.Base
open import Data.Nat.Properties
open import Data.Fin.Base using (Fin; zero; suc)
open import Data.List.Base as List using (List)
open import Data.Product as Prod using (∃; ∃₂; _×_; _,_)
Expand Down Expand Up @@ -183,23 +184,34 @@ module DiagonalBind where
------------------------------------------------------------------------
-- Operations for reducing vectors

foldr : ∀ {a b} {A : Set a} (B : ℕ → Set b) {m} →
(∀ {n} → A → B n → B (suc n)) →
module _ (A : Set a) (B : ℕ → Set b) where

FoldrOp = ∀ {n} → A → B n → B (suc n)
FoldlOp = ∀ {n} → B n → A → B (suc n)

foldr : ∀ (B : ℕ → Set b) {m} →
FoldrOp A B →
B zero →
Vec A m → B m
foldr B _⊕_ n [] = n
foldr B _⊕_ n (x ∷ xs) = x ⊕ foldr B _⊕_ n xs

foldl : ∀ (B : ℕ → Set b) {m} →
FoldlOp A B →
B zero →
Vec A m → B m
foldr b _⊕_ n [] = n
foldr b _⊕_ n (x ∷ xs) = x ⊕ foldr b _⊕_ n xs
foldl B _⊕_ n [] = n
foldl B _⊕_ n (x ∷ xs) = foldl (B ∘ suc) _⊕_ (n ⊕ x) xs

foldr₀ : ∀ {n} → (A → A → A) → A → Vec A n → A
foldr₀ _⊕_ = foldr _ λ {n} → _⊕_

foldr₁ : ∀ {n} → (A → A → A) → Vec A (suc n) → A
foldr₁ _⊕_ (x ∷ []) = x
foldr₁ _⊕_ (x ∷ y ∷ ys) = x ⊕ foldr₁ _⊕_ (y ∷ ys)

foldl : ∀ {a b} {A : Set a} (B : ℕ → Set b) {m} →
(∀ {n} → B n → A → B (suc n)) →
B zero →
Vec A m → B m
foldl b _⊕_ n [] = n
foldl b _⊕_ n (x ∷ xs) = foldl (λ n → b (suc n)) _⊕_ (n ⊕ x) xs
foldl₀ : ∀ {n} → (A → A → A) → A → Vec A n → A
foldl₀ _⊕_ = foldl _ λ {n} → _⊕_

foldl₁ : ∀ {n} → (A → A → A) → Vec A (suc n) → A
foldl₁ _⊕_ (x ∷ xs) = foldl _ _⊕_ x xs
Expand Down Expand Up @@ -280,15 +292,28 @@ fromList (List._∷_ x xs) = x ∷ fromList xs
------------------------------------------------------------------------
-- Operations for reversing vectors

reverse : ∀ {n} → Vec A n → Vec A n
reverse {A = A} = foldl (Vec A) (λ rev x → x ∷ rev) []
-- snoc

infixl 5 _∷ʳ_

_∷ʳ_ : ∀ {n} → Vec A n → A → Vec A (1 + n)
_∷ʳ_ : ∀ {n} → Vec A n → A → Vec A (suc n)
[] ∷ʳ y = [ y ]
(x ∷ xs) ∷ʳ y = x ∷ (xs ∷ʳ y)

-- vanilla reverse

reverse : ∀ {n} → Vec A n → Vec A n
reverse {A = A} = foldl (Vec A) (λ rev x → x ∷ rev) []

-- reverse-append

infix 5 _ʳ++_

_ʳ++_ : ∀ {m n} → Vec A m → Vec A n → Vec A (m + n)
_ʳ++_ {A = A} {n = n} xs ys = foldl ((Vec A) ∘ (_+ n)) (λ rev x → x ∷ rev) ys xs

-- init and last

initLast : ∀ {n} (xs : Vec A (1 + n)) →
∃₂ λ (ys : Vec A n) (y : A) → xs ≡ ys ∷ʳ y
initLast {n = zero} (x ∷ []) = ([] , x , refl)
Expand Down
Loading