Skip to content

Commit c36598a

Browse files
committed
feat(Data/Nat/DivSequence): add divisibility sequences and strong divisibility sequences (#41204)
This PR moves divisibility sequences from `NumberTheory/EllipticDivisibilitySequence.lean` to a new file `Data/Nat/DivSequence.lean` and adds strong divisibility sequences. Co-authored-by: tb65536 <thomas.l.browning@gmail.com>
1 parent 3aa8562 commit c36598a

4 files changed

Lines changed: 104 additions & 12 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4184,6 +4184,7 @@ public import Mathlib.Data.Nat.Digits.Defs
41844184
public import Mathlib.Data.Nat.Digits.Div
41854185
public import Mathlib.Data.Nat.Digits.Lemmas
41864186
public import Mathlib.Data.Nat.Dist
4187+
public import Mathlib.Data.Nat.DvdSequence
41874188
public import Mathlib.Data.Nat.EvenOddRec
41884189
public import Mathlib.Data.Nat.Factorial.Basic
41894190
public import Mathlib.Data.Nat.Factorial.BigOperators

Mathlib/Data/Nat/DvdSequence.lean

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/-
2+
Copyright (c) 2026 Thomas Browning. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Thomas Browning
5+
-/
6+
module
7+
8+
public import Mathlib.Algebra.Divisibility.Basic
9+
public import Mathlib.Algebra.Group.Action.Pi
10+
11+
/-!
12+
# Divisibility sequences
13+
14+
A sequence `f : ℕ → ℕ` is a *divisibility sequence* if it satisfies `f a ∣ f b` whenever `a ∣ b`.
15+
16+
A sequence `f : ℕ → ℕ` is a *strong divisibility sequence* if `gcd (f a) (f b) = f (gcd a b)`.
17+
18+
This file defines divisibility sequences and strong divisibility sequences, and provides some basic
19+
API for these definitions.
20+
21+
## Main definitions
22+
23+
* `IsDvdSeq`: A function `f` is a divisibility sequence if `a ∣ b` implies `f a ∣ f b`.
24+
* `Nat.IsStrongDvdSeq`: A function `f : ℕ → ℕ` is a strong divisibility sequence if `f` satisfies
25+
`gcd (f a) (f b) = f (gcd a b)`.
26+
-/
27+
28+
@[expose] public section
29+
30+
variable {α β γ : Type*}
31+
32+
-- this lemma regarding interaction between `smul` and `dvd` does not have a good home in mathlib
33+
lemma smul_dvd_smul [Monoid α] [Monoid β] [SMul α β] [IsScalarTower α β β]
34+
[IsScalarTower α α β] [SMulCommClass α β β] {a b : α} {c d : β}
35+
(hab : a ∣ b) (hcd : c ∣ d) : (a • c) ∣ (b • d) := by
36+
obtain ⟨⟨x, rfl⟩, ⟨y, rfl⟩⟩ := hab, hcd
37+
exact ⟨x • y, mul_smul_mul_comm a x c y⟩
38+
39+
/-- A function `f : α → β` is a divisibility sequence if `a ∣ b` implies `f a ∣ f b`. -/
40+
def IsDvdSequence [Dvd α] [Dvd β] (f : α → β) : Prop :=
41+
∀ a b, a ∣ b → f a ∣ f b
42+
43+
namespace IsDvdSequence
44+
45+
variable (α) in
46+
protected theorem id [Dvd α] : IsDvdSequence (id : α → α) :=
47+
fun _ _ ↦ id
48+
49+
variable (α) in
50+
protected theorem const [Dvd α] [Monoid β] (b : β) : IsDvdSequence (fun _ : α ↦ b) := by
51+
simp [IsDvdSequence]
52+
53+
protected theorem smul' [Dvd α] [Monoid β] [Monoid γ] {f : α → β} {g : α → γ} [SMul β γ]
54+
[IsScalarTower β γ γ] [IsScalarTower β β γ] [SMulCommClass β γ γ]
55+
(hf : IsDvdSequence f) (hg : IsDvdSequence g) : IsDvdSequence (f • g) :=
56+
fun a b hab ↦ smul_dvd_smul (hf a b hab) (hg a b hab)
57+
58+
protected theorem mul [Dvd α] [CommMonoid β] {f g : α → β}
59+
(hf : IsDvdSequence f) (hg : IsDvdSequence g) : IsDvdSequence (f * g) :=
60+
.smul' hf hg
61+
62+
protected theorem smul [Dvd α] [Monoid β] [Monoid γ] {f : α → γ} [SMul β γ]
63+
[IsScalarTower β γ γ] [IsScalarTower β β γ] [SMulCommClass β γ γ]
64+
(b : β) (hg : IsDvdSequence f) : IsDvdSequence (b • f) :=
65+
.smul' (.const α b) hg
66+
67+
end IsDvdSequence
68+
69+
namespace Nat
70+
71+
/-- A function `f : ℕ → ℕ` is a strong divisibility sequence if `gcd (f a) (f b) = f (gcd a b)`. -/
72+
def IsStrongDvdSequence (f : ℕ → ℕ) : Prop :=
73+
∀ a b, (f a).gcd (f b) = f (a.gcd b)
74+
75+
namespace IsStrongDvdSequence
76+
77+
theorem isDvdSequence {f : ℕ → ℕ} (hf : IsStrongDvdSequence f) : IsDvdSequence f := by
78+
intro a b hab
79+
simpa [gcd_eq_left hab, gcd_eq_left_iff_dvd] using hf a b
80+
81+
protected theorem id : IsStrongDvdSequence (id : ℕ → ℕ) :=
82+
fun _ _ ↦ rfl
83+
84+
protected theorem const (n : ℕ) : IsStrongDvdSequence (fun _ ↦ n) := by
85+
simp [IsStrongDvdSequence]
86+
87+
end IsStrongDvdSequence
88+
89+
end Nat

Mathlib/Data/Nat/Fib/Basic.lean

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module
88
public import Mathlib.Data.Finset.NatAntidiagonal
99
public import Mathlib.Data.Nat.GCD.Basic
1010
public import Mathlib.Data.Nat.BinaryRec
11+
public import Mathlib.Data.Nat.DvdSequence
1112
public import Mathlib.Logic.Function.Iterate
1213
public import Mathlib.Tactic.Ring
1314
public import Mathlib.Tactic.Zify
@@ -243,8 +244,13 @@ theorem fib_gcd (m n : ℕ) : fib (gcd m n) = gcd (fib m) (fib n) := by
243244
conv_rhs => rw [← mod_add_div' n m]
244245
rwa [gcd_fib_add_mul_self m (n % m) (n / m), gcd_comm (fib m) _]
245246

246-
theorem fib_dvd (m n : ℕ) (h : m ∣ n) : fib m ∣ fib n := by
247-
rwa [← gcd_eq_left_iff_dvd, ← fib_gcd, gcd_eq_left_iff_dvd.mpr]
247+
theorem isStrongDvdSequence_fib : IsStrongDvdSequence fib :=
248+
fun m n ↦ (fib_gcd m n).symm
249+
250+
theorem isDvdSequence_fib : IsDvdSequence fib :=
251+
isStrongDvdSequence_fib.isDvdSequence
252+
253+
alias fib_dvd := isDvdSequence_fib
248254

249255
theorem fib_succ_eq_sum_choose :
250256
∀ n : ℕ, fib (n + 1) = ∑ p ∈ Finset.antidiagonal n, choose p.1 p.2 :=

Mathlib/NumberTheory/EllipticDivisibilitySequence.lean

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Authors: David Kurniadi Angdinata
55
-/
66
module
77

8+
public import Mathlib.Data.Nat.DvdSequence
89
public import Mathlib.Data.Nat.EvenOddRec
910
public import Mathlib.Tactic.Linarith
1011
public import Mathlib.Tactic.LinearCombination
@@ -30,7 +31,6 @@ Some examples of EDSs include
3031
## Main definitions
3132
3233
* `IsEllSequence`: a sequence indexed by integers is an elliptic sequence.
33-
* `IsDivSequence`: a sequence indexed by integers is a divisibility sequence.
3434
* `IsEllDivSequence`: a sequence indexed by integers is an EDS.
3535
* `preNormEDS'`: the auxiliary sequence for a normalised EDS indexed by `ℕ`.
3636
* `preNormEDS`: the auxiliary sequence for a normalised EDS indexed by `ℤ`.
@@ -83,32 +83,28 @@ def IsEllSequence : Prop :=
8383
∀ m n r : ℤ, W (m + n) * W (m - n) * W r ^ 2 =
8484
W (m + r) * W (m - r) * W n ^ 2 - W (n + r) * W (n - r) * W m ^ 2
8585

86-
/-- The proposition that a sequence indexed by integers is a divisibility sequence. -/
87-
def IsDivSequence : Prop :=
88-
∀ m n : ℕ, m ∣ n → W m ∣ W n
86+
@[deprecated (since := "2026-06-30")] alias IsDivSequence := IsDvdSequence
8987

9088
/-- The proposition that a sequence indexed by integers is an EDS. -/
9189
def IsEllDivSequence : Prop :=
92-
IsEllSequence W ∧ IsDivSequence W
90+
IsEllSequence W ∧ IsDvdSequence W
9391

9492
lemma isEllSequence_id : IsEllSequence id :=
9593
fun _ _ _ => by simp_rw [id_eq]; ring1
9694

97-
lemma isDivSequence_id : IsDivSequence id :=
98-
fun _ _ => Int.ofNat_dvd.mpr
95+
@[deprecated (since := "2026-06-30")] alias isDivSequence_id := IsDvdSequence.id
9996

10097
/-- The identity sequence is an EDS. -/
10198
theorem isEllDivSequence_id : IsEllDivSequence id :=
102-
⟨isEllSequence_id, isDivSequence_id
99+
⟨isEllSequence_id, .id ℤ
103100

104101
variable {W}
105102

106103
lemma IsEllSequence.smul (h : IsEllSequence W) (x : R) : IsEllSequence (x • W) :=
107104
fun m n r => by
108105
linear_combination (norm := (simp_rw [Pi.smul_apply, smul_eq_mul]; ring1)) x ^ 4 * h m n r
109106

110-
lemma IsDivSequence.smul (h : IsDivSequence W) (x : R) : IsDivSequence (x • W) :=
111-
fun m n r => mul_dvd_mul_left x <| h m n r
107+
@[deprecated (since := "2026-06-30")] alias IsDivSequence.smul := IsDvdSequence.smul
112108

113109
lemma IsEllDivSequence.smul (h : IsEllDivSequence W) (x : R) : IsEllDivSequence (x • W) :=
114110
⟨h.left.smul x, h.right.smul x⟩

0 commit comments

Comments
 (0)