Skip to content

Commit 2d33bff

Browse files
committed
feat(NumberTheory): Frobenius number exists & ℕ is Noetherian semiring (#27743)
+ The Frobenius number of a set of natural numbers exist iff the set has gcd 1 and doesn't contain 1. + All additive submonoids (= ideals) of ℕ are finitely generated. + The game of Sylver coinage always terminates. This is the outcome of a course project at Heidelberg University: [matematiflo.github.io/CompAssistedMath2025](https://matematiflo.github.io/CompAssistedMath2025/) Co-authored-by: Daniel Buth @greymatter8 Co-authored-by: Sebastian Meier @SebastianMeierUni
1 parent ec25e80 commit 2d33bff

File tree

5 files changed

+194
-28
lines changed

5 files changed

+194
-28
lines changed

Mathlib/Data/Set/Finite/Basic.lean

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,17 @@ end Multiset
388388
theorem List.finite_toSet (l : List α) : { x | x ∈ l }.Finite :=
389389
(show Multiset α from ⟦l⟧).finite_toSet
390390

391+
/-- `Finset α` is order isomorphic to the type of finite sets in `α`. -/
392+
@[simps] noncomputable def OrderIso.finsetSetFinite : Finset α ≃o {s : Set α // s.Finite} where
393+
toFun s := ⟨s, s.finite_toSet⟩
394+
invFun s := s.2.toFinset
395+
left_inv _ := by simp
396+
right_inv _ := by simp
397+
map_rel_iff' := .rfl
398+
399+
instance : WellFoundedLT {s : Set α // s.Finite} :=
400+
OrderIso.finsetSetFinite.symm.toOrderEmbedding.wellFoundedLT
401+
391402
/-! ### Finite instances
392403
393404
There is seemingly some overlap between the following instances and the `Fintype` instances

Mathlib/LinearAlgebra/FreeModule/PID.lean

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,11 @@ theorem eq_bot_of_generator_maximal_submoduleImage_eq_zero {N O : Submodule R M}
8181

8282
end Ring
8383

84-
section IsDomain
85-
86-
variable {ι : Type*} {R : Type*} [CommRing R] [IsDomain R]
87-
variable {M : Type*} [AddCommGroup M] [Module R M] {b : ι → M}
88-
89-
open Submodule.IsPrincipal Set Submodule
90-
91-
theorem dvd_generator_iff {I : Ideal R} [I.IsPrincipal] {x : R} (hx : x ∈ I) :
92-
x ∣ generator I ↔ I = Ideal.span {x} := by
93-
conv_rhs => rw [← span_singleton_generator I]
94-
rw [Ideal.submodule_span_eq, Ideal.span_singleton_eq_span_singleton, ← dvd_dvd_iff_associated,
95-
← mem_iff_generator_dvd]
96-
exact ⟨fun h ↦ ⟨hx, h⟩, fun h ↦ h.2
97-
98-
end IsDomain
84+
open Submodule.IsPrincipal in
85+
theorem dvd_generator_iff {R : Type*} [CommSemiring R] {I : Ideal R} [I.IsPrincipal] {x : R}
86+
(hx : x ∈ I) : x ∣ generator I ↔ I = Ideal.span {x} := by
87+
simp_rw [le_antisymm_iff, I.span_singleton_le_iff_mem.2 hx, and_true, ← Ideal.mem_span_singleton]
88+
conv_rhs => rw [← span_singleton_generator I, Submodule.span_singleton_le_iff_mem]
9989

10090
section PrincipalIdealDomain
10191

@@ -106,7 +96,7 @@ variable {M : Type*} [AddCommGroup M] [Module R M] {b : ι → M}
10696

10797
section StrongRankCondition
10898

109-
variable [IsDomain R] [IsPrincipalIdealRing R]
99+
variable [IsPrincipalIdealRing R]
110100

111101
open Submodule.IsPrincipal
112102

@@ -142,6 +132,8 @@ theorem generator_maximal_submoduleImage_dvd {N O : Submodule R M} (hNO : N ≤
142132
exact Ideal.span_singleton_le_span_singleton.mpr d_dvd_left
143133
· exact subset_span (mem_insert _ _)
144134

135+
variable [IsDomain R]
136+
145137
/-- The induction hypothesis of `Submodule.basisOfPid` and `Submodule.smithNormalForm`.
146138
147139
Basically, it says: let `N ≤ M` be a pair of submodules, then we can find a pair of

Mathlib/NumberTheory/FrobeniusNumber.lean

Lines changed: 155 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
/-
22
Copyright (c) 2021 Alex Zhao. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
4-
Authors: Alex Zhao
4+
Authors: Alex Zhao, Daniel Buth, Sebastian Meier, Junyan Xu
55
-/
6-
import Mathlib.Algebra.Group.Submonoid.Membership
7-
import Mathlib.Data.Nat.ModEq
8-
import Mathlib.Tactic.Ring
9-
import Mathlib.Tactic.Zify
6+
import Mathlib.RingTheory.Ideal.NatInt
107

118
/-!
12-
# Frobenius Number in Two Variables
9+
# Frobenius Number
1310
1411
In this file we first define a predicate for Frobenius numbers, then solve the 2-variable variant
15-
of this problem.
12+
of this problem. We also show the Frobenius number exists for any set of coprime natural numbers
13+
that doesn't contain 1. This is closely related to the fact that all ideals of ℕ are finitely
14+
generated, which we also prove in this file.
1615
1716
## Theorem Statement
1817
@@ -33,7 +32,7 @@ is a multiple of n, and we're done.
3332
3433
## Tags
3534
36-
frobenius number, chicken mcnugget, chinese remainder theorem, add_submonoid.closure
35+
frobenius number, chicken mcnugget, chinese remainder theorem, AddSubmonoid.closure
3736
-/
3837

3938

@@ -45,6 +44,10 @@ In other words, it is the largest number that cannot be expressed as a sum of nu
4544
def FrobeniusNumber (n : ℕ) (s : Set ℕ) : Prop :=
4645
IsGreatest { k | k ∉ AddSubmonoid.closure s } n
4746

47+
theorem frobeniusNumber_iff {n : ℕ} {s : Set ℕ} :
48+
FrobeniusNumber n s ↔ n ∉ AddSubmonoid.closure s ∧ ∀ k > n, k ∈ AddSubmonoid.closure s := by
49+
simp_rw [FrobeniusNumber, IsGreatest, upperBounds, Set.mem_setOf, not_imp_comm, not_le]
50+
4851
variable {m n : ℕ}
4952

5053
/-- The **Chicken McNugget theorem** stating that the Frobenius number
@@ -77,3 +80,147 @@ theorem frobeniusNumber_pair (cop : Coprime m n) (hm : 1 < m) (hn : 1 < n) :
7780
ModEq.le_of_lt_add
7881
(x.2.1.trans (modEq_zero_iff_dvd.mpr (Nat.dvd_sub (dvd_mul_right m n) dvd_rfl)).symm)
7982
(lt_of_lt_of_le hx le_tsub_add)
83+
84+
namespace Nat
85+
86+
open Submodule.IsPrincipal
87+
88+
/-- The gcd of a set of natural numbers is defined to be the nonnegative generator
89+
of the ideal of `ℤ` generated by them. -/
90+
noncomputable def setGcd (s : Set ℕ) : ℕ :=
91+
(generator <| Ideal.span <| ((↑) : ℕ → ℤ) '' s).natAbs
92+
93+
variable {s t : Set ℕ} {n : ℕ}
94+
95+
lemma setGcd_dvd_of_mem (h : n ∈ s) : setGcd s ∣ n := by
96+
rw [setGcd, ← Int.dvd_natCast, ← mem_iff_generator_dvd]
97+
exact Ideal.subset_span ⟨n, h, rfl⟩
98+
99+
lemma setGcd_dvd_of_mem_closure (h : n ∈ AddSubmonoid.closure s) : setGcd s ∣ n :=
100+
AddSubmonoid.closure_induction (fun _ ↦ setGcd_dvd_of_mem) (dvd_zero _) (fun _ _ _ _ ↦ dvd_add) h
101+
102+
/-- The characterizing property of `Nat.setGcd`. -/
103+
lemma dvd_setGcd_iff : n ∣ setGcd s ↔ ∀ m ∈ s, n ∣ m := by
104+
simp_rw [setGcd, ← Int.natCast_dvd, dvd_generator_span_iff,
105+
Set.forall_mem_image, Int.natCast_dvd_natCast]
106+
107+
lemma setGcd_mono (h : s ⊆ t) : setGcd t ∣ setGcd s :=
108+
dvd_setGcd_iff.mpr fun _m hm ↦ setGcd_dvd_of_mem (h hm)
109+
110+
lemma dvdNotUnit_setGcd_insert (h : ¬ setGcd s ∣ n) :
111+
DvdNotUnit (setGcd (insert n s)) (setGcd s) :=
112+
dvdNotUnit_of_dvd_of_not_dvd (setGcd_mono <| Set.subset_insert ..)
113+
fun dvd ↦ h <| dvd_setGcd_iff.mp dvd _ (Set.mem_insert ..)
114+
115+
lemma setGcd_insert_of_dvd (h : setGcd s ∣ n) : setGcd (insert n s) = setGcd s :=
116+
(setGcd_mono <| Set.subset_insert ..).antisymm <| dvd_setGcd_iff.mpr
117+
fun m ↦ by rintro (rfl | hm); exacts [h, setGcd_dvd_of_mem hm]
118+
119+
lemma setGcd_eq_zero_iff : setGcd s = 0 ↔ s ⊆ {0} := by
120+
simp_rw [setGcd, Int.natAbs_eq_zero, ← eq_bot_iff_generator_eq_zero, Ideal.span_eq_bot,
121+
Set.forall_mem_image, Int.natCast_eq_zero, Set.subset_def, Set.mem_singleton_iff]
122+
123+
lemma exists_ne_zero_of_setGcd_ne_zero (hs : setGcd s ≠ 0) : ∃ n ∈ s, n ≠ 0 := by
124+
contrapose! hs
125+
exact setGcd_eq_zero_iff.mpr hs
126+
127+
variable (s)
128+
129+
lemma span_singleton_setGcd : Ideal.span {(setGcd s : ℤ)} = Ideal.span (((↑) : ℕ → ℤ) '' s) := by
130+
rw [setGcd, ← Ideal.span_singleton_eq_span_singleton.mpr (Int.associated_natAbs _),
131+
Ideal.span, span_singleton_generator]
132+
133+
lemma subset_span_setGcd : s ⊆ Ideal.span {setGcd s} :=
134+
fun _x hx ↦ Ideal.mem_span_singleton.mpr (setGcd_dvd_of_mem hx)
135+
136+
open Ideal in
137+
theorem exists_mem_span_nat_finset_of_ge :
138+
∃ (t : Finset ℕ) (n : ℕ), ↑t ⊆ s ∧ ∀ m ≥ n, setGcd s ∣ m → m ∈ Ideal.span t := by
139+
by_cases h0 : setGcd s = 0
140+
· refine ⟨∅, 0, by simp, fun _ _ dvd ↦ by cases zero_dvd_iff.mp (h0 ▸ dvd); exact zero_mem _⟩
141+
-- Write the gcd of `s` as a ℤ-linear combination of a finite subset `t`.
142+
have ⟨t, hts, a, eq⟩ := (Submodule.mem_span_image_iff_exists_fun _).mp
143+
(span_singleton_setGcd s ▸ mem_span_singleton_self _)
144+
-- Let `x` be an arbitrary nonzero element in `s`.
145+
have ⟨x, hxs, hx⟩ := exists_ne_zero_of_setGcd_ne_zero h0
146+
let n := (x / setGcd s) * ∑ i, (-a i).toNat * i
147+
refine ⟨insert x t, n, by simpa [Set.insert_subset_iff] using ⟨hxs, hts⟩, fun m ge dvd ↦ ?_⟩
148+
-- For `m ≥ n`, write `m = q * x + (r + n)` with 0 ≤ r < x.
149+
obtain ⟨c, rfl⟩ := exists_add_of_le ge
150+
rw [← c.div_add_mod' x]
151+
set q := c / x
152+
set r := c % x
153+
rw [add_comm, add_assoc]
154+
refine add_mem (mul_mem_left _ q (subset_span (Finset.mem_insert_self ..)))
155+
(Submodule.span_mono (s := t) (Finset.subset_insert ..) ?_)
156+
-- It suffices to show `r + n` lies in the ℕ-span of `t`.
157+
obtain ⟨rx, hrx⟩ : setGcd s ∣ r := (dvd_mod_iff (setGcd_dvd_of_mem hxs)).mpr <|
158+
(Nat.dvd_add_right <| dvd_mul_of_dvd_right (Finset.dvd_sum fun i _ ↦
159+
dvd_mul_of_dvd_right (setGcd_dvd_of_mem (hts i.2)) _) _).mp dvd
160+
convert (sum_mem fun i _ ↦ mul_mem_left _ _ (subset_span i.2) :
161+
-- an explicit ℕ-linear combination of elements of `t` that is equal to `r + n`
162+
∑ i : t, (if 0 ≤ a i then rx else x / setGcd s - rx) * (a i).natAbs * i ∈ span t)
163+
simp_rw [← Int.natCast_inj, hrx, n, Finset.mul_sum, mul_comm _ rx, cast_add, cast_sum, cast_mul,
164+
← eq, Finset.mul_sum, smul_eq_mul, ← mul_assoc, ← Finset.sum_add_distrib, ← add_mul]
165+
congr! 2 with i
166+
split_ifs with hai
167+
· rw [Int.toNat_eq_zero.mpr (by omega), cast_zero, mul_zero, add_zero,
168+
Int.natCast_natAbs, abs_eq_self.mpr hai]
169+
· rw [cast_sub, Int.natCast_natAbs, abs_eq_neg_self.mpr (by omega), sub_mul,
170+
← Int.eq_natCast_toNat.mpr (by omega), mul_neg (rx : ℤ), sub_neg_eq_add, add_comm]
171+
rw [← Nat.mul_le_mul_left_iff (pos_of_ne_zero h0), ← hrx,
172+
Nat.mul_div_cancel' (setGcd_dvd_of_mem hxs)]
173+
exact (c.mod_lt (pos_of_ne_zero hx)).le
174+
175+
theorem exists_mem_closure_of_ge : ∃ n, ∀ m ≥ n, setGcd s ∣ m → m ∈ AddSubmonoid.closure s :=
176+
have ⟨_t, n, hts, hn⟩ := exists_mem_span_nat_finset_of_ge s
177+
⟨n, fun m ge dvd ↦ (Submodule.span_nat_eq_addSubmonoidClosure s).le
178+
(Submodule.span_mono hts (hn m ge dvd))⟩
179+
180+
theorem finite_setOf_setGcd_dvd_and_mem_span :
181+
{n | setGcd s ∣ n ∧ n ∉ Ideal.span s}.Finite :=
182+
have ⟨n, hn⟩ := exists_mem_closure_of_ge s
183+
(Finset.range n).finite_toSet.subset fun m h ↦ Finset.mem_range.mpr <|
184+
lt_of_not_ge fun ge ↦ h.2 <| (Submodule.span_nat_eq_addSubmonoidClosure s).ge (hn m ge h.1)
185+
186+
/-- `ℕ` is a Noetherian `ℕ`-module, i.e., `ℕ` is a Noetherian semiring. -/
187+
instance : IsNoetherian ℕ ℕ where
188+
noetherian s := by
189+
have ⟨t, n, hts, hn⟩ := exists_mem_span_nat_finset_of_ge s
190+
classical
191+
refine ⟨t ∪ {m ∈ Finset.range n | m ∈ s}, (Submodule.span_le.mpr ?_).antisymm fun m hm ↦ ?_⟩
192+
· simpa using ⟨hts, fun _ ↦ And.right⟩
193+
obtain le | gt := le_or_gt n m
194+
· exact Submodule.span_mono (by simp) (hn m le (setGcd_dvd_of_mem hm))
195+
· exact Submodule.subset_span (by simpa using .inr ⟨gt, hm⟩)
196+
197+
theorem addSubmonoid_fg (s : AddSubmonoid ℕ) : s.FG := by
198+
rw [← s.toNatSubmodule_toAddSubmonoid, ← Submodule.fg_iff_addSubmonoid_fg]
199+
apply IsNoetherian.noetherian
200+
201+
end Nat
202+
203+
/-- A set of natural numbers has a Frobenius number iff their gcd is 1; if 1 is in the set,
204+
the Frobenius number is -1, so the Frobenius number doesn't exist as a natural number.
205+
[Wikipedia](https://en.wikipedia.org/wiki/Coin_problem#Statement) seems to attribute this to
206+
Issai Schur, but [Schur's theorem](https://en.wikipedia.org/wiki/Schur%27s_theorem#Combinatorics)
207+
is a more precise statement about asymptotics of the number of ℕ-linear combinations, and the
208+
existence of the Frobenius number for a set with gcd 1 is probably well known before that. -/
209+
theorem exists_frobeniusNumber_iff {s : Set ℕ} :
210+
(∃ n, FrobeniusNumber n s) ↔ setGcd s = 11 ∉ s where
211+
mp := fun ⟨n, hn⟩ ↦ by
212+
rw [frobeniusNumber_iff] at hn
213+
exact ⟨dvd_one.mp <| Nat.dvd_add_iff_right (setGcd_dvd_of_mem_closure (hn.2 (n + 1)
214+
(by omega))) (n := 1) |>.mpr (setGcd_dvd_of_mem_closure (hn.2 (n + 2) (by omega))),
215+
fun h ↦ hn.1 <| AddSubmonoid.closure_mono (Set.singleton_subset_iff.mpr h)
216+
(addSubmonoidClosure_one.ge ⟨⟩)⟩
217+
mpr h := by
218+
have ⟨n, hn⟩ := exists_mem_closure_of_ge s
219+
let P n := n ∉ AddSubmonoid.closure s
220+
have : P 1 := h.2 ∘ one_mem_closure_iff.mp
221+
classical
222+
refine ⟨findGreatest P n, frobeniusNumber_iff.mpr ⟨findGreatest_spec (P := P) (m := 1)
223+
(le_of_not_gt fun lt ↦ this (hn _ lt.le h.1.dvd)) this, fun k gt ↦ ?_⟩⟩
224+
obtain le | le := le_total k n
225+
· exact of_not_not (findGreatest_is_greatest gt le)
226+
· exact hn k le (h.1.dvd.trans <| one_dvd k)

Mathlib/RingTheory/Ideal/NatInt.lean

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,22 @@ theorem Nat.mem_maximalIdeal_iff {n : ℕ} : n ∈ maximalIdeal ℕ ↔ n ≠ 1
3434

3535
theorem Nat.coe_maximalIdeal : (maximalIdeal ℕ : Set ℕ) = {1}ᶜ := by ext; simp
3636

37-
theorem Nat.maximalIdeal_eq_span_two_three : maximalIdeal ℕ = .span {2, 3} := by
37+
theorem Nat.maximalIdeal_eq_span_two_three : maximalIdeal ℕ = span {2, 3} := by
3838
refine le_antisymm (fun n h ↦ ?_) (span_le.mpr <| Set.pair_subset (by simp) (by simp))
3939
obtain lt | lt := (mem_maximalIdeal_iff.mp h).lt_or_gt
4040
· obtain rfl := lt_one_iff.mp lt; exact zero_mem _
4141
exact mem_span_pair.mpr <|
4242
exists_add_mul_eq_of_gcd_dvd_of_mul_pred_le 2 3 n (by simp) (show 2 ≤ n by omega)
4343

44+
theorem Nat.one_mem_span_iff {s : Set ℕ} : 1 ∈ span s ↔ 1 ∈ s := by
45+
rw [← SetLike.mem_coe, ← not_iff_not]
46+
simp_rw [← Set.mem_compl_iff, ← Set.singleton_subset_iff, Set.subset_compl_comm,
47+
← coe_maximalIdeal, SetLike.coe_subset_coe, span_le]
48+
49+
theorem Nat.one_mem_closure_iff {s : Set ℕ} : 1 ∈ AddSubmonoid.closure s ↔ 1 ∈ s := by
50+
rw [← Submodule.span_nat_eq_addSubmonoidClosure]
51+
exact one_mem_span_iff
52+
4453
theorem Ideal.isPrime_nat_iff {P : Ideal ℕ} :
4554
P.IsPrime ↔ P = ⊥ ∨ P = maximalIdeal ℕ ∨ ∃ p : ℕ, p.Prime ∧ P = span {p} := by
4655
refine .symm ⟨?_, fun h ↦ or_iff_not_imp_left.mpr fun h0 ↦ or_iff_not_imp_right.mpr fun hsp ↦

Mathlib/RingTheory/PrincipalIdealDomain.lean

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ instance (priority := 100) _root_.IsPrincipalIdealRing.of_isNoetherianRing_of_is
115115

116116
end Semiring
117117

118-
section CommRing
118+
section CommSemiring
119119

120-
variable [CommRing R] [Module R M]
120+
variable [CommSemiring R] [Module R M]
121121

122122
theorem associated_generator_span_self [IsDomain R] (r : R) :
123123
Associated (generator <| Ideal.span {r}) r := by
@@ -146,7 +146,14 @@ theorem generator_submoduleImage_dvd_of_mem {N O : Submodule R M} (hNO : N ≤ O
146146
rw [← mem_iff_generator_dvd, LinearMap.mem_submoduleImage_of_le hNO]
147147
exact ⟨x, hx, rfl⟩
148148

149-
end CommRing
149+
theorem dvd_generator_span_iff {r : R} {s : Set R} [(Ideal.span s).IsPrincipal] :
150+
r ∣ generator (Ideal.span s) ↔ ∀ x ∈ s, r ∣ x where
151+
mp h x hx := h.trans <| (mem_iff_generator_dvd _).mp (Ideal.subset_span hx)
152+
mpr h := have : (span R s).IsPrincipal := ‹_›
153+
span_induction h (dvd_zero _) (fun _ _ _ _ ↦ dvd_add) (fun _ _ _ ↦ (·.mul_left _))
154+
(generator_mem _)
155+
156+
end CommSemiring
150157

151158
end Submodule.IsPrincipal
152159

0 commit comments

Comments
 (0)