-
Notifications
You must be signed in to change notification settings - Fork 253
Added Z mod n as Fin #2073
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
Added Z mod n as Fin #2073
Changes from 1 commit
19566db
94d8aa9
c87e35a
af96faa
7e6a392
467b190
600035c
5cdbaf7
e64b543
d3d4770
1d28e8e
3773f2c
e853059
fccf44d
e7edaee
ab5493d
7ccd05e
644a8cb
417fa28
4d3a4ab
84cc27b
473ac6d
b539e70
aeb1c4a
bdf0651
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,107 @@ | ||||
------------------------------------------------------------------------ | ||||
-- The Agda standard library | ||||
-- | ||||
-- ℤ module n | ||||
------------------------------------------------------------------------ | ||||
|
||||
{-# OPTIONS --cubical-compatible --safe #-} | ||||
|
||||
module Data.Fin.Mod where | ||||
|
||||
open import Function using (_$_; _∘_) | ||||
open import Data.Bool using (true; false) | ||||
open import Data.Nat as ℕ using (ℕ; s≤s) | ||||
guilhermehas marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
open import Data.Nat.Properties as ℕ | ||||
using (m≤n⇒m≤1+n; 1+n≰n; module ≤-Reasoning) | ||||
open import Data.Fin as F hiding (suc; pred; _+_; _-_) | ||||
guilhermehas marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
open import Data.Fin.Properties | ||||
open import Relation.Nullary using (Dec; yes; no; contradiction) | ||||
guilhermehas marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
open import Relation.Binary.PropositionalEquality | ||||
using (_≡_; _≢_; refl; sym; trans; cong; module ≡-Reasoning) | ||||
import Algebra.Definitions as ADef | ||||
|
||||
private variable | ||||
m n : ℕ | ||||
guilhermehas marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
|
||||
open module AD {n} = ADef {A = Fin n} _≡_ | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be an anonymous module? |
||||
|
||||
private | ||||
hs : ∀ {i : Fin (ℕ.suc n)} → i ≢ fromℕ n → Fin (ℕ.suc n) | ||||
hs {i = i} i≢n = lower₁ (F.suc i) help | ||||
where | ||||
help : _ | ||||
help = i≢n ∘ sym ∘ toℕ-injective ∘ trans (toℕ-fromℕ _) ∘ cong ℕ.pred | ||||
|
||||
suc : Fin n → Fin n | ||||
suc {ℕ.suc n} i with i ≟ fromℕ n | ||||
... | yes _ = zero | ||||
... | no i≢n = hs i≢n | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider the following alternative definition (which doesn't actually use the view; but simulates its effect, in the same way as the definition of suc : Fin n → Fin n
suc {n = ℕ.suc ℕ.zero} zero = zero
suc {n = ℕ.suc n@(ℕ.suc _)} zero = Fin.suc zero
suc {n = ℕ.suc n@(ℕ.suc _)} (Fin.suc i) with suc {n} i
... | zero = zero
... | j@(Fin.suc _) = Fin.suc j for which one may then prove injectivity, and the view-related inversions, as follows: suc[fromℕ]≡zero : ∀ n → suc (fromℕ n) ≡ zero
suc[fromℕ]≡zero ℕ.zero = refl
suc[fromℕ]≡zero (ℕ.suc n) rewrite suc[fromℕ]≡zero n = refl
suc[fromℕ]≡zero⁻¹ : (i : Fin (ℕ.suc n)) → (suc i ≡ zero) → i ≡ fromℕ n
suc[fromℕ]≡zero⁻¹ {n = ℕ.zero} zero _ = refl
suc[fromℕ]≡zero⁻¹ {n = ℕ.suc _} (Fin.suc i) _ with zero ← suc i in eq
= cong Fin.suc (suc[fromℕ]≡zero⁻¹ i eq)
suc[inject₁]≡suc[j] : (j : Fin n) → suc (inject₁ j) ≡ Fin.suc j
suc[inject₁]≡suc[j] zero = refl
suc[inject₁]≡suc[j] (Fin.suc j) rewrite suc[inject₁]≡suc[j] j = refl
suc[inject₁]≡suc[j]⁻¹ : (i : Fin (ℕ.suc n)) {j : Fin n} →
(suc i ≡ Fin.suc j) → i ≡ inject₁ j
suc[inject₁]≡suc[j]⁻¹ zero {zero} = λ _ → refl
suc[inject₁]≡suc[j]⁻¹ (Fin.suc i) {j} with suc i in eqᵢ
... | zero rewrite eqᵢ = λ ()
... | Fin.suc p rewrite eqᵢ = λ eq → begin
Fin.suc i ≡⟨ cong Fin.suc (suc[inject₁]≡suc[j]⁻¹ i eqᵢ) ⟩
inject₁ (Fin.suc p) ≡⟨ cong inject₁ (Fin.suc-injective eq) ⟩
inject₁ j ∎ where open ≡-Reasoning
suc-injective : {i j : Fin n} → suc i ≡ suc j → i ≡ j
suc-injective {n = n} {i} {j} eq with suc i in eqᵢ | suc j in eqⱼ
... | zero | zero
= trans (suc[fromℕ]≡zero⁻¹ i eqᵢ) (sym (suc[fromℕ]≡zero⁻¹ j eqⱼ))
... | Fin.suc p | Fin.suc q
= begin
i ≡⟨ suc[inject₁]≡suc[j]⁻¹ i eqᵢ ⟩
inject₁ p ≡⟨ cong inject₁ (Fin.suc-injective eq) ⟩
inject₁ q ≡⟨ sym (suc[inject₁]≡suc[j]⁻¹ j eqⱼ) ⟩
j ∎ where open ≡-Reasoning |
||||
|
||||
pred : Fin n → Fin n | ||||
pred zero = fromℕ _ | ||||
pred (F.suc i) = inject₁ i | ||||
|
||||
_ℕ+_ : ℕ → Fin n → Fin n | ||||
guilhermehas marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
ℕ.zero ℕ+ i = i | ||||
ℕ.suc n ℕ+ i = suc (n ℕ+ i) | ||||
|
||||
_+_ : Fin m → Fin n → Fin n | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you give me an example of a use-case of this operation? Seems a little unnatural to me adding together two numbers of different mods and arbitrarily returning the result mod the right one? And why does |
||||
i + j = toℕ i ℕ+ j | ||||
|
||||
_+‵_ : Fin n → Fin n → Fin n | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this ever necessary over There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could be necessary if someone wants a more restrictive version. agda-stdlib/src/Function/Base.agda Line 134 in 78e11bd
|
||||
_+‵_ = _+_ | ||||
|
||||
_-_ : Fin n → Fin n → Fin n | ||||
i - j = i + opposite j | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This suggests that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, for a possible alternative (re-)definition of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now, it is with the alternative re-definition. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Except that there's still an asymmetry. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made it assymmetric. |
||||
|
||||
guilhermehas marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
private | ||||
inject₁≢fromℕ : {i : Fin n} → inject₁ i ≢ fromℕ n | ||||
inject₁≢fromℕ {n} {i} i≡n = 1+n≰n $ begin-strict | ||||
toℕ (fromℕ n) ≡˘⟨ cong toℕ i≡n ⟩ | ||||
toℕ (inject₁ i) <⟨ inject₁ℕ< i ⟩ | ||||
n ≡˘⟨ toℕ-fromℕ n ⟩ | ||||
toℕ (fromℕ n) ∎ | ||||
where open ≤-Reasoning | ||||
|
||||
suc-inj≡fsuc : (i : Fin n) → suc (inject₁ i) ≡ F.suc i | ||||
guilhermehas marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
suc-inj≡fsuc {n} i with inject₁ i ≟ fromℕ _ | ||||
... | yes i≡n = contradiction i≡n inject₁≢fromℕ | ||||
... | no i≢n = cong F.suc (toℕ-injective (trans (toℕ-lower₁ _ _) (toℕ-inject₁ _))) | ||||
|
||||
pred-fsuc≡inj : (i : Fin n) → pred (F.suc i) ≡ inject₁ i | ||||
guilhermehas marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
pred-fsuc≡inj _ = refl | ||||
|
||||
suc-pred≡id : (i : Fin n) → suc (pred i) ≡ i | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be |
||||
suc-pred≡id {ℕ.suc n} zero with fromℕ n ≟ fromℕ n | ||||
... | yes _ = refl | ||||
... | no n≢n = contradiction refl n≢n | ||||
suc-pred≡id {ℕ.suc n} (F.suc i) = suc-inj≡fsuc i | ||||
|
||||
pred-suc≡id : (i : Fin n) → pred (suc i) ≡ i | ||||
guilhermehas marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
pred-suc≡id {ℕ.suc n} i with i ≟ fromℕ n | ||||
... | yes refl = refl | ||||
... | no _ = inject₁-lower₁ _ _ | ||||
|
||||
+-identityˡ : LeftIdentity {ℕ.suc n} zero _+_ | ||||
+-identityˡ _ = refl | ||||
|
||||
+ℕ-identityʳ : ∀ {n′} (let n = ℕ.suc n′) → m ℕ.≤ n → toℕ (m ℕ+ zero {n}) ≡ m | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The proof of this seems very fiddly, but I admit I'm finding it harder to do better, even for the alternative definition of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this lemma not also provable in the case |
||||
+ℕ-identityʳ {ℕ.zero} m≤n = refl | ||||
+ℕ-identityʳ {ℕ.suc m} {n} (s≤s m≤n) with (m ℕ+ zero) ≟ F.suc (fromℕ n) | ||||
... | yes m+0≡sn = contradiction (begin-strict | ||||
ℕ.suc n ≡˘⟨ cong ℕ.suc (toℕ-fromℕ n) ⟩ | ||||
ℕ.suc (toℕ (fromℕ n)) ≡˘⟨ cong toℕ m+0≡sn ⟩ | ||||
toℕ (m ℕ+ zero) ≡⟨ +ℕ-identityʳ (m≤n⇒m≤1+n m≤n) ⟩ | ||||
m <⟨ s≤s m≤n ⟩ | ||||
ℕ.suc n ∎) 1+n≰n | ||||
where open ≤-Reasoning | ||||
|
||||
... | no _ = cong ℕ.suc (begin | ||||
toℕ (lower₁ (m ℕ+ zero) _) ≡⟨ toℕ-lower₁ (m ℕ+ zero) _ ⟩ | ||||
toℕ (m ℕ+ zero) ≡⟨ +ℕ-identityʳ (m≤n⇒m≤1+n m≤n) ⟩ | ||||
m ∎) | ||||
where open ≡-Reasoning | ||||
|
||||
+-identityʳ : RightIdentity {ℕ.suc n} zero _+_ | ||||
guilhermehas marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
+-identityʳ {ℕ.zero} zero = refl | ||||
+-identityʳ {ℕ.suc _} = toℕ-injective ∘ +ℕ-identityʳ ∘ toℕ≤pred[n] |
Uh oh!
There was an error while loading. Please reload this page.