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) 2021 Gabriel Ebner. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Gabriel Ebner, Mario Carneiro
-/
import Std.Tactic.RCases
import Std.Lean.Command

namespace Std.Tactic.Ext
open Lean Meta

/-- `declare_ext_theorems_for A` declares the extensionality theorems for the structure `A`. -/
syntax "declare_ext_theorems_for" ident prio ? : command

/-- Information about an extensionality theorem, stored in the environment extension. -/
structure 
ExtTheorem: Type
ExtTheorem
where /-- Declaration name of the extensionality theorem. -/
declName: ExtTheoremName
declName
:
Name: Type
Name
/-- Priority of the extensionality theorem. -/
priority: ExtTheoremNat
priority
:
Nat: Type
Nat
/-- Key in the discrimination tree. -/ keys :
Array: Type ?u.68 → Type ?u.68
Array
(
DiscrTree.Key: BoolType
DiscrTree.Key
true: Bool
true
) deriving
Inhabited: Sort u → Sort (max1u)
Inhabited
,
Repr: Type u → Type u
Repr
,
BEq: Type u → Type u
BEq
,
Hashable: Sort u → Sort (max1u)
Hashable
/-- The environment extension to track `@[ext]` lemmas. -/ initialize extExtension :
SimpleScopedEnvExtension: TypeTypeType
SimpleScopedEnvExtension
ExtTheorem: Type
ExtTheorem
(
DiscrTree: TypeBoolType
DiscrTree
ExtTheorem: Type
ExtTheorem
true: Bool
true
) ←
registerSimpleScopedEnvExtension: {α σ : Type} → SimpleScopedEnvExtension.Descr α σIO (SimpleScopedEnvExtension α σ)
registerSimpleScopedEnvExtension
{ addEntry := fun
dt: ?m.3411
dt
thm: ?m.3414
thm
=>
dt: ?m.3411
dt
.
insertCore: {α : Type} → {s : Bool} → [inst : BEq α] → DiscrTree α sArray (DiscrTree.Key s)αDiscrTree α s
insertCore
thm: ?m.3414
thm
.keys
thm: ?m.3414
thm
initial :=
{}: DiscrTree ?m.3458 ?m.3459
{}
} /-- Get the list of `@[ext]` lemmas corresponding to the key `ty`. -/ @[inline] def
getExtLemmas: ExprMetaM (Array ExtTheorem)
getExtLemmas
(
ty: Expr
ty
:
Expr: Type
Expr
) :
MetaM: TypeType
MetaM
(
Array: Type ?u.6695 → Type ?u.6695
Array
ExtTheorem: Type
ExtTheorem
) := return
(← (extExtension.getState (← getEnv)).getMatch ty): ?m.6848
(← (
extExtension
(← (extExtension.getState (← getEnv)).getMatch ty): ?m.6848
.
getState: {σ α β : Type} → [inst : Inhabited σ] → ScopedEnvExtension α β σEnvironmentσ
getState
(← (extExtension.getState (← getEnv)).getMatch ty): ?m.6848
(← getEnv): ?m.6764
(←
getEnv: {m : TypeType} → [self : MonadEnv m] → m Environment
getEnv
(← getEnv): ?m.6764
)
(← (extExtension.getState (← getEnv)).getMatch ty): ?m.6848
).
getMatch: {α : Type} → {s : Bool} → DiscrTree α sExprMetaM (Array α)
getMatch
(← (extExtension.getState (← getEnv)).getMatch ty): ?m.6848
ty: Expr
ty
(← (extExtension.getState (← getEnv)).getMatch ty): ?m.6848
)
|>.
insertionSort: {α : Type ?u.6875} → Array α(ααBool) → Array α
insertionSort
fun
a: ?m.6882
a
b: ?m.6885
b
=>
a: ?m.6882
a
.
priority: ExtTheoremNat
priority
>
b: ?m.6885
b
.
priority: ExtTheoremNat
priority
/-- Registers an extensionality lemma. When `@[ext]` is applied to a structure, it generates `.ext` and `.ext_iff` theorems and registers them for the `ext` tactic. When `@[ext]` is applied to a theorem, the theorem is registered for the `ext` tactic. You can use `@[ext 9000]` to specify a priority for the attribute. -/ syntax (name := ext) "ext" prio ? : attr initialize
registerBuiltinAttribute: AttributeImplIO Unit
registerBuiltinAttribute
{ name :=
`ext: Name
`ext
descr :=
"Marks a lemma as extensionality lemma": String
"Marks a lemma as extensionality lemma"
add := fun
declName: ?m.8013
declName
stx: ?m.8016
stx
kind: ?m.8019
kind
=> do let `(attr| ext $[$
prio: ?m.8073 x✝
prio
]?) :=
stx: ?m.8016
stx
| throwError "unexpected @[ext] attribute {
stx: ?m.8016
stx
}" if
isStructure: EnvironmentNameBool
isStructure
(← getEnv): ?m.8487
(←
getEnv: {m : TypeType} → [self : MonadEnv m] → m Environment
getEnv
(← getEnv): ?m.8487
)
declName: ?m.8013
declName
then
liftCommandElabM: {α : Type} → Elab.Command.CommandElabM αCoreM α
liftCommandElabM
<|
Elab.Command.elabCommand: SyntaxElab.Command.CommandElabM Unit
Elab.Command.elabCommand
<| ← `(declare_ext_theorems_for $(
mkCIdentFrom: SyntaxNameoptParam Bool falseIdent
mkCIdentFrom
stx: ?m.8016
stx
declName: ?m.8013
declName
) $[$
prio: ?m.8073 x✝
prio
]?) else
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.9438
declTy
:=
(← getConstInfo declName): ?m.9435
(←
getConstInfo: {m : TypeType} → [inst : Monad m] → [inst : MonadEnv m] → [inst : MonadError m] → Namem ConstantInfo
getConstInfo
(← getConstInfo declName): ?m.9435
declName: ?m.8013
declName
(← getConstInfo declName): ?m.9435
)
.
type: ConstantInfoExpr
type
let (_, _,
declTy: Expr
declTy
) ←
withDefault: {n : TypeType ?u.9477} → [inst : MonadControlT MetaM n] → [inst : Monad n] → {α : Type} → n αn α
withDefault
<|
forallMetaTelescopeReducing: ExproptParam (Option Nat) noneoptParam MetavarKind MetavarKind.naturalMetaM (Array Expr × Array BinderInfo × Expr)
forallMetaTelescopeReducing
declTy: ?m.9438
declTy
let
failNotEq: ?m.9620
failNotEq
:= throwError "@[ext] attribute only applies to structures or lemmas proving x = y, got {
declTy: Expr
declTy
}" let
some: {α : Type ?u.9833} → αOption α
some
(
ty: Expr
ty
,
lhs: Expr
lhs
,
rhs: Expr
rhs
) :=
declTy: Expr
declTy
.eq? |
failNotEq: ?m.9620
failNotEq
unless
lhs: Expr
lhs
.
isMVar: ExprBool
isMVar
&&
rhs: Expr
rhs
.
isMVar: ExprBool
isMVar
do
failNotEq: MetaM (?m.9883 y✝)
failNotEq
let
keys: ?m.10223
keys
withReducible: {n : TypeType ?u.10166} → [inst : MonadControlT MetaM n] → [inst : Monad n] → {α : Type} → n αn α
withReducible
<|
DiscrTree.mkPath: {s : Bool} → ExprMetaM (Array (DiscrTree.Key s))
DiscrTree.mkPath
ty: Expr
ty
let
priority: ?m.10959
priority
liftCommandElabM: {α : Type} → Elab.Command.CommandElabM αCoreM α
liftCommandElabM
do
Elab.liftMacroM: {m : TypeType} → {α : Type} → [inst : Monad m] → [inst : Elab.MonadMacroAdapter m] → [inst : MonadEnv m] → [inst : MonadRecDepth m] → [inst : MonadError m] → [inst : MonadResolveName m] → [inst : MonadTrace m] → [inst : MonadOptions m] → [inst : AddMessageContext m] → [inst : MonadLiftT IO m] → MacroM αm α
Elab.liftMacroM
do
evalPrio: SyntaxMacroM Nat
evalPrio
(
prio: ?m.8073 x✝
prio
.
getD: {α : Type ?u.10712} → Option ααα
getD
(← `(prio| default)): ?m.10708
(← `(
prio
(← `(prio| default)): ?m.10708
|
(← `(prio| default)): ?m.10708
default
(← `(prio| default)): ?m.10708
))
) extExtension.
add: {m : TypeType} → {α β σ : Type} → [inst : Monad m] → [inst : MonadResolveName m] → [inst : MonadEnv m] → ScopedEnvExtension α β σβoptParam AttributeKind AttributeKind.globalm Unit
add
{
declName: ?m.8013
declName
, keys, priority}
kind: ?m.8019
kind
}