Zulip Chat Archive
Stream: lean4
Topic: Replacing certain keywords during syntax evaluation
Marx (Dec 02 2024 at 23:01):
Hi everyone,
I’m working on defining a syntax that looks like this:
{x0 > 0}
or
{x1 = 2 /\ 0 <= x3 /\ x0 = 0}
The goal is for this syntax to evaluate to the following in the next step:
fun n : Nat => {(n.add 0) > 0}
or
fun n : Nat => {(n.add 0) = 2 /\ 0 <= (n.add 3) /\ (n.add 0) = 0}
So every occurence of any (xn)
with n being a numeral literal gets replaced.
I’m trying to achieve this while adhering to the following constraints:
- Preserve existing term syntax: Avoid polluting or modifying the existing syntax category for terms.
- Reuse existing definitions: Ensure it’s not necessary to redefine all operations for natural numbers and propositions. However, if redefining them is unavoidable, I’d appreciate guidance on a simple, non-redundant approach to achieve this
This is what I have so far:
import Lean
open Lean Elab
declare_syntax_cat testSyntax
declare_syntax_cat toBeReplaced
syntax term: testSyntax
syntax "(x" num ")" : toBeReplaced
syntax toBeReplaced : testSyntax
syntax toBeReplaced testSyntax : testSyntax
def getNum (reg: TSyntax `toBeReplaced): Nat :=
match reg with
| `(toBeReplaced | (x$n:num)) => n.getNat
| _ => 9999 -- This is bad but I am lazy
partial def testFun (term: TSyntax `testSyntax): TermElabM (TSyntax `term) := do
match term with
| `(testSyntax | $r:toBeReplaced) =>
let t := getNum r
return ←`(term | $(mkIdent s!"{t}".toName))
| `(testSyntax | $r:toBeReplaced $t:testSyntax) =>
let t1 := getNum r
let t2 ← testFun t
return ←`(term | $(mkIdent s!"{t1}".toName) $t2)
| `(testSyntax | $t:term) =>
let t1 ← `(term | term)
return ←`(term | $t1)
| _ => `(term | NOTHING)
elab "start" t:testSyntax "end" : term => do
let processedTerm ← testFun t
logInfo processedTerm
-- let result ← Lean.Elab.Term.elabTerm processedTerm (some (.const ``Nat []))
return mkNatLit 0 -- return result
However, this approach encounters the following issues:
- The
toBeReplaced
syntax is not replaced correctly when nested inside another term. - Attempting to use individual components of the
toBeReplaced
syntax as operands in other expressions.
I would really appreciate any input.
Sebastian Ullrich (Dec 03 2024 at 09:54):
Likely you don't want a new syntax category but to parse a term
and then recursively replace ident
s inside of it. See docs#Lean.Elab.Term.expandCDot? for a similar approach.
Marx (Dec 05 2024 at 16:46):
Thank you for the suggestion, I'm gonna give it a try
Marx (Dec 08 2024 at 16:46):
Sebastian Ullrich said:
Likely you don't want a new syntax category but to parse a
term
and then recursively replaceident
s inside of it. See docs#Lean.Elab.Term.expandCDot? for a similar approach.
So i've had a look at it and this look pretty much like what I could use. Unfortunately I find it very difficult to understand in detail. Could you provide me some further documentation or information about this. I would really appreciate that.
Last updated: May 02 2025 at 03:31 UTC