Zulip Chat Archive
Stream: mathlib4
Topic: norm_num extensions
Patrick Massot (Oct 27 2023 at 19:02):
Terence Tao was disappointed that Lean cannot provide numerical estimates for common functions. He specifically points out:
import Mathlib
open Real
example : rexp 1 * 2 - 2 ≤ 8 * (rexp 1 - 2) := by
linarith [quadratic_le_exp_of_nonneg (show 0 ≤ 1 by norm_num)]
example : 2*sqrt 7 ≤ 7 := by
sorry
example : exp (4/exp 1) ≤ 7 := by
sorry
where the first example works but requires an idea. I guess the second example would be doable pretty quickly deducing from concavity of sqrt
that sqrt x ≤ (x-9)/6+3
(the right-hand side is the first-order approximation at (9, 3)). And I don't want to think about the third example. But really all three examples should be by norm_num
. How far are we from that? @Mario Carneiro
Geoffrey Irving (Oct 27 2023 at 19:26):
I’m working on fixed point interval arithmetic now, which could be one attack on this problem if it’s lifted to floating point (fixed point works only if one is willing do to manual work to pick the exponent).
Rob Lewis (Oct 27 2023 at 19:36):
I agree this kind of thing should be automated, but I'm not convinced norm_num
is the tool. This sounds like a numeric approximation tactic, not numeral normalization.
Patrick Massot (Oct 27 2023 at 19:54):
Ok, I would be happy with approx_num
.
Geoffrey Irving (Oct 27 2023 at 19:56):
I’ll share my interval arithmetic code once it’s in reasonable shape. Unless someone else has a better version, in which case I’ll switch to that. :)
Geoffrey Irving (Oct 27 2023 at 19:57):
It uses only UInt64
arithmetic, so no additional axioms (though it’ll be fastest with reduce_bool
).
Rob Lewis (Oct 27 2023 at 20:02):
Incidentally, I tried this (thinking of a sequence of lemmas for rexp 1
parallel to docs#Real.pi_gt_three) and it failed. Looks like linarith
's parser needs to learn about ofScientific
.
import Mathlib
open Real
lemma two_lt_rexp_1 : 2.5 < rexp 1 := sorry
example : rexp 1 * 2 - 2 ≤ 8 * (rexp 1 - 2) := by
linarith [two_lt_rexp_1]
Jireh Loreaux (Oct 27 2023 at 21:25):
Here @Mario Carneiro mentions he has some version of an approx
tactic, but it's not clear to me if it is still in Lean 3, ported to Lean 4, almost ready for a PR, or what.
Mario Carneiro (Oct 27 2023 at 22:48):
It's not almost ready for a PR. In lean 3 it was almost ready as a backend (there was no frontend to speak of), and since mathporting there is still a lot of stuff that has to be done manually to port the tactic part, and after that one also has to design a usable frontend. I tried to give this out as a project but it wasn't a good choice at the time, and right now I think there are other projects higher on the priority list for me.
Joseph Myers (Oct 28 2023 at 01:50):
You could no doubt prove the third inequality along the lines of my Lean 3 example of bounding powers - https://leanprover.zulipchat.com/#narrow/stream/208328-IMO-grand-challenge/topic/IMO.202020/near/212247641 (the bounds for are now in mathlib) - though of course an approx
tactic would be much better.
Joseph Myers (Oct 28 2023 at 12:19):
The square root example is at least straightforward by squaring both sides.
import Mathlib.Data.Real.Sqrt
open Real
example : 2 * sqrt 7 ≤ 7 := by
refine nonneg_le_nonneg_of_sq_le_sq (by positivity) ?_
rw [← pow_two, mul_pow]
norm_num
Arend Mellendijk (Oct 28 2023 at 12:30):
For what it's worth this bound is loose enough that you can get away with some pretty bad estimates for the exponential case. That said this really should be a one-liner.
import Mathlib
open Real
lemma expon_help : 4 / exp 1 ≤ 8/5 := by
have h := Real.one_sub_div_pow_le_exp_neg (n:=6) (t:=-1) (by norm_num)
norm_num at h
rw [div_le_iff (by positivity)]
linarith
lemma help : exp (8/5) ≤ 7 := by
have h := Real.one_sub_div_pow_le_exp_neg (n:=5) (t:=8/5) (by norm_num)
rw[←inv_le_inv (by positivity) (by positivity), ←Real.exp_neg] at h
norm_num at h
linarith
example : exp (4/exp 1) ≤ 7 :=
(exp_le_exp.mpr expon_help).trans help
Bolton Bailey (Oct 28 2023 at 12:57):
A tactic like this has been desired for a while.
Gareth Ma (Oct 28 2023 at 15:44):
I think for these lemmas one possible way is to evaluate exp
and other terms to some precision using the taylor series using Complex.exp_bound' or their Real equivalent, then use linarith
to handle the rest?
Adomas Baliuka (Nov 03 2023 at 00:26):
For the general tactic, maybe the approach used for the Coq Interval library is an idea?
There's also something confusing me about Never mind, it just can't deal with decimal notation... Replace the goal linarith
4.96 => 496 / 100
and it works.
import Mathlib
open Real
-- Note `exp (8/5) ≈ 4.953032424395114803654286356423964256413`
lemma help : exp (8/5) ≤ 4.96 := by
have h := Real.one_sub_div_pow_le_exp_neg (n:=9999) (t:=8/5) (by norm_num)
rw[←inv_le_inv (by positivity) (by positivity), ←Real.exp_neg] at h
norm_num at h
-- the bound obtained is `exp (8/5) ≤ 4.953666584191391635467168979...`
linarith -- so maybe this could work?
Last updated: Dec 20 2023 at 11:08 UTC