Skip to content

Commit 106f523

Browse files
Merge master into nightly-testing
2 parents ba09c43 + 883384f commit 106f523

File tree

9 files changed

+54
-66
lines changed

9 files changed

+54
-66
lines changed

Mathlib/Algebra/Polynomial/FieldDivision.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ theorem mod_X_sub_C_eq_C_eval (p : R[X]) (a : R) : p % (X - C a) = C (p.eval a)
338338
theorem mul_div_eq_iff_isRoot : (X - C a) * (p / (X - C a)) = p ↔ IsRoot p a :=
339339
divByMonic_eq_div p (monic_X_sub_C a) ▸ mul_divByMonic_eq_iff_isRoot
340340

341+
alias ⟨_, IsRoot.mul_div_eq⟩ := mul_div_eq_iff_isRoot
342+
341343
instance instEuclideanDomain : EuclideanDomain R[X] :=
342344
{ Polynomial.commRing,
343345
Polynomial.nontrivial with

Mathlib/RingTheory/AdjoinRoot.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ variable (f)
401401

402402
theorem mul_div_root_cancel [Fact (Irreducible f)] :
403403
(X - C (root f)) * ((f.map (of f)) / (X - C (root f))) = f.map (of f) :=
404-
mul_div_eq_iff_isRoot.2 <| isRoot_root _
404+
(isRoot_root _).mul_div_eq
405405

406406
end Irreducible
407407

Mathlib/Tactic/NormNum/Pow.lean

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -59,24 +59,25 @@ so we use an additional trick to do binary subdivision on `log2 b`. As a result
5959
a proof of depth `log (log b)` which will essentially never overflow before the numbers involved
6060
themselves exceed memory limits.
6161
-/
62-
partial def evalNatPow (a b : Q(ℕ)) : (c : Q(ℕ)) × Q(Nat.pow $a $b = $c) :=
62+
partial def evalNatPow (a b : Q(ℕ)) : OptionT CoreM ((c : Q(ℕ)) × Q(Nat.pow $a $b = $c)) := do
6363
if b.natLit! = 0 then
6464
haveI : $b =Q 0 := ⟨⟩
65-
⟨q(nat_lit 1), q(natPow_zero)⟩
65+
return ⟨q(nat_lit 1), q(natPow_zero)⟩
6666
else if a.natLit! = 0 then
6767
haveI : $a =Q 0 := ⟨⟩
6868
have b' : Q(ℕ) := mkRawNatLit (b.natLit! - 1)
6969
haveI : $b =Q Nat.succ $b' := ⟨⟩
70-
⟨q(nat_lit 0), q(zero_natPow)⟩
70+
return ⟨q(nat_lit 0), q(zero_natPow)⟩
7171
else if a.natLit! = 1 then
7272
haveI : $a =Q 1 := ⟨⟩
73-
⟨q(nat_lit 1), q(one_natPow)⟩
73+
return ⟨q(nat_lit 1), q(one_natPow)⟩
7474
else if b.natLit! = 1 then
7575
haveI : $b =Q 1 := ⟨⟩
76-
⟨a, q(natPow_one)⟩
76+
return ⟨a, q(natPow_one)⟩
7777
else
78+
guard <| ← Lean.checkExponent b.natLit!
7879
let ⟨c, p⟩ := go b.natLit!.log2 a q(nat_lit 1) a b _ .rfl
79-
⟨c, q(($p).run)⟩
80+
return ⟨c, q(($p).run)⟩
8081
where
8182
/-- Invariants: `a ^ b₀ = c₀`, `depth > 0`, `b >>> depth = b₀`, `p := Nat.pow $a $b₀ = $c₀` -/
8283
go (depth : Nat) (a b₀ c₀ b : Q(ℕ)) (p : Q(Prop)) (hp : $p =Q (Nat.pow $a $b₀ = $c₀)) :
@@ -120,28 +121,29 @@ theorem intPow_negOfNat_bit1 {b' c' : ℕ} (h1 : Nat.pow a b' = c')
120121
simp [mul_comm, mul_left_comm]
121122

122123
/-- Evaluates `Int.pow a b = c` where `a` and `b` are raw integer literals. -/
123-
partial def evalIntPow (za : ℤ) (a : Q(ℤ)) (b : Q(ℕ)) : ℤ × (c : Q(ℤ)) × Q(Int.pow $a $b = $c) :=
124+
partial def evalIntPow (za : ℤ) (a : Q(ℤ)) (b : Q(ℕ)) :
125+
OptionT CoreM (ℤ × (c : Q(ℤ)) × Q(Int.pow $a $b = $c)) := do
124126
have a' : Q(ℕ) := a.appArg!
125127
if 0 ≤ za then
126-
haveI : $a =Q .ofNat $a' := ⟨⟩
127-
let ⟨c, p⟩ := evalNatPow a' b
128-
⟨c.natLit!, q(.ofNat $c), q(intPow_ofNat $p)⟩
128+
have : $a =Q .ofNat $a' := ⟨⟩
129+
let ⟨c, p⟩ evalNatPow a' b
130+
return ⟨c.natLit!, q(.ofNat $c), q(intPow_ofNat $p)⟩
129131
else
130-
haveI : $a =Q .negOfNat $a' := ⟨⟩
132+
have : $a =Q .negOfNat $a' := ⟨⟩
131133
let b' := b.natLit!
132134
have b₀ : Q(ℕ) := mkRawNatLit (b' >>> 1)
133-
let ⟨c₀, p⟩ := evalNatPow a' b₀
135+
let ⟨c₀, p⟩ := evalNatPow a' b₀
134136
let c' := c₀.natLit!
135137
if b' &&& 1 == 0 then
136138
have c : Q(ℕ) := mkRawNatLit (c' * c')
137139
have pc : Q($c₀ * $c₀ = $c) := (q(Eq.refl $c) : Expr)
138140
have pb : Q(2 * $b₀ = $b) := (q(Eq.refl $b) : Expr)
139-
⟨c.natLit!, q(.ofNat $c), q(intPow_negOfNat_bit0 $p $pb $pc)⟩
141+
return ⟨c.natLit!, q(.ofNat $c), q(intPow_negOfNat_bit0 $p $pb $pc)⟩
140142
else
141143
have c : Q(ℕ) := mkRawNatLit (c' * (c' * a'.natLit!))
142144
have pc : Q($c₀ * ($c₀ * $a') = $c) := (q(Eq.refl $c) : Expr)
143145
have pb : Q(2 * $b₀ + 1 = $b) := (q(Eq.refl $b) : Expr)
144-
⟨-c.natLit!, q(.negOfNat $c), q(intPow_negOfNat_bit1 $p $pb $pc)⟩
146+
return ⟨-c.natLit!, q(.negOfNat $c), q(intPow_negOfNat_bit1 $p $pb $pc)⟩
145147

146148
-- see note [norm_num lemma function equality]
147149
theorem isNat_pow {α} [Semiring α] : ∀ {f : α → ℕ → α} {a : α} {b a' b' c : ℕ},
@@ -175,30 +177,30 @@ theorem isNNRat_pow {α} [Semiring α] {f : α → ℕ → α} {a : α} {an cn :
175177
/-- Main part of `evalPow`. -/
176178
def evalPow.core {u : Level} {α : Q(Type u)} (e : Q(«»)) (f : Q(«» → ℕ → «»)) (a : Q(«»))
177179
(b nb : Q(ℕ)) (pb : Q(IsNat «$b» «$nb»)) (sα : Q(Semiring «»)) (ra : Result a) :
178-
Option (Result e) := do
180+
OptionT CoreM (Result e) := do
179181
haveI' : $e =Q $a ^ $b := ⟨⟩
180182
haveI' : $f =Q HPow.hPow := ⟨⟩
181183
match ra with
182184
| .isBool .. => failure
183185
| .isNat sα na pa =>
184186
assumeInstancesCommute
185-
have ⟨c, r⟩ := evalNatPow na nb
187+
let ⟨c, r⟩ evalNatPow na nb
186188
return .isNat sα c q(isNat_pow (f := $f) (.refl $f) $pa $pb $r)
187189
| .isNegNat rα .. =>
188190
assumeInstancesCommute
189-
let ⟨za, na, pa⟩ ← ra.toInt rα
190-
have ⟨zc, c, r⟩ := evalIntPow za na nb
191+
let ⟨za, na, pa⟩ ← OptionT.mk <| pure (ra.toInt rα)
192+
let ⟨zc, c, r⟩ evalIntPow za na nb
191193
return .isInt rα c zc q(isInt_pow (f := $f) (.refl $f) $pa $pb $r)
192194
| .isNNRat dα _qa na da pa =>
193195
assumeInstancesCommute
194-
have ⟨nc, r1⟩ := evalNatPow na nb
195-
have ⟨dc, r2⟩ := evalNatPow da nb
196+
let ⟨nc, r1⟩ evalNatPow na nb
197+
let ⟨dc, r2⟩ evalNatPow da nb
196198
let qc := mkRat nc.natLit! dc.natLit!
197199
return .isNNRat dα qc nc dc q(isNNRat_pow (f := $f) (.refl $f) $pa $pb $r1 $r2)
198200
| .isNegNNRat dα qa na da pa =>
199201
assumeInstancesCommute
200-
have ⟨zc, nc, r1⟩ := evalIntPow qa.num q(Int.negOfNat $na) nb
201-
have ⟨dc, r2⟩ := evalNatPow da nb
202+
let ⟨zc, nc, r1⟩ evalIntPow qa.num q(Int.negOfNat $na) nb
203+
let ⟨dc, r2⟩ evalNatPow da nb
202204
let qc := mkRat zc dc.natLit!
203205
return .isRat dα qc nc dc q(isRat_pow (f := $f) (.refl $f) $pa $pb $r1 $r2)
204206

@@ -214,7 +216,9 @@ def evalPow : NormNumExt where eval {u α} e := do
214216
guard <|← withDefault <| withNewMCtxDepth <| isDefEq f q(HPow.hPow (α := $α))
215217
haveI' : $e =Q $a ^ $b := ⟨⟩
216218
haveI' : $f =Q HPow.hPow := ⟨⟩
217-
evalPow.core q($e) q($f) q($a) q($b) q($nb) q($pb) q($sα) ra
219+
let .some r ←
220+
liftM <| OptionT.run (evalPow.core q($e) q($f) q($a) q($b) q($nb) q($pb) q($sα) ra) | failure
221+
return r
218222

219223
theorem isNat_zpow_pos {α : Type*} [DivisionSemiring α] {a : α} {b : ℤ} {nb ne : ℕ}
220224
(pb : IsNat b nb) (pe' : IsNat (a ^ nb) ne) :

Mathlib/Tactic/Ring/Basic.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,11 @@ theorem mul_pow {ea₁ b c₁ : ℕ} {xa₁ : R}
890890
(_ : ea₁ * b = c₁) (_ : a₂ ^ b = c₂) : (xa₁ ^ ea₁ * a₂ : R) ^ b = xa₁ ^ c₁ * c₂ := by
891891
subst_vars; simp [_root_.mul_pow, pow_mul]
892892

893+
-- needed to lift from `OptionT CoreM` to `OptionT MetaM`
894+
private local instance {m m'} [Monad m] [Monad m'] [MonadLiftT m m'] :
895+
MonadLiftT (OptionT m) (OptionT m') where
896+
monadLift x := OptionT.mk x.run
897+
893898
/-- There are several special cases when exponentiating monomials:
894899
895900
* `1 ^ n = 1`

Mathlib/Topology/Algebra/Valued/LocallyCompact.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ lemma locallyFiniteOrder_units_mrange_of_isCompact_integer (hc : IsCompact (X :=
224224
· intro w
225225
simp only [U]
226226
split_ifs with hw
227-
· exact Valued.isOpen_closedball _ z0.ne'
227+
· exact Valued.isOpen_closedBall _ z0.ne'
228228
· refine Valued.isOpen_sphere _ ?_
229229
push_neg at hw
230230
refine (hw.trans' ?_).ne'

Mathlib/Topology/Algebra/Valued/ValuationTopology.lean

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,17 @@ theorem isClopen_ball (r : Γ₀) : IsClopen (X := R) {x | v x < r} :=
216216
⟨isClosed_ball _ _, isOpen_ball _ _⟩
217217

218218
/-- A closed ball centred at the origin in a valued ring is open. -/
219-
theorem isOpen_closedball {r : Γ₀} (hr : r ≠ 0) : IsOpen (X := R) {x | v x ≤ r} := by
219+
theorem isOpen_closedBall {r : Γ₀} (hr : r ≠ 0) : IsOpen (X := R) {x | v x ≤ r} := by
220220
rw [isOpen_iff_mem_nhds]
221221
intro x hx
222222
rw [mem_nhds]
223223
simp only [setOf_subset_setOf]
224224
exact ⟨Units.mk0 _ hr,
225225
fun y hy => (sub_add_cancel y x).symm ▸ le_trans (v.map_add _ _) (max_le (le_of_lt hy) hx)⟩
226226

227+
@[deprecated (since := "2025-10-09")]
228+
alias isOpen_closedball := isOpen_closedBall
229+
227230
/-- A closed ball centred at the origin in a valued ring is closed. -/
228231
theorem isClosed_closedBall (r : Γ₀) : IsClosed (X := R) {x | v x ≤ r} := by
229232
rw [← isOpen_compl_iff, isOpen_iff_mem_nhds]
@@ -235,7 +238,7 @@ theorem isClosed_closedBall (r : Γ₀) : IsClosed (X := R) {x | v x ≤ r} := b
235238

236239
/-- A closed ball centred at the origin in a valued ring is clopen. -/
237240
theorem isClopen_closedBall {r : Γ₀} (hr : r ≠ 0) : IsClopen (X := R) {x | v x ≤ r} :=
238-
⟨isClosed_closedBall _ _, isOpen_closedball _ hr⟩
241+
⟨isClosed_closedBall _ _, isOpen_closedBall _ hr⟩
239242

240243
/-- A sphere centred at the origin in a valued ring is clopen. -/
241244
theorem isClopen_sphere {r : Γ₀} (hr : r ≠ 0) : IsClopen (X := R) {x | v x = r} := by
@@ -257,7 +260,7 @@ theorem isClosed_sphere (r : Γ₀) : IsClosed (X := R) {x | v x = r} := by
257260

258261
/-- The closed unit ball in a valued ring is open. -/
259262
theorem isOpen_integer : IsOpen (_i.v.integer : Set R) :=
260-
isOpen_closedball _ one_ne_zero
263+
isOpen_closedBall _ one_ne_zero
261264

262265
@[deprecated (since := "2025-04-25")]
263266
alias integer_isOpen := isOpen_integer

Mathlib/Topology/ContinuousMap/CompactlySupported.lean

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -715,45 +715,10 @@ lemma exists_add_nnrealPart_add_eq (f g : C_c(α, ℝ)) : ∃ (h : C_c(α, ℝ
715715
use h
716716
refine ⟨hh, ?_⟩
717717
ext x
718+
have hhx := congr(($hh x : ℝ))
718719
simp only [coe_add, Pi.add_apply, nnrealPart_apply, coe_neg, Pi.neg_apply, NNReal.coe_add,
719-
Real.coe_toNNReal', ← neg_add]
720-
have hhx : (f x + g x) ⊔ 0 + ↑(h x) = f x ⊔ 0 + g x ⊔ 0 := by
721-
rw [← Real.coe_toNNReal', ← Real.coe_toNNReal', ← Real.coe_toNNReal', ← NNReal.coe_add,
722-
← NNReal.coe_add]
723-
have hhx' : ((f + g).nnrealPart + h) x = (f.nnrealPart + g.nnrealPart) x := by congr
724-
simp only [coe_add, Pi.add_apply, nnrealPart_apply] at hhx'
725-
exact congrArg toReal hhx'
726-
rcases le_total 0 (f x) with hfx | hfx
727-
· rcases le_total 0 (g x) with hgx | hgx
728-
· simp only [hfx, hgx, add_nonneg, sup_of_le_left, add_eq_left, coe_eq_zero] at hhx
729-
simp [hhx, hfx, hgx, add_nonpos]
730-
· rcases le_total 0 (f x + g x) with hfgx | hfgx
731-
· simp only [hfgx, sup_of_le_left, add_assoc, hfx, hgx, sup_of_le_right, add_zero,
732-
add_eq_left] at hhx
733-
rw [sup_of_le_right (neg_nonpos.mpr hfx), sup_of_le_left (neg_nonneg.mpr hgx),
734-
sup_of_le_right (neg_nonpos.mpr hfgx)]
735-
linarith
736-
· simp only [hfgx, sup_of_le_right, zero_add, hfx, sup_of_le_left, hgx, add_zero] at hhx
737-
rw [sup_of_le_right (neg_nonpos.mpr hfx), sup_of_le_left (neg_nonneg.mpr hgx),
738-
sup_of_le_left (neg_nonneg.mpr hfgx), hhx]
739-
ring
740-
· rcases le_total 0 (g x) with hgx | hgx
741-
· rcases le_total 0 (f x + g x) with hfgx | hfgx
742-
· simp only [hfgx, sup_of_le_left, add_comm, hfx, sup_of_le_right, hgx, zero_add] at hhx
743-
rw [sup_of_le_left (neg_nonneg.mpr hfx), sup_of_le_right (neg_nonpos.mpr hgx),
744-
sup_of_le_right (neg_nonpos.mpr hfgx), zero_add, add_zero]
745-
linarith
746-
· simp only [hfgx, sup_of_le_right, zero_add, hfx, hgx, sup_of_le_left] at hhx
747-
rw [sup_of_le_left (neg_nonneg.mpr hfx), sup_of_le_right (neg_nonpos.mpr hgx),
748-
sup_of_le_left (neg_nonneg.mpr hfgx), hhx]
749-
ring
750-
· simp only [(add_nonpos hfx hgx), sup_of_le_right, zero_add, hfx, hgx, add_zero,
751-
coe_eq_zero] at hhx
752-
rw [sup_of_le_left (neg_nonneg.mpr hfx),
753-
sup_of_le_left (neg_nonneg.mpr hgx),
754-
sup_of_le_left (neg_nonneg.mpr (add_nonpos hfx hgx)), hhx, neg_add_rev, NNReal.coe_zero,
755-
add_zero]
756-
ring
720+
Real.coe_toNNReal', ← neg_add, max_neg_zero] at hhx ⊢
721+
linear_combination hhx
757722

758723
/-- The compactly supported continuous `ℝ≥0`-valued function as a compactly supported `ℝ`-valued
759724
function. -/

MathlibTest/norm_num.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,3 +751,9 @@ example : (1 : R PUnit.{u+1} PUnit.{v+1}) <= 2 := by
751751
-- asymptotically slower than the GMP implementation.
752752
-- It would be great to fix that, and restore this test.
753753
example : 10^400000 = 10^400000 := by norm_num
754+
755+
theorem large1 {α} [Ring α] : 2^(2^2000) + (2*2) - 2^(2^2000) = (4 : α) := by
756+
-- large powers ignored rather than hanging
757+
set_option exponentiation.threshold 20 in
758+
norm_num1 -- TODO: this should warn, but the warning is discarded
759+
simp only [add_sub_cancel_left]

MathlibTest/norm_num_ext.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ import Mathlib.Tactic.Simproc.Factors
2727
Some tests of unported extensions are still commented out.
2828
-/
2929

30+
-- The default is very low, and we want to test performance on large numbers.
31+
set_option exponentiation.threshold 2000
32+
3033
-- set_option profiler true
3134
-- set_option trace.profiler true
3235
-- set_option trace.Tactic.norm_num true

0 commit comments

Comments
 (0)