| /- | |
| Copyright (c) 2022 Microsoft Corporation. All rights reserved. | |
| Released under Apache 2.0 license as described in the file LICENSE. | |
| Authors: Leonardo de Moura | |
| -/ | |
| 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 |