Zulip Chat Archive

Stream: new members

Topic: A simpler way to do numerical calculations


Yongxi Lin (Aaron) (Jan 20 2026 at 23:06):

import Mathlib

open Real

example : 1 / (16 : ) * (2 - (8 * (2 ^ (1 / (12 : )) - 1) + 2 ^ (12 / (5 : )) * (2 ^ (2 / (15 : )) - 1) +
    4 * (2 ^ (1 / (6 : )) - 1) + 2 ^ (12 / (6 : )) * (2 ^ (4 / (21 : )) - 1) + 2 ^ (3 / (2 : )) * (2 ^ (5 / (24 : )) - 1) +
    2 ^ (4 / (3 : )) * (2 ^ (2 / (9 : )) - 1) + 2 ^ (6 / (5 : )) * (2 ^ (7 / (30 : )) - 1) +
    2 ^ (12 / (11 : )) * (2 ^ (8 / (33 : )) - 1))) < 0 := by
  have := add_one_lt_exp (by positivity : log 2 * (1 / 12)  0)
  have := add_one_lt_exp (by positivity: log 2 * (12 / 5)  0)
  have := add_one_lt_exp (by positivity : log 2 * (2 / 15)  0)
  have := add_one_lt_exp (by positivity : log 2 * (1 / 6)  0)
  have := add_one_lt_exp (by positivity : log 2 * (12 / 7)  0)
  have := add_one_lt_exp (by positivity : log 2 * (4 / 21)  0)
  have := add_one_lt_exp (by positivity : log 2 * (3 / 2)  0)
  have := add_one_lt_exp (by positivity : log 2 * (5 / 24)  0)
  have := add_one_lt_exp (by positivity : log 2 * (4 / 3)  0)
  have := add_one_lt_exp (by positivity : log 2 * (2 / 9)  0)
  have := add_one_lt_exp (by positivity : log 2 * (6 / 5)  0)
  have := add_one_lt_exp (by positivity : log 2 * (7 / 30)  0)
  have := add_one_lt_exp (by positivity : log 2 * (12 / 11)  0)
  have := add_one_lt_exp (by positivity : log 2 * (8 / 33)  0)
  norm_num [exp_mul, exp_log] at *
  have := log_two_gt_d9
  nlinarith

Is there a way to make the code more concise? I am asking because I have 10 other similar goals like this that I need to finish.

Jakub Nowak (Jan 21 2026 at 01:57):

Maybe tactics from this project would help you? #general > LeanCert - Verified Computation & Interval Arithmetic
I haven't used it, but from what I understand it should deal with this kind of goals with only constants.

Bbbbbbbbba (Jan 21 2026 at 11:16):

Hmm, so I found out that even if I proved hf : ∀ x, x ≠ 0 → 0 < f x, positivity seems unable to use it unless I give it every case it needs to use explicitly. Is there a way around this?

Jakub Nowak (Jan 21 2026 at 11:18):

Maybe you could try hf {x} (h : x ≠ 0 := by positivity) : 0 < f x?

Bbbbbbbbba (Jan 21 2026 at 11:28):

Hmm, when I write have hf {x} (h : x ≠ 0 := by positivity) : 0 < f x := by, the default value for h does not seem to work

Bbbbbbbbba (Jan 21 2026 at 11:28):

As a lemma the default for h works, but I still need to manually specify x for positivity to use it

Jakub Nowak (Jan 21 2026 at 11:50):

@Yongxi Lin (Aaron) I wouldn't say it's simpler, but it automates your proof, so it might help with other goals?

import Mathlib

open Real

example : 1 / (16 : ) * (2 - (8 * (2 ^ (1 / (12 : )) - 1) + 2 ^ (12 / (5 : )) * (2 ^ (2 / (15 : )) - 1) +
    4 * (2 ^ (1 / (6 : )) - 1) + 2 ^ (12 / (6 : )) * (2 ^ (4 / (21 : )) - 1) + 2 ^ (3 / (2 : )) * (2 ^ (5 / (24 : )) - 1) +
    2 ^ (4 / (3 : )) * (2 ^ (2 / (9 : )) - 1) + 2 ^ (6 / (5 : )) * (2 ^ (7 / (30 : )) - 1) +
    2 ^ (12 / (11 : )) * (2 ^ (8 / (33 : )) - 1))) < 0 := by
  have h₁ {x} (h : x  0 := by positivity) : log 2 * x + 1 < 2 ^ x := by
    have := add_one_lt_exp (by positivity : log 2 * x  0)
    norm_num [exp_mul, exp_log] at this
    exact this
  have h₂ {x : } (h : 0  x := by positivity) : (0 : )  2 ^ x - 1 := by
    norm_num
    exact Real.one_le_rpow (by norm_num) h
  repeat grw [h₁]
  · have := log_two_gt_d9
    nlinarith
  all_goals exact h₂

Bbbbbbbbba (Jan 21 2026 at 11:57):

Yongxi Lin (Aaron) said:

import Mathlib

open Real

example : 1 / (16 : ) * (2 - (8 * (2 ^ (1 / (12 : )) - 1) + 2 ^ (12 / (5 : )) * (2 ^ (2 / (15 : )) - 1) +
    4 * (2 ^ (1 / (6 : )) - 1) + 2 ^ (12 / (6 : )) * (2 ^ (4 / (21 : )) - 1) + 2 ^ (3 / (2 : )) * (2 ^ (5 / (24 : )) - 1) +
    2 ^ (4 / (3 : )) * (2 ^ (2 / (9 : )) - 1) + 2 ^ (6 / (5 : )) * (2 ^ (7 / (30 : )) - 1) +
    2 ^ (12 / (11 : )) * (2 ^ (8 / (33 : )) - 1))) < 0 := by
  have := add_one_lt_exp (by positivity : log 2 * (1 / 12)  0)
  have := add_one_lt_exp (by positivity: log 2 * (12 / 5)  0)
  have := add_one_lt_exp (by positivity : log 2 * (2 / 15)  0)
  have := add_one_lt_exp (by positivity : log 2 * (1 / 6)  0)
  have := add_one_lt_exp (by positivity : log 2 * (12 / 7)  0)
  have := add_one_lt_exp (by positivity : log 2 * (4 / 21)  0)
  have := add_one_lt_exp (by positivity : log 2 * (3 / 2)  0)
  have := add_one_lt_exp (by positivity : log 2 * (5 / 24)  0)
  have := add_one_lt_exp (by positivity : log 2 * (4 / 3)  0)
  have := add_one_lt_exp (by positivity : log 2 * (2 / 9)  0)
  have := add_one_lt_exp (by positivity : log 2 * (6 / 5)  0)
  have := add_one_lt_exp (by positivity : log 2 * (7 / 30)  0)
  have := add_one_lt_exp (by positivity : log 2 * (12 / 11)  0)
  have := add_one_lt_exp (by positivity : log 2 * (8 / 33)  0)
  norm_num [exp_mul, exp_log] at *
  have := log_two_gt_d9
  nlinarith

Is there a way to make the code more concise? I am asking because I have 10 other similar goals like this that I need to finish.

For that matter, why do you have a 12 / 6 in your statement but 12 / 7 in your proof? :laughing:

Jakub Nowak (Jan 21 2026 at 12:06):

You can in fact remove have := add_one_lt_exp (by positivity : log 2 * (12 / 7) ≠ 0) and it still works. I've added have := add_one_lt_exp (by positivity : log 2 * (12 / 6) ≠ 0) and checked that only have := add_one_lt_exp (by positivity : log 2 * (12 / 6) ≠ 0) can be removed, not any other. Quite puzzling. Maybe the only bound needed for the proof is something that nlinarith can work out on its own, like 2 ^ (12 / (6 : ℝ)) > 0.

Bbbbbbbbba (Jan 21 2026 at 12:10):

Well, obviously norm_num simplifies 2 ^ (12 / 6) :laughing:

Yongxi Lin (Aaron) (Jan 21 2026 at 16:40):

Jakub Nowak said:

Yongxi Lin (Aaron) I wouldn't say it's simpler, but it automates your proof, so it might help with other goals?

import Mathlib

open Real

example : 1 / (16 : ) * (2 - (8 * (2 ^ (1 / (12 : )) - 1) + 2 ^ (12 / (5 : )) * (2 ^ (2 / (15 : )) - 1) +
    4 * (2 ^ (1 / (6 : )) - 1) + 2 ^ (12 / (6 : )) * (2 ^ (4 / (21 : )) - 1) + 2 ^ (3 / (2 : )) * (2 ^ (5 / (24 : )) - 1) +
    2 ^ (4 / (3 : )) * (2 ^ (2 / (9 : )) - 1) + 2 ^ (6 / (5 : )) * (2 ^ (7 / (30 : )) - 1) +
    2 ^ (12 / (11 : )) * (2 ^ (8 / (33 : )) - 1))) < 0 := by
  have h₁ {x} (h : x  0 := by positivity) : log 2 * x + 1 < 2 ^ x := by
    have := add_one_lt_exp (by positivity : log 2 * x  0)
    norm_num [exp_mul, exp_log] at this
    exact this
  have h₂ {x : } (h : 0  x := by positivity) : (0 : )  2 ^ x - 1 := by
    norm_num
    exact Real.one_le_rpow (by norm_num) h
  repeat grw [h₁]
  · have := log_two_gt_d9
    nlinarith
  all_goals exact h₂

Thanks for your code. This indeed seems much better. I guess doing numerical stuff is still kind of hard in lean.

Chris Henson (Jan 21 2026 at 18:42):

Some grind golfing:

import Mathlib

open Real

example : 1 / (16 : ) * (2 - (8 * (2 ^ (1 / (12 : )) - 1) + 2 ^ (12 / (5 : )) * (2 ^ (2 / (15 : )) - 1) +
    4 * (2 ^ (1 / (6 : )) - 1) + 2 ^ (12 / (6 : )) * (2 ^ (4 / (21 : )) - 1) + 2 ^ (3 / (2 : )) * (2 ^ (5 / (24 : )) - 1) +
    2 ^ (4 / (3 : )) * (2 ^ (2 / (9 : )) - 1) + 2 ^ (6 / (5 : )) * (2 ^ (7 / (30 : )) - 1) +
    2 ^ (12 / (11 : )) * (2 ^ (8 / (33 : )) - 1))) < 0 := by
  have h₁ {x} (h : x  0 := by grind) : log 2 * x + 1 < 2 ^ x := by
    grind [exp_mul, exp_log, add_one_lt_exp (by positivity : log 2 * x  0)]
  have h₂ {x : } (h : 0  x := by grind) : (0 : )  2 ^ x - 1 := by grind [Real.one_le_rpow]
  repeat grw [h₁]
  · have := log_two_gt_d9
    nlinarith
  all_goals exact h₂

Last updated: Feb 28 2026 at 14:05 UTC