Zulip Chat Archive
Stream: lean4
Topic: Recursive definition in `Expr`
Mathis Bouverot-Dupuis (Oct 04 2024 at 11:57):
Hello ! I'm building some terms in Expr
, and in particular I would like to define a recursive function. I'm having a hard time using recursors (.rec
, .recOn
, etc).
- What is the complete list of recursors which are automatically defined for an inductive ?
- Is there a way to do this with a higher-level API than recursors ?
Eric Wieser (Oct 04 2024 at 12:28):
You can write
def foo (e : Expr) : Nat :=
match e with
| .proj _ _ => sorry
| .app f a => foo f + foo a
-- etc
Henrik Böving (Oct 04 2024 at 12:29):
I think Mathis means generating an Expr
that represents a recursive function
Mathis Bouverot-Dupuis (Oct 04 2024 at 12:30):
Henrik Böving said:
I think Mathis means generating an
Expr
that represents a recursive function
Yes exactly.
Eric Wieser (Oct 04 2024 at 12:34):
I guess my suggeston then becomes "can you emit Syntax
and elaborate it, rather than building an Expr
"?
Mathis Bouverot-Dupuis (Oct 04 2024 at 12:37):
I would prefer not as I use some Expr
-related machinery to build my terms, such as unification or local declarations. Is there a way to stay in Expr
?
Eric Wieser (Oct 04 2024 at 13:16):
By Expr
-related, do you mean TermElabM
-related?
Eric Wieser (Oct 04 2024 at 13:16):
You can jump back and forth between Expr
and Syntax
using docs#Lean.Expr.toSyntax and docs#Lean.Elab.Term.elabTerm
Mathis Bouverot-Dupuis (Oct 04 2024 at 13:36):
Eric Wieser said:
By
Expr
-related, do you meanTermElabM
-related?
Yes, I'm using TermElabM
and MetaM
.
Mathis Bouverot-Dupuis (Oct 04 2024 at 13:37):
I see, so how would I use Syntax
to build a match expression ? EDIT : a recursive definition (I was thinking about fixpoints)
Eric Wieser (Oct 04 2024 at 13:45):
Can you give an example of the kind of expression you want to build?
Mathis Bouverot-Dupuis (Oct 04 2024 at 13:49):
I would like to build something like this :
def myListMap (f : α → β) (xs : List α) : List β :=
match xs with
| [] => []
| x :: xs => f x :: myListMap f xs
Eric Wieser (Oct 04 2024 at 13:55):
import Lean
open Lean Meta Elab Term
def foo : TermElabM Expr := do
let stx ← `(term|
let rec myListMap {α β} (f : α → β) (xs : List α) : List β :=
match xs with
| [] => []
| x :: xs => f x :: myListMap f xs
myListMap)
elabTerm stx none
Mathis Bouverot-Dupuis (Oct 04 2024 at 14:08):
With your definition foo
, I tried inspecting the resulting term :
#eval do
let e ← instantiateMVars =<< foo
IO.println s!"{ ← ppExpr e }"
And I get (fun myListMap ↦ myListMap) ?m.16
. How come the result has unassigned metavars ?
Eric Wieser (Oct 04 2024 at 14:50):
I think that metavariable is one satisfying docs#Lean.Elab.Term.isLetRecAuxMVar
Eric Wieser (Oct 04 2024 at 14:55):
I think the idea is that once you finally add the declaration to the environment, the let rec
is added at the same time and the metavariable resolved; but I've not tried using let rec
s in meta code before
Last updated: May 02 2025 at 03:31 UTC