Zulip Chat Archive
Stream: lean4
Topic: OfScientific pretty printing after `simp`
Geoffrey Irving (Jan 18 2024 at 11:53):
If I do simp
, explicit numbers like 0.123712
expand and look worse:
import Mathlib
lemma with_number : (0.123712 : ℝ) < 0.8482312 := by
-- Goal print as `0.123712 < 0.8482312`
simp only
-- Goal prints as `OfScientific.ofScientific 123712 true 6 < OfScientific.ofScientific 8482312 true 7`
norm_num
Is there a way to keep the pretty printing nice? (I'm tightening some bounds of very nonlinear things, and it results in explicit numbers popping up.)
Kyle Miller (Jan 18 2024 at 11:56):
The reason this is happening is that the OfScientific literals contain raw natural number literals, but after simp only
they become normalized as literals using OfNat. This is potentially a bug in OfScientific literals.
Something you could do is add your own pretty printer for OfScientific that can handle OfNat literals.
Eric Wieser (Jan 18 2024 at 11:57):
This is potentially a bug in OfScientific literals.
Do you mean a bug in simp
, in that it should not be doing this normalization?
Eric Wieser (Jan 18 2024 at 11:57):
Or that it should not contain raw numerals in the first place?
Kyle Miller (Jan 18 2024 at 11:58):
I was think it's the OfScientific literal containing a raw nat, but you could point your finger at simp too. It's aware of OfNat.ofNat, so maybe it should be aware of OfScientific.ofScientific too.
Mario Carneiro (Jan 18 2024 at 11:59):
I think OfScientific should be using raw nats
Mario Carneiro (Jan 18 2024 at 11:59):
so I would point the blame at simp here
Kyle Miller (Jan 18 2024 at 12:00):
@Geoffrey Irving Want to make a Lean 4 issue documenting the fact that simp only
does this to these literals? Make sure it doesn't use mathlib -- you can use Float instead of Real. No need for the issue to suggest a solution -- we just want to track the problem.
Geoffrey Irving (Jan 18 2024 at 12:00):
Yep, will do.
Eric Wieser (Jan 18 2024 at 12:00):
Is #simp 0.5
a sufficient repro?
Kyle Miller (Jan 18 2024 at 12:03):
@Geoffrey Irving Here's a free delaborator for you in the meantime, hacked from the core one:
import Mathlib
open Lean PrettyPrinter Delaborator SubExpr in
@[delab app.OfScientific.ofScientific]
def delabOfScientific : Delab := whenPPOption getPPCoercions <| withOverApp 5 do
let expr ← getExpr
guard <| expr.getAppNumArgs == 5
let some m := (expr.getArg! 2).nat? | failure
let some e := (expr.getArg! 4).nat? | failure
let s ← match expr.getArg! 3 with
| Expr.const ``Bool.true _ => pure true
| Expr.const ``Bool.false _ => pure false
| _ => failure
let str := toString m
if s && e == str.length then
return Syntax.mkScientificLit ("0." ++ str)
else if s && e < str.length then
let mStr := str.extract 0 ⟨str.length - e⟩
let eStr := str.extract ⟨str.length - e⟩ ⟨str.length⟩
return Syntax.mkScientificLit (mStr ++ "." ++ eStr)
else
return Syntax.mkScientificLit (str ++ "e" ++ (if s then "-" else "") ++ toString e)
Geoffrey Irving (Jan 18 2024 at 12:05):
Neat, thank you!
Kyle Miller (Jan 18 2024 at 12:05):
I only had to modify the let ... m := ...
and let ... e := ...
lines
Geoffrey Irving (Jan 18 2024 at 12:52):
Github issue: https://github.com/leanprover/lean4/issues/3194
Last updated: May 02 2025 at 03:31 UTC