@@ -125,3 +125,39 @@ lemma monotone_ofReal : Monotone ofReal' := by
125125 simp only [ofReal_eq_coe, real_le_real, hxy]
126126
127127end Complex
128+
129+ namespace Mathlib.Meta.Positivity
130+ open Lean Meta Qq Complex
131+ open scoped ComplexOrder
132+
133+ private alias ⟨_, ofReal_pos⟩ := zero_lt_real
134+ private alias ⟨_, ofReal_nonneg⟩ := zero_le_real
135+ private alias ⟨_, ofReal_ne_zero_of_ne_zero⟩ := ofReal_ne_zero
136+
137+ /-- Extension for the `positivity` tactic: `Complex.ofReal` is positive/nonnegative/nonzero if its
138+ input is. -/
139+ @[positivity Complex.ofReal' _, Complex.ofReal _]
140+ def evalComplexOfReal : PositivityExt where eval {u α} _ _ e := do
141+ -- TODO: Can we avoid duplicating the code?
142+ match u, α, e with
143+ | 0 , ~q(ℂ), ~q(Complex.ofReal' $a) =>
144+ assumeInstancesCommute
145+ match ← core q(inferInstance) q(inferInstance) a with
146+ | .positive pa => return .positive q(ofReal_pos $pa)
147+ | .nonnegative pa => return .nonnegative q(ofReal_nonneg $pa)
148+ | .nonzero pa => return .nonzero q(ofReal_ne_zero_of_ne_zero $pa)
149+ | _ => return .none
150+ | 0 , ~q(ℂ), ~q(Complex.ofReal $a) =>
151+ assumeInstancesCommute
152+ match ← core q(inferInstance) q(inferInstance) a with
153+ | .positive pa => return .positive q(ofReal_pos $pa)
154+ | .nonnegative pa => return .nonnegative q(ofReal_nonneg $pa)
155+ | .nonzero pa => return .nonzero q(ofReal_ne_zero_of_ne_zero $pa)
156+ | _ => return .none
157+ | _, _ => throwError "not Complex.ofReal'"
158+
159+ example (x : ℝ) (hx : 0 < x) : 0 < (x : ℂ) := by positivity
160+ example (x : ℝ) (hx : 0 ≤ x) : 0 ≤ (x : ℂ) := by positivity
161+ example (x : ℝ) (hx : x ≠ 0 ) : (x : ℂ) ≠ 0 := by positivity
162+
163+ end Mathlib.Meta.Positivity
0 commit comments