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

a recursive view of Fin n #1923

Merged
merged 43 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
75fa9d0
a view of `Fin (suc n)`
jamesmckinna Feb 9, 2023
629b415
documentation
jamesmckinna Feb 9, 2023
c6a9994
theory of `opposite` also
jamesmckinna Feb 9, 2023
d6e7b9c
tweak
jamesmckinna Feb 9, 2023
d2173fb
first of Jacques' review changes
jamesmckinna Feb 10, 2023
6e0c4be
refactored according to Jacques' prescriptions; renamed the inverse
jamesmckinna Feb 10, 2023
1021deb
fix whitespace
jamesmckinna Feb 10, 2023
a870d69
tightened imports
jamesmckinna Feb 10, 2023
c766cc7
tightened imports
jamesmckinna Feb 11, 2023
f43a21f
tightened imports
jamesmckinna Feb 11, 2023
66bc0c7
cosmetics
jamesmckinna Feb 11, 2023
8eff5d6
rmeoved redundant
jamesmckinna Feb 11, 2023
6576fe5
made `Instances` not public
jamesmckinna Feb 11, 2023
c18173c
slight refactor
jamesmckinna Feb 11, 2023
d4069e9
symmetry typo
jamesmckinna Feb 11, 2023
6d4cc58
imports
jamesmckinna Feb 11, 2023
0e6db5e
other use of `lower₁` in `Data.Fin.Induction`
jamesmckinna Feb 14, 2023
fa28f4c
previously uncommitted comment on the `View` itself
jamesmckinna Feb 15, 2023
c51dd63
tidied up imports for `Top` view
jamesmckinna Apr 17, 2023
904fdbe
made `--cubical-compatible`
jamesmckinna Apr 17, 2023
f3550ad
better use of `variable`s
jamesmckinna May 12, 2023
9a0d6ad
(vertical) whitespace)
jamesmckinna May 14, 2023
1dd382e
made the view recursive; with simplifications
jamesmckinna Aug 7, 2023
f10cb3f
final tweaks; use of variable `{n}` still needed in places
jamesmckinna Aug 7, 2023
d878b2c
streamlined use of instances
jamesmckinna Aug 7, 2023
c0d5651
revised names, as per discusison
jamesmckinna Aug 8, 2023
2c94427
factored out `Instances`; revised `README` and `CHANGELOG`
jamesmckinna Aug 8, 2023
9bce07e
followed Matthew's suggestion better; added uniqueness proof for the …
jamesmckinna Aug 8, 2023
9012225
typo
jamesmckinna Aug 8, 2023
c7e7c9e
revised `Instances`
jamesmckinna Sep 12, 2023
1f1f9f3
fresh round of `variable` review comments
jamesmckinna Sep 12, 2023
a88d39c
sharpened use of `instance`s in response to review comments
jamesmckinna Sep 12, 2023
c962e14
reordering
jamesmckinna Sep 12, 2023
6ba18be
`fromℕ≢inject₁` now takes implicit argument
jamesmckinna Sep 12, 2023
c7b3acf
`CHANGELOG`!
jamesmckinna Sep 12, 2023
eae3f83
tidy up comments and binders
jamesmckinna Sep 14, 2023
4a4a4e2
Change to use i rather than j in Top
MatthewDaggitt Sep 15, 2023
c8451d7
uniform naming scheme
jamesmckinna Sep 15, 2023
6d8979d
Merge branch 'top-view' of github.com:jamesmckinna/agda-stdlib into t…
jamesmckinna Sep 15, 2023
21500e9
removed `Instances`
jamesmckinna Sep 17, 2023
c5ed38f
removed `inject₁⁻¹`
jamesmckinna Sep 17, 2023
cb3eb95
removed `Top.Instances`
jamesmckinna Sep 17, 2023
7207c6e
drastic `import` simplification
jamesmckinna Sep 17, 2023
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,11 @@ New modules
Data.Default
```

* A small library defining a structurally recursive view of `Fin n`:
```
Data.Fin.Relation.Unary.Top
```

* A small library for a non-empty fresh list:
```
Data.List.Fresh.NonEmpty
Expand Down Expand Up @@ -1913,6 +1918,8 @@ Other minor changes
cast-is-id : cast eq k ≡ k
subst-is-cast : subst Fin eq k ≡ cast eq k
cast-trans : cast eq₂ (cast eq₁ k) ≡ cast (trans eq₁ eq₂) k

fromℕ≢inject₁ : {i : Fin n} → fromℕ n ≢ inject₁ i
```

* Added new functions in `Data.Integer.Base`:
Expand Down
100 changes: 100 additions & 0 deletions README/Data/Fin/Relation/Unary/Top.agda
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
------------------------------------------------------------------------
-- The Agda standard library
--
-- Example use of the 'top' view of Fin
--
-- This is an example of a view of (elements of) a datatype,
-- here i : Fin (suc n), which exhibits every such i as
-- * either, i = fromℕ n
-- * or, i = inject₁ j for a unique j : Fin n
--
-- Using this view, we can redefine certain operations in `Data.Fin.Base`,
-- together with their corresponding properties in `Data.Fin.Properties`.
------------------------------------------------------------------------

{-# OPTIONS --cubical-compatible --safe #-}

module README.Data.Fin.Relation.Unary.Top where

open import Data.Nat.Base using (ℕ; zero; suc; _∸_; _≤_)
open import Data.Nat.Properties using (n∸n≡0; +-∸-assoc; ≤-reflexive)
open import Data.Fin.Base using (Fin; zero; suc; toℕ; fromℕ; inject₁; _>_)
open import Data.Fin.Properties using (toℕ-fromℕ; toℕ<n; toℕ-inject₁)
open import Data.Fin.Induction hiding (>-weakInduction)
open import Data.Fin.Relation.Unary.Top
import Induction.WellFounded as WF
open import Level using (Level)
open import Relation.Binary.PropositionalEquality
open import Relation.Unary using (Pred)

private
variable
ℓ : Level
n : ℕ

------------------------------------------------------------------------
-- Reimplementation of `Data.Fin.Base.opposite`, and its properties

-- Definition

opposite : Fin n → Fin n
opposite {suc n} i with view i
... | ‵fromℕ = zero
... | ‵inject₁ j = suc (opposite {n} j)

-- Properties

opposite-zero≡fromℕ : ∀ n → opposite {suc n} zero ≡ fromℕ n
opposite-zero≡fromℕ zero = refl
opposite-zero≡fromℕ (suc n) = cong suc (opposite-zero≡fromℕ n)

opposite-fromℕ≡zero : ∀ n → opposite {suc n} (fromℕ n) ≡ zero
opposite-fromℕ≡zero n rewrite view-fromℕ n = refl

opposite-suc≡inject₁-opposite : (j : Fin n) →
opposite (suc j) ≡ inject₁ (opposite j)
opposite-suc≡inject₁-opposite {suc n} i with view i
... | ‵fromℕ = refl
... | ‵inject₁ j = cong suc (opposite-suc≡inject₁-opposite {n} j)

opposite-involutive : (j : Fin n) → opposite (opposite j) ≡ j
opposite-involutive {suc n} zero
rewrite opposite-zero≡fromℕ n
| view-fromℕ n = refl
opposite-involutive {suc n} (suc i)
rewrite opposite-suc≡inject₁-opposite i
| view-inject₁ (opposite i) = cong suc (opposite-involutive i)

opposite-suc : (j : Fin n) → toℕ (opposite (suc j)) ≡ toℕ (opposite j)
opposite-suc j = begin
toℕ (opposite (suc j)) ≡⟨ cong toℕ (opposite-suc≡inject₁-opposite j) ⟩
toℕ (inject₁ (opposite j)) ≡⟨ toℕ-inject₁ (opposite j) ⟩
toℕ (opposite j) ∎ where open ≡-Reasoning

opposite-prop : (j : Fin n) → toℕ (opposite j) ≡ n ∸ suc (toℕ j)
opposite-prop {suc n} i with view i
... | ‵fromℕ rewrite toℕ-fromℕ n | n∸n≡0 n = refl
... | ‵inject₁ j = begin
suc (toℕ (opposite j)) ≡⟨ cong suc (opposite-prop j) ⟩
suc (n ∸ suc (toℕ j)) ≡˘⟨ +-∸-assoc 1 (toℕ<n j) ⟩
n ∸ toℕ j ≡˘⟨ cong (n ∸_) (toℕ-inject₁ j) ⟩
n ∸ toℕ (inject₁ j) ∎ where open ≡-Reasoning

------------------------------------------------------------------------
-- Reimplementation of `Data.Fin.Induction.>-weakInduction`

open WF using (Acc; acc)

>-weakInduction : (P : Pred (Fin (suc n)) ℓ) →
P (fromℕ n) →
(∀ i → P (suc i) → P (inject₁ i)) →
∀ i → P i
>-weakInduction P Pₙ Pᵢ₊₁⇒Pᵢ i = induct (>-wellFounded i)
where
induct : ∀ {i} → Acc _>_ i → P i
induct {i} (acc rec) with view i
... | ‵fromℕ = Pₙ
... | ‵inject₁ j = Pᵢ₊₁⇒Pᵢ j (induct (rec _ inject₁[j]+1≤[j+1]))
where
inject₁[j]+1≤[j+1] : suc (toℕ (inject₁ j)) ≤ toℕ (suc j)
inject₁[j]+1≤[j+1] = ≤-reflexive (toℕ-inject₁ (suc j))
3 changes: 3 additions & 0 deletions src/Data/Fin/Properties.agda
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,9 @@ toℕ-inject {i = suc i} (suc j) = cong suc (toℕ-inject j)
-- inject₁
------------------------------------------------------------------------

fromℕ≢inject₁ : fromℕ n ≢ inject₁ i
fromℕ≢inject₁ {i = suc i} eq = fromℕ≢inject₁ {i = i} (suc-injective eq)

inject₁-injective : inject₁ i ≡ inject₁ j → i ≡ j
inject₁-injective {i = zero} {zero} i≡j = refl
inject₁-injective {i = suc i} {suc j} i≡j =
Expand Down
79 changes: 79 additions & 0 deletions src/Data/Fin/Relation/Unary/Top.agda
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
------------------------------------------------------------------------
-- The Agda standard library
--
-- The 'top' view of Fin.
--
-- This is an example of a view of (elements of) a datatype,
-- here i : Fin (suc n), which exhibits every such i as
-- * either, i = fromℕ n
-- * or, i = inject₁ j for a unique j : Fin n
------------------------------------------------------------------------

{-# OPTIONS --cubical-compatible --safe #-}

module Data.Fin.Relation.Unary.Top where

open import Data.Nat.Base using (ℕ; zero; suc)
open import Data.Fin.Base using (Fin; zero; suc; fromℕ; inject₁)
open import Relation.Binary.PropositionalEquality.Core

private
variable
n : ℕ
i : Fin n

------------------------------------------------------------------------
-- The View, considered as a unary relation on Fin n

-- NB `Data.Fin.Properties.fromℕ≢inject₁` establishes that the following
-- inductively defined family on `Fin n` has constructors which target
-- *disjoint* instances of the family (moreover at indices `n = suc _`);
-- hence the interpretations of the View constructors will also be disjoint.

data View : (i : Fin n) → Set where
‵fromℕ : View (fromℕ n)
‵inj₁ : View i → View (inject₁ i)

pattern ‵inject₁ i = ‵inj₁ {i = i} _

-- The view covering function, witnessing soundness of the view

view : (i : Fin n) → View i
view zero = view-zero where
view-zero : View (zero {n})
view-zero {n = zero} = ‵fromℕ
view-zero {n = suc _} = ‵inj₁ view-zero
view (suc i) with view i
... | ‵fromℕ = ‵fromℕ
... | ‵inject₁ i = ‵inj₁ (view (suc i))

-- Interpretation of the view constructors

⟦_⟧ : {i : Fin n} → View i → Fin n
⟦ ‵fromℕ ⟧ = fromℕ _
⟦ ‵inject₁ i ⟧ = inject₁ i

-- Completeness of the view

view-complete : (v : View i) → ⟦ v ⟧ ≡ i
view-complete ‵fromℕ = refl
view-complete (‵inj₁ _) = refl

-- 'Computational' behaviour of the covering function

view-fromℕ : ∀ n → view (fromℕ n) ≡ ‵fromℕ
view-fromℕ zero = refl
view-fromℕ (suc n) rewrite view-fromℕ n = refl

view-inject₁ : (i : Fin n) → view (inject₁ i) ≡ ‵inj₁ (view i)
view-inject₁ zero = refl
view-inject₁ (suc i) rewrite view-inject₁ i = refl

-- Uniqueness of the view

view-unique : (v : View i) → view i ≡ v
view-unique ‵fromℕ = view-fromℕ _
view-unique (‵inj₁ {i = i} v) = begin
view (inject₁ i) ≡⟨ view-inject₁ i ⟩
‵inj₁ (view i) ≡⟨ cong ‵inj₁ (view-unique v) ⟩
‵inj₁ v ∎ where open ≡-Reasoning