53 lines
1.5 KiB
Text
53 lines
1.5 KiB
Text
/-
|
|
Copyright (c) 2022 Microsoft Corporation. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
Authors: Leonardo de Moura
|
|
-/
|
|
prelude
|
|
import Lean.Environment
|
|
|
|
namespace Lean.Compiler
|
|
|
|
namespace atMostOnce
|
|
|
|
structure AtMostOnceData where
|
|
found : Bool
|
|
result : Bool
|
|
|
|
def Visitor := AtMostOnceData → AtMostOnceData
|
|
|
|
@[inline] def seq (f g : Visitor) : Visitor := fun d =>
|
|
match f d with
|
|
| ⟨found, false⟩ => ⟨found, false⟩
|
|
| other => g other
|
|
|
|
instance : AndThen Visitor where
|
|
andThen a b := seq a (b ())
|
|
|
|
@[inline] def skip : Visitor := id
|
|
|
|
@[inline] def visitFVar (x y : FVarId) : Visitor
|
|
| d@{result := false, ..} => d
|
|
| {found := false, result := true} => {found := x == y, result := true}
|
|
| {found := true, result := true} => {found := true, result := x != y}
|
|
|
|
def visit (x : FVarId) : Expr → Visitor
|
|
| Expr.fvar y => visitFVar y x
|
|
| Expr.app f a => visit x a >> visit x f
|
|
| Expr.lam _ d b _ => visit x d >> visit x b
|
|
| Expr.forallE _ d b _ => visit x d >> visit x b
|
|
| Expr.letE _ t v b _ => visit x t >> visit x v >> visit x b
|
|
| Expr.mdata _ e => visit x e
|
|
| Expr.proj _ _ e => visit x e
|
|
| _ => skip
|
|
|
|
end atMostOnce
|
|
|
|
open atMostOnce (visit) in
|
|
/-- Return true iff the free variable with id `x` occurs at most once in `e` -/
|
|
@[export lean_at_most_once]
|
|
def atMostOnce (e : Expr) (x : FVarId) : Bool :=
|
|
let {result := result, ..} := visit x e {found := false, result := true}
|
|
result
|
|
|
|
end Lean.Compiler
|