Skip to content

Commit 211b784

Browse files
committed
feat(*): add simp/gcongr attrs and use them (#27718)
Also weaken assumptions of `Polynomial.X_pow_sub_one_mul_prod_cyclotomic_eq_X_pow_sub_one_of_dvd`. Co-authored-by: Yury Kudryashov <162619279+yury-harmonic@users.noreply.github.com>
1 parent d7257f6 commit 211b784

File tree

21 files changed

+97
-58
lines changed

21 files changed

+97
-58
lines changed

Mathlib/Algebra/Divisibility/Basic.lean

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ Schreier domain if it is moreover integrally closed. -/
9696
theorem exists_dvd_and_dvd_of_dvd_mul [DecompositionMonoid α] {b c a : α} (H : a ∣ b * c) :
9797
∃ a₁ a₂, a₁ ∣ b ∧ a₂ ∣ c ∧ a = a₁ * a₂ := DecompositionMonoid.primal a H
9898

99+
@[gcongr]
100+
theorem mul_dvd_mul_left (a : α) (h : b ∣ c) : a * b ∣ a * c := by
101+
obtain ⟨d, rfl⟩ := h
102+
use d
103+
rw [mul_assoc]
104+
99105
end Semigroup
100106

101107
section Monoid
@@ -117,6 +123,7 @@ theorem dvd_of_eq (h : a = b) : a ∣ b := by rw [h]
117123

118124
alias Eq.dvd := dvd_of_eq
119125

126+
@[gcongr]
120127
lemma pow_dvd_pow (a : α) (h : m ≤ n) : a ^ m ∣ a ^ n :=
121128
⟨a ^ (n - m), by rw [← pow_add, Nat.add_comm, Nat.sub_add_cancel h]⟩
122129

@@ -128,11 +135,6 @@ alias Dvd.dvd.pow := dvd_pow
128135

129136
lemma dvd_pow_self (a : α) {n : ℕ} (hn : n ≠ 0) : a ∣ a ^ n := dvd_rfl.pow hn
130137

131-
theorem mul_dvd_mul_left (a : α) (h : b ∣ c) : a * b ∣ a * c := by
132-
obtain ⟨d, rfl⟩ := h
133-
use d
134-
rw [mul_assoc]
135-
136138
end Monoid
137139

138140
section CommSemigroup
@@ -166,6 +168,7 @@ alias Dvd.dvd.mul_left := dvd_mul_of_dvd_right
166168

167169
attribute [local simp] mul_assoc mul_comm mul_left_comm
168170

171+
@[gcongr]
169172
theorem mul_dvd_mul : ∀ {a b c d : α}, a ∣ b → c ∣ d → a * c ∣ b * d
170173
| a, _, c, _, ⟨e, rfl⟩, ⟨f, rfl⟩ => ⟨e * f, by simp⟩
171174

@@ -176,21 +179,28 @@ theorem dvd_mul [DecompositionMonoid α] {k m n : α} :
176179
k ∣ m * n ↔ ∃ d₁ d₂, d₁ ∣ m ∧ d₂ ∣ n ∧ k = d₁ * d₂ := by
177180
refine ⟨exists_dvd_and_dvd_of_dvd_mul, ?_⟩
178181
rintro ⟨d₁, d₂, hy, hz, rfl⟩
179-
exact mul_dvd_mul hy hz
182+
gcongr
180183

181184
end CommSemigroup
182185

183186
section CommMonoid
184187

185188
variable [CommMonoid α] {a b : α}
186189

190+
@[gcongr]
187191
theorem mul_dvd_mul_right (h : a ∣ b) (c : α) : a * c ∣ b * c :=
188192
mul_dvd_mul h (dvd_refl c)
189193

190-
theorem pow_dvd_pow_of_dvd (h : a ∣ b) : ∀ n : ℕ, a ^ n ∣ b ^ n
191-
| 0 => by rw [pow_zero, pow_zero]
192-
| n + 1 => by
194+
@[gcongr]
195+
theorem pow_dvd_pow_of_dvd (h : a ∣ b) (n : ℕ) : a ^ n ∣ b ^ n := by
196+
induction n with
197+
| zero => simp
198+
| succ =>
193199
rw [pow_succ, pow_succ]
194-
exact mul_dvd_mul (pow_dvd_pow_of_dvd h n) h
200+
gcongr
201+
202+
@[gcongr]
203+
lemma pow_dvd_pow_of_dvd_of_le {m n : ℕ} (hab : a ∣ b) (hmn : m ≤ n) : a ^ m ∣ b ^ n := by
204+
trans (a ^ n) <;> gcongr
195205

196206
end CommMonoid

Mathlib/Algebra/GCDMonoid/Nat.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def associatesIntEquivNat : Associates ℤ ≃ ℕ := by
146146
refine ⟨(·.out.natAbs), (Associates.mk ·), ?_, fun n ↦ ?_⟩
147147
· refine Associates.forall_associated.2 fun a ↦ ?_
148148
refine Associates.mk_eq_mk_iff_associated.2 <| Associated.symm <| ⟨normUnit a, ?_⟩
149-
simp [Int.abs_eq_normalize, normalize_apply]
149+
simp [Int.natCast_natAbs, Int.abs_eq_normalize, normalize_apply]
150150
· dsimp only [Associates.out_mk]
151151
rw [← Int.abs_eq_normalize, Int.natAbs_abs, Int.natAbs_natCast]
152152

Mathlib/Algebra/Order/Group/Unbundled/Int.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ theorem abs_eq_natAbs : ∀ a : ℤ, |a| = natAbs a
3737
| (n : ℕ) => abs_of_nonneg <| ofNat_zero_le _
3838
| -[_+1] => abs_of_nonpos <| le_of_lt <| negSucc_lt_zero _
3939

40-
@[simp, norm_cast] lemma natCast_natAbs (n : ℤ) : (n.natAbs : ℤ) = |n| := n.abs_eq_natAbs.symm
40+
@[norm_cast] lemma natCast_natAbs (n : ℤ) : (n.natAbs : ℤ) = |n| := n.abs_eq_natAbs.symm
4141

4242
theorem natAbs_abs (a : ℤ) : natAbs |a| = natAbs a := by rw [abs_eq_natAbs]; rfl
4343

Mathlib/Algebra/Order/Ring/Int.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ instance instIsStrictOrderedRing : IsStrictOrderedRing ℤ := .of_mul_pos @Int.m
4343
lemma isCompl_even_odd : IsCompl { n : ℤ | Even n } { n | Odd n } := by
4444
simp [← not_even_iff_odd, ← Set.compl_setOf, isCompl_compl]
4545

46+
@[simp]
4647
lemma _root_.Nat.cast_natAbs {α : Type*} [AddGroupWithOne α] (n : ℤ) : (n.natAbs : α) = |n| := by
4748
rw [← natCast_natAbs, Int.cast_natCast]
4849

Mathlib/Combinatorics/SimpleGraph/Finite.lean

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,11 @@ theorem edgeFinset_subset_edgeFinset : G₁.edgeFinset ⊆ G₂.edgeFinset ↔ G
7171

7272
theorem edgeFinset_ssubset_edgeFinset : G₁.edgeFinset ⊂ G₂.edgeFinset ↔ G₁ < G₂ := by simp
7373

74-
@[gcongr] alias ⟨_, edgeFinset_mono⟩ := edgeFinset_subset_edgeFinset
74+
@[mono, gcongr] alias ⟨_, edgeFinset_mono⟩ := edgeFinset_subset_edgeFinset
7575

76+
@[mono, gcongr]
7677
alias ⟨_, edgeFinset_strict_mono⟩ := edgeFinset_ssubset_edgeFinset
7778

78-
attribute [mono] edgeFinset_mono edgeFinset_strict_mono
79-
8079
@[simp]
8180
theorem edgeFinset_bot : (⊥ : SimpleGraph V).edgeFinset = ∅ := by simp [edgeFinset]
8281

Mathlib/Data/Finset/Card.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ theorem card_filter_eq_zero_iff {p : α → Prop} [DecidablePred p] :
292292
#(s.filter p) = 0 ↔ ∀ x ∈ s, ¬ p x := by
293293
rw [card_eq_zero, filter_eq_empty_iff]
294294

295+
@[gcongr]
295296
nonrec lemma card_lt_card (h : s ⊂ t) : #s < #t := card_lt_card <| val_lt_iff.2 h
296297

297298
lemma card_strictMono : StrictMono (card : Finset α → ℕ) := fun _ _ ↦ card_lt_card

Mathlib/Data/Int/Log.lean

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,17 @@ theorem log_zpow {b : ℕ} (hb : 1 < b) (z : ℤ) : log b (b ^ z : R) = z := by
142142
neg_nonpos.2 (Int.natCast_nonneg _)),
143143
zpow_neg, inv_inv, zpow_natCast, ← Nat.cast_pow, Nat.ceil_natCast, Nat.clog_pow _ _ hb]
144144

145-
@[mono]
145+
@[mono, gcongr]
146146
theorem log_mono_right {b : ℕ} {r₁ r₂ : R} (h₀ : 0 < r₁) (h : r₁ ≤ r₂) : log b r₁ ≤ log b r₂ := by
147147
rcases le_total r₁ 1 with h₁ | h₁ <;> rcases le_total r₂ 1 with h₂ | h₂
148-
· rw [log_of_right_le_one _ h₁, log_of_right_le_one _ h₂, neg_le_neg_iff, Int.ofNat_le]
149-
exact Nat.clog_mono_right _ (Nat.ceil_mono <| inv_anti₀ h₀ h)
148+
· rw [log_of_right_le_one _ h₁, log_of_right_le_one _ h₂]
149+
gcongr
150150
· rw [log_of_right_le_one _ h₁, log_of_one_le_right _ h₂]
151151
exact (neg_nonpos.mpr (Int.natCast_nonneg _)).trans (Int.natCast_nonneg _)
152152
· obtain rfl := le_antisymm h (h₂.trans h₁)
153153
rfl
154-
· rw [log_of_one_le_right _ h₁, log_of_one_le_right _ h₂, Int.ofNat_le]
155-
exact Nat.log_mono_right (Nat.floor_mono h)
154+
· rw [log_of_one_le_right _ h₁, log_of_one_le_right _ h₂]
155+
gcongr
156156

157157
variable (R) in
158158
/-- Over suitable subtypes, `zpow` and `Int.log` form a galois coinsertion -/
@@ -269,7 +269,8 @@ theorem clog_zpow {b : ℕ} (hb : 1 < b) (z : ℤ) : clog b (b ^ z : R) = z := b
269269
theorem clog_mono_right {b : ℕ} {r₁ r₂ : R} (h₀ : 0 < r₁) (h : r₁ ≤ r₂) :
270270
clog b r₁ ≤ clog b r₂ := by
271271
rw [← neg_log_inv_eq_clog, ← neg_log_inv_eq_clog, neg_le_neg_iff]
272-
exact log_mono_right (inv_pos.mpr <| h₀.trans_le h) (inv_anti₀ h₀ h)
272+
gcongr
273+
exact inv_pos.2 (h₀.trans_le h)
273274

274275
variable (R) in
275276
/-- Over suitable subtypes, `Int.clog` and `zpow` form a galois insertion -/

Mathlib/Data/Int/ModEq.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ end ModEq
6262

6363
theorem modEq_comm : a ≡ b [ZMOD n] ↔ b ≡ a [ZMOD n] := ⟨ModEq.symm, ModEq.symm⟩
6464

65+
@[simp]
6566
theorem natCast_modEq_iff {a b n : ℕ} : a ≡ b [ZMOD n] ↔ a ≡ b [MOD n] := by
6667
unfold ModEq Nat.ModEq; rw [← Int.ofNat_inj]; simp
6768

Mathlib/Data/Multiset/Defs.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,14 @@ def card : Multiset α → ℕ := Quot.lift length fun _l₁ _l₂ => Perm.lengt
222222
theorem coe_card (l : List α) : card (l : Multiset α) = length l :=
223223
rfl
224224

225+
@[gcongr]
225226
theorem card_le_card {s t : Multiset α} (h : s ≤ t) : card s ≤ card t :=
226227
leInductionOn h Sublist.length_le
227228

228229
theorem eq_of_le_of_card_le {s t : Multiset α} (h : s ≤ t) : card t ≤ card s → s = t :=
229230
leInductionOn h fun s h₂ => congr_arg _ <| s.eq_of_length_le h₂
230231

232+
@[gcongr]
231233
theorem card_lt_card {s t : Multiset α} (h : s < t) : card s < card t :=
232234
lt_of_not_ge fun h₂ => _root_.ne_of_lt h <| eq_of_le_of_card_le (le_of_lt h) h₂
233235

Mathlib/Data/Nat/Log.lean

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ theorem log_eq_of_pow_le_of_lt_pow {b m n : ℕ} (h₁ : b ^ m ≤ n) (h₂ : n
146146
exact log_of_lt h₂
147147
· exact (log_eq_iff (Or.inl hm)).2 ⟨h₁, h₂⟩
148148

149+
@[simp]
149150
theorem log_pow {b : ℕ} (hb : 1 < b) (x : ℕ) : log b (b ^ x) = x :=
150151
log_eq_of_pow_le_of_lt_pow le_rfl (Nat.pow_lt_pow_right hb x.lt_succ_self)
151152

@@ -156,6 +157,7 @@ theorem log_eq_one_iff {b n : ℕ} : log b n = 1 ↔ n < b * b ∧ 1 < b ∧ b
156157
log_eq_one_iff'.trans
157158
fun h => ⟨h.2, lt_mul_self_iff.1 (h.1.trans_lt h.2), h.1⟩, fun h => ⟨h.2.2, h.1⟩⟩
158159

160+
@[simp]
159161
theorem log_mul_base {b n : ℕ} (hb : 1 < b) (hn : n ≠ 0) : log b (n * b) = log b n + 1 := by
160162
apply log_eq_of_pow_le_of_lt_pow <;> rw [pow_succ', Nat.mul_comm b]
161163
exacts [Nat.mul_le_mul_right _ (pow_log_le_self _ hn),
@@ -172,7 +174,7 @@ theorem log_monotone {b : ℕ} : Monotone (log b) := by
172174
exact zero_le _
173175
· exact le_log_of_pow_le hb (pow_log_le_add_one _ _)
174176

175-
@[mono]
177+
@[mono, gcongr]
176178
theorem log_mono_right {b n m : ℕ} (h : n ≤ m) : log b n ≤ log b m :=
177179
log_monotone h
178180

@@ -190,7 +192,7 @@ theorem log_eq_log_succ_iff {b n : ℕ} (hb : 1 < b) (hn : n ≠ 0) :
190192
simp only [le_antisymm_iff, and_iff_right_iff_imp]
191193
exact fun _ ↦ log_monotone (le_add_right n 1)
192194

193-
@[mono]
195+
@[mono, gcongr]
194196
theorem log_anti_left {b c n : ℕ} (hc : 1 < c) (hb : c ≤ b) : log b n ≤ log c n := by
195197
rcases eq_or_ne n 0 with (rfl | hn); · rw [log_zero_right, log_zero_right]
196198
apply le_log_of_pow_le hc
@@ -201,6 +203,12 @@ theorem log_anti_left {b c n : ℕ} (hc : 1 < c) (hb : c ≤ b) : log b n ≤ lo
201203
theorem log_antitone_left {n : ℕ} : AntitoneOn (fun b => log b n) (Set.Ioi 1) := fun _ hc _ _ hb =>
202204
log_anti_left (Set.mem_Iio.1 hc) hb
203205

206+
@[gcongr]
207+
theorem log_mono {b c m n : ℕ} (hc : 1 < c) (hb : c ≤ b) (hmn : m ≤ n) :
208+
log b m ≤ log c n := by
209+
trans log c m <;> gcongr
210+
assumption
211+
204212
@[simp]
205213
theorem log_div_base (b n : ℕ) : log b (n / b) = log b n - 1 := by
206214
rcases le_or_gt b 1 with hb | hb
@@ -293,6 +301,7 @@ theorem le_pow_iff_clog_le {b : ℕ} (hb : 1 < b) {x y : ℕ} : x ≤ b ^ y ↔
293301
theorem pow_lt_iff_lt_clog {b : ℕ} (hb : 1 < b) {x y : ℕ} : b ^ y < x ↔ y < clog b x :=
294302
lt_iff_lt_of_le_iff_le (le_pow_iff_clog_le hb)
295303

304+
@[simp]
296305
theorem clog_pow (b x : ℕ) (hb : 1 < b) : clog b (b ^ x) = x :=
297306
eq_of_forall_ge_iff fun z ↦ by rw [← le_pow_iff_clog_le hb, Nat.pow_le_pow_iff_right hb]
298307

@@ -304,15 +313,15 @@ theorem pow_pred_clog_lt_self {b : ℕ} (hb : 1 < b) {x : ℕ} (hx : 1 < x) :
304313
theorem le_pow_clog {b : ℕ} (hb : 1 < b) (x : ℕ) : x ≤ b ^ clog b x :=
305314
(le_pow_iff_clog_le hb).2 le_rfl
306315

307-
@[mono]
316+
@[mono, gcongr]
308317
theorem clog_mono_right (b : ℕ) {n m : ℕ} (h : n ≤ m) : clog b n ≤ clog b m := by
309318
rcases le_or_gt b 1 with hb | hb
310319
· rw [clog_of_left_le_one hb]
311320
exact zero_le _
312321
· rw [← le_pow_iff_clog_le hb]
313322
exact h.trans (le_pow_clog hb _)
314323

315-
@[mono]
324+
@[mono, gcongr]
316325
theorem clog_anti_left {b c n : ℕ} (hc : 1 < c) (hb : c ≤ b) : clog b n ≤ clog c n := by
317326
rw [← le_pow_iff_clog_le (lt_of_lt_of_le hc hb)]
318327
calc
@@ -324,6 +333,12 @@ theorem clog_monotone (b : ℕ) : Monotone (clog b) := fun _ _ => clog_mono_righ
324333
theorem clog_antitone_left {n : ℕ} : AntitoneOn (fun b : ℕ => clog b n) (Set.Ioi 1) :=
325334
fun _ hc _ _ hb => clog_anti_left (Set.mem_Iio.1 hc) hb
326335

336+
@[gcongr]
337+
theorem clog_mono {b c m n : ℕ} (hc : 1 < c) (hb : c ≤ b) (hmn : m ≤ n) :
338+
clog b m ≤ clog c n := by
339+
trans clog b n <;> gcongr; assumption
340+
341+
@[simp]
327342
theorem log_le_clog (b n : ℕ) : log b n ≤ clog b n := by
328343
obtain hb | hb := le_or_gt b 1
329344
· rw [log_of_left_le_one hb]

0 commit comments

Comments
 (0)