Skip to content

Commit df6fcac

Browse files
[ add ] injectivity of suc for relation m ≡ n (mod o) for {{NonZero o}} (#2971)
* [ add ] proof of Carette's Lemma * refactor: remove simple lemmas * add: one half of the equivalence * refactor: in terms of `_on_` and `_⇒_`; introduce name for equality mod `o` * add: new lemmas relating `SymClosure` and `on` * use: new lemmas * rename: according to review comments * change notation, following review comments * chnage comment text to reflect the analysis better * refactor: in terms of `wlog` * refactor: export Jacques' lemma; leave Alex' proof `private` * refactor: comment out the `wlog` proof; tidy up the presentation * removed `wlog` proof * refactor: appeal to `Sum` elimination, rather than `with` * Remove Zulip reference --------- Co-authored-by: Matthew Daggitt <matthewdaggitt@gmail.com>
1 parent 70f3f0f commit df6fcac

File tree

3 files changed

+120
-7
lines changed

3 files changed

+120
-7
lines changed

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,23 @@ Additions to existing modules
344344
n≤o⇒m^n∣m^o : ∀ m → .(n ≤ o) → m ^ n ∣ m ^ o
345345
```
346346

347+
* In `Data.Nat.DivMod`:
348+
```agda
349+
infix 4 _≡%[_]_ : ∀ m o .{{_ : NonZero o}} n → Set _
350+
m ≡%[ o ] n = m % o ≡ n % o
351+
352+
infix 4 _≲%[_]_ _≅%[_]_ : ∀ m o n → Set _
353+
m ≲%[ o ] n = ∃ λ k → n ≡ m + k * o
354+
m ≅%[ o ] n = SymClosure _≲%[ o ]_ m n
355+
356+
≲%[o]⇒≡[o]% : .{{_ : NonZero o}} → _≲%[ o ]_ ⇒ _≡%[ o ]_
357+
≅%[o]⇒≡[o]% : .{{_ : NonZero o}} → _≅%[ o ]_ ⇒ _≡%[ o ]_
358+
≡[o]%⇒≲%[o] : .{{_ : NonZero o}} → m % o ≡ n % o → m ≤ n → m ≲%[ o ] n
359+
≡[o]%⇒≅%[o] : .{{_ : NonZero o}} → _≡%[ o ]_ ⇒ _≅%[ o ]_
360+
361+
≡%-suc-injective : .{{_ : NonZero o}} → Injective _≡%[ o ]_ _≡%[ o ]_ suc
362+
```
363+
347364
* In `Data.Nat.Logarithm`
348365
```agda
349366
2^⌊log₂n⌋≤n : ∀ n .{{ _ : NonZero n }} → 2 ^ ⌊log₂ n ⌋ ≤ n
@@ -608,6 +625,14 @@ Additions to existing modules
608625
≤⁺-resp-≈⁺ : _≤_ Respects₂ _≈_ → _≤⁺_ Respects₂ _≈⁺_
609626
```
610627

628+
* In `Relation.Binary.Construct.Closure.Symmetric`:
629+
```
630+
hmap : ∀ (g : C → A) (f : C → B) → (R on g) ⇒ (S on f) →
631+
((SymClosure R) on g) ⇒ ((SymClosure S) on f)
632+
on⁺ : ((SymClosure R) on g) ⇒ SymClosure (R on g)
633+
on⁻ : SymClosure (R on g) ⇒ ((SymClosure R) on g)
634+
```
635+
611636
* In `Data.Vec.Relation.Binary.Pointwise.Inductive`
612637
```agda
613638
irrelevant : ∀ {_∼_ : REL A B ℓ} {n m} → Irrelevant _∼_ → Irrelevant (Pointwise _∼_ {n} {m})

src/Data/Nat/DivMod.agda

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@ open import Data.Nat.DivMod.Core
1717
open import Data.Nat.Divisibility.Core
1818
open import Data.Nat.Induction
1919
open import Data.Nat.Properties
20-
open import Data.Product.Base using (_,_)
21-
open import Data.Sum.Base using (inj₁; inj₂)
22-
open import Function.Base using (_$_; _∘_)
20+
open import Data.Product.Base using (_,_; ∃)
21+
open import Data.Sum.Base as Sum using (inj₁; inj₂)
22+
open import Function.Base using (id; _$_; _∘_; _on_)
23+
open import Function.Definitions using (Injective)
24+
open import Relation.Binary.Core using (Rel; _⇒_)
25+
open import Relation.Binary.Construct.Closure.Symmetric
26+
as SymClosure using (SymClosure; fwd; bwd)
2327
open import Relation.Binary.PropositionalEquality.Core
2428
using (_≡_; cong; cong₂; refl; trans; _≢_; sym)
2529
open import Relation.Nullary.Negation using (contradiction)
@@ -463,6 +467,78 @@ m%n*o≡m*o%[n*o] m n o = begin-equality
463467
p-1 * n + n ≡⟨ +-comm (p-1 * n) n ⟩
464468
pn ∎
465469

470+
------------------------------------------------------------------------
471+
-- Lemmas characterising the relation `m ≡ n (mod o)`
472+
473+
infix 4 _≡%[_]_
474+
_≡%[_]_ : m o .{{_ : NonZero o}} n Set _
475+
m ≡%[ o ] n = m % o ≡ n % o
476+
477+
-- Definition of an alternative, *asymmetric* version of that relation
478+
-- whose `Relation.Binary.Construct.Closure.Symmetric` is equivalent.
479+
480+
infix 4 _≲%[_]_ _≅%[_]_
481+
_≲%[_]_ _≅%[_]_ : m o n Set _
482+
483+
m ≲%[ o ] n =λ k n ≡ m + k * o
484+
m ≅%[ o ] n = SymClosure _≲%[ o ]_ m n
485+
486+
-- Equivalence between _≅%[_]_ and _≡[_]%_
487+
488+
module _ .{{_ : NonZero o}} where
489+
490+
≲%[o]⇒≡[o]% : _≲%[ o ]_ ⇒ _≡%[ o ]_
491+
≲%[o]⇒≡[o]% {x = m} {y = n} (k , eq) = begin-equality
492+
m % o ≡⟨ [m+kn]%n≡m%n m k o ⟨
493+
(m + k * o) % o ≡⟨ cong (_% o) eq ⟨
494+
n % o ∎
495+
496+
≅%[o]⇒≡[o]% : _≅%[ o ]_ ⇒ _≡%[ o ]_
497+
≅%[o]⇒≡[o]% = SymClosure.fold sym ≲%[o]⇒≡[o]%
498+
499+
≡[o]%⇒≲%[o] : m % o ≡ n % o m ≤ n m ≲%[ o ] n
500+
≡[o]%⇒≲%[o] {m = m} {n = n} eq m≤n = k , (begin-equality
501+
n ≡⟨ m≡m%n+[m/n]*n n o ⟩
502+
n % o + n / o * o ≡⟨ cong (_+ n / o * o) eq ⟨
503+
m % o + n / o * o ≡⟨ cong ((m % o +_) ∘ (_* o)) (m+[n∸m]≡n (/-monoˡ-≤ o m≤n)) ⟨
504+
m % o + (m / o + k) * o ≡⟨ cong (m % o +_) (*-distribʳ-+ o (m / o) k) ⟩
505+
m % o + (m / o * o + k * o) ≡⟨ +-assoc (m % o) _ _ ⟨
506+
(m % o + m / o * o) + k * o ≡⟨ cong (_+ k * o) (m≡m%n+[m/n]*n m o) ⟨
507+
m + k * o ∎)
508+
where k = n / o ∸ m / o
509+
510+
≡[o]%⇒≅%[o] : _≡%[ o ]_ ⇒ _≅%[ o ]_
511+
≡[o]%⇒≅%[o] {x = m} {y = n} eq =
512+
Sum.[ fwd ∘ ≡[o]%⇒≲%[o] eq , bwd ∘ ≡[o]%⇒≲%[o] (sym eq) ]′ (≤-total m n)
513+
514+
≡%-suc-injective : Injective _≡%[ o ]_ _≡%[ o ]_ suc
515+
≡%-suc-injective = ≅%[o]⇒≡[o]% ∘ lemma-≅% ∘ ≡[o]%⇒≅%[o]
516+
where
517+
lemma-≲% : (_≲%[ o ]_ on suc) ⇒ _≲%[ o ]_
518+
lemma-≲% (k , eq) = k , cong pred eq
519+
520+
lemma-≅% : (_≅%[ o ]_ on suc) ⇒ _≅%[ o ]_
521+
lemma-≅% = SymClosure.hmap suc id lemma-≲%
522+
523+
private
524+
525+
-- Alex Rice's optimised direct proof of the above
526+
≡%[o]-suc-injective : .{{_ : NonZero o}} Injective _≡%[ o ]_ _≡%[ o ]_ suc
527+
≡%[o]-suc-injective {o = so@(suc o)} {x = m} {y = n} eq = begin-equality
528+
m % so ≡⟨ lemma m ⟩
529+
(suc m % so + o % so) % so ≡⟨ cong (λ a (a + o % so) % so) eq ⟩
530+
(suc n % so + o % so) % so ≡⟨ lemma n ⟨
531+
n % so ∎
532+
where
533+
lemma : n n % so ≡ (suc n % so + o % so) % so
534+
lemma n = begin-equality
535+
n % so ≡⟨ [m+n]%n≡m%n n so ⟨
536+
(n + so) % so ≡⟨⟩
537+
(n + suc o) % so ≡⟨ %-congˡ (+-suc n o) ⟩
538+
(suc n + o) % so ≡⟨ %-distribˡ-+ (suc n) o so ⟩
539+
(suc n % so + o % so) % so ∎
540+
541+
466542
------------------------------------------------------------------------
467543
-- A specification of integer division.
468544

src/Relation/Binary/Construct/Closure/Symmetric.agda

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import Relation.Binary.Construct.On as On
1717
private
1818
variable
1919
a ℓ ℓ₁ ℓ₂ : Level
20-
A B : Set a
20+
A B C : Set a
2121
R S : Rel A ℓ
2222

2323
------------------------------------------------------------------------
@@ -38,10 +38,22 @@ symmetric _ (bwd bRa) = fwd bRa
3838
------------------------------------------------------------------------
3939
-- Operations
4040

41-
-- A generalised variant of `map` which allows the index type to change.
41+
-- A generalised variant of `map` where *both* index types can change.
42+
hmap : (g : C A) (f : C B) (R on g) ⇒ (S on f)
43+
((SymClosure R) on g) ⇒ ((SymClosure S) on f)
44+
hmap _ _ g*R⇒f*S (fwd aRb) = fwd (g*R⇒f*S aRb)
45+
hmap _ _ g*R⇒f*S (bwd bRa) = bwd (g*R⇒f*S bRa)
46+
47+
-- Hence: SymClosure commutes with `on`
48+
on⁺ : (g : B A) ((SymClosure R) on g) ⇒ SymClosure (R on g)
49+
on⁺ g = hmap g id id
50+
51+
on⁻ : (g : B A) SymClosure (R on g) ⇒ ((SymClosure R) on g)
52+
on⁻ g = hmap id g id
53+
54+
-- And: the 'usual' generalised variant of `map`
4255
gmap : (f : A B) R =[ f ]⇒ S SymClosure R =[ f ]⇒ SymClosure S
43-
gmap _ g (fwd aRb) = fwd (g aRb)
44-
gmap _ g (bwd bRa) = bwd (g bRa)
56+
gmap = hmap id
4557

4658
map : R ⇒ S SymClosure R ⇒ SymClosure S
4759
map = gmap id

0 commit comments

Comments
 (0)