Zulip Chat Archive
Stream: Is there code for X?
Topic: Lean.ToExpr Rat
Eric Wieser (May 26 2025 at 17:18):
Aaron Liu said:
deriving instance Lean.ToExpr for Rat
I'm surprised that this isn't somewhere in mathlib already
Eric Wieser (May 26 2025 at 17:18):
Though I guess there's the question of whether it should use a / b or OfScientific
Aaron Liu (May 26 2025 at 17:28):
Eric Wieser said:
Though I guess there's the question of whether it should use
a / borOfScientific
How would you use OfScientific?
Eric Wieser (May 26 2025 at 17:34):
Only when b is of the form I guess
Aaron Liu (May 26 2025 at 17:42):
that sounds like it will cause some people debugging hell later
Eric Wieser (May 26 2025 at 17:43):
You mean to say that people care about other primes too?
Eric Wieser (May 26 2025 at 17:43):
You're right though, / is the reasonable choice
Aaron Liu (May 26 2025 at 17:55):
Is this a reasonable implementation?
import Batteries.Data.Rat.Basic
import Lean.ToExpr
open Lean
instance : ToExpr Rat where
toTypeExpr := .const ``Rat []
toExpr q :=
let lit r := mkApp3 (.const ``OfNat.ofNat [levelZero]) (.const ``Rat [])
(mkRawNatLit r) (.app (.const ``Rat.instOfNat []) (mkRawNatLit r))
let numAbs := lit q.num.natAbs
let num :=
if q.num ≥ 0 then numAbs else
mkApp3 (.const ``Neg.neg [levelZero]) (.const ``Rat []) (.const ``Rat.instNeg []) numAbs
if q.den = 1 then num else
let den := lit q.den
mkApp6 (.const ``HDiv.hDiv [levelZero, levelZero, levelZero])
(.const ``Rat []) (.const ``Rat []) (.const ``Rat [])
(mkApp2 (.const ``instHDiv [levelZero]) (.const ``Rat []) (.const ``Rat.instDiv []))
num den
Eric Wieser (May 26 2025 at 18:11):
I think we already have most of an instance inside norm_num
Eric Wieser (May 26 2025 at 18:12):
I guess the other question is whether we want (-a) / b or -(a/b)
Aaron Liu (May 26 2025 at 18:17):
(-a) / b pretty prints as -a / b, and -(a/b) pretty prints as -(a / b)
Andrew Yang (May 26 2025 at 18:18):
the normal form in norm_num is also (-a) / b
Eric Wieser (May 26 2025 at 18:18):
Neither of docs#neg_div or docs#neg_div' are simp though, interestingly
Eric Wieser (May 26 2025 at 18:19):
Andrew Yang said:
the normal form in
norm_numis also(-a) / b
Nice evidence that the toExpr function almost already exists!
Eric Wieser (May 26 2025 at 18:20):
This is the closest I got when I needed it quickly before:
-- hack, this should be constructed inline
def mkRatQ (q : ℚ) : MetaM Q(ℝ) := do
have m'n : Q(ℕ) := mkRawIntLit q.num
have m'd : Q(ℕ) := mkRawNatLit q.den
have r : Result q(0 : ℝ) := .isRat' q(inferInstance) q (m'n) (m'd) q(sorry)
let ⟨(m' : Q(ℝ)), hm', _⟩ ← r.toSimpResult
return m'
Eric Wieser (May 26 2025 at 18:21):
Where the relevant code is here
Notification Bot (May 26 2025 at 18:45):
16 messages were moved here from #new members > Unexpected token when deriving instance by Eric Wieser.
Mario Carneiro (May 26 2025 at 21:31):
Eric Wieser said:
Where the relevant code is here
This seems to contradict the claim that the normal form in norm_num is (-a) / b
Mario Carneiro (May 26 2025 at 21:31):
I can clearly see -(a / b) there
Mario Carneiro (May 26 2025 at 21:33):
and a test like example : -1 / (2:Rat) = sorry := by norm_num normalizes to -(1 / 2)
Kyle Miller (May 26 2025 at 21:46):
The pp.numericTypes option assumes that rational numbers are of the form HDiv.hDiv (nat <|> Neg.neg nat) nat for what it's worth.
Eric Wieser (May 26 2025 at 22:01):
I think that's the right behavior for printing whatever the norm_num-normal form is, to avoid printing (-(a / b) : Rat)
Last updated: Dec 20 2025 at 21:32 UTC