Zulip Chat Archive
Stream: new members
Topic: covariant_class ℝ and ring_nf in calc
Patrick Johnson (Dec 11 2021 at 16:20):
While practicing calc
proof mode, I got stuck on this simple inequality:
import tactic
import data.real.basic
example {a b : ℝ}
(h₁ : a > 0)
(h₂ : b > 0) :
(a + b) * (1 / a + 4 / b) ≥ 9 :=
begin
apply sub_nonneg.mp,
apply (mul_le_mul_right (mul_pos h₁ h₂)).mp,
rw zero_mul,
calc _ ≤ (2 * a - b) ^ 2 : sq_nonneg _
... ≤ (a + b) * (b + 4 * a) - 9 * a * b : by ring_nf
... ≤ ((a + b) * (1 / a + 4 / b) - 9) * (a * b) : sorry,
sorry,
end
So I am interested to know:
- Why can't the first
sorry
be solvedby ring_nf
? - Why does the second
sorry
ask me to provecovariant_class ℝ ℝ (function.swap has_add.add) has_le.le
? - Can this proof be simplified somehow?
Kevin Buzzard (Dec 11 2021 at 16:34):
Division isn't a thing in rings, and neither is <=, so the first sorry
is out of scope for ringlike tactics for two reasons. There's a "clear denominators" tactic, and you probably want to change the <= to an =.
Alex J. Best (Dec 11 2021 at 16:37):
Also if things are equalities rather than inequalities you can state them as such, calc will still produce an inequality from a chain of \le
and =
, edit: oops just saw kevin already wrote this
Alex J. Best (Dec 11 2021 at 16:38):
P.s. its always easier to help if you include the imports, in this case import data.real.basic
Kevin Buzzard (Dec 11 2021 at 16:39):
Why if I use the (correct) ring
instead of ring_nf
the line above the first sorry, does it close the relevant goal and still tell me to use ring_nf
? Is this a bug?
Rob Lewis (Dec 11 2021 at 16:46):
Kevin Buzzard said:
Why if I use the (correct)
ring
instead ofring_nf
the line above the first sorry, does it close the relevant goal and still tell me to usering_nf
? Is this a bug?
Is your mathlib up to date? Mario made a couple changes to ring
this week, one to address a bug exactly like this
Kevin Buzzard (Dec 11 2021 at 16:56):
Is your mathlib up to date?
It is!
Rob Lewis (Dec 11 2021 at 16:58):
Oh, ring_nf
is the right tactic there. ring
is for equations, this is proving an inequality by normalizing to 0 <= 0
Kevin Buzzard (Dec 11 2021 at 16:59):
Why does the second sorry ask me to
prove covariant_class ℝ ℝ (function.swap has_add.add) has_le.le
?
This goal appeared when you did the unconventional apply sub_nonneg.mp
, as you can see if you put your cursor before and after that tactic. apply
is not always the cleverest when it comes to type class inference. You would be better off doing rw \l sub_nonneg
. You can solve the second goal with apply_instance
, the tactic which says "solve this goal using type class inference".
Kevin Buzzard (Dec 11 2021 at 17:00):
Oh, except the rewrite fails because you have you have not written your example in Lean's normal form: you should use <= not >=.
Kevin Buzzard (Dec 11 2021 at 17:04):
import data.real.basic
import tactic.field_simp -- clear denominator tactic
example {a b : ℝ}
(h₁ : 0 < a)
(h₂ : 0 < b) :
9 ≤ (a + b) * (1 / a + 4 / b) :=
begin
rw ← sub_nonneg,
apply (mul_le_mul_right (mul_pos h₁ h₂)).mp,
rw zero_mul,
calc _ ≤ (2 * a - b) ^ 2 : sq_nonneg _
... = (a + b) * (b + 4 * a) - 9 * a * b : by ring
... = ((a + b) * (1 / a + 4 / b) - 9) * (a * b) : _,
field_simp [(ne_of_gt h₁), (ne_of_gt h₂)],
ring,
end
Last updated: Dec 20 2023 at 11:08 UTC