Zulip Chat Archive
Stream: general
Topic: Metaprogramming DSL to extract out rewrite rules
l1mey (Sep 07 2025 at 07:28):
I've been reading the Lean4 metaprogramming book and I'm stuck on a DSL I want to implement, which is for simple term rewriting. I can change the syntax if it makes parsing easier.
declare_syntax_cat rewrite
syntax num : rewrite
syntax ident : rewrite
inductive Inst : Type where
| const : Inst
| add : Nat → Nat → Inst
| sub : Nat → Nat → Inst
open Lean Elab Meta in
partial def elabIntoRewrite : Lean.Syntax → MetaM Expr
| `(rewrite| $n:num) => mkAppM ``Inst.const #[mkNatLit n.getNat]
| _ => throwUnsupportedSyntax
elab "[rewrite| " syn:rewrite "]" : term => elabIntoRewrite syn
#reduce [rewrite|{
%0:u = const c
%2:u = add %0
=>
%2:u = add %1 %0
}]
#reduce [rewrite|{
%0:u
=>
%0:u = const c
}]
It would be nice if there was more resources on implementing complex macros like this, maybe it would be better to use a more complex function and not simple pattern matching. Though using an external tool to generate the rewrite rules might be fine also.
Robin Arnez (Sep 07 2025 at 09:23):
Hmm this is currently a syntax error; is this more like what you want?
declare_syntax_cat rewrite
syntax num : rewrite
syntax "const " ident : rewrite
syntax "add " "%" noWs num : rewrite
syntax "add " "%" noWs num " %" noWs num : rewrite
syntax "sub " "%" noWs num : rewrite
syntax "sub " "%" noWs num " %" noWs num : rewrite
syntax rule := "%" noWs num noWs ":" noWs &"u" (" = " rewrite)?
syntax rewriteSeq := "{" withPosition(many(ppLine colEq rule) ppLine colEq "=>" ppLine colEq rule ppDedent(ppLine)) "}"
syntax "[rewrite| " rewriteSeq "]" : term
#reduce [rewrite|{
%0:u = const c
%2:u = add %0
=>
%2:u = add %1 %0
}]
#reduce [rewrite|{
%0:u
=>
%0:u = const c
}]
Last updated: Dec 20 2025 at 21:32 UTC