Skip to content

Commit

Permalink
feat: support let rec in #eval
Browse files Browse the repository at this point in the history
Makes `#eval` use the `elabMutualDef` machinery to process all the `let rec`s that might appear in the expression. This now works:
```lean
  let rec fact (n : Nat) : Nat :=
    match n with
    | 0 => 1
    | n' + 1 => n * fact n'
  fact 5
```

Closes leanprover#2374
  • Loading branch information
kmill committed Oct 11, 2024
1 parent 8e88e80 commit c6f8c74
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 18 deletions.
23 changes: 7 additions & 16 deletions src/Lean/Elab/BuiltinEvalCommand.lean
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kyle Miller
-/
prelude
import Lean.Util.CollectLevelParams
import Lean.Util.CollectAxioms
import Lean.Meta.Reduce
import Lean.Elab.Eval
import Lean.Elab.Deriving.Basic
import Lean.Elab.MutualDef

/-!
# Implementation of `#eval` command
Expand Down Expand Up @@ -81,19 +79,12 @@ where
return mkAppN m args

private def addAndCompileExprForEval (declName : Name) (value : Expr) (allowSorry := false) : TermElabM Unit := do
let value ← Term.levelMVarToParam (← instantiateMVars value)
let type ← inferType value
let us := collectLevelParams {} value |>.params
let decl := Declaration.defnDecl {
name := declName
levelParams := us.toList
type := type
value := value
hints := ReducibilityHints.opaque
safety := DefinitionSafety.unsafe
}
Term.ensureNoUnassignedMVars decl
addAndCompile decl
-- Use the `elabMutualDef` machinery to be able to support `let rec`.
-- Hack: since we are using the `TermElabM` version, we can insert the `value` as a metavariable via `exprToSyntax`.
let defView := mkDefViewOfDef { isUnsafe := true }
(← `(Parser.Command.definition|
def $(mkIdent <| `_root_ ++ declName) := $(← Term.exprToSyntax value)))
Term.elabMutualDef #[] { header := "" } #[defView]
unless allowSorry do
let axioms ← collectAxioms declName
if axioms.contains ``sorryAx then
Expand Down
16 changes: 16 additions & 0 deletions tests/lean/run/eval.lean
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,19 @@ info: hi
error: ex
-/
#guard_msgs in #eval throwsEx

/-!
Let rec support (issue #2374)
-/
/-- info: 37 : Nat -/
#guard_msgs in #eval
let rec bar : Nat := 1
37

/-- info: 120 : Nat -/
#guard_msgs in #eval
let rec fact (n : Nat) : Nat :=
match n with
| 0 => 1
| n' + 1 => n * fact n'
fact 5
4 changes: 2 additions & 2 deletions tests/lean/run/meta5.lean
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ info: [Meta.debug] ?_
[Meta.debug] fun y =>
let x := 0;
x.add y
[Meta.debug] ?_uniq.3014 : Nat
[Meta.debug] ?_uniq.3015 : Nat →
[Meta.debug] ?_uniq.3019 : Nat →
Nat →
let x := 0;
Nat
[Meta.debug] ?_uniq.3018 : Nat
-/
#guard_msgs in
#eval tst1

0 comments on commit c6f8c74

Please sign in to comment.