Zulip Chat Archive
Stream: mathlib4
Topic: Expr.foldlM
Jeremy Salwen (Jun 01 2023 at 17:03):
Is Expr.foldlM supposed to traverse all subexpressions recursively, or just direct children? The name and docstring suggest the former, but based on this example, it seems to do the latter:
import Qq
import Lean
import Lean.Expr
import Mathlib.Lean.Expr.Traverse
open Lean Meta Elab Term Lean.Meta Tactic Qq
def foo: Expr:= q(∀ (f:Nat->Nat) (a b c:Nat), f (a+b) = c)
def logSubexprs : Nat → Expr → MetaM Nat
| _, e => do
dbg_trace e
return 0
#eval foo.foldlM logSubexprs 0
Normally I would look at the implementation to figure out what it's supposed to do, but it's a bit over my head:
https://github.com/leanprover-community/mathlib4/blob/77ba88838571d5d50acc4a65740e1080026fa12e/Mathlib/Lean/Expr/Traverse.lean#L28-L30
/-- `e.foldlM f a` folds the monadic function `f` over the subterms of the expression `e`,
with initial value `a`. -/
def foldlM {α : Type} {m} [Monad m] (f : α → Expr → m α) (x : α) (e : Expr) : m α :=
Prod.snd <$> (StateT.run (e.traverseChildren $ fun e' =>
Functor.mapConst e' (get >>= monadLift ∘ flip f e' >>= set)) x : m _)
What would be the recommended way of folding over all children recursively, would I just use MetaM.transform
?
Kyle Miller (Jun 01 2023 at 17:13):
It's a fold over the immediate subexpressions of each expression
Kyle Miller (Jun 01 2023 at 17:15):
I don't know the answer to your question, but one recursive version of that is https://github.com/leanprover-community/mathlib4/blob/f7b450735677ab422ab00e78d84818f9c5f96d86/Mathlib/Lean/Expr/ReplaceRec.lean#L28
Jeremy Salwen (Jun 05 2023 at 05:19):
This seems to do the trick for me:
def Expr.foldlRecM [Monad m] [AddMessageContext m] [MonadOptions m] [MonadLiftT MetaM m] [MonadControlT MetaM m] [MonadTrace m] [MonadRef m]
(f: α -> Expr -> m α) (init: α) (e: Expr): m α := do
Prod.snd <$> (StateT.run (transform e $ fun e' =>
Functor.mapConst TransformStep.continue (get >>= monadLift ∘ flip f e' >>= set)) init : m _)
Last updated: Dec 20 2023 at 11:08 UTC