Skip to main content
Stack Overflow
  1. About
  2. For Teams

You are not logged in. Your edit will be placed in a queue until it is peer reviewed.

We welcome edits that make the post easier to understand and more valuable for readers. Because community members review edits, please try to make the post substantially better than how you found it, for example, by fixing grammar or adding additional resources and hyperlinks.

Required fields*

Lean4 lambda calculus DSL macro

I would like to define a DSL for writing lambda terms in Lean using macros a la the arithmetic example. I want to support syntax for multiple arguments in the lambda, and left-associativity. Thus far, I have come up with the following code:

inductive Λ where
 | var : String → Λ
 | apl : Λ → Λ → Λ
 | abstr : String → Λ → Λ
declare_syntax_cat lcplus
syntax ident : lcplus
syntax lcplus lcplus+ : lcplus
syntax "(λ" ident+ "." lcplus ")" : lcplus
syntax "(" lcplus ")" : lcplus
syntax "<[" term "]>" : lcplus
syntax "`[λ+| " lcplus "]" : term
macro_rules
 | `(`[λ+| $x:ident]) => `(Λ.var $(Lean.quote (toString x.getId)))
 | `(`[λ+| $x:lcplus $xs:lcplus*]) => do
 let mut acc <- `(`[λ+| $x])
 for x' in xs do
 acc <- `(Λ.apl $acc `[λ+| $x'])
 return acc
 | `(`[λ+| (λ $xs:ident* . $body:lcplus)]) => do
 let mut acc <- `(`[λ+| $body])
 for x in xs.reverse do
 acc <- `(Λ.abstr $(Lean.quote (toString x.getId)) $acc)
 return acc
 --xs.foldrM (init := `(`[λ+| $body])) λ x acc =>
 -- `(Λ.abstr $(Lean.quote (toString x.getId)) $acc) -- Type mismatch $acc, is Syntax, expected TSyntax `term
 | `(`[λ+| ($x:lcplus)]) => `(`[λ+| $x])
 | `(`[λ+| <[$e:term]>]) => pure e
 
#check `[λ+| (λ x y. x) a b ]

The issue is that `[λ+| (λ x y. x) a b ] parses as

Λ.apl (Λ.abstr "x" (Λ.abstr y (Λ.var "x"))) (Λ.apl (Λ.var "a") (Λ.var "b"))

while I would want it to parse as

Λ.apl (Λ.apl (Λ.abstr "x" (Λ.abstr y (Λ.var "x"))) (Λ.var "a")) (Λ.var "b")

i.e. it seems to be right-associative.

I suspect the issue lies in the syntax declaration

syntax lcplus lcplus+ : lcplus

and not in the macro itself, as I suspect that lcplus+ parses the rest of the lambda terms as another application rather than an array of lambda terms. I don't really know how to get around this, as my knowledge of Lean syntax and macros, and Lean in general, isn't great, and my knowledge of parsers is very rusty.

On another note, I could not figure out how to use a fold rather than do notation, as that is essentially what we are doing.

I would be grateful if someone could help me.

Answer*

Draft saved
Draft discarded
Cancel

AltStyle によって変換されたページ (->オリジナル) /