lean4-htt/src/Lean/Meta/Native.lean
Jason Yuen 3770b3dcb8
chore: fix spelling errors (#13274)
This PR fixed typos:

```
pip install codespell --upgrade
codespell --summary --ignore-words-list enew,forin,fro,happend,hge,ihs,iterm,spred --skip stage0 --check-filenames
codespell --summary --ignore-words-list enew,forin,fro,happend,hge,ihs,iterm,spred --skip stage0 --check-filenames --regex '[A-Z][a-z]*'
codespell --summary --ignore-words-list enew,forin,fro,happend,hge,ihs,iterm,spred --skip stage0 --check-filenames --regex "\b[a-z']*"
```
2026-04-04 07:34:34 +00:00

87 lines
3.1 KiB
Text

/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Joachim Breitner
-/
module
prelude
public import Lean.Meta.Basic
import Lean.Util.CollectLevelParams
import Lean.Elab.DeclarationRange
import Lean.Compiler.Options
open Lean Meta
namespace Lean.Meta
/-!
This module contains infrastructure for proofs by native evaluation (`native decide`, `bv_decide`).
Such proofs involve a native computation using the Lean kernel, and then asserting the result
of that computation as an axiom towards the logic.
-/
public inductive NativeEqTrueResult where
/-- The given expression `e` evaluates to true. `prf` is a proof of `e = true`. -/
| success (prf : Expr)
/-- The given expression `e` evaluates to false. -/
| notTrue
/--
A call to `nativeEqTrue tacName e`, where `e` is a closed value of type `Bool`, will compile and run
that value, check that it evaluates to `true`, and if so, will add an axiom asserting `e = true` and
return that axiom.
It is the basis for `native_decide` and `bv_decide` tactics.
-/
public def nativeEqTrue (tacticName : Name) (e : Expr) (axiomDeclRange? : Option Syntax := none) : MetaM NativeEqTrueResult := do
let e ← instantiateMVars e
if e.hasFVar then
throwError m!"Tactic `{tacticName}` failed: Cannot native decide proposition with free variables:{indentExpr e}"
if e.hasMVar then
throwError m!"Tactic `{tacticName}` failed: Cannot native decide proposition with metavariables:{indentExpr e}"
let levels := (collectLevelParams {} e).params.toList
let isTrue ← withoutModifyingEnv do
let auxDeclName ← mkAuxDeclName <| `_native ++ tacticName ++ `decl
let decl := Declaration.defnDecl {
name := auxDeclName
levelParams := levels
type := mkConst ``Bool
value := e
hints := .abbrev
safety := .safe
}
modifyEnv (markMeta · auxDeclName)
try
-- disable async/separate codegen so we can catch its exceptions; we don't want to report
-- `evalConst` failures below when the actual reason was a codegen failure
withOptions (Elab.async.set · false) do
withOptions (Compiler.compiler.postponeCompile.set · false) do
withOptions (Compiler.compiler.relaxedMetaCheck.set · true) do
addAndCompile decl
catch ex =>
throwError m!"Tactic `{tacticName}` failed. Error: {ex.toMessageData}"
-- Now evaluate the constant, and check that it is true.
try
unsafe evalConst Bool auxDeclName
catch ex =>
throwError m!"\
Tactic `{tacticName}` failed: Could not evaluate decidable instance. \
Error: {ex.toMessageData}"
unless isTrue do return .notTrue
let auxAxiomName ← mkAuxDeclName <| `_native ++ tacticName ++ `ax
let axDecl := Declaration.axiomDecl {
name := auxAxiomName
levelParams := levels
type := mkApp3 (mkConst ``Eq [1]) (mkConst ``Bool) e (mkConst ``Bool.true)
isUnsafe := false
}
addDecl axDecl
if let some ref := axiomDeclRange? then
Elab.addDeclarationRangesFromSyntax auxAxiomName ref
let levelParams := levels.map mkLevelParam
return .success <| mkConst auxAxiomName levelParams