You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lean4game/server/GameServer/Tactic/LetIntros.lean

68 lines
2.1 KiB
Plaintext

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import Lean.Elab.Binders
import Lean.Elab.Tactic.Basic
import Lean.Meta.Tactic.Intro
/-!
# `let_intros` Tactic
`let_intros` is a weaker form of `intros` aimed to only introduce `let` statements,
but not for example `∀`-binders.
Note: Mathlib has a tactic `extract_lets` which does essentially exactly this.
The only difference is that `let_intros` is unhygenic, in the sense that it will name
the introduced variables `f` instead of leaving them inaccessible `f✝`.
-/
namespace GameServer
open Lean Meta Elab Parser Tactic
/--
Copied from `Lean.Meta.getIntrosSize`.
-/
private partial def getLetIntrosSize : Expr → Nat
-- | .forallE _ _ b _ => getLetIntrosSize b + 1
| .letE _ _ _ b _ => getLetIntrosSize b + 1
| .mdata _ b => getLetIntrosSize b
| e =>
if let some (_, _, _, b) := e.letFun? then
getLetIntrosSize b + 1
else
0
/--
Copied and from `Lean.MVarId.intros`.
-/
def _root_.Lean.MVarId.letIntros (mvarId : MVarId) : MetaM (Array FVarId × MVarId) := do
let type ← mvarId.getType
let type ← instantiateMVars type
let n := getLetIntrosSize type
if n == 0 then
return (#[], mvarId)
else
-- `introNP` preserves the binder names
mvarId.introNP n
/--
`let_intros` introduces all `let` statements that are preceding the proof. Concretely
it does a subset of what `intros` does.
If names are provided, it will introduce as many `let` statements as there are names.
-/
syntax (name := letIntros) "let_intros" : tactic
-- (ppSpace colGt (ident <|> hole))*
@[tactic letIntros] def evalLetIntros : Tactic := fun stx => do
match stx with
| `(tactic| let_intros) => liftMetaTactic fun mvarId => do
let (_, mvarId) ← mvarId.letIntros
return [mvarId]
-- | `(tactic| let_intros $ids*) => do
-- let fvars ← liftMetaTacticAux fun mvarId => do
-- let (fvars, mvarId) ← mvarId.introN ids.size (ids.map getNameOfIdent').toList
-- return (fvars, [mvarId])
-- withMainContext do
-- for stx in ids, fvar in fvars do
-- Term.addLocalVarInfo stx (mkFVar fvar)
| _ => throwUnsupportedSyntax