Zulip Chat Archive
Stream: mathlib4
Topic: Notation for family of orderings
Moritz R (Jan 28 2026 at 19:49):
How does one get good notation in the output, when one has a family of orerings G -> PartialOrder F?
I currently have something alike:
import Mathlib.Data.Set.Defs
import Mathlib.Order.Defs.PartialOrder
class clWithOrder (F G : Type*) (order : outParam (G -> PartialOrder F))
abbrev clWithOrder.order [clWithOrder F G O] := O
set_option quotPrecheck false in
notation:50 a " <[" D:30 "] " b:50 => (clWithOrder.order D).lt a b
def usesOrder[clWithOrder F G O] (g : G) := { C : F | ∃ C', C' <[g] C}
/- prints with `<` instead of `<[D]`
def usesOrder.{u_1, u_2} : {F : Type u_1} →
{G : Type u_2} → {O : G → PartialOrder F} → [clWithOrder F G O] → G → Set F :=
fun {F} {G} {O} [clWithOrder F G O] g => {C | ∃ C', C' < C}
-/
#print usesOrder
This has the issue, that it hides which ordering (i.e. which g) is used in the output, since it just uses <.
Aaron Liu (Jan 28 2026 at 20:02):
see also #metaprogramming / tactics > Delaborators for `IsOpen[t]` etc
Moritz R (Jan 28 2026 at 20:18):
So i should check in a custom delaborator wether my instance of lt comes from clWithOrder and if so, then pretty print it differently?
Moritz R (Jan 28 2026 at 21:01):
like this?
import Mathlib.Data.Set.Defs
import Mathlib.Order.Defs.PartialOrder
import Lean.PrettyPrinter.Delaborator
section bla
open Lean PrettyPrinter Delaborator SubExpr
class clWithOrder (F G : Type*) (order : outParam (G → PartialOrder F))
abbrev clWithOrder.order [clWithOrder F G O] := O
set_option quotPrecheck false in
notation:50 a " <[" D:30 "] " b:50 => (clWithOrder.order D).lt a b
-- Custom delaborator for LT.lt when used with clWithOrder
@[delab app.LT.lt]
def delabOrderLt : Delab := whenPPOption Lean.getPPNotation do
let e ← getExpr
guard <| e.isAppOfArity ``LT.lt 4
-- Get the LT instance
let ltInst := e.getArg! 1
-- Check if it comes from clWithOrder.order
if ltInst |>.getArg! 1 |>.getArg! 1 |>.isAppOf ``clWithOrder.order then
let gExpr := ltInst.getArg! 1 |>.getArg! 1 |>.getArg! 4 -- Extract g
let g ← delab gExpr
let a ← withNaryArg 2 delab
let b ← withNaryArg 3 delab
`($a <[ $g ] $b)
else
failure
def usesOrder [clWithOrder F G O] (g : G) :=
{ C : F | ∃ C', C' <[g] C }
#print usesOrder -- now shows <[g]
end bla
Aaron Liu (Jan 28 2026 at 21:03):
you might wanna also check if it changes delab of just regular lt expressions
Moritz R (Jan 28 2026 at 21:04):
Do you mean testing it, or putting some programmatical check that i don't know?
Moritz R (Jan 28 2026 at 21:05):
lemma zzz (a B : Nat) : a < b := by sorry
#print zzz
this still prints correctly
Moritz R (Jan 28 2026 at 21:05):
Is that what you mean?
Aaron Liu (Jan 28 2026 at 21:07):
yeah I mean just testing it
Moritz R (Jan 28 2026 at 22:21):
i have been getting some random Panics every few minutes, even while only staring at the screen.
I have now guarded all the indexes, which seems to work:
@[delab app.LT.lt]
meta def delabOrderLt : Delab := whenPPOption Lean.getPPNotation do
let e ← getExpr
guard <| e.isAppOfArity ``LT.lt 4
-- Get the LT instance
let ltInst := e.getArg! 1
guard <| ltInst.getAppNumArgs ≥ 2
let ltInst_arg1 := ltInst |>.getArg! 1
guard <| ltInst_arg1.getAppNumArgs ≥ 2
let ltInst_arg1_arg1 := ltInst_arg1 |>.getArg! 1
guard <| ltInst_arg1_arg1.getAppNumArgs ≥ 6
let ltInst_arg1_arg1_arg5 := ltInst_arg1_arg1 |>.getArg! 5
-- Check if it comes from clWithOrder.order
if ltInst_arg1_arg1 |>.isAppOf ``clWithOrder.order.order then
let gExpr := ltInst_arg1_arg1_arg5 -- Extract g
let g ← delab gExpr
let a ← withNaryArg 2 delab
let b ← withNaryArg 3 delab
`($a <[ $g ] $b)
else
failure
Last updated: Feb 28 2026 at 14:05 UTC