forked from leanprover/lean4
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReduceEval.lean
61 lines (50 loc) · 1.83 KB
/
ReduceEval.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/-
Copyright (c) 2020 Sebastian Ullrich. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Sebastian Ullrich
-/
import Lean.Meta.Offset
/-! Evaluation by reduction -/
namespace Lean.Meta
class ReduceEval (α : Type) where
reduceEval : Expr → MetaM α
def reduceEval [ReduceEval α] (e : Expr) : MetaM α :=
withAtLeastTransparency TransparencyMode.default $
ReduceEval.reduceEval e
private def throwFailedToEval (e : Expr) : MetaM α :=
throwError "reduceEval: failed to evaluate argument{indentExpr e}"
instance : ReduceEval Nat where
reduceEval e := do
let e ← whnf e
let some n ← evalNat e | throwFailedToEval e
pure n
instance [ReduceEval α] : ReduceEval (Option α) where
reduceEval e := do
let e ← whnf e
let Expr.const c .. ← pure e.getAppFn | throwFailedToEval e
let nargs := e.getAppNumArgs
if c == ``Option.none && nargs == 0 then pure none
else if c == ``Option.some && nargs == 1 then some <$> reduceEval e.appArg!
else throwFailedToEval e
instance : ReduceEval String where
reduceEval e := do
let Expr.lit (Literal.strVal s) ← whnf e | throwFailedToEval e
pure s
private partial def evalName (e : Expr) : MetaM Name := do
let e ← whnf e
let Expr.const c _ ← pure e.getAppFn | throwFailedToEval e
let nargs := e.getAppNumArgs
if c == ``Lean.Name.anonymous && nargs == 0 then pure Name.anonymous
else if c == ``Lean.Name.str && nargs == 2 then do
let n ← evalName $ e.getArg! 0
let s ← reduceEval $ e.getArg! 1
pure $ Name.mkStr n s
else if c == ``Lean.Name.num && nargs == 2 then do
let n ← evalName $ e.getArg! 0
let u ← reduceEval $ e.getArg! 1
pure $ Name.mkNum n u
else
throwFailedToEval e
instance : ReduceEval Name where
reduceEval := evalName
end Lean.Meta