1
1
/-
2
2
Copyright (c) 2021 Alex Zhao. All rights reserved.
3
3
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
5
5
-/
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
10
7
11
8
/-!
12
- # Frobenius Number in Two Variables
9
+ # Frobenius Number
13
10
14
11
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.
16
15
17
16
## Theorem Statement
18
17
@@ -33,7 +32,7 @@ is a multiple of n, and we're done.
33
32
34
33
## Tags
35
34
36
- frobenius number, chicken mcnugget, chinese remainder theorem, add_submonoid .closure
35
+ frobenius number, chicken mcnugget, chinese remainder theorem, AddSubmonoid .closure
37
36
-/
38
37
39
38
@@ -45,6 +44,10 @@ In other words, it is the largest number that cannot be expressed as a sum of nu
45
44
def FrobeniusNumber (n : ℕ) (s : Set ℕ) : Prop :=
46
45
IsGreatest { k | k ∉ AddSubmonoid.closure s } n
47
46
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
+
48
51
variable {m n : ℕ}
49
52
50
53
/-- 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) :
77
80
ModEq.le_of_lt_add
78
81
(x.2 .1 .trans (modEq_zero_iff_dvd.mpr (Nat.dvd_sub (dvd_mul_right m n) dvd_rfl)).symm)
79
82
(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 = 1 ∧ 1 ∉ 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)
0 commit comments