Zulip Chat Archive
Stream: lean4
Topic: Local notations : issue and workaround
Julien Marquet (May 13 2021 at 22:27):
I'm interested in defining local notations, to have for instance fancy group laws, custom symbols for orders, etc.
It looks like I'm not the only one interested in this (there are already issues #435 and #358 that are close to my point), so I'll write here
- A minimal example of the problem
- A (not fully satisfying) workaround
- The tracks that I've found to solve this issue (and that I couldn't follow on my own :/)
[ This is a lengthy post because I just summarize what I have found. I would have loved to have simply fixed the issue, PR'd Lean 4 and just announced the feature without making too much noise but this is out of my reach :/ ]
The problem arises in scenarios like this one :
set_option quotPrecheck.allowSectionVars true
variable (O : Type) (rel : O → O → Prop)
infixl:50 " ◃ " => rel
theorem foo : ∀ x y : O, x ◃ y :=
by /- Goal is `∀ (x y : O), rel x y` :'( -/ admit
So here's a workaround if you want fancy notation and pretty printing !
set_option quotPrecheck.allowSectionVars true
variable (O : Type) (rel : O → O → Prop)
infixl:50 " ◃ " => id rel
@[appUnexpander id] def unexpandAppRel : Lean.PrettyPrinter.Unexpander
| `(id rel $x $y) => `($x ◃ $y)
| _ => throw ()
theorem foo : ∀ x y : O, x ◃ y :=
by /- Goal is `∀ (x y : O), x ◃ y` !! -/ admit
The Unexpander just finds all the instances of app rel x y
and displays them as x ◃ y
.
This pattern works well in more compex cases. Here is an example that demonstrates this, and by the way I give examples of what does _not_ work :
set_option quotPrecheck.allowSectionVars true
variable (O : Type) (rel rel' : O → O → O)
infixl:70 " ◃ " => id rel -- Notice we can directly use `infixl`
@[appUnexpander id] def unexpandAppRel : Lean.PrettyPrinter.Unexpander
| `(id rel $x $y) => `($x ◃ $y)
| _ => throw ()
-- This one does _not_ work (explained just after)
@[appUnexpander rel] def unexpandRel : Lean.PrettyPrinter.Unexpander
| `(rel $x $y) => `($x ◃ $y)
| _ => throw ()
theorem foo : ∀ x y z : O, x ◃ y ◃ z = rel x y :=
by
-- Goal is : ∀ (x y z : O), x ◃ y ◃ z = rel x y
admit
#print foo -- Prints correctly "x ◃ y ◃ z" but still prints "rel" on the right
Up to my understanding, the original problem arises from mkSimpleDelab
:
- It only accepts right hand side expressions that are just a function (no function applications, because functions and function applications are _not_ the same syntactically), which rules out the
app rel
rhs; - And the function that is given must be global, which makes having
rel
in the rhs impossible becauserel
was introduced byvariable
.
And apparently it isn't possible to use a local name as a parameter to appUnexpander
(or I didn't understand how to do that).
Mac (May 13 2021 at 22:49):
actually, this is something I find quite useful myself and have been playing around with a lot
Mac (May 13 2021 at 22:59):
first thing to note is that you could use the builtin id
instead of having to use define your own app
Mac (May 13 2021 at 23:00):
also, the idea of using app
/id
this way in order to able to write an appUnexpander
is genius! I never would have thought of that!
Julien Marquet (May 13 2021 at 23:03):
Mac said:
first thing to note is that you could use the builtin
id
instead of having to use define your ownapp
This is indeed better with id
, thanks ! I updated my original message.
Julien Marquet (May 13 2021 at 23:03):
I opened an issue on lean4 : #465
Mac (May 14 2021 at 00:17):
Fyi, I had a related discussion a while back: https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Custom.20identifiers.3F/near/234451179 and @Sebastian Ullrich (a Lean 4 developer) suggested some ways local notation may be addressed in the future
Last updated: Dec 20 2023 at 11:08 UTC