lean4-htt/src/Lean/Util/FoldConsts.lean
Sebastian Ullrich 2e66341f69
feat: Environment.realizeConst (#7076)
This PR introduces the central parallelism API for ensuring that helper
declarations can be generated lazily without duplicating work or
creating conflicts across threads.
2025-02-26 19:32:21 +00:00

74 lines
2.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import Lean.Expr
import Lean.Util.PtrSet
import Lean.Declaration
namespace Lean
namespace Expr
namespace FoldConstsImpl
unsafe structure State where
visited : PtrSet Expr := mkPtrSet
visitedConsts : NameHashSet := {}
unsafe abbrev FoldM := StateM State
unsafe def fold {α : Type} (f : Name → αα) (e : Expr) (acc : α) : FoldM α :=
let rec visit (e : Expr) (acc : α) : FoldM α := do
if (← get).visited.contains e then
return acc
modify fun s => { s with visited := s.visited.insert e }
match e with
| .forallE _ d b _ => visit b (← visit d acc)
| .lam _ d b _ => visit b (← visit d acc)
| .mdata _ b => visit b acc
| .letE _ t v b _ => visit b (← visit v (← visit t acc))
| .app f a => visit a (← visit f acc)
| .proj _ _ b => visit b acc
| .const c _ =>
if (← get).visitedConsts.contains c then
return acc
else
modify fun s => { s with visitedConsts := s.visitedConsts.insert c };
return f c acc
| _ => return acc
visit e acc
@[inline] unsafe def foldUnsafe {α : Type} (e : Expr) (init : α) (f : Name → αα) : α :=
(fold f e init).run' {}
end FoldConstsImpl
/-- Apply `f` to every constant occurring in `e` once. -/
@[implemented_by FoldConstsImpl.foldUnsafe]
opaque foldConsts {α : Type} (e : Expr) (init : α) (f : Name → αα) : α := init
def getUsedConstants (e : Expr) : Array Name :=
e.foldConsts #[] fun c cs => cs.push c
/-- Like `Expr.getUsedConstants`, but produce a `NameSet`. -/
def getUsedConstantsAsSet (e : Expr) : NameSet :=
e.foldConsts {} fun c cs => cs.insert c
end Expr
namespace ConstantInfo
/-- Return all names appearing in the type or value of a `ConstantInfo`. -/
def getUsedConstantsAsSet (c : ConstantInfo) : NameSet :=
c.type.getUsedConstantsAsSet ++ match c.value? with
| some v => v.getUsedConstantsAsSet
| none => match c with
| .inductInfo val => .ofList val.ctors
| .opaqueInfo val => val.value.getUsedConstantsAsSet
| .ctorInfo val => ({} : NameSet).insert val.name
| .recInfo val => .ofList val.all
| _ => {}
end ConstantInfo
end Lean