-
Notifications
You must be signed in to change notification settings - Fork 240
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
Add Data.Nat.Bounded
#2257
Draft
jamesmckinna
wants to merge
37
commits into
agda:master
Choose a base branch
from
jamesmckinna:bounded-nat
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Add Data.Nat.Bounded
#2257
Changes from 9 commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
85c485f
Add `Data.Nat.Bounded`
jamesmckinna 92fa7e9
renamed type; removed `instance`-based field; stumbled over isomorphism
jamesmckinna f07cc16
got there in the end: yuk!
jamesmckinna dc8e53e
added `nonZeroIndex`
jamesmckinna 3d850f4
added `ℕ<` literals
jamesmckinna 659d892
added `DecidableEquality`
jamesmckinna 11bb699
too hasty to push
jamesmckinna 51b6280
added projection from Nat; additional constructors
jamesmckinna 04fae4f
tweak to [[1]]<
jamesmckinna 32eb86b
Merge branch 'master' into bounded-nat
jamesmckinna e560b6f
tweak
jamesmckinna 0fe029e
rename projection from `Nat`
jamesmckinna 6052c4f
added `Equivalence` proof
jamesmckinna 821f51c
inverting `fromℕ` lemmas
jamesmckinna 194f122
added quotient equivalence relation
jamesmckinna 9a734c1
module refactoring
jamesmckinna dca2d54
cosmetic
jamesmckinna 823016b
added two simple lemmas about underlying values
jamesmckinna 623d854
final lemma about the retraction
jamesmckinna 4076cc5
tweaks to accomodate #2292
jamesmckinna f0f4883
additions to support #2292
jamesmckinna e1214bd
refactored arithmetic
jamesmckinna 10d4083
revised imports
jamesmckinna 771b501
Merge branch 'master' into bounded-nat
jamesmckinna 8d523c8
Merge branch 'master' into bounded-nat
jamesmckinna 9b4ee0e
Merge branch 'master' into bounded-nat
jamesmckinna 078d4f6
fixed up `CHANGELOG`
jamesmckinna 97f9cf9
Merge branch 'master' into bounded-nat
jamesmckinna eccf88d
Merge branch 'master' into bounded-nat
jamesmckinna f3e2550
Merge branch 'master' into bounded-nat
jamesmckinna 383529a
Merge branch 'master' into bounded-nat
jamesmckinna 3c3cbf3
update `CHANGELOG` to v2.2
jamesmckinna ba4e922
Merge branch 'agda:master' into bounded-nat
jamesmckinna 00421a6
update `CHANGELOG`
jamesmckinna 49430b3
Merge branch 'master' into bounded-nat
jamesmckinna 594d35c
Merge branch 'agda:master' into bounded-nat
jamesmckinna 716d585
Merge branch 'agda:master' into bounded-nat
jamesmckinna File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
------------------------------------------------------------------------ | ||
-- The Agda standard library | ||
-- | ||
-- Bounded natural numbers, and their equivalence to `Fin` | ||
------------------------------------------------------------------------ | ||
|
||
{-# OPTIONS --cubical-compatible --safe #-} | ||
|
||
module Data.Nat.Bounded where | ||
|
||
open import Data.Bool.Base using (T) | ||
open import Data.Nat.Base as ℕ | ||
import Data.Nat.DivMod as ℕ | ||
import Data.Nat.Properties as ℕ | ||
open import Data.Fin.Base as Fin using (Fin; zero; suc; toℕ) | ||
import Data.Fin.Properties as Fin | ||
open import Data.Product.Base using (_,_) | ||
open import Function.Base using (id; _∘_; _$_; _on_) | ||
open import Function.Bundles using (_⤖_; mk⤖) | ||
open import Function.Consequences.Propositional | ||
using (inverseᵇ⇒bijective; strictlyInverseˡ⇒inverseˡ; strictlyInverseʳ⇒inverseʳ) | ||
open import Relation.Binary.Core using (_⇒_) | ||
open import Relation.Binary.Definitions | ||
open import Relation.Binary.PropositionalEquality using (_≡_; refl; cong; _≗_) | ||
open import Relation.Nullary.Decidable.Core using (recompute; map′) | ||
open import Relation.Nullary.Negation.Core using (¬_) | ||
|
||
private | ||
variable | ||
m n : ℕ | ||
|
||
------------------------------------------------------------------------ | ||
-- Definition | ||
|
||
record ℕ< (n : ℕ) : Set where | ||
constructor ⟦_⟧<_ | ||
field | ||
value : ℕ | ||
.bounded : value < n | ||
|
||
open ℕ< public using () renaming (value to ⟦_⟧) | ||
|
||
-- Constructors: '0 mod n', 'n-1 mod n', '1 mod n' | ||
|
||
⟦0⟧< ⟦-1⟧< : .{{ NonZero n }} → ℕ< n | ||
⟦0⟧< = ⟦ 0 ⟧< >-nonZero⁻¹ _ | ||
⟦-1⟧< {n = suc m} = ⟦ m ⟧< ℕ.n<1+n m | ||
|
||
⟦1⟧< : .{{ NonZero n }} → ℕ< n | ||
⟦1⟧< {n = 1} = ⟦0⟧< | ||
⟦1⟧< {n = 2+ _} = ⟦ 1 ⟧< nonTrivial⇒n>1 _ | ||
|
||
-- Projection from ℕ | ||
jamesmckinna marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
π : .{{ NonZero n }} → ℕ → ℕ< n | ||
π {n} m = ⟦ m % n ⟧< ℕ.m%n<n m n | ||
|
||
-- Destructors | ||
|
||
¬ℕ<[0] : ¬ ℕ< 0 | ||
¬ℕ<[0] () | ||
|
||
nonZeroIndex : ℕ< n → NonZero n | ||
nonZeroIndex {n = suc _} _ = _ | ||
|
||
isBounded : (i : ℕ< n) → ⟦ i ⟧ < n | ||
isBounded (⟦ _ ⟧< i<n) = recompute (_ ℕ.<? _) i<n | ||
|
||
-- Equality on values is propositional equality | ||
|
||
bounded≡⇒⟦⟧≡⟦⟧ : _≡_ {A = ℕ< n} ⇒ (_≡_ on ⟦_⟧) | ||
bounded≡⇒⟦⟧≡⟦⟧ = cong ⟦_⟧ | ||
|
||
⟦⟧≡⟦⟧⇒bounded≡ : (_≡_ on ⟦_⟧) ⇒ _≡_ {A = ℕ< n} | ||
⟦⟧≡⟦⟧⇒bounded≡ refl = refl | ||
|
||
infix 4 _≟_ | ||
_≟_ : DecidableEquality (ℕ< n) | ||
i ≟ j = map′ ⟦⟧≡⟦⟧⇒bounded≡ bounded≡⇒⟦⟧≡⟦⟧ (⟦ i ⟧ ℕ.≟ ⟦ j ⟧) | ||
|
||
------------------------------------------------------------------------ | ||
-- Conversion to and from `Fin n` | ||
jamesmckinna marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
toFin : ℕ< n → Fin n | ||
toFin (⟦ _ ⟧< i<n) = Fin.fromℕ< i<n | ||
|
||
fromFin : Fin n → ℕ< n | ||
fromFin i = ⟦ toℕ i ⟧< Fin.toℕ<n i | ||
|
||
toFin∘fromFin≐id : toFin ∘ fromFin ≗ id {A = Fin n} | ||
toFin∘fromFin≐id i = Fin.fromℕ<-toℕ i (Fin.toℕ<n i) | ||
|
||
fromFin∘toFin≐id : fromFin ∘ toFin ≗ id {A = ℕ< n} | ||
fromFin∘toFin≐id (⟦ _ ⟧< i<n) = ⟦⟧≡⟦⟧⇒bounded≡ (Fin.toℕ-fromℕ< i<n) | ||
|
||
boundedNat⤖Fin : ℕ< n ⤖ Fin n | ||
boundedNat⤖Fin = mk⤖ $ inverseᵇ⇒bijective $ | ||
strictlyInverseˡ⇒inverseˡ {f⁻¹ = fromFin} toFin toFin∘fromFin≐id | ||
, | ||
strictlyInverseʳ⇒inverseʳ {f⁻¹ = fromFin} toFin fromFin∘toFin≐id | ||
|
||
------------------------------------------------------------------------ | ||
-- Literals | ||
|
||
module Literals n where | ||
|
||
Constraint : ℕ → Set | ||
Constraint m = T (m <ᵇ n) | ||
|
||
fromNat : ∀ m → {{Constraint m}} → ℕ< n | ||
fromNat m {{lt}} = ⟦ m ⟧< ℕ.<ᵇ⇒< m n lt | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
------------------------------------------------------------------------ | ||
-- The Agda standard library | ||
-- | ||
-- ℕ< Literals | ||
------------------------------------------------------------------------ | ||
|
||
{-# OPTIONS --cubical-compatible --safe #-} | ||
|
||
module Data.Nat.Bounded.Literals where | ||
|
||
open import Agda.Builtin.FromNat | ||
open import Data.Nat.Bounded using (ℕ<; module Literals) | ||
|
||
number : ∀ n → Number (ℕ< n) | ||
number n = record { Literals n } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So to touch on your question of whether this belongs in the library or a readme file, I guess my question is what circumstances is this easier to work with than
Fin
? In general we try to avoid duplicate but equivalent definitions unless there is clear reason that sometimes one representation is easier to work with than the other...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Matthew! I can think of two or three, some already in the initial preamble (which was really about helping someone solve a related problem of representation, where
Fin
didn't seem to fit well):Digit
bases for arithmetic, as a specialised instance/mode of use of the above;Data.Nat.DivMod
, to avoid the marshalling/unmarshalling required by the use ofFin
to ensure thatmod
is suitably bounded.Now, none of these could be said to be a deal-breaker, but I increasingly wonder whether
Fin
is better suited to its use as an indexing type (forVec
,List
, de Bruijn representations,Reflection
/deeply embedded syntaxes more generally, etc.), withℕ<
as an arithmetic type/Number
instance... cf. #2073 which I might now think makes the 'wrong' choice in usingFin
...Perhaps other pros (and cons!) might be lurking off-stage...
... UPDATED: (pro)
Data.Nat.DivMod.WithK
(no longer any need to consider erasing proofs of_≤″_
...?) and hence perhaps to the deprecation of_≤″_
altogether, cf. Remove (almost!) all external use of_≤″_
beyondData.Nat.*
#2262