Built with doc-gen4, running Lean4. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+โ†‘Ctrl+โ†“to navigate, Ctrl+๐Ÿ–ฑ๏ธto focus. On Mac, use Cmdinstead of Ctrl.
/-
Copyright (c) 2022 Newell Jensen. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Newell Jensen
-/
import Lean
import Mathlib.Lean.Meta

/-!
# `rfl` tactic extension for reflexive relations

This extends the `rfl` tactic so that it works on any reflexive relation,
provided the reflexivity lemma has been marked as `@[refl]`.
-/

namespace Mathlib.Tactic

open Lean Meta

/-- Environment extensions for `refl` lemmas -/
initialize reflExt :
    
SimpleScopedEnvExtension: Type โ†’ Type โ†’ Type
SimpleScopedEnvExtension
(
Name: Type
Name
ร—
Array: Type ?u.559 โ†’ Type ?u.559
Array
(
DiscrTree.Key: Bool โ†’ Type
DiscrTree.Key
true: Bool
true
)) (
DiscrTree: Type โ†’ Bool โ†’ Type
DiscrTree
Name: Type
Name
true: Bool
true
) โ†
registerSimpleScopedEnvExtension: {ฮฑ ฯƒ : Type} โ†’ SimpleScopedEnvExtension.Descr ฮฑ ฯƒ โ†’ IO (SimpleScopedEnvExtension ฮฑ ฯƒ)
registerSimpleScopedEnvExtension
{ addEntry := fun
dt: ?m.39
dt
(
n: Name
n
, ks) โ†ฆ
dt: ?m.39
dt
.
insertCore: {ฮฑ : Type} โ†’ {s : Bool} โ†’ [inst : BEq ฮฑ] โ†’ DiscrTree ฮฑ s โ†’ Array (DiscrTree.Key s) โ†’ ฮฑ โ†’ DiscrTree ฮฑ s
insertCore
ks
n: Name
n
initial :=
{}: DiscrTree ?m.171 ?m.172
{}
} initialize
registerBuiltinAttribute: AttributeImpl โ†’ IO Unit
registerBuiltinAttribute
{ name :=
`refl: Name
`refl
descr :=
"reflexivity relation": String
"reflexivity relation"
add := fun
decl: ?m.619
decl
_: ?m.622
_
kind: ?m.625
kind
โ†ฆ
MetaM.run': {ฮฑ : Type} โ†’ MetaM ฮฑ โ†’ optParam Context { config := { foApprox := false, ctxApprox := false, quasiPatternApprox := false, constApprox := false, isDefEqStuckEx := false, transparency := TransparencyMode.default, zetaNonDep := true, trackZeta := false, unificationHints := true, proofIrrelevance := true, assignSyntheticOpaque := false, offsetCnstrs := true, etaStruct := EtaStructMode.all }, lctx := { fvarIdToDecl := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 }, decls := { root := PersistentArrayNode.node (Array.mkEmpty (USize.toNat PersistentArray.branching)), tail := Array.mkEmpty (USize.toNat PersistentArray.branching), size := 0, shift := PersistentArray.initShift, tailOff := 0 } }, localInstances := #[], defEqCtx? := none, synthPendingDepth := 0, canUnfold? := none } โ†’ optParam State { mctx := { depth := 0, levelAssignDepth := 0, mvarCounter := 0, lDepth := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 }, decls := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 }, userNames := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 }, lAssignment := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 }, eAssignment := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 }, dAssignment := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 } }, cache := { inferType := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 }, funInfo := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 }, synthInstance := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 }, whnfDefault := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 }, whnfAll := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 }, defEq := { root := PersistentHashMap.Node.entries PersistentHashMap.mkEmptyEntriesArray, size := 0 } }, zetaFVarIds := โˆ…, postponed := { root := PersistentArrayNode.node (Array.mkEmpty (USize.toNat PersistentArray.branching)), tail := Array.mkEmpty (USize.toNat PersistentArray.branching), size := 0, shift := PersistentArray.initShift, tailOff := 0 } } โ†’ CoreM ฮฑ
MetaM.run'
do let
declTy: ?m.929
declTy
:=
(โ† getConstInfo decl): ?m.926
(โ†
getConstInfo: {m : Type โ†’ Type} โ†’ [inst : Monad m] โ†’ [inst : MonadEnv m] โ†’ [inst : MonadError m] โ†’ Name โ†’ m ConstantInfo
getConstInfo
(โ† getConstInfo decl): ?m.926
decl: ?m.619
decl
(โ† getConstInfo decl): ?m.926
)
.
type: ConstantInfo โ†’ Expr
type
let (_, _,
targetTy: Expr
targetTy
) โ†
withReducible: {n : Type โ†’ Type ?u.968} โ†’ [inst : MonadControlT MetaM n] โ†’ [inst : Monad n] โ†’ {ฮฑ : Type} โ†’ n ฮฑ โ†’ n ฮฑ
withReducible
<|
forallMetaTelescopeReducing: Expr โ†’ optParam (Option Nat) none โ†’ optParam MetavarKind MetavarKind.natural โ†’ MetaM (Array Expr ร— Array BinderInfo ร— Expr)
forallMetaTelescopeReducing
declTy: ?m.929
declTy
let
fail: ?m.1121
fail
:= throwError "@[refl] attribute only applies to lemmas proving x โˆผ x, got {
declTy: ?m.929
declTy
}" let
.app: Expr โ†’ Expr โ†’ Expr
.app
(
.app: Expr โ†’ Expr โ†’ Expr
.app
rel: Expr
rel
lhs: Expr
lhs
)
rhs: Expr
rhs
:=
targetTy: Expr
targetTy
|
fail: ?m.1121
fail
unless โ†
withNewMCtxDepth: {n : Type โ†’ Type ?u.1388} โ†’ [inst : MonadControlT MetaM n] โ†’ [inst : Monad n] โ†’ {ฮฑ : Type} โ†’ n ฮฑ โ†’ optParam Bool false โ†’ n ฮฑ
withNewMCtxDepth
<|
isDefEq: Expr โ†’ Expr โ†’ MetaM Bool
isDefEq
lhs: Expr
lhs
rhs: Expr
rhs
do
fail: ?m.1121
fail
let
key: ?m.1765
key
โ†
DiscrTree.mkPath: {s : Bool} โ†’ Expr โ†’ MetaM (Array (DiscrTree.Key s))
DiscrTree.mkPath
rel: Expr
rel
reflExt.
add: {m : Type โ†’ Type} โ†’ {ฮฑ ฮฒ ฯƒ : Type} โ†’ [inst : Monad m] โ†’ [inst : MonadResolveName m] โ†’ [inst : MonadEnv m] โ†’ ScopedEnvExtension ฮฑ ฮฒ ฯƒ โ†’ ฮฒ โ†’ optParam AttributeKind AttributeKind.global โ†’ m Unit
add
(
decl: ?m.619
decl
,
key: ?m.1765
key
)
kind: ?m.625
kind
} open Elab Tactic /-- `MetaM` version of the `rfl` tactic. This tactic applies to a goal whose target has the form `x ~ x`, where `~` is a reflexive relation, that is, a relation which has a reflexive lemma tagged with the attribute [refl]. -/ def
_root_.Lean.MVarId.rfl: MVarId โ†’ MetaM Unit
_root_.Lean.MVarId.rfl
(
goal: MVarId
goal
:
MVarId: Type
MVarId
) :
MetaM: Type โ†’ Type
MetaM
Unit: Type
Unit
:= do let
.app: Expr โ†’ Expr โ†’ Expr
.app
(
.app: Expr โ†’ Expr โ†’ Expr
.app
rel: Expr
rel
_) _ โ†
whnfR: Expr โ†’ MetaM Expr
whnfR
<|โ†
instantiateMVars: {m : Type โ†’ Type} โ†’ [inst : Monad m] โ†’ [inst : MonadMCtx m] โ†’ Expr โ†’ m Expr
instantiateMVars
<|โ†
goal: MVarId
goal
.
getType: MVarId โ†’ MetaM Expr
getType
| throwError "reflexivity lemmas only apply to binary relations, not {
indentExpr: Expr โ†’ MessageData
indentExpr
(โ† goal.getType): ?m.9236
(โ†
goal: MVarId
goal
(โ† goal.getType): ?m.9236
.
getType: MVarId โ†’ MetaM Expr
getType
(โ† goal.getType): ?m.9236
)
}" let
s: ?m.6530
s
โ†
saveState: {s : outParam Type} โ†’ {m : Type โ†’ Type} โ†’ [self : MonadBacktrack s m] โ†’ m s
saveState
let mut
ex?: ?m.8321
ex?
:=
none: {ฮฑ : Type ?u.6534} โ†’ Option ฮฑ
none
for
lem: ?m.6767
lem
in โ† (reflExt.
getState: {ฯƒ ฮฑ ฮฒ : Type} โ†’ [inst : Inhabited ฯƒ] โ†’ ScopedEnvExtension ฮฑ ฮฒ ฯƒ โ†’ Environment โ†’ ฯƒ
getState
(โ† getEnv): ?m.6582
(โ†
getEnv: {m : Type โ†’ Type} โ†’ [self : MonadEnv m] โ†’ m Environment
getEnv
(โ† getEnv): ?m.6582
)
).
getMatch: {ฮฑ : Type} โ†’ {s : Bool} โ†’ DiscrTree ฮฑ s โ†’ Expr โ†’ MetaM (Array ฮฑ)
getMatch
rel: Expr
rel
do try let
gs: ?m.6939
gs
โ†
goal: MVarId
goal
.
apply: MVarId โ†’ Expr โ†’ optParam ApplyConfig { newGoals := ApplyNewGoals.nonDependentFirst, synthAssignedInstances := true, approx := true } โ†’ MetaM (List MVarId)
apply
(โ† mkConstWithFreshMVarLevels lem): ?m.6882
(โ†
mkConstWithFreshMVarLevels: Name โ†’ MetaM Expr
mkConstWithFreshMVarLevels
(โ† mkConstWithFreshMVarLevels lem): ?m.6882
lem: ?m.6767
lem
(โ† mkConstWithFreshMVarLevels lem): ?m.6882
)
if
gs: ?m.6939
gs
.
isEmpty: {ฮฑ : Type ?u.6941} โ†’ List ฮฑ โ†’ Bool
isEmpty
then return
(): Unit
()
else
logError: {m : Type โ†’ Type} โ†’ [inst : Monad m] โ†’ [inst : MonadLog m] โ†’ [inst : AddMessageContext m] โ†’ [inst : MonadOptions m] โ†’ MessageData โ†’ m Unit
logError
<|
MessageData.tagged: Name โ†’ MessageData โ†’ MessageData
MessageData.tagged
`Tactic.unsolvedGoals: Name
`Tactic.unsolvedGoals
<| m!"unsolved goals\n {
goalsToMessageData: List MVarId โ†’ MessageData
goalsToMessageData
gs: ?m.6939
gs
}" catch
e: ?m.7376
e
=>
ex?: ?m.7425
ex?
:=
ex?: ?m.6781
ex?
<|> (
some: {ฮฑ : Type ?u.7429} โ†’ ฮฑ โ†’ Option ฮฑ
some
(โ†
saveState: {s : outParam Type} โ†’ {m : Type โ†’ Type} โ†’ [self : MonadBacktrack s m] โ†’ m s
saveState
,
e: ?m.7376
e
)) -- stash the first failure of `apply`
s: ?m.6530
s
.
restore: Meta.SavedState โ†’ MetaM Unit
restore
if let
some: {ฮฑ : Type ?u.8538} โ†’ ฮฑ โ†’ Option ฮฑ
some
(sErr, e) :=
ex?: ?m.8321
ex?
then sErr.
restore: Meta.SavedState โ†’ MetaM Unit
restore
throw: {ฮต : outParam (Type ?u.8629)} โ†’ {m : Type ?u.8628 โ†’ Type ?u.8627} โ†’ [self : MonadExcept ฮต m] โ†’ {ฮฑ : Type ?u.8628} โ†’ ฮต โ†’ m ฮฑ
throw
e else
throwError "rfl failed, no lemma with @[refl] applies": ?m.8866 ?m.8867
throwError
throwError "rfl failed, no lemma with @[refl] applies": ?m.8866 ?m.8867
"rfl failed, no lemma with @[refl] applies"
/-- This tactic applies to a goal whose target has the form `x ~ x`, where `~` is a reflexive relation, that is, a relation which has a reflexive lemma tagged with the attribute [refl]. -/ elab_rules : tactic | `(tactic| rfl) =>
withMainContext: {ฮฑ : Type} โ†’ TacticM ฮฑ โ†’ TacticM ฮฑ
withMainContext
do
liftMetaFinishingTactic: (MVarId โ†’ MetaM Unit) โ†’ TacticM Unit
liftMetaFinishingTactic
(ยท.
rfl: MVarId โ†’ MetaM Unit
rfl
)