@@ -44,6 +44,8 @@ theorem coe_rpow (x : ℝ≥0) (y : ℝ) : ((x ^ y : ℝ≥0) : ℝ) = (x : ℝ)
4444theorem rpow_zero (x : ℝ≥0 ) : x ^ (0 : ℝ) = 1 :=
4545 NNReal.eq <| Real.rpow_zero _
4646
47+ theorem rpow_zero_pos (x : ℝ≥0 ) : 0 < x ^ (0 : ℝ) := by rw [rpow_zero]; exact one_pos
48+
4749@[simp]
4850theorem rpow_eq_zero_iff {x : ℝ≥0 } {y : ℝ} : x ^ y = 0 ↔ x = 0 ∧ y ≠ 0 := by
4951 rw [← NNReal.coe_inj, coe_rpow, ← NNReal.coe_eq_zero]
@@ -456,6 +458,8 @@ theorem rpow_zero {x : ℝ≥0∞} : x ^ (0 : ℝ) = 1 := by
456458 · dsimp only [(· ^ ·), Pow.pow, rpow]
457459 simp
458460
461+ theorem rpow_zero_pos (x : ℝ≥0 ∞) : 0 < x ^ (0 : ℝ) := by rw [rpow_zero]; exact one_pos
462+
459463theorem top_rpow_def (y : ℝ) : (⊤ : ℝ≥0 ∞) ^ y = if 0 < y then ⊤ else if y = 0 then 1 else 0 :=
460464 rfl
461465
@@ -1062,3 +1066,62 @@ end ENNReal
10621066-- end Tactic
10631067
10641068-- end Tactics
1069+
1070+ /-! ### Positivity extension -/
1071+
1072+ namespace Mathlib.Meta.Positivity
1073+ open Lean Meta Qq
1074+
1075+ /-- Extension for the `positivity` tactic: exponentiation by a real number is nonnegative when
1076+ the base is nonnegative and positive when the base is positive.
1077+ This is the `NNReal` analogue of `evalRpow` for `Real`. -/
1078+ @[positivity (_ : ℝ≥0) ^ (_ : ℝ)]
1079+ def evalNNRealRpow : PositivityExt where eval {u α} _ _ e := do
1080+ match u, α, e with
1081+ | 0 , ~q(ℝ≥0 ), ~q($a ^ (0 : ℝ)) =>
1082+ assertInstancesCommute
1083+ pure (.positive q(NNReal.rpow_zero_pos $a))
1084+ | 0 , ~q(ℝ≥0 ), ~q($a ^ ($b : ℝ)) =>
1085+ let ra ← core q(inferInstance) q(inferInstance) a
1086+ assertInstancesCommute
1087+ match ra with
1088+ | .positive pa =>
1089+ pure (.positive q(NNReal.rpow_pos $pa))
1090+ | _ => pure (.nonnegative q(zero_le $e))
1091+ | _, _, _ => throwError "not NNReal.rpow"
1092+
1093+ private def isFiniteM? (x : Q(ℝ≥0 ∞)) : MetaM (Option Q($x ≠ (⊤ : ℝ≥0 ∞))) := do
1094+ let mvar ← mkFreshExprMVar q($x ≠ (⊤ : ℝ≥0 ∞))
1095+ let save ← saveState
1096+ let (goals, _) ← Elab.runTactic mvar.mvarId! <|← `(tactic| finiteness)
1097+ if goals.isEmpty then
1098+ pure <| some <|← instantiateMVars mvar
1099+ else
1100+ restoreState save
1101+ pure none
1102+
1103+ /-- Extension for the `positivity` tactic: exponentiation by a real number is nonnegative when
1104+ the base is nonnegative and positive when the base is positive.
1105+ This is the `ENNReal` analogue of `evalRpow` for `Real`. -/
1106+ @[positivity (_ : ℝ≥0∞) ^ (_ : ℝ)]
1107+ def evalENNRealRpow : PositivityExt where eval {u α} _ _ e := do
1108+ match u, α, e with
1109+ | 0 , ~q(ℝ≥0 ∞), ~q($a ^ (0 : ℝ)) =>
1110+ assertInstancesCommute
1111+ pure (.positive q(ENNReal.rpow_zero_pos $a))
1112+ | 0 , ~q(ℝ≥0 ∞), ~q($a ^ ($b : ℝ)) =>
1113+ let ra ← core q(inferInstance) q(inferInstance) a
1114+ let rb ← catchNone <| core q(inferInstance) q(inferInstance) b
1115+ assertInstancesCommute
1116+ match ra, rb with
1117+ | .positive pa, .positive pb =>
1118+ pure (.positive q(ENNReal.rpow_pos_of_nonneg $pa <| le_of_lt $pb))
1119+ | .positive pa, .nonnegative pb =>
1120+ pure (.positive q(ENNReal.rpow_pos_of_nonneg $pa $pb))
1121+ | .positive pa, _ =>
1122+ let some ha ← isFiniteM? a | pure <| .nonnegative q(zero_le $e)
1123+ pure <| .positive q(ENNReal.rpow_pos $pa $ha)
1124+ | _, _ => pure <| .nonnegative q(zero_le $e)
1125+ | _, _, _ => throwError "not ENNReal.rpow"
1126+
1127+ end Mathlib.Meta.Positivity
0 commit comments