File: .lake/packages/lean4/src/lean/Init/Ext.lean

full_name: Lean.Parser.Attr.ext
code: /-- Registers an extensionality theorem.

* 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.

* An optional natural number argument, e.g. `@[ext 9000]`, specifies a priority for the lemma. Higher-priority lemmas are chosen first, and the default is `1000`.

* The flag `@[ext (flat := false)]` causes generated structure extensionality theorems to show inherited fields based on their representation,
  rather than flattening the parents' fields into the lemma's equality hypotheses.
  structures in the generated extensionality theorems. -/
syntax (name := ext) "ext" (" (" &"flat" " := " term ")")? (ppSpace prio)? : attr
goal: Lean.ParserDescr

full_name: Lean.Elab.Tactic.Ext.extType
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.
-/
scoped syntax (name := extType) "ext_type% " term:max ppSpace ident : term
goal: Lean.ParserDescr

full_name: Lean.Elab.Tactic.Ext.extIffType
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.
-/
scoped syntax (name := extIffType) "ext_iff_type% " term:max ppSpace ident : term
goal: Lean.ParserDescr

full_name: Lean.Elab.Tactic.Ext.declareExtTheoremFor
code: /--
`declare_ext_theorems_for A` declares the extensionality theorems for the structure `A`.

These theorems state that two expressions with the structure type are equal if their fields are equal.
-/
syntax (name := declareExtTheoremFor) "declare_ext_theorems_for " ("(" &"flat" " := " term ") ")? ident (ppSpace prio)? : command
goal: Lean.ParserDescr

full_name: Lean.Elab.Tactic.Ext.«_aux_.lake_packages_lean4_src_lean_Init_Ext___macroRules_Lean_Elab_Tactic_Ext_declareExtTheoremFor_1»
code: macro_rules | `(declare_ext_theorems_for $[(flat := $f)]? $struct:ident $(prio)?) => do
  let flat := f.getD (mkIdent `true)
  let names ← Macro.resolveGlobalName struct.getId.eraseMacroScopes
  let name ← match names.filter (·.2.isEmpty) with
    | [] => Macro.throwError s!"unknown constant {struct.getId}"
    | [(name, _)] => pure name
    | _ => Macro.throwError s!"ambiguous name {struct.getId}"
  let extName := mkIdentFrom struct (canonical := true) <| name.mkStr "ext"
  let extIffName := mkIdentFrom struct (canonical := true) <| name.mkStr "ext_iff"
  `(@[ext $(prio)?] protected theorem $extName:ident : ext_type% $flat $struct:ident :=
      fun {..} {..} => by intros; subst_eqs; rfl
    protected theorem $extIffName:ident : ext_iff_type% $flat $struct:ident :=
      fun {..} {..} =>
        ⟨fun h => by cases h; and_intros <;> rfl,
         fun _ => by (repeat cases ‹_ ∧ _›); subst_eqs; rfl⟩)
goal: Lean.Macro

full_name: Lean.Elab.Tactic.Ext.ext
code: /--
Applies extensionality lemmas that are registered with the `@[ext]` attribute.
* `ext pat*` applies extensionality theorems as much as possible,
  using the patterns `pat*` to introduce the variables in extensionality theorems using `rintro`.
  For example, the patterns are used to name the variables introduced by lemmas such as `funext`.
* Without patterns,`ext` applies extensionality lemmas as much
  as possible but introduces anonymous hypotheses whenever needed.
* `ext pat* : n` applies ext theorems only up to depth `n`.

The `ext1 pat*` tactic is like `ext pat*` except that it only applies a single extensionality theorem.

Unused patterns will generate warning.
Patterns that don't match the variables will typically result in the introduction of anonymous hypotheses.
-/
syntax (name := ext) "ext" (colGt ppSpace rintroPat)* (" : " num)? : tactic
goal: Lean.ParserDescr

full_name: Lean.Elab.Tactic.Ext.applyExtTheorem
code: /-- Apply a single extensionality theorem to the current goal. -/
syntax (name := applyExtTheorem) "apply_ext_theorem" : tactic
goal: Lean.ParserDescr

full_name: Lean.Elab.Tactic.Ext.«_aux_.lake_packages_lean4_src_lean_Init_Ext___macroRules_Lean_Elab_Tactic_Ext_tacticExt1____1»
code: macro "ext1" xs:(colGt ppSpace rintroPat)* : tactic =>
  if xs.isEmpty then `(tactic| apply_ext_theorem <;> intros)
  else `(tactic| apply_ext_theorem <;> rintro $xs*)
goal: Lean.Macro

full_name: Lean.Elab.Tactic.Ext.tacticExt1___
code: macro "ext1" xs:(colGt ppSpace rintroPat)* : tactic =>
  if xs.isEmpty then `(tactic| apply_ext_theorem <;> intros)
  else `(tactic| apply_ext_theorem <;> rintro $xs*)
goal: Lean.ParserDescr

full_name: Prod.ext
code: @[ext] theorem Prod.ext : {x y : Prod α β} → x.fst = y.fst → x.snd = y.snd → x = y
  
goal: x.fst = y.fst → x.snd = y.snd → x = y

full_name: PProd.ext
code: @[ext] theorem PProd.ext : {x y : PProd α β} → x.fst = y.fst → x.snd = y.snd → x = y
  
goal: x.fst = y.fst → x.snd = y.snd → x = y

full_name: Sigma.ext
code: @[ext] theorem Sigma.ext : {x y : Sigma β} → x.fst = y.fst → HEq x.snd y.snd → x = y
  
goal: ∀ {α : Type u_1} {β : α → Type u_2} {x y : Sigma β}, x.fst = y.fst → HEq x.snd y.snd → x = y

full_name: PSigma.ext
code: @[ext] theorem PSigma.ext : {x y : PSigma β} → x.fst = y.fst → HEq x.snd y.snd → x = y
  
goal: ∀ {α : Sort u_1} {β : α → Sort u_2} {x y : PSigma β}, x.fst = y.fst → HEq x.snd y.snd → x = y

full_name: PUnit.ext
code: @[ext] protected theorem PUnit.ext (x y : PUnit) : x = y 
goal: x = y

full_name: Unit.ext
code: protected theorem Unit.ext (x y : Unit) : x = y 
goal: x = y