File: .lake/packages/lean4/src/lean/Lean/Elab/Tactic/Ext.lean

full_name: Lean.Elab.Tactic.Ext.ExtTheorem
code: /-- Information about an extensionality theorem, stored in the environment extension. -/
structure ExtTheorem where
  /-- Declaration name of the extensionality theorem. -/
  declName : Name
  /-- Priority of the extensionality theorem. -/
  priority : Nat
  /--
  Key in the discrimination tree,
  for the type in which the extensionality theorem holds.
  -/
  keys : Array DiscrTree.Key
  deriving Inhabited, Repr, BEq, Hashable
goal: Type

full_name: Lean.Elab.Tactic.Ext.ExtTheorem.declName
code: /-- Information about an extensionality theorem, stored in the environment extension. -/
structure ExtTheorem where
  /-- Declaration name of the extensionality theorem. -/
  declName : Name
  /-- Priority of the extensionality theorem. -/
  priority : Nat
  /--
  Key in the discrimination tree,
  for the type in which the extensionality theorem holds.
  -/
  keys : Array DiscrTree.Key
  deriving Inhabited, Repr, BEq, Hashable
goal: Lean.Name

full_name: Lean.Elab.Tactic.Ext.instBEqExtTheorem
code: /-- Information about an extensionality theorem, stored in the environment extension. -/
structure ExtTheorem where
  /-- Declaration name of the extensionality theorem. -/
  declName : Name
  /-- Priority of the extensionality theorem. -/
  priority : Nat
  /--
  Key in the discrimination tree,
  for the type in which the extensionality theorem holds.
  -/
  keys : Array DiscrTree.Key
  deriving Inhabited, Repr, BEq, Hashable
goal: BEq Lean.Elab.Tactic.Ext.ExtTheorem

full_name: Lean.Elab.Tactic.Ext.ExtTheorem.priority
code: /-- Information about an extensionality theorem, stored in the environment extension. -/
structure ExtTheorem where
  /-- Declaration name of the extensionality theorem. -/
  declName : Name
  /-- Priority of the extensionality theorem. -/
  priority : Nat
  /--
  Key in the discrimination tree,
  for the type in which the extensionality theorem holds.
  -/
  keys : Array DiscrTree.Key
  deriving Inhabited, Repr, BEq, Hashable
goal: Nat

full_name: Lean.Elab.Tactic.Ext.ExtTheorem.keys
code: /-- Information about an extensionality theorem, stored in the environment extension. -/
structure ExtTheorem where
  /-- Declaration name of the extensionality theorem. -/
  declName : Name
  /-- Priority of the extensionality theorem. -/
  priority : Nat
  /--
  Key in the discrimination tree,
  for the type in which the extensionality theorem holds.
  -/
  keys : Array DiscrTree.Key
  deriving Inhabited, Repr, BEq, Hashable
goal: Array Lean.Meta.DiscrTree.Key

full_name: Lean.Elab.Tactic.Ext.instHashableExtTheorem
code: /-- Information about an extensionality theorem, stored in the environment extension. -/
structure ExtTheorem where
  /-- Declaration name of the extensionality theorem. -/
  declName : Name
  /-- Priority of the extensionality theorem. -/
  priority : Nat
  /--
  Key in the discrimination tree,
  for the type in which the extensionality theorem holds.
  -/
  keys : Array DiscrTree.Key
  deriving Inhabited, Repr, BEq, Hashable
goal: Hashable Lean.Elab.Tactic.Ext.ExtTheorem

full_name: Lean.Elab.Tactic.Ext.instReprExtTheorem
code: /-- Information about an extensionality theorem, stored in the environment extension. -/
structure ExtTheorem where
  /-- Declaration name of the extensionality theorem. -/
  declName : Name
  /-- Priority of the extensionality theorem. -/
  priority : Nat
  /--
  Key in the discrimination tree,
  for the type in which the extensionality theorem holds.
  -/
  keys : Array DiscrTree.Key
  deriving Inhabited, Repr, BEq, Hashable
goal: Repr Lean.Elab.Tactic.Ext.ExtTheorem

full_name: Lean.Elab.Tactic.Ext.instInhabitedExtTheorem
code: /-- Information about an extensionality theorem, stored in the environment extension. -/
structure ExtTheorem where
  /-- Declaration name of the extensionality theorem. -/
  declName : Name
  /-- Priority of the extensionality theorem. -/
  priority : Nat
  /--
  Key in the discrimination tree,
  for the type in which the extensionality theorem holds.
  -/
  keys : Array DiscrTree.Key
  deriving Inhabited, Repr, BEq, Hashable
goal: Inhabited Lean.Elab.Tactic.Ext.ExtTheorem

full_name: Lean.Elab.Tactic.Ext.ExtTheorems.erased
code: /-- The state of the `ext` extension environment -/
structure ExtTheorems where
  /-- The tree of `ext` extensions. -/
  tree   : DiscrTree ExtTheorem := {}
  /-- Erased `ext`s via `attribute [-ext]`. -/
  erased  : PHashSet Name := {}
  deriving Inhabited
goal: Lean.PHashSet Lean.Name

full_name: Lean.Elab.Tactic.Ext.instInhabitedExtTheorems
code: /-- The state of the `ext` extension environment -/
structure ExtTheorems where
  /-- The tree of `ext` extensions. -/
  tree   : DiscrTree ExtTheorem := {}
  /-- Erased `ext`s via `attribute [-ext]`. -/
  erased  : PHashSet Name := {}
  deriving Inhabited
goal: Inhabited Lean.Elab.Tactic.Ext.ExtTheorems

full_name: Lean.Elab.Tactic.Ext.ExtTheorems
code: /-- The state of the `ext` extension environment -/
structure ExtTheorems where
  /-- The tree of `ext` extensions. -/
  tree   : DiscrTree ExtTheorem := {}
  /-- Erased `ext`s via `attribute [-ext]`. -/
  erased  : PHashSet Name := {}
  deriving Inhabited
goal: Type

full_name: Lean.Elab.Tactic.Ext.ExtTheorems.tree
code: /-- The state of the `ext` extension environment -/
structure ExtTheorems where
  /-- The tree of `ext` extensions. -/
  tree   : DiscrTree ExtTheorem := {}
  /-- Erased `ext`s via `attribute [-ext]`. -/
  erased  : PHashSet Name := {}
  deriving Inhabited
goal: Lean.Meta.DiscrTree Lean.Elab.Tactic.Ext.ExtTheorem

full_name: Lean.Elab.Tactic.Ext.extExt.config
code: /-- Discrimation tree settings for the `ext` extension. -/
def extExt.config : WhnfCoreConfig 
goal: Lean.Meta.WhnfCoreConfig

full_name: Lean.Elab.Tactic.Ext.extExtension
code: /-- The environment extension to track `@[ext]` theorems. -/
builtin_initialize extExtension :
    SimpleScopedEnvExtension ExtTheorem ExtTheorems ←
  registerSimpleScopedEnvExtension {
    addEntry := fun { tree, erased } thm =>
      { tree := tree.insertCore thm.keys thm, erased := erased.erase thm.declName }
    initial := {}
  }
goal: Lean.SimpleScopedEnvExtension Lean.Elab.Tactic.Ext.ExtTheorem Lean.Elab.Tactic.Ext.ExtTheorems

full_name: Lean.Elab.Tactic.Ext.initFn._@..lake.packages.lean4.src.lean.Lean.Elab.Tactic.Ext._hyg.330
code: /-- The environment extension to track `@[ext]` theorems. -/
builtin_initialize extExtension :
    SimpleScopedEnvExtension ExtTheorem ExtTheorems ←
  registerSimpleScopedEnvExtension {
    addEntry := fun { tree, erased } thm =>
      { tree := tree.insertCore thm.keys thm, erased := erased.erase thm.declName }
    initial := {}
  }
goal: IO (Lean.SimpleScopedEnvExtension Lean.Elab.Tactic.Ext.ExtTheorem Lean.Elab.Tactic.Ext.ExtTheorems)

full_name: Lean.Elab.Tactic.Ext.getExtTheorems
code: /-- Gets the list of `@[ext]` theorems corresponding to the key `ty`,
ordered from high priority to low. -/
@[inline] def getExtTheorems (ty : Expr) : MetaM (Array ExtTheorem) 
goal: Lean.MetaM (Array Lean.Elab.Tactic.Ext.ExtTheorem)

full_name: Lean.Elab.Tactic.Ext.ExtTheorems.eraseCore
code: /--
Erases a name marked `ext` by adding it to the state's `erased` field and
removing it from the state's list of `Entry`s.

This is triggered by `attribute [-ext] name`.
-/
def ExtTheorems.eraseCore (d : ExtTheorems) (declName : Name) : ExtTheorems 
goal: Lean.Elab.Tactic.Ext.ExtTheorems

full_name: Lean.Elab.Tactic.Ext.ExtTheorems.erase
code: /--
  Erases a name marked as a `ext` attribute.
  Check that it does in fact have the `ext` attribute by making sure it names a `ExtTheorem`
  found somewhere in the state's tree, and is not erased.
-/
def ExtTheorems.erase [Monad m] [MonadError m] (d : ExtTheorems) (declName : Name) :
    m ExtTheorems 
goal: m Lean.Elab.Tactic.Ext.ExtTheorems

full_name: Lean.Elab.Tactic.Ext.initFn._@..lake.packages.lean4.src.lean.Lean.Elab.Tactic.Ext._hyg.630
code: builtin_initialize registerBuiltinAttribute {
  name := `ext
  descr := "Marks a theorem as an extensionality theorem"
  add := fun declName stx kind => do
    let `(attr| ext $[(flat := $f)]? $(prio)?) := stx
      | throwError "unexpected @[ext] attribute {stx}"
    if isStructure (← getEnv) declName then
      liftCommandElabM <| Elab.Command.elabCommand <|
        ← `(declare_ext_theorems_for $[(flat := $f)]? $(mkCIdentFrom stx declName) $[$prio]?)
    else MetaM.run' do
      if let some flat := f then
        throwErrorAt flat "unexpected 'flat' config on @[ext] theorem"
      let declTy := (← getConstInfo declName).type
      let (_, _, declTy) ← withDefault <| forallMetaTelescopeReducing declTy
      let failNotEq := throwError
        "@[ext] attribute only applies to structures or theorems proving x = y, got {declTy}"
      let some (ty, lhs, rhs) := declTy.eq? | failNotEq
      unless lhs.isMVar && rhs.isMVar do failNotEq
      let keys ← withReducible <| DiscrTree.mkPath ty extExt.config
      let priority ← liftCommandElabM do Elab.liftMacroM do
        evalPrio (prio.getD (← `(prio| default)))
      extExtension.add {declName, keys, priority} kind
  erase := fun declName => do
    let s := extExtension.getState (← getEnv)
    let s ← s.erase declName
    modifyEnv fun env => extExtension.modifyState env fun _ => s
}
goal: IO Unit

full_name: Lean.Elab.Tactic.Ext.withExtHyps
code: /--
Constructs the hypotheses for the structure extensionality theorem that
states that two structures are equal if their fields are equal.

Calls the continuation `k` with the list of parameters to the structure,
two structure variables `x` and `y`, and a list of pairs `(field, ty)`
where `ty` is `x.field = y.field` or `HEq x.field y.field`.

If `flat` parses to `true`, any fields inherited from parent structures
are treated fields of the given structure type.
If it is `false`, then the behind-the-scenes encoding of inherited fields
is visible in the extensionality lemma.
-/
-- TODO: this is probably the wrong place to have this function
def withExtHyps (struct : Name) (flat : Term)
    (k : Array Expr → (x y : Expr) → Array (Name × Expr) → MetaM α) : MetaM α 
goal: Lean.MetaM α

full_name: Lean.Elab.Tactic.Ext.elabExtType
code: /--
Creates the type of the extensionality theorem for the given structure,
elaborating to `x.1 = y.1 → x.2 = y.2 → x = y`, for example.
-/
@[builtin_term_elab extType] def elabExtType : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Tactic.Ext.elabExtIffType
code: /--
Creates the type of the iff-variant of the extensionality theorem for the given structure,
elaborating to `x = y ↔ x.1 = y.1 ∧ x.2 = y.2`, for example.
-/
@[builtin_term_elab extIffType] def elabExtIffType : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Tactic.Ext.applyExtTheoremAt
code: /-- Apply a single extensionality theorem to `goal`. -/
def applyExtTheoremAt (goal : MVarId) : MetaM (List MVarId) 
goal: Lean.MetaM (List Lean.MVarId)

full_name: Lean.Elab.Tactic.Ext.evalApplyExtTheorem
code: /-- Apply a single extensionality theorem to the current goal. -/
@[builtin_tactic applyExtTheorem] def evalApplyExtTheorem : Tactic 
goal: Lean.Elab.Tactic.Tactic

full_name: Lean.Elab.Tactic.Ext.tryIntros
code: /--
Postprocessor for `withExt` which runs `rintro` with the given patterns when the target is a
pi type.
-/
def tryIntros [Monad m] [MonadLiftT TermElabM m] (g : MVarId) (pats : List (TSyntax `rcasesPat))
    (k : MVarId → List (TSyntax `rcasesPat) → m Nat) : m Nat 
goal: m Nat

full_name: Lean.Elab.Tactic.Ext.withExt1
code: /--
Applies a single extensionality theorem, using `pats` to introduce variables in the result.
Runs continuation `k` on each subgoal.
-/
def withExt1 [Monad m] [MonadLiftT TermElabM m] (g : MVarId) (pats : List (TSyntax `rcasesPat))
    (k : MVarId → List (TSyntax `rcasesPat) → m Nat) : m Nat 
goal: m Nat

full_name: Lean.Elab.Tactic.Ext.withExtN
code: /--
Applies extensionality theorems recursively, using `pats` to introduce variables in the result.
Runs continuation `k` on each subgoal.
-/
def withExtN [Monad m] [MonadLiftT TermElabM m] [MonadExcept Exception m]
    (g : MVarId) (pats : List (TSyntax `rcasesPat)) (k : MVarId → List (TSyntax `rcasesPat) → m Nat)
    (depth := 1000000) (failIfUnchanged := true) : m Nat 
goal: m Nat

full_name: Lean.Elab.Tactic.Ext.extCore
code: /--
Apply extensionality theorems as much as possible, using `pats` to introduce the variables
in extensionality theorems like `funext`. Returns a list of subgoals.

This is built on top of `withExtN`, running in `TermElabM` to build the list of new subgoals.
(And, for each goal, the patterns consumed.)
-/
def extCore (g : MVarId) (pats : List (TSyntax `rcasesPat))
    (depth := 1000000) (failIfUnchanged := true) :
    TermElabM (Nat × Array (MVarId × List (TSyntax `rcasesPat))) 
goal: Lean.Elab.TermElabM (Nat × Array (Lean.MVarId × List (Lean.TSyntax `rcasesPat)))

full_name: Lean.Elab.Tactic.Ext.evalExt
code: @[builtin_tactic ext] def evalExt : Tactic 
goal: Lean.Elab.Tactic.Tactic