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

chore(Algebra/Group/Defs): use Nat.binaryRec #17892

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
de06324
chore: move binary recursion on `Nat` into a new file
FR-vdash-bot Aug 6, 2024
3033105
fix
FR-vdash-bot Aug 6, 2024
8506e10
name
FR-vdash-bot Aug 6, 2024
751f288
shake
FR-vdash-bot Aug 6, 2024
6bc124d
shake
FR-vdash-bot Aug 6, 2024
a57d78f
fix shake
FR-vdash-bot Aug 6, 2024
d5931d2
noshake
FR-vdash-bot Aug 6, 2024
23e2cb7
do not need now
FR-vdash-bot Aug 6, 2024
a80d55d
Update Size.lean
FR-vdash-bot Aug 7, 2024
c317792
fix
FR-vdash-bot Aug 7, 2024
3e04e87
Merge branch 'master' into FR_binrec_move
FR-vdash-bot Oct 18, 2024
68a1ea8
fix merge
FR-vdash-bot Oct 18, 2024
4258b9a
fix merge
FR-vdash-bot Oct 18, 2024
e75ec4a
`@[elab_as_elim]`
FR-vdash-bot Oct 18, 2024
d50abd4
fix
FR-vdash-bot Oct 18, 2024
17887a9
chore(Algebra/Group/Defs): use `Nat.binaryRec`
FR-vdash-bot Oct 18, 2024
4e82f35
fix
FR-vdash-bot Oct 18, 2024
5f8b6f1
fix merge
FR-vdash-bot Oct 18, 2024
cf0f0c0
fix
FR-vdash-bot Oct 18, 2024
666559e
shake
FR-vdash-bot Oct 18, 2024
d05154d
Merge branch 'FR_binrec_move' into FR_use_binrec
FR-vdash-bot Oct 18, 2024
acd96c1
docs
FR-vdash-bot Oct 18, 2024
6ecf59e
Merge branch 'master' into FR_binrec_move
FR-vdash-bot Oct 18, 2024
59c99d6
fix merge
FR-vdash-bot Oct 18, 2024
5a1ffd8
fix merge
FR-vdash-bot Oct 18, 2024
482dc99
chore(Data/Nat/{Bit, Bitwise}): make `Nat.bit_mod_two` `Nat.bit_eq_ze…
FR-vdash-bot Oct 18, 2024
0ad6c92
fix
FR-vdash-bot Oct 18, 2024
8e55b14
shake
FR-vdash-bot Oct 19, 2024
51a9eb2
fix shake
FR-vdash-bot Oct 19, 2024
cd22f61
Merge branch 'master' into FR_bit_simp
FR-vdash-bot Oct 19, 2024
d0457d0
Update BinaryRec.lean
FR-vdash-bot Oct 19, 2024
ae00268
fix merge
FR-vdash-bot Oct 19, 2024
d9077a5
Merge branch 'master' into FR_binrec_move
FR-vdash-bot Oct 19, 2024
10eb2d1
reduce diffs
FR-vdash-bot Oct 19, 2024
5eb3319
fix merge
FR-vdash-bot Oct 19, 2024
9522165
style
FR-vdash-bot Oct 19, 2024
9bb2be3
motive
FR-vdash-bot Oct 19, 2024
4ee3f7e
docs
FR-vdash-bot Oct 19, 2024
c48963f
Merge branch 'master' into FR_binrec_move
FR-vdash-bot Oct 19, 2024
c91878e
Merge branch 'FR_bit_simp' into FR_binrec_move
FR-vdash-bot Oct 19, 2024
2323b04
fix shake
FR-vdash-bot Oct 19, 2024
e2eb4d6
Revert "reduce diffs"
FR-vdash-bot Oct 19, 2024
96b026b
Merge branch 'master' into FR_binrec_move
FR-vdash-bot Oct 19, 2024
57a6f2c
copyright
FR-vdash-bot Oct 19, 2024
8d91e67
`Authors`
FR-vdash-bot Oct 19, 2024
307db7f
Merge branch 'FR_binrec_move' into FR_use_binrec
FR-vdash-bot Oct 20, 2024
39fd67e
Merge branch 'master' into FR_use_binrec
FR-vdash-bot Oct 20, 2024
de61000
Merge remote-tracking branch 'origin/master' into FR_use_binrec
eric-wieser Oct 21, 2024
7104392
suggestion
FR-vdash-bot Oct 22, 2024
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
107 changes: 30 additions & 77 deletions Mathlib/Algebra/Group/Defs.lean
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jeremy Avigad, Leonardo de Moura, Simon Hudon, Mario Carneiro
-/
import Mathlib.Data.Int.Notation
import Mathlib.Data.Nat.BinaryRec
import Mathlib.Algebra.Group.ZeroOne
import Mathlib.Logic.Function.Defs
import Mathlib.Tactic.Lemma
Expand Down Expand Up @@ -583,40 +584,16 @@ needed. These problems do not come up in practice, so most of the time we will n
the `npow` field when defining multiplicative objects.
-/

/--
Scalar multiplication by repeated self-addition,
the additive version of exponentation by repeated squaring.
-/
-- Ideally this would be generated by `@[to_additive]` from `npowBinRec`.
def nsmulBinRec {M : Type*} [Zero M] [Add M] (k : ℕ) (m : M) : M :=
go k 0 m
where
/-- Auxiliary tail-recursive implementation for `nsmulBinRec`-/
go : ℕ → M → M → M
| 0, y, _ => y
| (k + 1), y, x =>
let k' := (k + 1) >>> 1
if k &&& 1 = 1 then
go k' y (x + x)
else
go k' (y + x) (x + x)

/-- Exponentiation by repeated squaring. -/
@[to_additive existing]
def npowBinRec {M : Type*} [One M] [Mul M] (k : ℕ) (m : M) : M :=
go k 1 m
@[to_additive "Scalar multiplication by repeated self-addition,
the additive version of exponentation by repeated squaring."]
def npowBinRec {M : Type*} [One M] [Mul M] (k : ℕ) : M → M :=
npowBinRec.go k 1
where
/-- Auxiliary tail-recursive implementation for `npowBinRec`-/
go : ℕ → M → M → M
| 0, y, _ => y
| (k + 1), y, x =>
let k' := (k + 1) >>> 1
if k &&& 1 = 1 then
go k' y (x * x)
else
go k' (y * x) (x * x)

attribute [to_additive existing] npowBinRec.go
/-- Auxiliary tail-recursive implementation for `npowBinRec`. -/
@[to_additive nsmulBinRec.go "Auxiliary tail-recursive implementation for `nsmulBinRec`."]
go (k : ℕ) : M → M → M :=
k.binaryRec (fun y _ ↦ y) fun bn _n fn y x ↦ fn (cond bn (y * x) y) (x * x)

/--
A variant of `npowRec` which is a semigroup homomorphisms from `ℕ₊` to `M`.
Expand All @@ -637,9 +614,10 @@ def nsmulRec' {M : Type*} [Zero M] [Add M] : ℕ → M → M
attribute [to_additive existing] npowRec'

@[to_additive]
theorem npowRec'_succ {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) :
npowRec' (k + 2) m = npowRec' (k + 1) m * m := by
rfl
theorem npowRec'_succ {M : Type*} [Semigroup M] [One M] {k : ℕ} (_ : k ≠ 0) (m : M) :
npowRec' (k + 1) m = npowRec' k m * m :=
match k with
| _ + 1 => rfl

@[to_additive]
theorem npowRec'_two_mul {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) :
Expand All @@ -652,12 +630,11 @@ theorem npowRec'_two_mul {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) :
| k + 2 => simp [npowRec', ← mul_assoc, ← ih]

@[to_additive]
theorem npowRec'_mul_comm {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) :
m * npowRec' (k + 1) m = npowRec' (k + 1) m * m := by
theorem npowRec'_mul_comm {M : Type*} [Semigroup M] [One M] {k : ℕ} (k0 : k ≠ 0) (m : M) :
m * npowRec' k m = npowRec' k m * m := by
induction k using Nat.strongRecOn with
| ind k' ih =>
match k' with
| 0 => rfl
| 1 => simp [npowRec', mul_assoc]
| k + 2 => simp [npowRec', ← mul_assoc, ih]

Expand All @@ -669,41 +646,25 @@ theorem npowRec_eq {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) :
match k' with
| 0 => rfl
| k + 1 =>
rw [npowRec, npowRec'_succ, ← mul_assoc]
rw [npowRec, npowRec'_succ k.succ_ne_zero, ← mul_assoc]
congr
simp [ih]

@[to_additive]
theorem npowBinRec.go_spec {M : Type*} [Semigroup M] [One M] (k : ℕ) (m n : M) :
npowBinRec.go (k + 1) m n = m * npowRec' (k + 1) n := by
induction k using Nat.strongRecOn generalizing m n with
| ind k' ih =>
cases k' with
| zero => simp [go, npowRec']
| succ k' =>
rw [go]
split <;> rename_i w <;> rw [(by omega : (k' + 1 + 1) >>> 1 = k' >>> 1 + 1)]
· rw [ih]
· congr 1
rw [← npowRec'_two_mul]
congr 1
rw [Nat.shiftRight_eq_div_pow, Nat.pow_one, Nat.mul_add, Nat.mul_div_cancel']
simp only [Nat.and_one_is_mod] at w
omega
· omega
· rw [ih]
· rw [mul_assoc]
rw [← npowRec'_two_mul]
congr 1
conv =>
rhs
rw [npowRec']
rw [← npowRec'_mul_comm]
congr 2
· rw [Nat.shiftRight_eq_div_pow, Nat.pow_one]
simp only [Nat.and_one_is_mod] at w
omega
· omega
unfold go
generalize hk : k + 1 = k'
replace hk : k' ≠ 0 := by omega
induction k' using Nat.binaryRecFromOne generalizing n m with
| z₀ => simp at hk
| z₁ => simp [npowRec']
| f b k' k'0 ih =>
rw [Nat.binaryRec_eq rfl, ih _ _ k'0]
cases b <;> simp only [Nat.bit, cond_false, cond_true, ← Nat.two_mul, npowRec'_two_mul]
rw [npowRec'_succ (by omega), npowRec'_two_mul, ← npowRec'_two_mul,
← npowRec'_mul_comm (by omega), mul_assoc]

/--
An abbreviation for `npowRec` with an additional typeclass assumption on associativity
so that we can use `@[csimp]` to replace it with an implementation by repeated squaring
Expand All @@ -727,20 +688,12 @@ as an automatic parameter."]
abbrev npowBinRecAuto {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) : M :=
npowBinRec k m

@[csimp]
theorem nsmulRec_eq_nsmulBinRec : @nsmulRecAuto = @nsmulBinRecAuto := by
funext M _ _ k m
rw [nsmulBinRecAuto, nsmulRecAuto, nsmulBinRec]
match k with
| 0 => rw [nsmulRec, nsmulBinRec.go]
| k + 1 => rw [nsmulBinRec.go_spec, nsmulRec_eq]

@[csimp]
@[to_additive (attr := csimp)]
theorem npowRec_eq_npowBinRec : @npowRecAuto = @npowBinRecAuto := by
funext M _ _ k m
rw [npowBinRecAuto, npowRecAuto, npowBinRec]
match k with
| 0 => rw [npowRec, npowBinRec.go]
| 0 => rw [npowRec, npowBinRec.go, Nat.binaryRec_zero]
| k + 1 => rw [npowBinRec.go_spec, npowRec_eq]

/-- An `AddMonoid` is an `AddSemigroup` with an element `0` such that `0 + a = a + 0 = a`. -/
Expand Down