Zulip Chat Archive
Stream: metaprogramming / tactics
Topic: defining notations with an attribute
Chris Henson (Jul 15 2025 at 17:58):
Is it possible to define a notation with an attribute? As an example I defined this command macro:
import Mathlib
import Lean
syntax "reduce_notation" ident Lean.Parser.Command.notationItem : command
macro_rules
| `(reduce_notation $rel $sym) =>
`(
notation:39 t " ⇢"$sym t' => $rel t t'
notation:39 t " ↠"$sym t' => Relation.ReflTransGen $rel t t'
notation:39 t " ≈"$sym t' => Relation.EqvGen $rel t t'
)
def foo : Nat → Nat → Prop := λ _ _ ↦ False
reduce_notation foo "β"
#check 0 ⇢β 0 -- 0 ⇢β 0 : Prop
#check 0 ↠β 0 -- Relation.ReflTransGen foo 0 0 : Prop
#check 0 ≈β 0 -- Relation.EqvGen foo 0 0 : Prop
Instead of a command, I would want to annotate foo with @[reduce_notation β]. I was not sure if this is possible in the AttrM monad.
Aaron Liu (Jul 15 2025 at 18:12):
It is possible to do this probably
Chris Henson (Jul 15 2025 at 18:55):
With the above command definition the following works to assemble a TSyntax `command:
syntax (name := reduce_notation_attr) "reduce_notation" Lean.Parser.Command.notationItem : attr
initialize Lean.registerBuiltinAttribute {
name := `reduce_notation_attr
descr := ""
add := fun decl stx _attrKind =>
match stx with
| `(attr | reduce_notation $sym) => do
let cmd ← `(reduce_notation decl sym)
| _ => throwUnsupportedSyntax
}
but I don't know how to actually "run" the command from within AttrM.
Adam Topaz (Jul 15 2025 at 18:59):
I think you can use liftCommandElabM
Adam Topaz (Jul 15 2025 at 19:00):
Chris Henson (Jul 15 2025 at 19:35):
Thanks Adam, that worked. For the benefit of those that come after, here's the full mwe I ended with:
import Mathlib
open Lean Lean.Elab Lean.Elab.Command Lean.Meta
syntax "reduce_notation" ident Lean.Parser.Command.notationItem : command
macro_rules
| `(reduce_notation $rel $sym) =>
`(
notation:39 t " ⇢"$sym t' => $rel t t'
notation:39 t " ↠"$sym t' => Relation.ReflTransGen $rel t t'
notation:39 t " ≈"$sym t' => Relation.EqvGen $rel t t'
)
syntax (name := reduce_notation_attr) "reduce_notation" Lean.Parser.Command.notationItem : attr
initialize Lean.registerBuiltinAttribute {
name := `reduce_notation_attr
descr := ""
add := fun decl stx kind => MetaM.run' do
let `(attr | reduce_notation $sym) := stx
| throwError "invalid syntax for 'reduce_notation' attribute"
let cmd ← `(reduce_notation $(mkIdent decl) $sym)
liftCommandElabM <| Command.elabCommand cmd
}
Last updated: Dec 20 2025 at 21:32 UTC