feat: add hand-written rfl tactic
It requires update stage0
This commit is contained in:
parent
298281baaf
commit
03f6b87647
5 changed files with 47 additions and 2 deletions
|
|
@ -348,8 +348,10 @@ macro "try " t:tacticSeq : tactic => `(first | $t | skip)
|
|||
/-- `tac <;> tac'` runs `tac` on the main goal and `tac'` on each produced goal, concatenating all goals produced by `tac'`. -/
|
||||
macro:1 x:tactic " <;> " y:tactic:0 : tactic => `(tactic| focus ($x:tactic; all_goals $y:tactic))
|
||||
|
||||
/-- `rfl` is a shorthand for `exact rfl`. -/
|
||||
macro "rfl" : tactic => `(exact rfl)
|
||||
/-- `rfl` is equivalent to `exact rfl`, but has a few optimizatons. -/
|
||||
syntax (name := refl) "rfl" : tactic
|
||||
|
||||
macro_rules | `(tactic| rfl) => `(tactic| exact rfl)
|
||||
|
||||
/--
|
||||
Similar to `rfl`, but disables smart unfolding and unfolds all kinds of definitions,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ Copyright (c) 2021 Microsoft Corporation. All rights reserved.
|
|||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
import Lean.Meta.Tactic.Refl
|
||||
import Lean.Elab.Tactic.Basic
|
||||
import Lean.Elab.Tactic.ElabTerm
|
||||
|
||||
|
|
@ -144,6 +145,9 @@ partial def evalChoiceAux (tactics : Array Syntax) (i : Nat) : TacticM Unit :=
|
|||
@[builtinTactic Lean.Parser.Tactic.contradiction] def evalContradiction : Tactic := fun stx =>
|
||||
liftMetaTactic fun mvarId => do Meta.contradiction mvarId; pure []
|
||||
|
||||
@[builtinTactic Lean.Parser.Tactic.refl] def evalRefl : Tactic := fun stx =>
|
||||
liftMetaTactic fun mvarId => do Meta.refl mvarId; pure []
|
||||
|
||||
@[builtinTactic Lean.Parser.Tactic.intro] def evalIntro : Tactic := fun stx => do
|
||||
match stx with
|
||||
| `(tactic| intro) => introStep none `_
|
||||
|
|
|
|||
|
|
@ -41,4 +41,7 @@ partial def reduce (e : Expr) (explicitOnly skipTypes skipProofs := true) : Meta
|
|||
| _ => return e
|
||||
visit e |>.run
|
||||
|
||||
def reduceAll (e : Expr) : MetaM Expr :=
|
||||
reduce e false false false
|
||||
|
||||
end Lean.Meta
|
||||
|
|
|
|||
|
|
@ -27,3 +27,4 @@ import Lean.Meta.Tactic.Unfold
|
|||
import Lean.Meta.Tactic.Rename
|
||||
import Lean.Meta.Tactic.LinearArith
|
||||
import Lean.Meta.Tactic.AC
|
||||
import Lean.Meta.Tactic.Refl
|
||||
|
|
|
|||
35
src/Lean/Meta/Tactic/Refl.lean
Normal file
35
src/Lean/Meta/Tactic/Refl.lean
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/-
|
||||
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.Meta.Reduce
|
||||
import Lean.Meta.Tactic.Util
|
||||
|
||||
namespace Lean.Meta
|
||||
|
||||
def refl (mvarId : MVarId) (reduceIfGround := true) : MetaM Unit := do
|
||||
withMVarContext mvarId do
|
||||
checkNotAssigned mvarId `apply
|
||||
let targetType ← getMVarType' mvarId
|
||||
unless targetType.isAppOfArity ``Eq 3 do
|
||||
throwTacticEx `rfl mvarId "equality expected{indentExpr targetType}"
|
||||
let lhs ← instantiateMVars targetType.appFn!.appArg!
|
||||
let rhs ← instantiateMVars targetType.appArg!
|
||||
let success ←
|
||||
if (← useReduceAll lhs rhs) then
|
||||
pure ((← reduceAll lhs) == (← reduceAll rhs))
|
||||
else
|
||||
isDefEq lhs rhs
|
||||
unless success do
|
||||
throwTacticEx `rfl mvarId "equality left-hand-side{indentExpr lhs}\nis not definitionally equal right-hand-side{indentExpr rhs}"
|
||||
let us := targetType.getAppFn.constLevels!
|
||||
let α := targetType.appFn!.appFn!.appArg!
|
||||
assignExprMVar mvarId (mkApp2 (mkConst ``Eq.refl us) α lhs)
|
||||
where
|
||||
useReduceAll (lhs rhs : Expr) : MetaM Bool := do
|
||||
if !reduceIfGround then return false
|
||||
else if lhs.hasFVar || lhs.hasMVar || lhs.hasFVar || lhs.hasMVar then return false
|
||||
else return (← getTransparency) matches TransparencyMode.default | TransparencyMode.all
|
||||
|
||||
end Lean.Meta
|
||||
Loading…
Add table
Reference in a new issue