feat: add hand-written rfl tactic

It requires update stage0
This commit is contained in:
Leonardo de Moura 2022-04-09 11:57:27 -07:00
parent 298281baaf
commit 03f6b87647
5 changed files with 47 additions and 2 deletions

View file

@ -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,

View file

@ -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 `_

View file

@ -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

View file

@ -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

View 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