doc-next-gen

Mathlib.Logic.Equiv.Basic

Module docstring

{"# Equivalence between types

In this file we continue the work on equivalences begun in Mathlib/Logic/Equiv/Defs.lean, defining a lot of equivalences between various types and operations on these equivalences.

More definitions of this kind can be found in other files. E.g., Mathlib/Algebra/Equiv/TransferInstance.lean does it for many algebraic type classes like Group, Module, etc.

Tags

equivalence, congruence, bijective map "}

Equiv.piOptionEquivProd definition
{α} {β : Option α → Type*} : (∀ a : Option α, β a) ≃ β none × ∀ a : α, β (some a)
Full source
/-- The product over `Option α` of `β a` is the binary product of the
product over `α` of `β (some α)` and `β none` -/
@[simps]
def piOptionEquivProd {α} {β : Option α → Type*} :
    (∀ a : Option α, β a) ≃ β none × ∀ a : α, β (some a) where
  toFun f := (f none, fun a => f (some a))
  invFun x a := Option.casesOn a x.fst x.snd
  left_inv f := funext fun a => by cases a <;> rfl
  right_inv x := by simp
Equivalence between product over options and binary product
Informal description
For any type $\alpha$ and any family of types $\beta : \text{Option } \alpha \to \text{Type*}$, there is an equivalence between the product of $\beta$ over $\text{Option } \alpha$ and the binary product of $\beta$ none with the product of $\beta$ over $\alpha$ (via $\text{some}$). More precisely, the equivalence maps a function $f : \forall a : \text{Option } \alpha, \beta a$ to the pair $(f(\text{none}), \lambda a, f(\text{some } a))$, and its inverse reconstructs the original function by case analysis on the option type.
Equiv.subtypeCongr definition
{α} {p q : α → Prop} [DecidablePred p] [DecidablePred q] (e : { x // p x } ≃ { x // q x }) (f : { x // ¬p x } ≃ { x // ¬q x }) : Perm α
Full source
/-- Combines an `Equiv` between two subtypes with an `Equiv` between their complements to form a
  permutation. -/
def subtypeCongr {α} {p q : α → Prop} [DecidablePred p] [DecidablePred q]
    (e : { x // p x }{ x // p x } ≃ { x // q x }) (f : { x // ¬p x }{ x // ¬p x } ≃ { x // ¬q x }) : Perm α :=
  (sumCompl p).symm.trans ((sumCongr e f).trans (sumCompl q))
Permutation from equivalences on subtype and complement
Informal description
Given a type $\alpha$ with decidable predicates $p$ and $q$, an equivalence $e$ between the subtypes $\{x \mid p\ x\}$ and $\{x \mid q\ x\}$, and an equivalence $f$ between the complements $\{x \mid \neg p\ x\}$ and $\{x \mid \neg q\ x\}$, the function `subtypeCongr` constructs a permutation of $\alpha$ by combining these equivalences via the canonical decomposition of $\alpha$ into these subtypes and their complements.
Equiv.Perm.subtypeCongr definition
: Equiv.Perm ε
Full source
/-- Combining permutations on `ε` that permute only inside or outside the subtype
split induced by `p : ε → Prop` constructs a permutation on `ε`. -/
def Perm.subtypeCongr : Equiv.Perm ε :=
  permCongr (sumCompl p) (sumCongr ep en)
Permutation by combining permutations on subtype and its complement
Informal description
Given a type $\varepsilon$ with a decidable predicate $p : \varepsilon \to \text{Prop}$, a permutation $e_p$ of the subtype $\{x \mid p\ x\}$, and a permutation $e_n$ of the subtype $\{x \mid \neg p\ x\}$, the function `Equiv.Perm.subtypeCongr` constructs a permutation of $\varepsilon$ by combining $e_p$ and $e_n$ via the canonical decomposition of $\varepsilon$ into these two subtypes. Specifically, for any $a \in \varepsilon$, the permutation acts as $e_p$ on elements satisfying $p$ and as $e_n$ on elements not satisfying $p$.
Equiv.Perm.subtypeCongr.apply theorem
(a : ε) : ep.subtypeCongr en a = if h : p a then (ep ⟨a, h⟩ : ε) else en ⟨a, h⟩
Full source
theorem Perm.subtypeCongr.apply (a : ε) : ep.subtypeCongr en a =
    if h : p a then (ep ⟨a, h⟩ : ε) else en ⟨a, h⟩ := by
  by_cases h : p a <;> simp [Perm.subtypeCongr, h]
Application of Permutation Constructed from Subtype and Complement Permutations
Informal description
For any element $a$ of type $\varepsilon$, the permutation $\text{subtypeCongr}(e_p, e_n)$ applied to $a$ equals $e_p(\langle a, h \rangle)$ if $p(a)$ holds (with witness $h$), and equals $e_n(\langle a, h \rangle)$ otherwise.
Equiv.Perm.subtypeCongr.left_apply theorem
{a : ε} (h : p a) : ep.subtypeCongr en a = ep ⟨a, h⟩
Full source
@[simp]
theorem Perm.subtypeCongr.left_apply {a : ε} (h : p a) : ep.subtypeCongr en a = ep ⟨a, h⟩ := by
  simp [Perm.subtypeCongr.apply, h]
Action of Subtype Permutation on Elements Satisfying Predicate
Informal description
For any element $a$ of type $\varepsilon$ and a proof $h$ that $p(a)$ holds, the permutation $\text{subtypeCongr}(e_p, e_n)$ applied to $a$ equals $e_p$ applied to the subtype element $\langle a, h \rangle$.
Equiv.Perm.subtypeCongr.left_apply_subtype theorem
(a : { a // p a }) : ep.subtypeCongr en a = ep a
Full source
@[simp]
theorem Perm.subtypeCongr.left_apply_subtype (a : { a // p a }) : ep.subtypeCongr en a = ep a :=
    Perm.subtypeCongr.left_apply ep en a.property
Action of Subtype Permutation on Subtype Elements
Informal description
For any element $a$ in the subtype $\{x \mid p(x)\}$ of $\varepsilon$, the permutation $\text{subtypeCongr}(e_p, e_n)$ applied to $a$ equals $e_p$ applied to $a$.
Equiv.Perm.subtypeCongr.right_apply theorem
{a : ε} (h : ¬p a) : ep.subtypeCongr en a = en ⟨a, h⟩
Full source
@[simp]
theorem Perm.subtypeCongr.right_apply {a : ε} (h : ¬p a) : ep.subtypeCongr en a = en ⟨a, h⟩ := by
  simp [Perm.subtypeCongr.apply, h]
Application of Permutation on Complement Subtype
Informal description
For any element $a$ of type $\varepsilon$ such that $\neg p(a)$ holds, the permutation $\text{subtypeCongr}(e_p, e_n)$ applied to $a$ equals $e_n$ applied to the subtype $\langle a, h \rangle$, where $h$ is the proof that $\neg p(a)$ holds.
Equiv.Perm.subtypeCongr.right_apply_subtype theorem
(a : { a // ¬p a }) : ep.subtypeCongr en a = en a
Full source
@[simp]
theorem Perm.subtypeCongr.right_apply_subtype (a : { a // ¬p a }) : ep.subtypeCongr en a = en a :=
  Perm.subtypeCongr.right_apply ep en a.property
Permutation Action on Complement Subtype via `subtypeCongr`
Informal description
For any element $a$ in the subtype $\{a \mid \neg p(a)\}$, the permutation $\text{subtypeCongr}(e_p, e_n)$ applied to $a$ equals $e_n$ applied to $a$.
Equiv.Perm.subtypeCongr.refl theorem
: Perm.subtypeCongr (Equiv.refl { a // p a }) (Equiv.refl { a // ¬p a }) = Equiv.refl ε
Full source
@[simp]
theorem Perm.subtypeCongr.refl :
    Perm.subtypeCongr (Equiv.refl { a // p a }) (Equiv.refl { a // ¬p a }) = Equiv.refl ε := by
  ext x
  by_cases h : p x <;> simp [h]
Identity Permutation Decomposition via Subtypes
Informal description
For any type $\varepsilon$ with a decidable predicate $p : \varepsilon \to \text{Prop}$, the permutation obtained by combining the identity permutations on the subtypes $\{a \mid p\ a\}$ and $\{a \mid \neg p\ a\}$ is equal to the identity permutation on $\varepsilon$.
Equiv.Perm.subtypeCongr.symm theorem
: (ep.subtypeCongr en).symm = Perm.subtypeCongr ep.symm en.symm
Full source
@[simp]
theorem Perm.subtypeCongr.symm : (ep.subtypeCongr en).symm = Perm.subtypeCongr ep.symm en.symm := by
  ext x
  by_cases h : p x
  · have : p (ep.symm ⟨x, h⟩) := Subtype.property _
    simp [Perm.subtypeCongr.apply, h, symm_apply_eq, this]
  · have : ¬p (en.symm ⟨x, h⟩) := Subtype.property (en.symm _)
    simp [Perm.subtypeCongr.apply, h, symm_apply_eq, this]
Inverse of Combined Permutation Equals Combination of Inverses
Informal description
The inverse of the permutation constructed by combining permutations $e_p$ on the subtype $\{a \mid p\ a\}$ and $e_n$ on the subtype $\{a \mid \neg p\ a\}$ is equal to the permutation obtained by combining the inverses $e_p^{-1}$ and $e_n^{-1}$ of the respective permutations.
Equiv.Perm.subtypeCongr.trans theorem
: (ep.subtypeCongr en).trans (ep'.subtypeCongr en') = Perm.subtypeCongr (ep.trans ep') (en.trans en')
Full source
@[simp]
theorem Perm.subtypeCongr.trans :
    (ep.subtypeCongr en).trans (ep'.subtypeCongr en')
    = Perm.subtypeCongr (ep.trans ep') (en.trans en') := by
  ext x
  by_cases h : p x
  · have : p (ep ⟨x, h⟩) := Subtype.property _
    simp [Perm.subtypeCongr.apply, h, this]
  · have : ¬p (en ⟨x, h⟩) := Subtype.property (en _)
    simp [Perm.subtypeCongr.apply, h, symm_apply_eq, this]
Composition of Combined Permutations Equals Combination of Compositions
Informal description
Given permutations $e_p, e_p'$ of the subtype $\{a \mid p\ a\}$ and $e_n, e_n'$ of the subtype $\{a \mid \neg p\ a\}$, the composition of the combined permutations $\text{subtypeCongr}(e_p, e_n)$ and $\text{subtypeCongr}(e_p', e_n')$ is equal to the permutation obtained by combining the compositions $e_p \circ e_p'$ and $e_n \circ e_n'$ on their respective subtypes.
Equiv.subtypePreimage definition
: { x : α → β // x ∘ Subtype.val = x₀ } ≃ ({ a // ¬p a } → β)
Full source
/-- For a fixed function `x₀ : {a // p a} → β` defined on a subtype of `α`,
the subtype of functions `x : α → β` that agree with `x₀` on the subtype `{a // p a}`
is naturally equivalent to the type of functions `{a // ¬ p a} → β`. -/
@[simps]
def subtypePreimage : { x : α → β // x ∘ Subtype.val = x₀ }{ x : α → β // x ∘ Subtype.val = x₀ } ≃ ({ a // ¬p a } → β) where
  toFun (x : { x : α → β // x ∘ Subtype.val = x₀ }) a := (x : α → β) a
  invFun x := ⟨fun a => if h : p a then x₀ ⟨a, h⟩ else x ⟨a, h⟩, funext fun ⟨_, h⟩ => dif_pos h⟩
  left_inv := fun ⟨x, hx⟩ =>
    Subtype.val_injective <|
      funext fun a => by
        dsimp only
        split_ifs
        · rw [← hx]; rfl
        · rfl
  right_inv x :=
    funext fun ⟨a, h⟩ =>
      show dite (p a) _ _ = _ by
        dsimp only
        rw [dif_neg h]
Equivalence between restricted function space and complement function space
Informal description
Given a predicate $p$ on a type $\alpha$ and a fixed function $x_0 : \{a \in \alpha \mid p a\} \to \beta$ defined on the subtype of elements satisfying $p$, the equivalence maps between: 1. The subtype of functions $x : \alpha \to \beta$ that agree with $x_0$ on $\{a \in \alpha \mid p a\}$ (i.e., $x \circ \text{Subtype.val} = x_0$) 2. The type of functions $\{a \in \alpha \mid \neg p a\} \to \beta$ defined on the complement subtype. The forward direction simply restricts the function $x$ to the entire $\alpha$, while the inverse direction constructs a function on $\alpha$ that uses $x_0$ where $p$ holds and the given function where $p$ fails.
Equiv.subtypePreimage_symm_apply_coe_pos theorem
(x : { a // ¬p a } → β) (a : α) (h : p a) : ((subtypePreimage p x₀).symm x : α → β) a = x₀ ⟨a, h⟩
Full source
theorem subtypePreimage_symm_apply_coe_pos (x : { a // ¬p a } → β) (a : α) (h : p a) :
    ((subtypePreimage p x₀).symm x : α → β) a = x₀ ⟨a, h⟩ :=
  dif_pos h
Inverse Equivalence Evaluation on Positive Subtype
Informal description
Let $p$ be a predicate on a type $\alpha$, and let $x_0 : \{a \in \alpha \mid p a\} \to \beta$ be a fixed function defined on the subtype where $p$ holds. For any function $x : \{a \in \alpha \mid \neg p a\} \to \beta$ defined on the complement subtype, and for any element $a \in \alpha$ such that $p a$ holds, the application of the inverse equivalence $(subtypePreimage\, p\, x_0)^{-1}\, x$ to $a$ equals $x_0$ evaluated at the subtype $\langle a, h\rangle$.
Equiv.subtypePreimage_symm_apply_coe_neg theorem
(x : { a // ¬p a } → β) (a : α) (h : ¬p a) : ((subtypePreimage p x₀).symm x : α → β) a = x ⟨a, h⟩
Full source
theorem subtypePreimage_symm_apply_coe_neg (x : { a // ¬p a } → β) (a : α) (h : ¬p a) :
    ((subtypePreimage p x₀).symm x : α → β) a = x ⟨a, h⟩ :=
  dif_neg h
Inverse Equivalence Evaluation on Complement Subtype
Informal description
Let $p$ be a predicate on a type $\alpha$, and let $x_0 : \{a \in \alpha \mid p a\} \to \beta$ be a fixed function defined on the subtype where $p$ holds. For any function $x : \{a \in \alpha \mid \neg p a\} \to \beta$ defined on the complement subtype, and for any element $a \in \alpha$ such that $\neg p a$ holds, the application of the inverse equivalence $(subtypePreimage\, p\, x_0)^{-1}\, x$ to $a$ equals $x$ evaluated at the subtype $\langle a, h\rangle$.
Equiv.piCongrRight definition
{β₁ β₂ : α → Sort*} (F : ∀ a, β₁ a ≃ β₂ a) : (∀ a, β₁ a) ≃ (∀ a, β₂ a)
Full source
/-- A family of equivalences `∀ a, β₁ a ≃ β₂ a` generates an equivalence between `∀ a, β₁ a` and
`∀ a, β₂ a`. -/
@[simps]
def piCongrRight {β₁ β₂ : α → Sort*} (F : ∀ a, β₁ a ≃ β₂ a) : (∀ a, β₁ a) ≃ (∀ a, β₂ a) :=
  ⟨Pi.map fun a ↦ F a, Pi.map fun a ↦ (F a).symm, fun H => funext <| by simp,
    fun H => funext <| by simp⟩
Equivalence of dependent function types via component-wise equivalences
Informal description
Given a family of equivalences \( F : \forall a, \beta_1 a \simeq \beta_2 a \) indexed by \( a \in \alpha \), there is an equivalence between the dependent function types \( \forall a, \beta_1 a \) and \( \forall a, \beta_2 a \). This equivalence is constructed by applying \( F a \) component-wise to each function value, with the inverse constructed similarly using the inverses of each \( F a \).
Equiv.piComm definition
(φ : α → β → Sort*) : (∀ a b, φ a b) ≃ ∀ b a, φ a b
Full source
/-- Given `φ : α → β → Sort*`, we have an equivalence between `∀ a b, φ a b` and `∀ b a, φ a b`.
This is `Function.swap` as an `Equiv`. -/
@[simps apply]
def piComm (φ : α → β → Sort*) : (∀ a b, φ a b) ≃ ∀ b a, φ a b :=
  ⟨swap, swap, fun _ => rfl, fun _ => rfl⟩
Equivalence between universally quantified argument orders
Informal description
For any family of types $\phi : \alpha \to \beta \to \text{Sort}*$, there is an equivalence between the types $\forall a\, b, \phi\, a\, b$ and $\forall b\, a, \phi\, a\, b$. This equivalence swaps the order of the arguments in the function, and is its own inverse.
Equiv.piComm_symm theorem
{φ : α → β → Sort*} : (piComm φ).symm = (piComm <| swap φ)
Full source
@[simp]
theorem piComm_symm {φ : α → β → Sort*} : (piComm φ).symm = (piComm <| swap φ) :=
  rfl
Inverse of Argument-Swapping Equivalence Equals Swapped Equivalence
Informal description
For any family of types $\phi : \alpha \to \beta \to \text{Sort}*$, the inverse of the equivalence $\forall a\, b, \phi\, a\, b \simeq \forall b\, a, \phi\, a\, b$ is equal to the equivalence obtained by first swapping the arguments of $\phi$ and then applying the original equivalence. In other words, $(e_{\phi})^{-1} = e_{\operatorname{swap}\phi}$, where $e_{\phi}$ is the equivalence that swaps the argument order in $\phi$.
Equiv.piCurry definition
{α} {β : α → Type*} (γ : ∀ a, β a → Type*) : (∀ x : Σ i, β i, γ x.1 x.2) ≃ ∀ a b, γ a b
Full source
/-- Dependent `curry` equivalence: the type of dependent functions on `Σ i, β i` is equivalent
to the type of dependent functions of two arguments (i.e., functions to the space of functions).

This is `Sigma.curry` and `Sigma.uncurry` together as an equiv. -/
def piCurry {α} {β : α → Type*} (γ : ∀ a, β a → Type*) :
    (∀ x : Σ i, β i, γ x.1 x.2) ≃ ∀ a b, γ a b where
  toFun := Sigma.curry
  invFun := Sigma.uncurry
  left_inv := Sigma.uncurry_curry
  right_inv := Sigma.curry_uncurry
Currying Equivalence for Dependent Functions on Sigma Types
Informal description
For a family of types $\gamma$ depending on $\alpha$ and $\beta$, there is an equivalence between the type of dependent functions on the sigma type $\Sigma i, \beta i$ (i.e., functions taking pairs $\langle x, y\rangle$ where $x : \alpha$ and $y : \beta x$) and the type of dependent functions of two arguments (i.e., functions taking $x : \alpha$ and $y : \beta x$ separately). This equivalence is given by the operations `Sigma.curry` and `Sigma.uncurry`, which satisfy the identities: - $\mathrm{curry}(\mathrm{uncurry}(f)) = f$ for any $f : \forall a\, b, \gamma\, a\, b$ - $\mathrm{uncurry}(\mathrm{curry}(g)) = g$ for any $g : \forall (x : \Sigma i, \beta i), \gamma\, x.1\, x.2$
Equiv.piCurry_apply theorem
{α} {β : α → Type*} (γ : ∀ a, β a → Type*) (f : ∀ x : Σ i, β i, γ x.1 x.2) : piCurry γ f = Sigma.curry f
Full source
@[simp] theorem piCurry_apply {α} {β : α → Type*} (γ : ∀ a, β a → Type*)
    (f : ∀ x : Σ i, β i, γ x.1 x.2) :
    piCurry γ f = Sigma.curry f :=
  rfl
Currying Equivalence Maps to Sigma Currying
Informal description
For a family of types $\gamma$ depending on $\alpha$ and $\beta$, the equivalence `piCurry γ` maps a function $f$ defined on the sigma type $\Sigma i, \beta i$ (taking pairs $\langle x, y\rangle$ where $x \in \alpha$ and $y \in \beta x$) to its curried version, which is a function taking $x \in \alpha$ and $y \in \beta x$ separately. Specifically, $\mathrm{piCurry}\, \gamma\, f = \mathrm{Sigma.curry}\, f$.
Equiv.piCurry_symm_apply theorem
{α} {β : α → Type*} (γ : ∀ a, β a → Type*) (f : ∀ a b, γ a b) : (piCurry γ).symm f = Sigma.uncurry f
Full source
@[simp] theorem piCurry_symm_apply {α} {β : α → Type*} (γ : ∀ a, β a → Type*) (f : ∀ a b, γ a b) :
    (piCurry γ).symm f = Sigma.uncurry f :=
  rfl
Inverse Currying Equivalence Maps to Sigma Uncurrying
Informal description
For a family of types $\gamma$ depending on $\alpha$ and $\beta$, the inverse of the currying equivalence $\mathrm{piCurry}\, \gamma$ maps a dependent function $f : \forall a\, b, \gamma\, a\, b$ to its uncurried version, which is a function on the sigma type $\Sigma i, \beta i$. Specifically, $(\mathrm{piCurry}\, \gamma)^{-1} f = \mathrm{Sigma.uncurry}\, f$.
Equiv.ofFiberEquiv definition
{α β γ} {f : α → γ} {g : β → γ} (e : ∀ c, { a // f a = c } ≃ { b // g b = c }) : α ≃ β
Full source
/-- A family of equivalences between fibers gives an equivalence between domains. -/
@[simps!]
def ofFiberEquiv {α β γ} {f : α → γ} {g : β → γ}
    (e : ∀ c, { a // f a = c }{ a // f a = c } ≃ { b // g b = c }) : α ≃ β :=
  (sigmaFiberEquiv f).symm.trans <| (Equiv.sigmaCongrRight e).trans (sigmaFiberEquiv g)
Equivalence from fiber-wise equivalences
Informal description
Given functions $f : \alpha \to \gamma$ and $g : \beta \to \gamma$, and a family of equivalences $e_c : \{a \mid f(a) = c\} \simeq \{b \mid g(b) = c\}$ for each $c \in \gamma$, the function `Equiv.ofFiberEquiv` constructs an equivalence $\alpha \simeq \beta$. This is done by composing the following equivalences: 1. The inverse of the equivalence that maps $\alpha$ to $\Sigma c, \{a \mid f(a) = c\}$, 2. The equivalence $\Sigma c, \{a \mid f(a) = c\} \simeq \Sigma c, \{b \mid g(b) = c\}$ obtained from $e_c$, 3. The equivalence that maps $\Sigma c, \{b \mid g(b) = c\}$ to $\beta$.
Equiv.ofFiberEquiv_map theorem
{α β γ} {f : α → γ} {g : β → γ} (e : ∀ c, { a // f a = c } ≃ { b // g b = c }) (a : α) : g (ofFiberEquiv e a) = f a
Full source
theorem ofFiberEquiv_map {α β γ} {f : α → γ} {g : β → γ}
    (e : ∀ c, { a // f a = c }{ a // f a = c } ≃ { b // g b = c }) (a : α) : g (ofFiberEquiv e a) = f a :=
  (_ : { b // g b = _ }).property
Compatibility of Fiber Equivalence with Original Functions: $g \circ e = f$
Informal description
Given functions $f \colon \alpha \to \gamma$ and $g \colon \beta \to \gamma$, and a family of equivalences $e_c \colon \{a \mid f(a) = c\} \simeq \{b \mid g(b) = c\}$ for each $c \in \gamma$, the constructed equivalence $\text{ofFiberEquiv}\, e \colon \alpha \simeq \beta$ satisfies $g((\text{ofFiberEquiv}\, e)(a)) = f(a)$ for any $a \in \alpha$.
Equiv.sigmaNatSucc definition
(f : ℕ → Type u) : (Σ n, f n) ≃ f 0 ⊕ Σ n, f (n + 1)
Full source
/-- An equivalence that separates out the 0th fiber of `(Σ (n : ℕ), f n)`. -/
def sigmaNatSucc (f :  → Type u) : (Σ n, f n) ≃ f 0 ⊕ Σ n, f (n + 1) :=
  ⟨fun x =>
    @Sigma.casesOn ℕ f (fun _ => f 0 ⊕ Σ n, f (n + 1)) x fun n =>
      @Nat.casesOn (fun i => f i → f 0 ⊕ Σ n : ℕ, f (n + 1)) n (fun x : f 0 => Sum.inl x)
        fun (n : ℕ) (x : f n.succ) => Sum.inr ⟨n, x⟩,
    Sum.elim (Sigma.mk 0) (Sigma.map Nat.succ fun _ => id), by rintro ⟨n | n, x⟩ <;> rfl, by
    rintro (x | ⟨n, x⟩) <;> rfl⟩
Equivalence between dependent sum and disjoint union with shifted index
Informal description
For any family of types $f : \mathbb{N} \to \text{Type}$, the dependent sum $\Sigma_{n \in \mathbb{N}} f(n)$ is equivalent to the disjoint union of $f(0)$ and $\Sigma_{n \in \mathbb{N}} f(n+1)$. The equivalence maps $\langle 0, x \rangle$ to $\text{inl}(x)$ and $\langle n+1, x \rangle$ to $\text{inr}(\langle n, x \rangle)$, with the inverse mapping $\text{inl}(x)$ to $\langle 0, x \rangle$ and $\text{inr}(\langle n, x \rangle)$ to $\langle n+1, x \rangle$.
Equiv.natEquivNatSumPUnit definition
: ℕ ≃ ℕ ⊕ PUnit
Full source
/-- The set of natural numbers is equivalent to `ℕ ⊕ PUnit`. -/
def natEquivNatSumPUnit : ℕ ≃ ℕ ⊕ PUnit where
  toFun n := Nat.casesOn n (inr PUnit.unit) inl
  invFun := Sum.elim Nat.succ fun _ => 0
  left_inv n := by cases n <;> rfl
  right_inv := by rintro (_ | _) <;> rfl
Equivalence between natural numbers and their disjoint union with a singleton
Informal description
The set of natural numbers $\mathbb{N}$ is equivalent to the disjoint union $\mathbb{N} \sqcup \{\ast\}$, where $\{\ast\}$ is a singleton set. The equivalence is given by mapping $0$ to the singleton element and all other natural numbers $n+1$ to $n \in \mathbb{N}$ on the left summand. The inverse maps elements from the left summand $\mathbb{N}$ to their successors in $\mathbb{N}$, and the singleton element to $0$.
Equiv.natSumPUnitEquivNat definition
: ℕ ⊕ PUnit ≃ ℕ
Full source
/-- `ℕ ⊕ PUnit` is equivalent to `ℕ`. -/
def natSumPUnitEquivNat : ℕ ⊕ PUnitℕ ⊕ PUnit ≃ ℕ :=
  natEquivNatSumPUnit.symm
Equivalence between $\mathbb{N} \sqcup \{\ast\}$ and $\mathbb{N}$
Informal description
The disjoint union of the natural numbers $\mathbb{N}$ and a singleton set $\{\ast\}$ is equivalent to $\mathbb{N}$. The equivalence is given by mapping elements from $\mathbb{N}$ to their successors in $\mathbb{N}$, and the singleton element to $0$. This is the inverse of the equivalence $\mathbb{N} \simeq \mathbb{N} \sqcup \{\ast\}$.
Equiv.intEquivNatSumNat definition
: ℤ ≃ ℕ ⊕ ℕ
Full source
/-- The type of integer numbers is equivalent to `ℕ ⊕ ℕ`. -/
def intEquivNatSumNat : ℤ ≃ ℕ ⊕ ℕ where
  toFun z := Int.casesOn z inl inr
  invFun := Sum.elim Int.ofNat Int.negSucc
  left_inv := by rintro (m | n) <;> rfl
  right_inv := by rintro (m | n) <;> rfl
Equivalence between integers and natural number pairs
Informal description
The type of integers $\mathbb{Z}$ is equivalent to the direct sum $\mathbb{N} \oplus \mathbb{N}$. The equivalence is given by mapping non-negative integers to the left summand via the natural inclusion $\mathbb{N} \to \mathbb{N} \oplus \mathbb{N}$, and negative integers to the right summand via the mapping $n \mapsto -n - 1$.
Equiv.uniqueCongr definition
(e : α ≃ β) : Unique α ≃ Unique β
Full source
/-- If `α` is equivalent to `β`, then `Unique α` is equivalent to `Unique β`. -/
def uniqueCongr (e : α ≃ β) : UniqueUnique α ≃ Unique β where
  toFun h := @Equiv.unique _ _ h e.symm
  invFun h := @Equiv.unique _ _ h e
  left_inv _ := Subsingleton.elim _ _
  right_inv _ := Subsingleton.elim _ _
Equivalence between unique structures
Informal description
Given an equivalence $e : \alpha \simeq \beta$ between types $\alpha$ and $\beta$, there is an equivalence between the types `Unique α` and `Unique β`. This equivalence maps any unique structure on $\alpha$ to a unique structure on $\beta$ via $e$, and vice versa via $e^{-1}$.
Equiv.isEmpty_congr theorem
(e : α ≃ β) : IsEmpty α ↔ IsEmpty β
Full source
/-- If `α` is equivalent to `β`, then `IsEmpty α` is equivalent to `IsEmpty β`. -/
theorem isEmpty_congr (e : α ≃ β) : IsEmptyIsEmpty α ↔ IsEmpty β :=
  ⟨fun h => @Function.isEmpty _ _ h e.symm, fun h => @Function.isEmpty _ _ h e⟩
Equivalence Preserves Emptiness
Informal description
Given an equivalence $e : \alpha \simeq \beta$ between types $\alpha$ and $\beta$, the type $\alpha$ is empty if and only if $\beta$ is empty.
Equiv.isEmpty theorem
(e : α ≃ β) [IsEmpty β] : IsEmpty α
Full source
protected theorem isEmpty (e : α ≃ β) [IsEmpty β] : IsEmpty α :=
  e.isEmpty_congr.mpr ‹_›
Emptiness Preservation via Equivalence
Informal description
Given an equivalence $e : \alpha \simeq \beta$ between types $\alpha$ and $\beta$, if $\beta$ is empty, then $\alpha$ is also empty.
Equiv.subtypeEquiv definition
{p : α → Prop} {q : β → Prop} (e : α ≃ β) (h : ∀ a, p a ↔ q (e a)) : { a : α // p a } ≃ { b : β // q b }
Full source
/-- If `α` is equivalent to `β` and the predicates `p : α → Prop` and `q : β → Prop` are equivalent
at corresponding points, then `{a // p a}` is equivalent to `{b // q b}`.
For the statement where `α = β`, that is, `e : perm α`, see `Perm.subtypePerm`. -/
@[simps apply]
def subtypeEquiv {p : α → Prop} {q : β → Prop} (e : α ≃ β) (h : ∀ a, p a ↔ q (e a)) :
    { a : α // p a }{ a : α // p a } ≃ { b : β // q b } where
  toFun a := ⟨e a, (h _).mp a.property⟩
  invFun b := ⟨e.symm b, (h _).mpr ((e.apply_symm_apply b).symm ▸ b.property)⟩
  left_inv a := Subtype.ext <| by simp
  right_inv b := Subtype.ext <| by simp
Equivalence of Subtypes via Predicate Equivalence
Informal description
Given an equivalence $e : \alpha \simeq \beta$ between types $\alpha$ and $\beta$, and predicates $p : \alpha \to \text{Prop}$ and $q : \beta \to \text{Prop}$ such that for every $a \in \alpha$, $p(a)$ holds if and only if $q(e(a))$ holds, then the subtype $\{a \in \alpha \mid p(a)\}$ is equivalent to the subtype $\{b \in \beta \mid q(b)\}$. The equivalence maps an element $\langle a, h_a \rangle$ of the first subtype to $\langle e(a), (h(a)).\text{mp}(h_a) \rangle$ in the second subtype, and its inverse maps $\langle b, h_b \rangle$ back to $\langle e^{-1}(b), (h(e^{-1}(b))).\text{mpr}(h_b) \rangle$.
Equiv.coe_subtypeEquiv_eq_map theorem
{X Y} {p : X → Prop} {q : Y → Prop} (e : X ≃ Y) (h : ∀ x, p x ↔ q (e x)) : ⇑(e.subtypeEquiv h) = Subtype.map e (h · |>.mp)
Full source
lemma coe_subtypeEquiv_eq_map {X Y} {p : X → Prop} {q : Y → Prop} (e : X ≃ Y)
    (h : ∀ x, p x ↔ q (e x)) : ⇑(e.subtypeEquiv h) = Subtype.map e (h · |>.mp) :=
  rfl
Underlying Function of Subtype Equivalence Equals Mapped Function
Informal description
Given types $X$ and $Y$, predicates $p : X \to \text{Prop}$ and $q : Y \to \text{Prop}$, an equivalence $e : X \simeq Y$, and a proof $h$ that for every $x \in X$, $p(x)$ holds if and only if $q(e(x))$ holds, then the underlying function of the equivalence $e.\text{subtypeEquiv}\, h$ is equal to the function $\text{Subtype.map}\, e$ applied to the forward implication of $h$.
Equiv.subtypeEquiv_symm theorem
{p : α → Prop} {q : β → Prop} (e : α ≃ β) (h : ∀ a : α, p a ↔ q (e a)) : (e.subtypeEquiv h).symm = e.symm.subtypeEquiv (by as_aux_lemma => intro a convert (h <| e.symm a).symm exact (e.apply_symm_apply a).symm)
Full source
@[simp]
theorem subtypeEquiv_symm {p : α → Prop} {q : β → Prop} (e : α ≃ β) (h : ∀ a : α, p a ↔ q (e a)) :
    (e.subtypeEquiv h).symm =
      e.symm.subtypeEquiv (by as_aux_lemma =>
        intro a
        convert (h <| e.symm a).symm
        exact (e.apply_symm_apply a).symm) :=
  rfl
Inverse of Subtype Equivalence via Predicate Condition
Informal description
Given an equivalence $e : \alpha \simeq \beta$ between types $\alpha$ and $\beta$, and predicates $p : \alpha \to \text{Prop}$ and $q : \beta \to \text{Prop}$ such that for every $a \in \alpha$, $p(a)$ holds if and only if $q(e(a))$ holds, then the inverse of the equivalence between subtypes $\{a \in \alpha \mid p(a)\}$ and $\{b \in \beta \mid q(b)\}$ is equal to the equivalence between $\{b \in \beta \mid q(b)\}$ and $\{a \in \alpha \mid p(a)\}$ induced by the inverse equivalence $e^{-1} : \beta \simeq \alpha$ with the corresponding condition on predicates.
Equiv.subtypeEquiv_trans theorem
{p : α → Prop} {q : β → Prop} {r : γ → Prop} (e : α ≃ β) (f : β ≃ γ) (h : ∀ a : α, p a ↔ q (e a)) (h' : ∀ b : β, q b ↔ r (f b)) : (e.subtypeEquiv h).trans (f.subtypeEquiv h') = (e.trans f).subtypeEquiv (by as_aux_lemma => exact fun a => (h a).trans (h' <| e a))
Full source
@[simp]
theorem subtypeEquiv_trans {p : α → Prop} {q : β → Prop} {r : γ → Prop} (e : α ≃ β) (f : β ≃ γ)
    (h : ∀ a : α, p a ↔ q (e a)) (h' : ∀ b : β, q b ↔ r (f b)) :
    (e.subtypeEquiv h).trans (f.subtypeEquiv h')
    = (e.trans f).subtypeEquiv (by as_aux_lemma => exact fun a => (h a).trans (h' <| e a)) :=
  rfl
Composition of Subtype Equivalences via Predicate Conditions
Informal description
Given types $\alpha$, $\beta$, and $\gamma$ with predicates $p : \alpha \to \text{Prop}$, $q : \beta \to \text{Prop}$, and $r : \gamma \to \text{Prop}$, and equivalences $e : \alpha \simeq \beta$ and $f : \beta \simeq \gamma$ such that: 1. For every $a \in \alpha$, $p(a) \leftrightarrow q(e(a))$, and 2. For every $b \in \beta$, $q(b) \leftrightarrow r(f(b))$, then the composition of the subtype equivalences $(e.\text{subtypeEquiv}\, h) \circ (f.\text{subtypeEquiv}\, h')$ is equal to the subtype equivalence induced by the composition $e \circ f$ with the combined predicate condition $\forall a \in \alpha, p(a) \leftrightarrow r((e \circ f)(a))$.
Equiv.subtypeEquivRight definition
{p q : α → Prop} (e : ∀ x, p x ↔ q x) : { x // p x } ≃ { x // q x }
Full source
/-- If two predicates `p` and `q` are pointwise equivalent, then `{x // p x}` is equivalent to
`{x // q x}`. -/
@[simps!]
def subtypeEquivRight {p q : α → Prop} (e : ∀ x, p x ↔ q x) : { x // p x }{ x // p x } ≃ { x // q x } :=
  subtypeEquiv (Equiv.refl _) e
Equivalence of Subtypes via Pointwise Equivalent Predicates
Informal description
Given two predicates $p$ and $q$ on a type $\alpha$ such that for every $x \in \alpha$, $p(x)$ holds if and only if $q(x)$ holds, then the subtype $\{x \in \alpha \mid p(x)\}$ is equivalent to the subtype $\{x \in \alpha \mid q(x)\}$. The equivalence maps an element $\langle x, h_x \rangle$ of the first subtype to $\langle x, (e(x)).\text{mp}(h_x) \rangle$ in the second subtype, and its inverse maps $\langle x, h_x \rangle$ back to $\langle x, (e(x)).\text{mpr}(h_x) \rangle$.
Equiv.subtypeEquivRight_apply theorem
{p q : α → Prop} (e : ∀ x, p x ↔ q x) (z : { x // p x }) : subtypeEquivRight e z = ⟨z, (e z.1).mp z.2⟩
Full source
lemma subtypeEquivRight_apply {p q : α → Prop} (e : ∀ x, p x ↔ q x)
    (z : { x // p x }) : subtypeEquivRight e z = ⟨z, (e z.1).mp z.2⟩ := rfl
Application of Subtype Equivalence via Predicate Equivalence
Informal description
Given two predicates $p, q : \alpha \to \text{Prop}$ and a proof $e$ that $\forall x, p(x) \leftrightarrow q(x)$, the application of the equivalence $\text{subtypeEquivRight}\, e$ to an element $z$ of the subtype $\{x \in \alpha \mid p(x)\}$ yields $\langle z, (e(z.1)).\text{mp}(z.2) \rangle$, where $z.1$ is the underlying element of $\alpha$ and $z.2$ is the proof that $p(z.1)$ holds.
Equiv.subtypeEquivRight_symm_apply theorem
{p q : α → Prop} (e : ∀ x, p x ↔ q x) (z : { x // q x }) : (subtypeEquivRight e).symm z = ⟨z, (e z.1).mpr z.2⟩
Full source
lemma subtypeEquivRight_symm_apply {p q : α → Prop} (e : ∀ x, p x ↔ q x)
    (z : { x // q x }) : (subtypeEquivRight e).symm z = ⟨z, (e z.1).mpr z.2⟩ := rfl
Inverse Application of Subtype Equivalence via Predicate Equivalence
Informal description
For any predicates $p$ and $q$ on a type $\alpha$ such that $p(x) \leftrightarrow q(x)$ holds for all $x \in \alpha$, and for any element $z$ of the subtype $\{x \in \alpha \mid q(x)\}$, the application of the inverse of the equivalence $\text{subtypeEquivRight}\,e$ to $z$ yields the pair $\langle z, (e(z.1)).\text{mpr}(z.2) \rangle$, where $z.1$ is the underlying element of $\alpha$ and $z.2$ is the proof that $q(z.1)$ holds.
Equiv.subtypeEquivOfSubtype definition
{p : β → Prop} (e : α ≃ β) : { a : α // p (e a) } ≃ { b : β // p b }
Full source
/-- If `α ≃ β`, then for any predicate `p : β → Prop` the subtype `{a // p (e a)}` is equivalent
to the subtype `{b // p b}`. -/
def subtypeEquivOfSubtype {p : β → Prop} (e : α ≃ β) : { a : α // p (e a) }{ a : α // p (e a) } ≃ { b : β // p b } :=
  subtypeEquiv e <| by simp
Equivalence of Subtypes via Predicate Transfer
Informal description
Given an equivalence $e : \alpha \simeq \beta$ between types $\alpha$ and $\beta$, and a predicate $p : \beta \to \text{Prop}$, the subtype $\{a \in \alpha \mid p(e(a))\}$ is equivalent to the subtype $\{b \in \beta \mid p(b)\}$. The equivalence maps an element $\langle a, h_a \rangle$ of the first subtype to $\langle e(a), h_a \rangle$ in the second subtype, and its inverse maps $\langle b, h_b \rangle$ back to $\langle e^{-1}(b), h_b \rangle$.
Equiv.subtypeEquivOfSubtype' definition
{p : α → Prop} (e : α ≃ β) : { a : α // p a } ≃ { b : β // p (e.symm b) }
Full source
/-- If `α ≃ β`, then for any predicate `p : α → Prop` the subtype `{a // p a}` is equivalent
to the subtype `{b // p (e.symm b)}`. This version is used by `equiv_rw`. -/
def subtypeEquivOfSubtype' {p : α → Prop} (e : α ≃ β) :
    { a : α // p a }{ a : α // p a } ≃ { b : β // p (e.symm b) } :=
  e.symm.subtypeEquivOfSubtype.symm
Equivalence of Subtypes via Predicate Transfer with Inverse
Informal description
Given an equivalence $e : \alpha \simeq \beta$ between types $\alpha$ and $\beta$, and a predicate $p : \alpha \to \text{Prop}$, the subtype $\{a \in \alpha \mid p(a)\}$ is equivalent to the subtype $\{b \in \beta \mid p(e^{-1}(b))\}$. The equivalence maps an element $\langle a, h_a \rangle$ of the first subtype to $\langle e(a), h_a \rangle$ in the second subtype, and its inverse maps $\langle b, h_b \rangle$ back to $\langle e^{-1}(b), h_b \rangle$.
Equiv.subtypeEquivProp definition
{p q : α → Prop} (h : p = q) : Subtype p ≃ Subtype q
Full source
/-- If two predicates are equal, then the corresponding subtypes are equivalent. -/
def subtypeEquivProp {p q : α → Prop} (h : p = q) : SubtypeSubtype p ≃ Subtype q :=
  subtypeEquiv (Equiv.refl α) fun _ => h ▸ Iff.rfl
Equivalence of subtypes with equal predicates
Informal description
Given two predicates $p$ and $q$ on a type $\alpha$ that are equal ($p = q$), the subtypes $\{a \in \alpha \mid p(a)\}$ and $\{a \in \alpha \mid q(a)\}$ are equivalent. The equivalence is given by the identity map on $\alpha$ restricted to these subtypes.
Equiv.subtypeSubtypeEquivSubtypeExists definition
(p : α → Prop) (q : Subtype p → Prop) : Subtype q ≃ { a : α // ∃ h : p a, q ⟨a, h⟩ }
Full source
/-- A subtype of a subtype is equivalent to the subtype of elements satisfying both predicates. This
version allows the “inner” predicate to depend on `h : p a`. -/
@[simps]
def subtypeSubtypeEquivSubtypeExists (p : α → Prop) (q : Subtype p → Prop) :
    SubtypeSubtype q ≃ { a : α // ∃ h : p a, q ⟨a, h⟩ } :=
  ⟨fun a =>
    ⟨a.1, a.1.2, by
      rcases a with ⟨⟨a, hap⟩, haq⟩
      exact haq⟩,
    fun a => ⟨⟨a, a.2.fst⟩, a.2.snd⟩, fun ⟨⟨_, _⟩, _⟩ => rfl, fun ⟨_, _, _⟩ => rfl⟩
Equivalence between nested subtypes and existential subtype
Informal description
Given a type $\alpha$ and predicates $p : \alpha \to \text{Prop}$ and $q : \{a \in \alpha \mid p a\} \to \text{Prop}$, the equivalence maps between: 1. The subtype of elements $\langle a, h \rangle$ where $a$ satisfies $p$ and $h$ is a proof of $p a$, and $\langle a, h \rangle$ further satisfies $q$. 2. The subtype of elements $a \in \alpha$ for which there exists a proof $h$ of $p a$ such that $\langle a, h \rangle$ satisfies $q$. In other words, it establishes a bijection between nested subtypes and a subtype with an existential condition.
Equiv.subtypeSubtypeEquivSubtypeInter definition
{α : Type u} (p q : α → Prop) : { x : Subtype p // q x.1 } ≃ Subtype fun x => p x ∧ q x
Full source
/-- A subtype of a subtype is equivalent to the subtype of elements satisfying both predicates. -/
@[simps!]
def subtypeSubtypeEquivSubtypeInter {α : Type u} (p q : α → Prop) :
    { x : Subtype p // q x.1 }{ x : Subtype p // q x.1 } ≃ Subtype fun x => p x ∧ q x :=
  (subtypeSubtypeEquivSubtypeExists p _).trans <|
    subtypeEquivRight fun x => @exists_prop (q x) (p x)
Equivalence between nested subtypes and intersection subtype
Informal description
Given a type $\alpha$ and two predicates $p, q : \alpha \to \text{Prop}$, the equivalence maps between: 1. The subtype of elements $\langle x, h_x \rangle$ where $x$ satisfies $p$ (with proof $h_x$) and $x$ also satisfies $q$. 2. The subtype of elements $x \in \alpha$ that satisfy both $p(x)$ and $q(x)$. In other words, it establishes a bijection between nested subtypes (where the outer predicate is $p$ and the inner is $q$) and the subtype of elements satisfying the conjunction $p \land q$.
Equiv.subtypeSubtypeEquivSubtype definition
{α} {p q : α → Prop} (h : ∀ {x}, q x → p x) : { x : Subtype p // q x.1 } ≃ Subtype q
Full source
/-- If the outer subtype has more restrictive predicate than the inner one,
then we can drop the latter. -/
@[simps!]
def subtypeSubtypeEquivSubtype {α} {p q : α → Prop} (h : ∀ {x}, q x → p x) :
    { x : Subtype p // q x.1 }{ x : Subtype p // q x.1 } ≃ Subtype q :=
  (subtypeSubtypeEquivSubtypeInter p _).trans <| subtypeEquivRight fun _ => and_iff_right_of_imp h
Equivalence between nested subtype and predicate subtype
Informal description
Given a type $\alpha$ and two predicates $p, q : \alpha \to \text{Prop}$ such that $q(x)$ implies $p(x)$ for all $x \in \alpha$, the nested subtype $\{x \in \{x \in \alpha \mid p(x)\} \mid q(x)\}$ is equivalent to the subtype $\{x \in \alpha \mid q(x)\}$. The equivalence is constructed by first establishing an equivalence with the intersection subtype $\{x \in \alpha \mid p(x) \land q(x)\}$ and then simplifying to $\{x \in \alpha \mid q(x)\}$ using the implication $q(x) \to p(x)$.
Equiv.subtypeUnivEquiv definition
{α} {p : α → Prop} (h : ∀ x, p x) : Subtype p ≃ α
Full source
/-- If a proposition holds for all elements, then the subtype is
equivalent to the original type. -/
@[simps apply symm_apply]
def subtypeUnivEquiv {α} {p : α → Prop} (h : ∀ x, p x) : SubtypeSubtype p ≃ α :=
  ⟨fun x => x, fun x => ⟨x, h x⟩, fun _ => Subtype.eq rfl, fun _ => rfl⟩
Subtype equivalence for universally true predicates
Informal description
Given a type $\alpha$ and a predicate $p : \alpha \to \text{Prop}$ such that $p(x)$ holds for all $x \in \alpha$, the subtype $\{x \in \alpha \mid p(x)\}$ is equivalent to $\alpha$ itself. The equivalence is given by the identity map in both directions.
Equiv.subtypeSigmaEquiv definition
{α} (p : α → Type v) (q : α → Prop) : { y : Sigma p // q y.1 } ≃ Σ x : Subtype q, p x.1
Full source
/-- A subtype of a sigma-type is a sigma-type over a subtype. -/
def subtypeSigmaEquiv {α} (p : α → Type v) (q : α → Prop) : { y : Sigma p // q y.1 }{ y : Sigma p // q y.1 } ≃ Σ x :
    Subtype q, p x.1 :=
  ⟨fun x => ⟨⟨x.1.1, x.2⟩, x.1.2⟩, fun x => ⟨⟨x.1.1, x.2⟩, x.1.2⟩, fun _ => rfl,
    fun _ => rfl⟩
Subtype-Sigma Equivalence
Informal description
Given a type $\alpha$, a family of types $p : \alpha \to \text{Type}$, and a predicate $q : \alpha \to \text{Prop}$, the subtype $\{ y \in \Sigma x : \alpha, p x \mid q y.1 \}$ is equivalent to the sigma type $\Sigma x : \{ x \in \alpha \mid q x \}, p x$. The equivalence is constructed by mapping $\langle \langle x, y \rangle, h \rangle$ to $\langle \langle x, h \rangle, y \rangle$ and vice versa.
Equiv.sigmaSubtypeEquivOfSubset definition
{α} (p : α → Type v) (q : α → Prop) (h : ∀ x, p x → q x) : (Σ x : Subtype q, p x) ≃ Σ x : α, p x
Full source
/-- A sigma type over a subtype is equivalent to the sigma set over the original type,
if the fiber is empty outside of the subset -/
def sigmaSubtypeEquivOfSubset {α} (p : α → Type v) (q : α → Prop) (h : ∀ x, p x → q x) :
    (Σ x : Subtype q, p x) ≃ Σ x : α, p x :=
  (subtypeSigmaEquiv p q).symm.trans <| subtypeUnivEquiv fun x => h x.1 x.2
Sigma type equivalence for subsets with non-empty fibers
Informal description
Given a type $\alpha$, a family of types $p : \alpha \to \text{Type}$, and a predicate $q : \alpha \to \text{Prop}$ such that for every $x \in \alpha$, if $y \in p(x)$ then $q(x)$ holds, the sigma type $\Sigma x : \{x \in \alpha \mid q(x)\}, p(x)$ is equivalent to the sigma type $\Sigma x : \alpha, p(x)$. The equivalence is constructed by composing the inverse of the subtype-sigma equivalence with the subtype equivalence for universally true predicates.
Equiv.sigmaSubtypeFiberEquiv definition
{α β : Type*} (f : α → β) (p : β → Prop) (h : ∀ x, p (f x)) : (Σ y : Subtype p, { x : α // f x = y }) ≃ α
Full source
/-- If a predicate `p : β → Prop` is true on the range of a map `f : α → β`, then
`Σ y : {y // p y}, {x // f x = y}` is equivalent to `α`. -/
def sigmaSubtypeFiberEquiv {α β : Type*} (f : α → β) (p : β → Prop) (h : ∀ x, p (f x)) :
    (Σ y : Subtype p, { x : α // f x = y }) ≃ α :=
  calc
    _ ≃ Σy : β, { x : α // f x = y } := sigmaSubtypeEquivOfSubset _ p fun _ ⟨x, h'⟩ => h' ▸ h x
    _ ≃ α := sigmaFiberEquiv f
Equivalence between Sigma Subtype Fiber and Domain
Informal description
Given types $\alpha$ and $\beta$, a function $f : \alpha \to \beta$, and a predicate $p : \beta \to \text{Prop}$ such that $p(f(x))$ holds for all $x \in \alpha$, the sigma type $\Sigma y : \{y \in \beta \mid p(y)\}, \{x \in \alpha \mid f(x) = y\}$ is equivalent to $\alpha$. This equivalence is constructed by first establishing an equivalence with $\Sigma y : \beta, \{x \in \alpha \mid f(x) = y\}$ (using the fact that $p$ holds on the range of $f$) and then using the fiber equivalence to $\alpha$.
Equiv.sigmaSubtypeFiberEquivSubtype definition
{α β : Type*} (f : α → β) {p : α → Prop} {q : β → Prop} (h : ∀ x, p x ↔ q (f x)) : (Σ y : Subtype q, { x : α // f x = y }) ≃ Subtype p
Full source
/-- If for each `x` we have `p x ↔ q (f x)`, then `Σ y : {y // q y}, f ⁻¹' {y}` is equivalent
to `{x // p x}`. -/
def sigmaSubtypeFiberEquivSubtype {α β : Type*} (f : α → β) {p : α → Prop} {q : β → Prop}
    (h : ∀ x, p x ↔ q (f x)) : (Σ y : Subtype q, { x : α // f x = y }) ≃ Subtype p :=
  calc
    (Σy : Subtype q, { x : α // f x = y }) ≃ Σy :
        Subtype q, { x : Subtype p // Subtype.mk (f x) ((h x).1 x.2) = y } := by {
          apply sigmaCongrRight
          intro y
          apply Equiv.symm
          refine (subtypeSubtypeEquivSubtypeExists _ _).trans (subtypeEquivRight ?_)
          intro x
          exact ⟨fun ⟨hp, h'⟩ => congr_arg Subtype.val h', fun h' => ⟨(h x).2 (h'.symm ▸ y.2),
            Subtype.eq h'⟩⟩ }
    _ ≃ Subtype p := sigmaFiberEquiv fun x : Subtype p => (⟨f x, (h x).1 x.property⟩ : Subtype q)
Equivalence between fibered sigma subtype and predicate subtype
Informal description
Given types $\alpha$ and $\beta$, a function $f : \alpha \to \beta$, and predicates $p : \alpha \to \text{Prop}$ and $q : \beta \to \text{Prop}$ such that for every $x \in \alpha$, $p(x)$ holds if and only if $q(f(x))$ holds, then the sigma type $\Sigma y : \{y \in \beta \mid q(y)\}, \{x \in \alpha \mid f(x) = y\}$ is equivalent to the subtype $\{x \in \alpha \mid p(x)\}$. In other words, the set of pairs $(y, x)$ where $y$ is in $\beta$ satisfying $q(y)$ and $x$ is in $\alpha$ with $f(x) = y$ is in bijection with the set of elements $x$ in $\alpha$ satisfying $p(x)$.
Equiv.sigmaOptionEquivOfSome definition
{α} (p : Option α → Type v) (h : p none → False) : (Σ x : Option α, p x) ≃ Σ x : α, p (some x)
Full source
/-- A sigma type over an `Option` is equivalent to the sigma set over the original type,
if the fiber is empty at none. -/
def sigmaOptionEquivOfSome {α} (p : Option α → Type v) (h : p noneFalse) :
    (Σ x : Option α, p x) ≃ Σ x : α, p (some x) :=
  haveI h' : ∀ x, p x → x.isSome := by
    intro x
    cases x
    · intro n
      exfalso
      exact h n
    · intro _
      exact rfl
  (sigmaSubtypeEquivOfSubset _ _ h').symm.trans (sigmaCongrLeft' (optionIsSomeEquiv α))
Equivalence between sigma types over Option and base type (non-empty fiber case)
Informal description
Given a type $\alpha$ and a family of types $p : \text{Option}\ \alpha \to \text{Type}$ such that $p(\text{none})$ is empty, the sigma type $\Sigma (x : \text{Option}\ \alpha), p(x)$ is equivalent to the sigma type $\Sigma (x : \alpha), p(\text{some}\ x)$. The equivalence is constructed by first establishing that every element in the domain must have $\text{isSome}$ property (since $p(\text{none})$ is empty), then using the equivalence between $\text{Option}\ \alpha$ and $\alpha$ via the $\text{some}$ constructor.
Equiv.piEquivSubtypeSigma definition
(ι) (π : ι → Type*) : (∀ i, π i) ≃ { f : ι → Σ i, π i // ∀ i, (f i).1 = i }
Full source
/-- The `Pi`-type `∀ i, π i` is equivalent to the type of sections `f : ι → Σ i, π i` of the
`Sigma` type such that for all `i` we have `(f i).fst = i`. -/
def piEquivSubtypeSigma (ι) (π : ι → Type*) :
    (∀ i, π i) ≃ { f : ι → Σ i, π i // ∀ i, (f i).1 = i } where
  toFun := fun f => ⟨fun i => ⟨i, f i⟩, fun _ => rfl⟩
  invFun := fun f i => by rw [← f.2 i]; exact (f.1 i).2
  left_inv := fun _ => funext fun _ => rfl
  right_inv := fun ⟨f, hf⟩ =>
    Subtype.eq <| funext fun i =>
      Sigma.eq (hf i).symm <| eq_of_heq <| rec_heq_of_heq _ <| by simp
Equivalence between dependent functions and sections of the sigma type
Informal description
For any index type $\iota$ and any family of types $\pi_i$ indexed by $\iota$, the type of dependent functions $\forall i, \pi_i$ is equivalent to the type of sections $f : \iota \to \Sigma i, \pi_i$ of the $\Sigma$-type such that for all $i$, the first component of $f(i)$ equals $i$.
Equiv.subtypePiEquivPi definition
{β : α → Sort v} {p : ∀ a, β a → Prop} : { f : ∀ a, β a // ∀ a, p a (f a) } ≃ ∀ a, { b : β a // p a b }
Full source
/-- The type of functions `f : ∀ a, β a` such that for all `a` we have `p a (f a)` is equivalent
to the type of functions `∀ a, {b : β a // p a b}`. -/
def subtypePiEquivPi {β : α → Sort v} {p : ∀ a, β a → Prop} :
    { f : ∀ a, β a // ∀ a, p a (f a) }{ f : ∀ a, β a // ∀ a, p a (f a) } ≃ ∀ a, { b : β a // p a b } where
  toFun := fun f a => ⟨f.1 a, f.2 a⟩
  invFun := fun f => ⟨fun a => (f a).1, fun a => (f a).2⟩
  left_inv := by
    rintro ⟨f, h⟩
    rfl
  right_inv := by
    rintro f
    funext a
    exact Subtype.ext_val rfl
Equivalence between restricted dependent functions and dependent functions of subtypes
Informal description
For any family of types $\beta_a$ indexed by $\alpha$ and any predicate $p$ on $\beta_a$, the type of functions $f : \forall a, \beta_a$ such that for all $a$, $p_a (f a)$ holds is equivalent to the type of functions $\forall a, \{b : \beta_a \mid p_a b\}$. The equivalence is given by: - The forward map takes a function $f$ and its proof $h$ that $p_a (f a)$ holds for all $a$, and returns the function $\lambda a, \langle f a, h a \rangle$. - The inverse map takes a function $f$ where each $f a$ is a subtype $\langle b, h \rangle$, and returns the function $\lambda a, b$ along with the proof $\lambda a, h$.
Equiv.subtypeEquivCodomain definition
(f : { x' // x' ≠ x } → Y) : { g : X → Y // g ∘ (↑) = f } ≃ Y
Full source
/-- The type of all functions `X → Y` with prescribed values for all `x' ≠ x`
is equivalent to the codomain `Y`. -/
def subtypeEquivCodomain (f : { x' // x' ≠ x } → Y) :
    { g : X → Y // g ∘ (↑) = f }{ g : X → Y // g ∘ (↑) = f } ≃ Y :=
  (subtypePreimage _ f).trans <|
    @funUnique { x' // ¬x' ≠ x } _ <|
      show Unique { x' // ¬x' ≠ x } from
        @Equiv.unique _ _
          (show Unique { x' // x' = x } from {
            default := ⟨x, rfl⟩, uniq := fun ⟨_, h⟩ => Subtype.val_injective h })
          (subtypeEquivRight fun _ => not_not)
Equivalence between restricted function extensions and codomain
Informal description
Given a type $X$ with a distinguished element $x \in X$ and a type $Y$, the type of functions $g : X \to Y$ that agree with a given function $f : \{x' \in X \mid x' \neq x\} \to Y$ on all elements except $x$ is equivalent to $Y$ itself. The equivalence maps a function $g$ to its value at $x$, and conversely, any element $y \in Y$ can be extended to a function $g$ that equals $f$ on $\{x' \in X \mid x' \neq x\}$ and sends $x$ to $y$.
Equiv.coe_subtypeEquivCodomain theorem
(f : { x' // x' ≠ x } → Y) : (subtypeEquivCodomain f : _ → Y) = fun g : { g : X → Y // g ∘ (↑) = f } => (g : X → Y) x
Full source
@[simp]
theorem coe_subtypeEquivCodomain (f : { x' // x' ≠ x } → Y) :
    (subtypeEquivCodomain f : _ → Y) =
      fun g : { g : X → Y // g ∘ (↑) = f } => (g : X → Y) x :=
  rfl
Evaluation at $x$ as the Underlying Function of `subtypeEquivCodomain`
Informal description
For a type $X$ with a distinguished element $x \in X$ and a type $Y$, given a function $f : \{x' \in X \mid x' \neq x\} \to Y$, the underlying function of the equivalence `subtypeEquivCodomain f` maps each $g \in \{g : X \to Y \mid g \circ (\text{inclusion}) = f\}$ to its evaluation at $x$, i.e., $g(x)$.
Equiv.subtypeEquivCodomain_apply theorem
(f : { x' // x' ≠ x } → Y) (g) : subtypeEquivCodomain f g = (g : X → Y) x
Full source
@[simp]
theorem subtypeEquivCodomain_apply (f : { x' // x' ≠ x } → Y) (g) :
    subtypeEquivCodomain f g = (g : X → Y) x :=
  rfl
Evaluation of Equivalence at Distinguished Point
Informal description
Given a type $X$ with a distinguished element $x \in X$ and a type $Y$, for any function $g : X \to Y$ that agrees with a given function $f : \{x' \in X \mid x' \neq x\} \to Y$ on all elements except $x$, the equivalence `subtypeEquivCodomain f` maps $g$ to its value at $x$, i.e., $g(x)$.
Equiv.coe_subtypeEquivCodomain_symm theorem
(f : { x' // x' ≠ x } → Y) : ((subtypeEquivCodomain f).symm : Y → _) = fun y => ⟨fun x' => if h : x' ≠ x then f ⟨x', h⟩ else y, by funext x' simp only [ne_eq, dite_not, comp_apply, Subtype.coe_eta, dite_eq_ite, ite_eq_right_iff] intro w exfalso exact x'.property w⟩
Full source
theorem coe_subtypeEquivCodomain_symm (f : { x' // x' ≠ x } → Y) :
    ((subtypeEquivCodomain f).symm : Y → _) = fun y =>
      ⟨fun x' => if h : x' ≠ x then f ⟨x', h⟩ else y, by
        funext x'
        simp only [ne_eq, dite_not, comp_apply, Subtype.coe_eta, dite_eq_ite, ite_eq_right_iff]
        intro w
        exfalso
        exact x'.property w⟩ :=
  rfl
Inverse of Restricted Function Extension Equivalence
Informal description
Given a type $X$ with a distinguished element $x \in X$ and a type $Y$, the inverse of the equivalence `subtypeEquivCodomain f` maps an element $y \in Y$ to the function $g : X \to Y$ defined by: \[ g(x') = \begin{cases} f(x') & \text{if } x' \neq x, \\ y & \text{if } x' = x. \end{cases} \] Moreover, this function $g$ satisfies the condition that its restriction to $\{x' \in X \mid x' \neq x\}$ equals $f$.
Equiv.subtypeEquivCodomain_symm_apply theorem
(f : { x' // x' ≠ x } → Y) (y : Y) (x' : X) : ((subtypeEquivCodomain f).symm y : X → Y) x' = if h : x' ≠ x then f ⟨x', h⟩ else y
Full source
@[simp]
theorem subtypeEquivCodomain_symm_apply (f : { x' // x' ≠ x } → Y) (y : Y) (x' : X) :
    ((subtypeEquivCodomain f).symm y : X → Y) x' = if h : x' ≠ x then f ⟨x', h⟩ else y :=
  rfl
Inverse of Restricted Function Extension Equivalence Evaluates to Piecewise Function
Informal description
Given a type $X$ with a distinguished element $x \in X$, a type $Y$, and a function $f : \{x' \in X \mid x' \neq x\} \to Y$, for any $y \in Y$ and $x' \in X$, the value of the function obtained from the inverse of the equivalence `subtypeEquivCodomain f` at $y$ evaluated at $x'$ is equal to $f(x')$ if $x' \neq x$, and $y$ otherwise. In other words, for the inverse equivalence $(\text{subtypeEquivCodomain}\, f)^{-1} : Y \to \{g : X \to Y \mid g \circ \iota = f\}$ (where $\iota$ is the inclusion map), the function $(\text{subtypeEquivCodomain}\, f)^{-1}(y)$ evaluated at $x'$ is given by: \[ ((\text{subtypeEquivCodomain}\, f)^{-1}(y))(x') = \begin{cases} f(x') & \text{if } x' \neq x, \\ y & \text{if } x' = x. \end{cases} \]
Equiv.subtypeEquivCodomain_symm_apply_eq theorem
(f : { x' // x' ≠ x } → Y) (y : Y) : ((subtypeEquivCodomain f).symm y : X → Y) x = y
Full source
theorem subtypeEquivCodomain_symm_apply_eq (f : { x' // x' ≠ x } → Y) (y : Y) :
    ((subtypeEquivCodomain f).symm y : X → Y) x = y :=
  dif_neg (not_not.mpr rfl)
Evaluation of Inverse Equivalence at Distinguished Point
Informal description
Let $X$ be a type with a distinguished element $x \in X$, and let $Y$ be any type. Given a function $f : \{x' \in X \mid x' \neq x\} \to Y$ and an element $y \in Y$, the function obtained as the inverse of the equivalence `subtypeEquivCodomain f` evaluates to $y$ at the point $x$, i.e., $((\text{subtypeEquivCodomain} f)^{-1} y)(x) = y$.
Equiv.subtypeEquivCodomain_symm_apply_ne theorem
(f : { x' // x' ≠ x } → Y) (y : Y) (x' : X) (h : x' ≠ x) : ((subtypeEquivCodomain f).symm y : X → Y) x' = f ⟨x', h⟩
Full source
theorem subtypeEquivCodomain_symm_apply_ne
    (f : { x' // x' ≠ x } → Y) (y : Y) (x' : X) (h : x' ≠ x) :
    ((subtypeEquivCodomain f).symm y : X → Y) x' = f ⟨x', h⟩ :=
  dif_pos h
Inverse of Subtype-Codomain Equivalence on Non-Distinguished Elements
Informal description
Let $X$ be a type with a distinguished element $x \in X$, and let $Y$ be any type. Given a function $f : \{x' \in X \mid x' \neq x\} \to Y$ and an element $y \in Y$, the function constructed as the inverse of the equivalence `subtypeEquivCodomain` satisfies $((\text{subtypeEquivCodomain}\, f)^{-1}\, y)\, x' = f \langle x', h \rangle$ for any $x' \in X$ and proof $h : x' \neq x$.
Equiv.instCanLiftForallCoeBijective instance
: CanLift (α → β) (α ≃ β) (↑) Bijective
Full source
instance : CanLift (α → β) (α ≃ β) (↑) Bijective where prf f hf := ⟨ofBijective f hf, rfl⟩
Lifting Functions to Equivalences via Bijectivity
Informal description
For any types $\alpha$ and $\beta$, there exists a lifting condition from the type of functions $\alpha \to \beta$ to the type of equivalences $\alpha \simeq \beta$ via the canonical coercion function, where the lifting condition is that the function must be bijective.
Equiv.Perm.extendDomain definition
: Perm β'
Full source
/-- Extend the domain of `e : Equiv.Perm α` to one that is over `β` via `f : α → Subtype p`,
where `p : β → Prop`, permuting only the `b : β` that satisfy `p b`.
This can be used to extend the domain across a function `f : α → β`,
keeping everything outside of `Set.range f` fixed. For this use-case `Equiv` given by `f` can
be constructed by `Equiv.of_leftInverse'` or `Equiv.of_leftInverse` when there is a known
inverse, or `Equiv.ofInjective` in the general case.
-/
def Perm.extendDomain : Perm β' :=
  (permCongr f e).subtypeCongr (Equiv.refl _)
Permutation extension via injective function
Informal description
Given a permutation `e` of a type `α` and an injective function `f : α → β` (where `β` has a decidable predicate `p` such that `p b` holds precisely when `b` is in the range of `f`), the function `Equiv.Perm.extendDomain` extends `e` to a permutation of `β` by applying `e` to elements in the range of `f` and leaving all other elements fixed. More precisely, for any `b : β`: - If `b` is in the range of `f` (i.e., `p b` holds), then `extendDomain e f b = f (e (f⁻¹ ⟨b, h⟩))`, where `h` is a proof that `p b` holds. - Otherwise, `extendDomain e f b = b`. This construction is useful for extending a permutation across a function while keeping elements outside the function's range unchanged.
Equiv.Perm.extendDomain_apply_image theorem
(a : α') : e.extendDomain f (f a) = f (e a)
Full source
@[simp]
theorem Perm.extendDomain_apply_image (a : α') : e.extendDomain f (f a) = f (e a) := by
  simp [Perm.extendDomain]
Action of Extended Permutation on Image Elements: $e.\text{extendDomain}\,f(f(a)) = f(e(a))$
Informal description
For any permutation $e$ of a type $\alpha'$, any injective function $f : \alpha' \to \beta'$, and any element $a \in \alpha'$, the extended permutation $e.\text{extendDomain}\,f$ satisfies $(e.\text{extendDomain}\,f)(f(a)) = f(e(a))$.
Equiv.Perm.extendDomain_apply_subtype theorem
{b : β'} (h : p b) : e.extendDomain f b = f (e (f.symm ⟨b, h⟩))
Full source
theorem Perm.extendDomain_apply_subtype {b : β'} (h : p b) :
    e.extendDomain f b = f (e (f.symm ⟨b, h⟩)) := by
  simp [Perm.extendDomain, h]
Action of Extended Permutation on Elements in Predicate Subset
Informal description
For any element $b$ of type $\beta'$ and a proof $h$ that $p(b)$ holds, the permutation obtained by extending $e$ via $f$ satisfies $(e.\text{extendDomain}\ f)\ b = f(e(f^{-1} \langle b, h \rangle))$.
Equiv.Perm.extendDomain_apply_not_subtype theorem
{b : β'} (h : ¬p b) : e.extendDomain f b = b
Full source
theorem Perm.extendDomain_apply_not_subtype {b : β'} (h : ¬p b) : e.extendDomain f b = b := by
  simp [Perm.extendDomain, h]
Fixed Points of Extended Permutation Outside Predicate Domain
Informal description
For any element $b$ of type $\beta'$ such that the predicate $p$ does not hold for $b$ (i.e., $\neg p(b)$), the permutation obtained by extending $e$ via $f$ leaves $b$ unchanged, i.e., $e.\text{extendDomain}\,f\,b = b$.
Equiv.Perm.extendDomain_refl theorem
: Perm.extendDomain (Equiv.refl _) f = Equiv.refl _
Full source
@[simp]
theorem Perm.extendDomain_refl : Perm.extendDomain (Equiv.refl _) f = Equiv.refl _ := by
  simp [Perm.extendDomain]
Extension of Identity Permutation Yields Identity
Informal description
For any injective function $f : \alpha \to \beta$, extending the identity permutation on $\alpha$ via $f$ yields the identity permutation on $\beta$. That is, $\text{extendDomain}(\text{id}_\alpha, f) = \text{id}_\beta$.
Equiv.Perm.extendDomain_symm theorem
: (e.extendDomain f).symm = Perm.extendDomain e.symm f
Full source
@[simp]
theorem Perm.extendDomain_symm : (e.extendDomain f).symm = Perm.extendDomain e.symm f :=
  rfl
Inverse of Extended Permutation Equals Extension of Inverse
Informal description
For any permutation $e$ of a type $\alpha$ and any injective function $f : \alpha \to \beta$, the inverse of the extended permutation $e.\text{extendDomain}\,f$ is equal to the extension of the inverse permutation $e^{-1}$ via $f$. In other words, $(e.\text{extendDomain}\,f)^{-1} = e^{-1}.\text{extendDomain}\,f$.
Equiv.Perm.extendDomain_trans theorem
(e e' : Perm α') : (e.extendDomain f).trans (e'.extendDomain f) = Perm.extendDomain (e.trans e') f
Full source
theorem Perm.extendDomain_trans (e e' : Perm α') :
    (e.extendDomain f).trans (e'.extendDomain f) = Perm.extendDomain (e.trans e') f := by
  simp [Perm.extendDomain, permCongr_trans]
Composition of Extended Permutations Equals Extension of Compositions
Informal description
For any permutations $e$ and $e'$ of a type $\alpha$ and any injective function $f : \alpha \to \beta$, the composition of the extended permutations $e.\text{extendDomain}\,f$ and $e'.\text{extendDomain}\,f$ is equal to the extension of the composition $e \circ e'$ via $f$. In other words, $(e.\text{extendDomain}\,f) \circ (e'.\text{extendDomain}\,f) = (e \circ e').\text{extendDomain}\,f$.
Equiv.subtypeQuotientEquivQuotientSubtype definition
(p₁ : α → Prop) {s₁ : Setoid α} {s₂ : Setoid (Subtype p₁)} (p₂ : Quotient s₁ → Prop) (hp₂ : ∀ a, p₁ a ↔ p₂ ⟦a⟧) (h : ∀ x y : Subtype p₁, s₂.r x y ↔ s₁.r x y) : { x // p₂ x } ≃ Quotient s₂
Full source
/-- Subtype of the quotient is equivalent to the quotient of the subtype. Let `α` be a setoid with
equivalence relation `~`. Let `p₂` be a predicate on the quotient type `α/~`, and `p₁` be the lift
of this predicate to `α`: `p₁ a ↔ p₂ ⟦a⟧`. Let `~₂` be the restriction of `~` to `{x // p₁ x}`.
Then `{x // p₂ x}` is equivalent to the quotient of `{x // p₁ x}` by `~₂`. -/
def subtypeQuotientEquivQuotientSubtype (p₁ : α → Prop) {s₁ : Setoid α} {s₂ : Setoid (Subtype p₁)}
    (p₂ : Quotient s₁ → Prop) (hp₂ : ∀ a, p₁ a ↔ p₂ ⟦a⟧)
    (h : ∀ x y : Subtype p₁, s₂.r x y ↔ s₁.r x y) : {x // p₂ x}{x // p₂ x} ≃ Quotient s₂ where
  toFun a :=
    Quotient.hrecOn a.1 (fun a h => ⟦⟨a, (hp₂ _).2 h⟩⟧)
      (fun a b hab => hfunext (by rw [Quotient.sound hab]) fun _ _ _ =>
        heq_of_eq (Quotient.sound ((h _ _).2 hab)))
      a.2
  invFun a :=
    Quotient.liftOn a (fun a => (⟨⟦a.1⟧, (hp₂ _).1 a.2⟩ : { x // p₂ x })) fun _ _ hab =>
      Subtype.ext_val (Quotient.sound ((h _ _).1 hab))
  left_inv := by exact fun ⟨a, ha⟩ => Quotient.inductionOn a (fun b hb => rfl) ha
  right_inv a := by exact Quotient.inductionOn a fun ⟨a, ha⟩ => rfl
Subtype of Quotient is Equivalent to Quotient of Subtype
Informal description
Given a setoid $\alpha$ with equivalence relation $\sim$, let $p_2$ be a predicate on the quotient type $\alpha/{\sim}$, and $p_1$ be the lift of this predicate to $\alpha$ (i.e., $p_1(a) \leftrightarrow p_2([a])$). Let $\sim_2$ be the restriction of $\sim$ to $\{x \mid p_1(x)\}$. Then the subtype $\{x \mid p_2(x)\}$ is equivalent to the quotient of $\{x \mid p_1(x)\}$ by $\sim_2$.
Equiv.subtypeQuotientEquivQuotientSubtype_mk theorem
(p₁ : α → Prop) [s₁ : Setoid α] [s₂ : Setoid (Subtype p₁)] (p₂ : Quotient s₁ → Prop) (hp₂ : ∀ a, p₁ a ↔ p₂ ⟦a⟧) (h : ∀ x y : Subtype p₁, s₂ x y ↔ (x : α) ≈ y) (x hx) : subtypeQuotientEquivQuotientSubtype p₁ p₂ hp₂ h ⟨⟦x⟧, hx⟩ = ⟦⟨x, (hp₂ _).2 hx⟩⟧
Full source
@[simp]
theorem subtypeQuotientEquivQuotientSubtype_mk (p₁ : α → Prop)
    [s₁ : Setoid α] [s₂ : Setoid (Subtype p₁)] (p₂ : Quotient s₁ → Prop) (hp₂ : ∀ a, p₁ a ↔ p₂ ⟦a⟧)
    (h : ∀ x y : Subtype p₁, s₂ x y ↔ (x : α) ≈ y)
    (x hx) : subtypeQuotientEquivQuotientSubtype p₁ p₂ hp₂ h ⟨⟦x⟧, hx⟩ = ⟦⟨x, (hp₂ _).2 hx⟩⟧ :=
  rfl
Equivalence Mapping for Subtype of Quotient to Quotient of Subtype
Informal description
Let $\alpha$ be a type with an equivalence relation $\sim$ (setoid $s_1$), and let $p_1$ be a predicate on $\alpha$. Let $s_2$ be the setoid on the subtype $\{x \mid p_1(x)\}$ induced by $\sim$, and let $p_2$ be a predicate on the quotient $\alpha/{\sim}$ such that $p_1(a) \leftrightarrow p_2([a])$ for all $a \in \alpha$. For any element $x \in \alpha$ and proof $hx$ that $p_2([x])$ holds, the equivalence `subtypeQuotientEquivQuotientSubtype` maps the pair $\langle [x], hx \rangle$ in the subtype $\{y \mid p_2(y)\}$ to the equivalence class $[\langle x, (hp_2 x).2 hx \rangle]$ in the quotient $\{x \mid p_1(x)\}/s_2$.
Equiv.subtypeQuotientEquivQuotientSubtype_symm_mk theorem
(p₁ : α → Prop) [s₁ : Setoid α] [s₂ : Setoid (Subtype p₁)] (p₂ : Quotient s₁ → Prop) (hp₂ : ∀ a, p₁ a ↔ p₂ ⟦a⟧) (h : ∀ x y : Subtype p₁, s₂ x y ↔ (x : α) ≈ y) (x) : (subtypeQuotientEquivQuotientSubtype p₁ p₂ hp₂ h).symm ⟦x⟧ = ⟨⟦x⟧, (hp₂ _).1 x.property⟩
Full source
@[simp]
theorem subtypeQuotientEquivQuotientSubtype_symm_mk (p₁ : α → Prop)
    [s₁ : Setoid α] [s₂ : Setoid (Subtype p₁)] (p₂ : Quotient s₁ → Prop) (hp₂ : ∀ a, p₁ a ↔ p₂ ⟦a⟧)
    (h : ∀ x y : Subtype p₁, s₂ x y ↔ (x : α) ≈ y) (x) :
    (subtypeQuotientEquivQuotientSubtype p₁ p₂ hp₂ h).symm ⟦x⟧ = ⟨⟦x⟧, (hp₂ _).1 x.property⟩ :=
  rfl
Inverse of Subtype-Quotient Equivalence Maps Equivalence Class to Subtype Pair
Informal description
Let $\alpha$ be a type with a setoid $s_1$ (an equivalence relation $\sim$), and let $p_1$ be a predicate on $\alpha$. Let $s_2$ be the setoid on the subtype $\{x \mid p_1(x)\}$ induced by $s_1$, and let $p_2$ be a predicate on the quotient $\alpha/{\sim}$ such that $p_1(a) \leftrightarrow p_2([a])$ for all $a \in \alpha$. For any element $x$ in the subtype $\{x \mid p_1(x)\}$, the inverse of the equivalence `subtypeQuotientEquivQuotientSubtype` maps the equivalence class $[x]$ in the quotient $\{x \mid p_1(x)\}/s_2$ to the pair $\langle [x], p_2([x]) \rangle$ in the subtype $\{y \mid p_2(y)\}$ of the quotient $\alpha/{\sim}$.
Equiv.swapCore definition
(a b r : α) : α
Full source
/-- A helper function for `Equiv.swap`. -/
def swapCore (a b r : α) : α :=
  if r = a then b else if r = b then a else r
Core swap function
Informal description
The function `swapCore` takes three elements `a`, `b`, and `r` of type `α` and returns `b` if `r = a`, `a` if `r = b`, and `r` otherwise. This is a helper function used to define the `swap` operation that exchanges two elements in a type.
Equiv.swapCore_self theorem
(r a : α) : swapCore a a r = r
Full source
theorem swapCore_self (r a : α) : swapCore a a r = r := by
  unfold swapCore
  split_ifs <;> simp [*]
Identity Property of Core Swap Function for Equal Elements
Informal description
For any elements $r$ and $a$ of a type $\alpha$, the core swap function satisfies $\text{swapCore}(a, a, r) = r$.
Equiv.swapCore_swapCore theorem
(r a b : α) : swapCore a b (swapCore a b r) = r
Full source
theorem swapCore_swapCore (r a b : α) : swapCore a b (swapCore a b r) = r := by
  unfold swapCore; split_ifs <;> cc
Double Application of Swap Core Function is Identity
Informal description
For any elements $r, a, b$ of a type $\alpha$, applying the core swap function twice with arguments $a$ and $b$ to $r$ returns $r$, i.e., $\text{swapCore}(a, b, \text{swapCore}(a, b, r)) = r$.
Equiv.swapCore_comm theorem
(r a b : α) : swapCore a b r = swapCore b a r
Full source
theorem swapCore_comm (r a b : α) : swapCore a b r = swapCore b a r := by
  unfold swapCore; split_ifs <;> cc
Commutativity of Core Swap Function
Informal description
For any elements $r, a, b$ of type $\alpha$, the core swap function satisfies $\text{swapCore}(a, b, r) = \text{swapCore}(b, a, r)$.
Equiv.swap definition
(a b : α) : Perm α
Full source
/-- `swap a b` is the permutation that swaps `a` and `b` and
  leaves other values as is. -/
def swap (a b : α) : Perm α :=
  ⟨swapCore a b, swapCore a b, fun r => swapCore_swapCore r a b,
    fun r => swapCore_swapCore r a b⟩
Permutation swapping two elements
Informal description
The function `swap a b` is the permutation of a type $\alpha$ that exchanges the elements $a$ and $b$ while leaving all other elements unchanged. It is defined using the core swap function and is proven to be bijective by construction.
Equiv.swap_self theorem
(a : α) : swap a a = Equiv.refl _
Full source
@[simp]
theorem swap_self (a : α) : swap a a = Equiv.refl _ :=
  ext fun r => swapCore_self r a
Swap of an Element with Itself is the Identity
Informal description
For any element $a$ of a type $\alpha$, the permutation that swaps $a$ with itself is equal to the identity equivalence on $\alpha$, i.e., $\mathrm{swap}(a, a) = \mathrm{id}_\alpha$.
Equiv.swap_comm theorem
(a b : α) : swap a b = swap b a
Full source
theorem swap_comm (a b : α) : swap a b = swap b a :=
  ext fun r => swapCore_comm r _ _
Commutativity of Swap Permutation: $\mathrm{swap}(a, b) = \mathrm{swap}(b, a)$
Informal description
For any two elements $a$ and $b$ in a type $\alpha$, the permutation swapping $a$ and $b$ is equal to the permutation swapping $b$ and $a$, i.e., $\mathrm{swap}(a, b) = \mathrm{swap}(b, a)$.
Equiv.swap_apply_def theorem
(a b x : α) : swap a b x = if x = a then b else if x = b then a else x
Full source
theorem swap_apply_def (a b x : α) : swap a b x = if x = a then b else if x = b then a else x :=
  rfl
Definition of Swap Permutation's Action
Informal description
For any elements $a, b, x$ in a type $\alpha$, the permutation $\mathrm{swap}(a, b)$ applied to $x$ is defined as: \[ \mathrm{swap}(a, b)(x) = \begin{cases} b & \text{if } x = a, \\ a & \text{if } x = b, \\ x & \text{otherwise.} \end{cases} \]
Equiv.swap_apply_left theorem
(a b : α) : swap a b a = b
Full source
@[simp]
theorem swap_apply_left (a b : α) : swap a b a = b :=
  if_pos rfl
Swap Permutation Maps First Element to Second
Informal description
For any elements $a$ and $b$ in a type $\alpha$, the permutation $\mathrm{swap}(a, b)$ maps $a$ to $b$, i.e., $\mathrm{swap}(a, b)(a) = b$.
Equiv.swap_apply_right theorem
(a b : α) : swap a b b = a
Full source
@[simp]
theorem swap_apply_right (a b : α) : swap a b b = a := by
  by_cases h : b = a <;> simp [swap_apply_def, h]
Swap Permutation Maps Second Element to First
Informal description
For any elements $a$ and $b$ in a type $\alpha$, the permutation $\mathrm{swap}(a, b)$ maps $b$ to $a$, i.e., $\mathrm{swap}(a, b)(b) = a$.
Equiv.swap_apply_of_ne_of_ne theorem
{a b x : α} : x ≠ a → x ≠ b → swap a b x = x
Full source
theorem swap_apply_of_ne_of_ne {a b x : α} : x ≠ ax ≠ bswap a b x = x := by
  simp +contextual [swap_apply_def]
Swap Permutation Fixes Elements Distinct from Both Arguments
Informal description
For any elements $a$, $b$, and $x$ in a type $\alpha$, if $x$ is distinct from both $a$ and $b$, then the permutation $\mathrm{swap}(a, b)$ leaves $x$ unchanged, i.e., $\mathrm{swap}(a, b)(x) = x$.
Equiv.swap_swap theorem
(a b : α) : (swap a b).trans (swap a b) = Equiv.refl _
Full source
@[simp]
theorem swap_swap (a b : α) : (swap a b).trans (swap a b) = Equiv.refl _ :=
  ext fun _ => swapCore_swapCore _ _ _
Double Swap is Identity: $\text{swap}(a, b)^2 = \text{id}$
Informal description
For any two elements $a$ and $b$ of a type $\alpha$, the composition of the swap permutation (swapping $a$ and $b$) with itself is equal to the identity permutation on $\alpha$, i.e., $\text{swap}(a, b) \circ \text{swap}(a, b) = \text{id}_\alpha$.
Equiv.symm_swap theorem
(a b : α) : (swap a b).symm = swap a b
Full source
@[simp]
theorem symm_swap (a b : α) : (swap a b).symm = swap a b :=
  rfl
Inverse of Swap Permutation is Itself
Informal description
For any two elements $a$ and $b$ of a type $\alpha$, the inverse of the permutation that swaps $a$ and $b$ is equal to the permutation itself, i.e., $(\text{swap } a b)^{-1} = \text{swap } a b$.
Equiv.swap_eq_refl_iff theorem
{x y : α} : swap x y = Equiv.refl _ ↔ x = y
Full source
@[simp]
theorem swap_eq_refl_iff {x y : α} : swapswap x y = Equiv.refl _ ↔ x = y := by
  refine ⟨fun h => (Equiv.refl _).injective ?_, fun h => h ▸ swap_self _⟩
  rw [← h, swap_apply_left, h, refl_apply]
Swap Permutation is Identity if and only if Elements are Equal: $\mathrm{swap}(x, y) = \mathrm{id}_\alpha \leftrightarrow x = y$
Informal description
For any elements $x$ and $y$ of a type $\alpha$, the swap permutation $\mathrm{swap}(x, y)$ is equal to the identity permutation $\mathrm{id}_\alpha$ if and only if $x = y$.
Equiv.swap_comp_apply theorem
{a b x : α} (π : Perm α) : π.trans (swap a b) x = if π x = a then b else if π x = b then a else π x
Full source
theorem swap_comp_apply {a b x : α} (π : Perm α) :
    π.trans (swap a b) x = if π x = a then b else if π x = b then a else π x := by
  cases π
  rfl
Action of Composition with Swap Permutation
Informal description
For any permutation $\pi$ of a type $\alpha$ and any elements $a, b, x \in \alpha$, the composition of $\pi$ with the swap permutation $\text{swap } a b$ evaluated at $x$ is given by: \[ (\pi \circ \text{swap } a b)(x) = \begin{cases} b & \text{if } \pi(x) = a, \\ a & \text{if } \pi(x) = b, \\ \pi(x) & \text{otherwise.} \end{cases} \]
Equiv.swap_eq_update theorem
(i j : α) : (Equiv.swap i j : α → α) = update (update id j i) i j
Full source
theorem swap_eq_update (i j : α) : (Equiv.swap i j : α → α) = update (update id j i) i j :=
  funext fun x => by rw [update_apply _ i j, update_apply _ j i, Equiv.swap_apply_def, id]
Swap Permutation as Double Update of Identity Function
Informal description
For any elements $i$ and $j$ of a type $\alpha$, the permutation $\mathrm{swap}(i, j)$ is equal to the function obtained by first updating the identity function at $j$ with value $i$, and then updating the result at $i$ with value $j$. In other words, the swap permutation can be expressed as: \[ \mathrm{swap}(i, j) = \text{update}(\text{update}(\text{id}, j, i), i, j) \] where $\text{id}$ is the identity function on $\alpha$.
Equiv.comp_swap_eq_update theorem
(i j : α) (f : α → β) : f ∘ Equiv.swap i j = update (update f j (f i)) i (f j)
Full source
theorem comp_swap_eq_update (i j : α) (f : α → β) :
    f ∘ Equiv.swap i j = update (update f j (f i)) i (f j) := by
  rw [swap_eq_update, comp_update, comp_update, comp_id]
Composition with Swap Permutation as Double Update: $f \circ \mathrm{swap}(i,j) = \text{update}(\text{update}(f, j, f(i)), i, f(j))$
Informal description
For any elements $i$ and $j$ of a type $\alpha$ and any function $f \colon \alpha \to \beta$, the composition of $f$ with the swap permutation $\mathrm{swap}(i, j)$ is equal to the function obtained by first updating $f$ at $j$ with $f(i)$, and then updating the result at $i$ with $f(j)$. In other words: \[ f \circ \mathrm{swap}(i, j) = \text{update}(\text{update}(f, j, f(i)), i, f(j)) \] where $\text{update}$ modifies a function at a specified point.
Equiv.symm_trans_swap_trans theorem
[DecidableEq β] (a b : α) (e : α ≃ β) : (e.symm.trans (swap a b)).trans e = swap (e a) (e b)
Full source
@[simp]
theorem symm_trans_swap_trans [DecidableEq β] (a b : α) (e : α ≃ β) :
    (e.symm.trans (swap a b)).trans e = swap (e a) (e b) :=
  Equiv.ext fun x => by
    have : ∀ a, e.symm x = a ↔ x = e a := fun a => by
      rw [@eq_comm _ (e.symm x)]
      constructor <;> intros <;> simp_all
    simp only [trans_apply, swap_apply_def, this]
    split_ifs <;> simp
Conjugation of Swap by Equivalence: $e^{-1} \circ \text{swap}(a, b) \circ e = \text{swap}(e(a), e(b))$
Informal description
Let $\alpha$ and $\beta$ be types with decidable equality on $\beta$, and let $a, b \in \alpha$ and $e : \alpha \simeq \beta$ be an equivalence between $\alpha$ and $\beta$. Then the composition of equivalences $e^{-1} \circ \text{swap}(a, b) \circ e$ is equal to the swap of $e(a)$ and $e(b)$ in $\beta$, i.e., $$ e^{-1} \circ \text{swap}(a, b) \circ e = \text{swap}(e(a), e(b)). $$
Equiv.trans_swap_trans_symm theorem
[DecidableEq β] (a b : β) (e : α ≃ β) : (e.trans (swap a b)).trans e.symm = swap (e.symm a) (e.symm b)
Full source
@[simp]
theorem trans_swap_trans_symm [DecidableEq β] (a b : β) (e : α ≃ β) :
    (e.trans (swap a b)).trans e.symm = swap (e.symm a) (e.symm b) :=
  symm_trans_swap_trans a b e.symm
Conjugation of Swap by Equivalence (Symmetric Version): $e \circ \text{swap}(a, b) \circ e^{-1} = \text{swap}(e^{-1}(a), e^{-1}(b))$
Informal description
Let $\alpha$ and $\beta$ be types with decidable equality on $\beta$, and let $a, b \in \beta$ and $e : \alpha \simeq \beta$ be an equivalence between $\alpha$ and $\beta$. Then the composition of equivalences $e \circ \text{swap}(a, b) \circ e^{-1}$ is equal to the swap of $e^{-1}(a)$ and $e^{-1}(b)$ in $\alpha$, i.e., $$ e \circ \text{swap}(a, b) \circ e^{-1} = \text{swap}(e^{-1}(a), e^{-1}(b)). $$
Equiv.swap_apply_self theorem
(i j a : α) : swap i j (swap i j a) = a
Full source
@[simp]
theorem swap_apply_self (i j a : α) : swap i j (swap i j a) = a := by
  rw [← Equiv.trans_apply, Equiv.swap_swap, Equiv.refl_apply]
Double Swap Acts as Identity: $\text{swap}(i,j)^2(a) = a$
Informal description
For any elements $i, j, a$ of a type $\alpha$, applying the swap permutation (swapping $i$ and $j$) twice to $a$ returns $a$ itself, i.e., $\text{swap}(i, j)(\text{swap}(i, j)(a)) = a$.
Equiv.apply_swap_eq_self theorem
{v : α → β} {i j : α} (hv : v i = v j) (k : α) : v (swap i j k) = v k
Full source
/-- A function is invariant to a swap if it is equal at both elements -/
theorem apply_swap_eq_self {v : α → β} {i j : α} (hv : v i = v j) (k : α) :
    v (swap i j k) = v k := by
  by_cases hi : k = i
  · rw [hi, swap_apply_left, hv]

  by_cases hj : k = j
  · rw [hj, swap_apply_right, hv]

  rw [swap_apply_of_ne_of_ne hi hj]
Function Invariance Under Swap Permutation
Informal description
For any function $v : \alpha \to \beta$ and elements $i, j \in \alpha$ such that $v(i) = v(j)$, the function $v$ is invariant under the swap permutation of $i$ and $j$, i.e., $v(\mathrm{swap}(i, j)(k)) = v(k)$ for all $k \in \alpha$.
Equiv.swap_apply_ne_self_iff theorem
{a b x : α} : swap a b x ≠ x ↔ a ≠ b ∧ (x = a ∨ x = b)
Full source
theorem swap_apply_ne_self_iff {a b x : α} : swapswap a b x ≠ xswap a b x ≠ x ↔ a ≠ b ∧ (x = a ∨ x = b) := by
  by_cases hab : a = b
  · simp [hab]

  by_cases hax : x = a
  · simp [hax, eq_comm]

  by_cases hbx : x = b
  · simp [hbx]

  simp [hab, hax, hbx, swap_apply_of_ne_of_ne]
Characterization of Non-Fixed Points under Swap Permutation: $\mathrm{swap}(a,b)(x) \neq x \leftrightarrow a \neq b \land (x = a \lor x = b)$
Informal description
For any elements $a, b, x$ in a type $\alpha$, the permutation $\mathrm{swap}(a, b)$ does not fix $x$ (i.e., $\mathrm{swap}(a, b)(x) \neq x$) if and only if $a$ and $b$ are distinct and $x$ is equal to either $a$ or $b$.
Equiv.Perm.sumCongr_swap_refl theorem
{α β : Sort _} [DecidableEq α] [DecidableEq β] (i j : α) : Equiv.Perm.sumCongr (Equiv.swap i j) (Equiv.refl β) = Equiv.swap (Sum.inl i) (Sum.inl j)
Full source
@[simp]
theorem sumCongr_swap_refl {α β : Sort _} [DecidableEq α] [DecidableEq β] (i j : α) :
    Equiv.Perm.sumCongr (Equiv.swap i j) (Equiv.refl β) = Equiv.swap (Sum.inl i) (Sum.inl j) := by
  ext x
  cases x
  · simp only [Equiv.sumCongr_apply, Sum.map, coe_refl, comp_id, Sum.elim_inl, comp_apply,
      swap_apply_def, Sum.inl.injEq]
    split_ifs <;> rfl
  · simp [Sum.map, swap_apply_of_ne_of_ne]
Sum Congruence of Swap and Identity Permutation Equals Swap on Inl Elements
Informal description
For any types $\alpha$ and $\beta$ with decidable equality, and for any elements $i, j \in \alpha$, the permutation obtained by taking the sum congruence of the swap permutation $\mathrm{swap}(i, j)$ on $\alpha$ and the identity permutation on $\beta$ is equal to the swap permutation $\mathrm{swap}(\mathrm{inl}(i), \mathrm{inl}(j))$ on the sum type $\alpha \oplus \beta$.
Equiv.Perm.sumCongr_refl_swap theorem
{α β : Sort _} [DecidableEq α] [DecidableEq β] (i j : β) : Equiv.Perm.sumCongr (Equiv.refl α) (Equiv.swap i j) = Equiv.swap (Sum.inr i) (Sum.inr j)
Full source
@[simp]
theorem sumCongr_refl_swap {α β : Sort _} [DecidableEq α] [DecidableEq β] (i j : β) :
    Equiv.Perm.sumCongr (Equiv.refl α) (Equiv.swap i j) = Equiv.swap (Sum.inr i) (Sum.inr j) := by
  ext x
  cases x
  · simp [Sum.map, swap_apply_of_ne_of_ne]

  · simp only [Equiv.sumCongr_apply, Sum.map, coe_refl, comp_id, Sum.elim_inr, comp_apply,
      swap_apply_def, Sum.inr.injEq]
    split_ifs <;> rfl
Direct Sum of Identity and Swap Permutation Equals Swap of Right Injections
Informal description
For any types $\alpha$ and $\beta$ with decidable equality, and for any elements $i, j \in \beta$, the permutation obtained by taking the direct sum of the identity permutation on $\alpha$ and the swap permutation of $i$ and $j$ on $\beta$ is equal to the swap permutation of the right injections $\mathrm{inr}(i)$ and $\mathrm{inr}(j)$ in the sum type $\alpha \oplus \beta$.
Equiv.setValue definition
(f : α ≃ β) (a : α) (b : β) : α ≃ β
Full source
/-- Augment an equivalence with a prescribed mapping `f a = b` -/
def setValue (f : α ≃ β) (a : α) (b : β) : α ≃ β :=
  (swap a (f.symm b)).trans f
Equivalence with prescribed value
Informal description
Given an equivalence $f : \alpha \simeq \beta$, an element $a \in \alpha$, and an element $b \in \beta$, the function constructs a new equivalence $\alpha \simeq \beta$ that maps $a$ to $b$ while preserving the bijectivity of $f$. This is achieved by composing $f$ with a permutation that swaps $a$ and $f^{-1}(b)$.
Equiv.setValue_eq theorem
(f : α ≃ β) (a : α) (b : β) : setValue f a b a = b
Full source
@[simp]
theorem setValue_eq (f : α ≃ β) (a : α) (b : β) : setValue f a b a = b := by
  simp [setValue, swap_apply_left]
Prescribed Value Property of Modified Equivalence: $f'(a) = b$
Informal description
Given an equivalence $f : \alpha \simeq \beta$, an element $a \in \alpha$, and an element $b \in \beta$, the modified equivalence $\mathrm{setValue}\,f\,a\,b$ maps $a$ to $b$, i.e., $(\mathrm{setValue}\,f\,a\,b)(a) = b$.
Function.Involutive.toPerm definition
(f : α → α) (h : Involutive f) : Equiv.Perm α
Full source
/-- Convert an involutive function `f` to a permutation with `toFun = invFun = f`. -/
def toPerm (f : α → α) (h : Involutive f) : Equiv.Perm α :=
  ⟨f, f, h.leftInverse, h.rightInverse⟩
Permutation from an involutive function
Informal description
Given an involutive function \( f : \alpha \to \alpha \) (i.e., \( f(f(x)) = x \) for all \( x \in \alpha \)), the function constructs a permutation (bijective map) on \( \alpha \) where both the forward and backward maps are equal to \( f \).
Function.Involutive.coe_toPerm theorem
{f : α → α} (h : Involutive f) : (h.toPerm f : α → α) = f
Full source
@[simp]
theorem coe_toPerm {f : α → α} (h : Involutive f) : (h.toPerm f : α → α) = f :=
  rfl
Permutation Construction Preserves Involutive Function
Informal description
For any involutive function $f : \alpha \to \alpha$ (i.e., $f(f(x)) = x$ for all $x \in \alpha$), the underlying function of the permutation constructed from $f$ via `h.toPerm` is equal to $f$ itself.
Function.Involutive.toPerm_symm theorem
{f : α → α} (h : Involutive f) : (h.toPerm f).symm = h.toPerm f
Full source
@[simp]
theorem toPerm_symm {f : α → α} (h : Involutive f) : (h.toPerm f).symm = h.toPerm f :=
  rfl
Inverse of Permutation from Involutive Function Equals Itself
Informal description
For any involutive function $f : \alpha \to \alpha$ (i.e., $f(f(x)) = x$ for all $x \in \alpha$), the inverse of the permutation constructed from $f$ via `h.toPerm` is equal to the permutation itself.
Function.Involutive.toPerm_involutive theorem
{f : α → α} (h : Involutive f) : Involutive (h.toPerm f)
Full source
theorem toPerm_involutive {f : α → α} (h : Involutive f) : Involutive (h.toPerm f) :=
  h
Involutive Property Preserved in Permutation Construction
Informal description
For any involutive function $f : \alpha \to \alpha$ (i.e., $f(f(x)) = x$ for all $x \in \alpha$), the permutation $\text{h.toPerm } f$ obtained from $f$ is also involutive.
Function.Involutive.symm_eq_self_of_involutive theorem
(f : Equiv.Perm α) (h : Involutive f) : f.symm = f
Full source
theorem symm_eq_self_of_involutive (f : Equiv.Perm α) (h : Involutive f) : f.symm = f :=
  DFunLike.coe_injective (h.leftInverse_iff.mp f.left_inv)
Involutive Permutation Has Self-Inverse Symmetry
Informal description
For any permutation $f$ of a type $\alpha$, if $f$ is involutive (i.e., $f(f(x)) = x$ for all $x \in \alpha$), then the inverse permutation $f^{-1}$ is equal to $f$.
Function.Injective.map_swap theorem
[DecidableEq α] [DecidableEq β] {f : α → β} (hf : Function.Injective f) (x y z : α) : f (Equiv.swap x y z) = Equiv.swap (f x) (f y) (f z)
Full source
theorem Function.Injective.map_swap [DecidableEq α] [DecidableEq β] {f : α → β}
    (hf : Function.Injective f) (x y z : α) :
    f (Equiv.swap x y z) = Equiv.swap (f x) (f y) (f z) := by
  conv_rhs => rw [Equiv.swap_apply_def]
  split_ifs with h₁ h₂
  · rw [hf h₁, Equiv.swap_apply_left]
  · rw [hf h₂, Equiv.swap_apply_right]
  · rw [Equiv.swap_apply_of_ne_of_ne (mt (congr_arg f) h₁) (mt (congr_arg f) h₂)]
Injective Function Commutes with Swap Permutation
Informal description
Let $\alpha$ and $\beta$ be types with decidable equality, and let $f : \alpha \to \beta$ be an injective function. For any elements $x, y, z \in \alpha$, the image of the swap permutation $\mathrm{swap}(x, y)$ applied to $z$ under $f$ is equal to the swap permutation $\mathrm{swap}(f(x), f(y))$ applied to $f(z)$. That is, \[ f(\mathrm{swap}(x, y)(z)) = \mathrm{swap}(f(x), f(y))(f(z)). \]
Equiv.piCongrLeft' definition
(P : α → Sort*) (e : α ≃ β) : (∀ a, P a) ≃ ∀ b, P (e.symm b)
Full source
/-- Transport dependent functions through an equivalence of the base space.
-/
@[simps apply, simps -isSimp symm_apply]
def piCongrLeft' (P : α → Sort*) (e : α ≃ β) : (∀ a, P a) ≃ ∀ b, P (e.symm b) where
  toFun f x := f (e.symm x)
  invFun f x := (e.symm_apply_apply x).ndrec (f (e x))
  left_inv f := funext fun x =>
    (by rintro _ rfl; rfl : ∀ {y} (h : y = x), h.ndrec (f y) = f x) (e.symm_apply_apply x)
  right_inv f := funext fun x =>
    (by rintro _ rfl; rfl : ∀ {y} (h : y = x), (congr_arg e.symm h).ndrec (f y) = f x)
      (e.apply_symm_apply x)
Equivalence of dependent function types under base equivalence
Informal description
Given a family of types $P : \alpha \to \text{Sort}*$ and an equivalence $e : \alpha \simeq \beta$, the function `Equiv.piCongrLeft'` constructs an equivalence between the dependent function types $(\forall a, P a)$ and $(\forall b, P (e^{-1} b))$. Specifically: - The forward map sends $f : \forall a, P a$ to the function $x \mapsto f(e^{-1} x)$. - The inverse map sends $g : \forall b, P (e^{-1} b)$ to the function $x \mapsto g(e x)$, using the fact that $e^{-1}(e x) = x$ to ensure well-definedness. This equivalence transports dependent functions through the base equivalence $e$.
Equiv.piCongrLeft'_symm theorem
(P : Sort*) (e : α ≃ β) : (piCongrLeft' (fun _ => P) e).symm = piCongrLeft' _ e.symm
Full source
/-- This lemma is impractical to state in the dependent case. -/
@[simp]
theorem piCongrLeft'_symm (P : Sort*) (e : α ≃ β) :
    (piCongrLeft' (fun _ => P) e).symm = piCongrLeft' _ e.symm := by ext; simp [piCongrLeft']
Inverse of `piCongrLeft'` for Constant Family Equals `piCongrLeft'` of Inverse Equivalence
Informal description
For any type $P$ and any equivalence $e : \alpha \simeq \beta$, the inverse of the equivalence `piCongrLeft'` (applied to the constant family $\lambda \_, P$) is equal to `piCongrLeft'` applied to $P$ and the inverse equivalence $e^{-1} : \beta \simeq \alpha$.
Equiv.piCongrLeft'_symm_apply_apply theorem
(P : α → Sort*) (e : α ≃ β) (g : ∀ b, P (e.symm b)) (b : β) : (piCongrLeft' P e).symm g (e.symm b) = g b
Full source
/-- Note: the "obvious" statement `(piCongrLeft' P e).symm g a = g (e a)` doesn't typecheck: the
LHS would have type `P a` while the RHS would have type `P (e.symm (e a))`. This lemma is a way
around it in the case where `a` is of the form `e.symm b`, so we can use `g b` instead of
`g (e (e.symm b))`. -/
@[simp]
lemma piCongrLeft'_symm_apply_apply (P : α → Sort*) (e : α ≃ β) (g : ∀ b, P (e.symm b)) (b : β) :
    (piCongrLeft' P e).symm g (e.symm b) = g b := by
  rw [piCongrLeft'_symm_apply, ← heq_iff_eq, rec_heq_iff_heq]
  exact congr_arg_heq _ (e.apply_symm_apply _)
Inverse Evaluation Property of `piCongrLeft'` Equivalence: $(e_{\text{piCongrLeft}'} P e)^{-1} g (e^{-1} b) = g b$
Informal description
Given a family of types $P : \alpha \to \text{Sort}*$, an equivalence $e : \alpha \simeq \beta$, and a dependent function $g : \forall b, P(e^{-1}(b))$, for any $b \in \beta$ we have $(e_{\text{piCongrLeft}'} P e)^{-1} g (e^{-1} b) = g b$, where $(e_{\text{piCongrLeft}'} P e)^{-1}$ denotes the inverse of the equivalence constructed by `piCongrLeft'`.
Equiv.piCongrLeft definition
: (∀ a, P (e a)) ≃ ∀ b, P b
Full source
/-- Transporting dependent functions through an equivalence of the base,
expressed as a "simplification".
-/
def piCongrLeft : (∀ a, P (e a)) ≃ ∀ b, P b :=
  (piCongrLeft' P e.symm).symm
Equivalence of dependent function types under base equivalence (reverse direction)
Informal description
Given a family of types $P : \beta \to \text{Sort}*$ and an equivalence $e : \alpha \simeq \beta$, the function `Equiv.piCongrLeft` constructs an equivalence between the dependent function types $(\forall a, P (e a))$ and $(\forall b, P b)$. Specifically: - The forward map sends $f : \forall a, P (e a)$ to the function $b \mapsto f(e^{-1} b)$, adjusted by the equivalence proof. - The inverse map sends $g : \forall b, P b$ to the function $a \mapsto g(e a)$. This equivalence transports dependent functions through the base equivalence $e$ in the opposite direction compared to `piCongrLeft'`.
Equiv.piCongrLeft_apply theorem
(f : ∀ a, P (e a)) (b : β) : (piCongrLeft P e) f b = e.apply_symm_apply b ▸ f (e.symm b)
Full source
/-- Note: the "obvious" statement `(piCongrLeft P e) f b = f (e.symm b)` doesn't typecheck: the
LHS would have type `P b` while the RHS would have type `P (e (e.symm b))`. For that reason,
we have to explicitly substitute along `e (e.symm b) = b` in the statement of this lemma. -/
@[simp]
lemma piCongrLeft_apply (f : ∀ a, P (e a)) (b : β) :
    (piCongrLeft P e) f b = e.apply_symm_apply b ▸ f (e.symm b) :=
  rfl
Application of Dependent Function Equivalence via Base Change: $(\text{piCongrLeft}\, P\, e)\, f\, b = \text{transport}_P (e(e^{-1}(b)) = b)\, (f(e^{-1}(b)))$
Informal description
Given an equivalence $e : \alpha \simeq \beta$ and a dependent function $f : \forall a, P(e(a))$, the application of the equivalence `piCongrLeft P e` to $f$ at $b \in \beta$ is equal to the transport of $f(e^{-1}(b))$ along the proof that $e(e^{-1}(b)) = b$. In other words: $$(\text{piCongrLeft}\, P\, e)\, f\, b = \text{transport}_P (e(e^{-1}(b)) = b)\, (f(e^{-1}(b)))$$
Equiv.piCongrLeft_symm_apply theorem
(g : ∀ b, P b) (a : α) : (piCongrLeft P e).symm g a = g (e a)
Full source
@[simp]
lemma piCongrLeft_symm_apply (g : ∀ b, P b) (a : α) :
    (piCongrLeft P e).symm g a = g (e a) :=
  piCongrLeft'_apply P e.symm g a
Inverse of Dependent Function Transport Equivalence Evaluates as Composition
Informal description
Given an equivalence $e : \alpha \simeq \beta$ and a family of types $P : \beta \to \text{Sort}*$, for any dependent function $g : \forall b, P b$ and any element $a \in \alpha$, the inverse of the equivalence $\text{piCongrLeft}\, P\, e$ applied to $g$ at $a$ equals $g$ evaluated at $e(a)$, i.e., $$(\text{piCongrLeft}\, P\, e)^{-1}(g)(a) = g(e(a)).$$
Equiv.piCongrLeft_apply_apply theorem
(f : ∀ a, P (e a)) (a : α) : (piCongrLeft P e) f (e a) = f a
Full source
/-- Note: the "obvious" statement `(piCongrLeft P e) f b = f (e.symm b)` doesn't typecheck: the
LHS would have type `P b` while the RHS would have type `P (e (e.symm b))`. This lemma is a way
around it in the case where `b` is of the form `e a`, so we can use `f a` instead of
`f (e.symm (e a))`. -/
lemma piCongrLeft_apply_apply (f : ∀ a, P (e a)) (a : α) :
    (piCongrLeft P e) f (e a) = f a :=
  piCongrLeft'_symm_apply_apply P e.symm f a
Evaluation of Transported Dependent Function at Equivalent Point: $(\text{piCongrLeft}\, P\, e)\, f\, (e(a)) = f(a)$
Informal description
Given an equivalence $e : \alpha \simeq \beta$, a family of types $P : \beta \to \text{Sort}*$, and a dependent function $f : \forall a, P(e(a))$, then for any $a \in \alpha$, the application of the equivalence-transported function $\text{piCongrLeft}\, P\, e\, f$ at $e(a)$ equals $f(a)$. That is: $$(\text{piCongrLeft}\, P\, e)\, f\, (e(a)) = f(a).$$
Equiv.piCongrLeft_apply_eq_cast theorem
{P : β → Sort v} {e : α ≃ β} (f : (a : α) → P (e a)) (b : β) : piCongrLeft P e f b = cast (congr_arg P (e.apply_symm_apply b)) (f (e.symm b))
Full source
lemma piCongrLeft_apply_eq_cast {P : β → Sort v} {e : α ≃ β}
    (f : (a : α) → P (e a)) (b : β) :
    piCongrLeft P e f b = cast (congr_arg P (e.apply_symm_apply b)) (f (e.symm b)) :=
  Eq.rec_eq_cast _ _
Equality of Transported Dependent Function via Equivalence and Cast
Informal description
Given a family of types $P : \beta \to \text{Sort}_v$, an equivalence $e : \alpha \simeq \beta$, and a dependent function $f : \forall a, P(e a)$, then for any $b \in \beta$, the application of the equivalence-transported function $\text{piCongrLeft}\, P\, e\, f$ at $b$ is equal to casting $f(e^{-1}b)$ along the equality proof $\text{congr\_arg}\, P\, (e(e^{-1}b) = b)$.
Equiv.piCongrLeft_sumInl theorem
{ι ι' ι''} (π : ι'' → Type*) (e : ι ⊕ ι' ≃ ι'') (f : ∀ i, π (e (inl i))) (g : ∀ i, π (e (inr i))) (i : ι) : piCongrLeft π e (sumPiEquivProdPi (fun x => π (e x)) |>.symm (f, g)) (e (inl i)) = f i
Full source
theorem piCongrLeft_sumInl {ι ι' ι''} (π : ι'' → Type*) (e : ι ⊕ ι'ι ⊕ ι' ≃ ι'') (f : ∀ i, π (e (inl i)))
    (g : ∀ i, π (e (inr i))) (i : ι) :
    piCongrLeft π e (sumPiEquivProdPi (fun x => π (e x)) |>.symm (f, g)) (e (inl i)) = f i := by
  simp_rw [piCongrLeft_apply_eq_cast, sumPiEquivProdPi_symm_apply,
    sum_rec_congr _ _ _ (e.symm_apply_apply (inl i)), cast_cast, cast_eq]
Equality of Left Component in Transported Sum-Dependent Function via Equivalence
Informal description
Let $\iota$, $\iota'$, and $\iota''$ be types, $\pi : \iota'' \to \text{Type}^*$ a family of types, and $e : \iota \oplus \iota' \simeq \iota''$ an equivalence. For any dependent functions $f : \forall i \in \iota, \pi(e(\text{inl}\, i))$ and $g : \forall i \in \iota', \pi(e(\text{inr}\, i))$, and any $i \in \iota$, we have: \[ \text{piCongrLeft}\, \pi\, e\, \left(\text{sumPiEquivProdPi}\, (\lambda x, \pi(e\, x))^{-1} (f, g)\right) (e(\text{inl}\, i)) = f\, i \] where $\text{sumPiEquivProdPi}$ is the equivalence between dependent functions on a sum type and pairs of dependent functions on the summands.
Equiv.piCongrLeft_sumInr theorem
{ι ι' ι''} (π : ι'' → Type*) (e : ι ⊕ ι' ≃ ι'') (f : ∀ i, π (e (inl i))) (g : ∀ i, π (e (inr i))) (j : ι') : piCongrLeft π e (sumPiEquivProdPi (fun x => π (e x)) |>.symm (f, g)) (e (inr j)) = g j
Full source
theorem piCongrLeft_sumInr {ι ι' ι''} (π : ι'' → Type*) (e : ι ⊕ ι'ι ⊕ ι' ≃ ι'') (f : ∀ i, π (e (inl i)))
    (g : ∀ i, π (e (inr i))) (j : ι') :
    piCongrLeft π e (sumPiEquivProdPi (fun x => π (e x)) |>.symm (f, g)) (e (inr j)) = g j := by
  simp_rw [piCongrLeft_apply_eq_cast, sumPiEquivProdPi_symm_apply,
    sum_rec_congr _ _ _ (e.symm_apply_apply (inr j)), cast_cast, cast_eq]
Equivalence Transport of Right Sum Component in Dependent Function Space
Informal description
Given types $\iota$, $\iota'$, $\iota''$, a family of types $\pi : \iota'' \to \text{Type}^*$, an equivalence $e : \iota \oplus \iota' \simeq \iota''$, dependent functions $f : \forall i, \pi(e(\text{inl}\, i))$ and $g : \forall i, \pi(e(\text{inr}\, i))$, and an element $j \in \iota'$, the application of the equivalence-transported function $\text{piCongrLeft}\, \pi\, e$ to the pair $(f, g)$ at $e(\text{inr}\, j)$ equals $g(j)$.
Equiv.piCongr definition
: (∀ a, W a) ≃ ∀ b, Z b
Full source
/-- Transport dependent functions through
an equivalence of the base spaces and a family
of equivalences of the matching fibers.
-/
def piCongr : (∀ a, W a) ≃ ∀ b, Z b :=
  (Equiv.piCongrRight h₂).trans (Equiv.piCongrLeft _ h₁)
Equivalence of dependent function types via index and component equivalences
Informal description
Given an equivalence $h_1 : \alpha \simeq \beta$ between index types and a family of equivalences $h_2 : \forall a, W a \simeq Z (h_1 a)$ between dependent types, the equivalence $\text{piCongr}$ constructs an equivalence between the dependent function types $(\forall a, W a)$ and $(\forall b, Z b)$. This is achieved by first applying the component-wise equivalence $\text{piCongrRight}$ using $h_2$, followed by transporting the base type via $\text{piCongrLeft}$ using $h_1$.
Equiv.coe_piCongr_symm theorem
: ((h₁.piCongr h₂).symm : (∀ b, Z b) → ∀ a, W a) = fun f a => (h₂ a).symm (f (h₁ a))
Full source
@[simp]
theorem coe_piCongr_symm : ((h₁.piCongr h₂).symm :
    (∀ b, Z b) → ∀ a, W a) = fun f a => (h₂ a).symm (f (h₁ a)) :=
  rfl
Explicit form of the inverse of $\text{piCongr}$ equivalence
Informal description
Given an equivalence $h_1 : \alpha \simeq \beta$ between index types and a family of equivalences $h_2 : \forall a, W a \simeq Z (h_1 a)$ between dependent types, the inverse of the equivalence $\text{piCongr}$ constructed from $h_1$ and $h_2$ is equal to the function that maps any dependent function $f : \forall b, Z b$ to the function $\lambda a, (h_2 a)^{-1}(f(h_1 a))$. In other words, the inverse equivalence $(h_1.\text{piCongr} h_2)^{-1}$ is explicitly given by $(f : \forall b, Z b) \mapsto \lambda a, (h_2 a)^{-1}(f(h_1 a))$.
Equiv.piCongr_symm_apply theorem
(f : ∀ b, Z b) : (h₁.piCongr h₂).symm f = fun a => (h₂ a).symm (f (h₁ a))
Full source
theorem piCongr_symm_apply (f : ∀ b, Z b) :
    (h₁.piCongr h₂).symm f = fun a => (h₂ a).symm (f (h₁ a)) :=
  rfl
Inverse of Dependent Function Type Equivalence via Component-wise Inverses
Informal description
Given an equivalence $h_1 : \alpha \simeq \beta$ between index types and a family of equivalences $h_2 : \forall a, W a \simeq Z (h_1 a)$ between dependent types, the inverse of the equivalence $\text{piCongr}(h_1, h_2)$ applied to a function $f : \forall b, Z b$ is the function $\lambda a, (h_2 a)^{-1}(f(h_1 a))$. In other words, the inverse equivalence maps $f$ to the function that, at each index $a$, applies the inverse of $h_2 a$ to $f(h_1 a)$.
Equiv.piCongr_apply_apply theorem
(f : ∀ a, W a) (a : α) : h₁.piCongr h₂ f (h₁ a) = h₂ a (f a)
Full source
@[simp]
theorem piCongr_apply_apply (f : ∀ a, W a) (a : α) : h₁.piCongr h₂ f (h₁ a) = h₂ a (f a) := by
  simp only [piCongr, piCongrRight, trans_apply, coe_fn_mk, piCongrLeft_apply_apply, Pi.map_apply]
Evaluation of Transported Dependent Function via Component Equivalence: $(h_1.\text{piCongr}\, h_2\, f)(h_1(a)) = h_2(a)(f(a))$
Informal description
Given an equivalence $h_1 : \alpha \simeq \beta$ between index types and a family of equivalences $h_2 : \forall a, W a \simeq Z (h_1 a)$ between dependent types, for any dependent function $f : \forall a, W a$ and any index $a \in \alpha$, the application of the equivalence-transported function $h_1.\text{piCongr}\, h_2\, f$ at $h_1(a)$ equals $h_2(a)(f(a))$. That is: $$(h_1.\text{piCongr}\, h_2\, f)(h_1(a)) = h_2(a)(f(a)).$$
Equiv.piCongr' definition
: (∀ a, W a) ≃ ∀ b, Z b
Full source
/-- Transport dependent functions through
an equivalence of the base spaces and a family
of equivalences of the matching fibres.
-/
def piCongr' : (∀ a, W a) ≃ ∀ b, Z b :=
  (piCongr h₁.symm fun b => (h₂ b).symm).symm
Equivalence of dependent function types via inverse index and component equivalences
Informal description
Given an equivalence $h_1 : \alpha \simeq \beta$ between index types and a family of equivalences $h_2 : \forall b, W (h_1^{-1} b) \simeq Z b$ between dependent types, the equivalence $\text{piCongr'}$ constructs an equivalence between the dependent function types $(\forall a, W a)$ and $(\forall b, Z b)$. This is achieved by first applying the inverse of $\text{piCongr}$ with $h_1^{-1}$ and component-wise inverses of $h_2$.
Equiv.coe_piCongr' theorem
: (h₁.piCongr' h₂ : (∀ a, W a) → ∀ b, Z b) = fun f b => h₂ b <| f <| h₁.symm b
Full source
@[simp]
theorem coe_piCongr' :
    (h₁.piCongr' h₂ : (∀ a, W a) → ∀ b, Z b) = fun f b => h₂ b <| f <| h₁.symm b :=
  rfl
Forward map of dependent function type equivalence via index and component equivalences
Informal description
Given an equivalence $h_1 : \alpha \simeq \beta$ between index types and a family of equivalences $h_2 : \forall b, W (h_1^{-1} b) \simeq Z b$ between dependent types, the forward function of the equivalence $\text{piCongr'}$ maps any dependent function $f : \forall a, W a$ to the function $\lambda b, h_2 b (f (h_1^{-1} b)) : \forall b, Z b$.
Equiv.piCongr'_apply theorem
(f : ∀ a, W a) : h₁.piCongr' h₂ f = fun b => h₂ b <| f <| h₁.symm b
Full source
theorem piCongr'_apply (f : ∀ a, W a) : h₁.piCongr' h₂ f = fun b => h₂ b <| f <| h₁.symm b :=
  rfl
Application of Dependent Function Type Equivalence via Index and Component Equivalences
Informal description
Given an equivalence $h₁ : α ≃ β$ between index types and a family of equivalences $h₂ : ∀ b, W(h₁^{-1}b) ≃ Z b$ between dependent types, for any dependent function $f : ∀ a, W a$, the application of the equivalence $\text{piCongr'}\ h₁\ h₂$ to $f$ yields the function $λ b, h₂ b (f (h₁^{-1} b))$.
Equiv.piCongr'_symm_apply_symm_apply theorem
(f : ∀ b, Z b) (b : β) : (h₁.piCongr' h₂).symm f (h₁.symm b) = (h₂ b).symm (f b)
Full source
@[simp]
theorem piCongr'_symm_apply_symm_apply (f : ∀ b, Z b) (b : β) :
    (h₁.piCongr' h₂).symm f (h₁.symm b) = (h₂ b).symm (f b) := by
  simp [piCongr', piCongr_apply_apply]
Inverse Evaluation of Transported Dependent Function via Component Equivalence: $(h_1.\text{piCongr'}\, h_2)^{-1}\, f (h_1^{-1}(b)) = h_2(b)^{-1}(f(b))$
Informal description
Given an equivalence $h_1 : \alpha \simeq \beta$ between index types and a family of equivalences $h_2 : \forall b, W(h_1^{-1}b) \simeq Z b$ between dependent types, for any dependent function $f : \forall b, Z b$ and any index $b \in \beta$, the application of the inverse of the equivalence-transported function $(h_1.\text{piCongr'}\, h_2)^{-1}\, f$ at $h_1^{-1}(b)$ equals $h_2(b)^{-1}(f(b))$. That is: $$(h_1.\text{piCongr'}\, h_2)^{-1}\, f (h_1^{-1}(b)) = h_2(b)^{-1}(f(b)).$$
Equiv.piCongrSet definition
{α} {W : α → Sort w} {s t : Set α} (h : s = t) : (∀ i : { i // i ∈ s }, W i) ≃ (∀ i : { i // i ∈ t }, W i)
Full source
/-- Transport dependent functions through an equality of sets. -/
@[simps!] def piCongrSet {α} {W : α → Sort w} {s t : Set α} (h : s = t) :
    (∀ i : {i // i ∈ s}, W i) ≃ (∀ i : {i // i ∈ t}, W i) where
  toFun f i := f ⟨i, h ▸ i.2⟩
  invFun f i := f ⟨i, h.symm ▸ i.2⟩
  left_inv f := rfl
  right_inv f := rfl
Equivalence of dependent function spaces over equal subsets
Informal description
Given a type $\alpha$ and a family of types $W : \alpha \to \text{Sort} w$, for any two subsets $s, t \subseteq \alpha$ that are equal ($s = t$), there is a natural equivalence between the dependent function spaces $\prod_{i \in s} W i$ and $\prod_{i \in t} W i$. The equivalence maps a function $f$ in $\prod_{i \in s} W i$ to the function that takes $i \in t$ and returns $f$ evaluated at the same $i$ (now viewed as an element of $s$ via the equality $s = t$), and similarly for the inverse.
Equiv.semiconj_conj theorem
(f : α₁ → α₁) : Semiconj e f (e.conj f)
Full source
theorem semiconj_conj (f : α₁ → α₁) : Semiconj e f (e.conj f) := fun x => by simp
Semiconjugation of Endomorphisms by an Equivalence
Informal description
For any equivalence $e : \alpha \simeq \beta$ and any endomorphism $f : \alpha \to \alpha$, the function $e$ semiconjugates $f$ to its conjugate $e \circ f \circ e^{-1} : \beta \to \beta$. That is, for all $x \in \alpha$, we have $e(f(x)) = (e \circ f \circ e^{-1})(e(x))$.
Equiv.semiconj₂_conj theorem
: Semiconj₂ e f (e.arrowCongr e.conj f)
Full source
theorem semiconj₂_conj : Semiconj₂ e f (e.arrowCongr e.conj f) := fun x y => by simp [arrowCongr]
Semiconjugacy of Binary Operations under Equivalence Conjugation
Informal description
Given an equivalence $e : \alpha \simeq \beta$ and a binary operation $f : \alpha \to \alpha \to \alpha$, the function $e$ semiconjugates $f$ to the conjugated operation $e.arrowCongr\, e.conj\, f : \beta \to \beta \to \beta$. That is, for all $x, y \in \alpha$, we have: $$ e(f(x, y)) = (e.arrowCongr\, e.conj\, f)(e(x), e(y)) $$
Equiv.instAssociativeCoeForallForallArrowCongr instance
[Std.Associative f] : Std.Associative (e.arrowCongr (e.arrowCongr e) f)
Full source
instance [Std.Associative f] : Std.Associative (e.arrowCongr (e.arrowCongr e) f) :=
  (e.semiconj₂_conj f).isAssociative_right e.surjective
Conjugation Preserves Associativity of Binary Operations
Informal description
Given an equivalence $e : \alpha \simeq \beta$ and an associative binary operation $f : \alpha \to \alpha \to \alpha$, the conjugated operation $e.arrowCongr\, (e.arrowCongr\, e)\, f : \beta \to \beta \to \beta$ is also associative.
Equiv.instIdempotentOpCoeForallForallArrowCongr instance
[Std.IdempotentOp f] : Std.IdempotentOp (e.arrowCongr (e.arrowCongr e) f)
Full source
instance [Std.IdempotentOp f] : Std.IdempotentOp (e.arrowCongr (e.arrowCongr e) f) :=
  (e.semiconj₂_conj f).isIdempotent_right e.surjective
Idempotence Preservation under Equivalence Conjugation
Informal description
Given an equivalence $e : \alpha \simeq \beta$ and an idempotent binary operation $f : \alpha \to \alpha \to \alpha$, the conjugated operation $e.arrowCongr\, (e.arrowCongr\, e)\, f : \beta \to \beta \to \beta$ is also idempotent.
Equiv.ulift_symm_down theorem
{α} (x : α) : (Equiv.ulift.{u, v}.symm x).down = x
Full source
@[simp]
theorem ulift_symm_down {α} (x : α) : (Equiv.ulift.{u, v}.symm x).down = x :=
  rfl
Inverse ULift Equivalence Preserves Down Projection
Informal description
For any element $x$ of type $\alpha$, applying the inverse of the `ULift` equivalence followed by the `down` projection returns $x$ itself, i.e., $\text{down}(e^{-1}(x)) = x$ where $e : \text{ULift} \alpha \simeq \alpha$ is the equivalence.
Function.Injective.swap_apply theorem
[DecidableEq α] [DecidableEq β] {f : α → β} (hf : Function.Injective f) (x y z : α) : Equiv.swap (f x) (f y) (f z) = f (Equiv.swap x y z)
Full source
theorem Function.Injective.swap_apply
    [DecidableEq α] [DecidableEq β] {f : α → β} (hf : Function.Injective f) (x y z : α) :
    Equiv.swap (f x) (f y) (f z) = f (Equiv.swap x y z) := by
  by_cases hx : z = x
  · simp [hx]

  by_cases hy : z = y
  · simp [hy]

  rw [Equiv.swap_apply_of_ne_of_ne hx hy, Equiv.swap_apply_of_ne_of_ne (hf.ne hx) (hf.ne hy)]
Injective Functions Commute with Swap Permutations
Informal description
Let $\alpha$ and $\beta$ be types with decidable equality, and let $f : \alpha \to \beta$ be an injective function. For any elements $x, y, z \in \alpha$, the permutation $\mathrm{swap}(f(x), f(y))$ applied to $f(z)$ equals $f$ applied to $\mathrm{swap}(x, y)(z)$. In other words, the following diagram commutes: $$\mathrm{swap}(f(x), f(y))(f(z)) = f(\mathrm{swap}(x, y)(z))$$
Function.Injective.swap_comp theorem
[DecidableEq α] [DecidableEq β] {f : α → β} (hf : Function.Injective f) (x y : α) : Equiv.swap (f x) (f y) ∘ f = f ∘ Equiv.swap x y
Full source
theorem Function.Injective.swap_comp
    [DecidableEq α] [DecidableEq β] {f : α → β} (hf : Function.Injective f) (x y : α) :
    Equiv.swapEquiv.swap (f x) (f y) ∘ f = f ∘ Equiv.swap x y :=
  funext fun _ => hf.swap_apply _ _ _
Commutativity of Injective Functions with Swap Permutations
Informal description
Let $\alpha$ and $\beta$ be types with decidable equality, and let $f : \alpha \to \beta$ be an injective function. For any elements $x, y \in \alpha$, the composition of the permutation $\mathrm{swap}(f(x), f(y))$ with $f$ equals the composition of $f$ with the permutation $\mathrm{swap}(x, y)$. In other words, the following diagram commutes: $$ \mathrm{swap}(f(x), f(y)) \circ f = f \circ \mathrm{swap}(x, y) $$
equivOfSubsingletonOfSubsingleton definition
[Subsingleton α] [Subsingleton β] (f : α → β) (g : β → α) : α ≃ β
Full source
/-- To give an equivalence between two subsingleton types, it is sufficient to give any two
    functions between them. -/
def equivOfSubsingletonOfSubsingleton [Subsingleton α] [Subsingleton β] (f : α → β) (g : β → α) :
    α ≃ β where
  toFun := f
  invFun := g
  left_inv _ := Subsingleton.elim _ _
  right_inv _ := Subsingleton.elim _ _
Equivalence between subsingleton types
Informal description
Given two subsingleton types $\alpha$ and $\beta$ (i.e., types with at most one element), any pair of functions $f : \alpha \to \beta$ and $g : \beta \to \alpha$ defines an equivalence (bijection) between $\alpha$ and $\beta$.
Equiv.punitOfNonemptyOfSubsingleton definition
[h : Nonempty α] [Subsingleton α] : α ≃ PUnit
Full source
/-- A nonempty subsingleton type is (noncomputably) equivalent to `PUnit`. -/
noncomputable def Equiv.punitOfNonemptyOfSubsingleton [h : Nonempty α] [Subsingleton α] :
    α ≃ PUnit :=
  equivOfSubsingletonOfSubsingleton (fun _ => PUnit.unit) fun _ => h.some
Equivalence between a nonempty subsingleton type and the unit type
Informal description
For any nonempty subsingleton type $\alpha$ (i.e., a type with exactly one element), there exists a (noncomputable) equivalence between $\alpha$ and the unit type `PUnit`. This equivalence maps every element of $\alpha$ to the unique element `PUnit.unit` and its inverse maps `PUnit.unit` back to the unique element of $\alpha$.
uniqueUniqueEquiv definition
: Unique (Unique α) ≃ Unique α
Full source
/-- `Unique (Unique α)` is equivalent to `Unique α`. -/
def uniqueUniqueEquiv : UniqueUnique (Unique α) ≃ Unique α :=
  equivOfSubsingletonOfSubsingleton (fun h => h.default) fun h =>
    { default := h, uniq := fun _ => Subsingleton.elim _ _ }
Equivalence between `Unique (Unique α)` and `Unique α`
Informal description
The equivalence between the type `Unique (Unique α)` (the type of unique instances of `Unique α`) and `Unique α` itself. This states that having a unique instance of `Unique α` is equivalent to having a unique instance of `α`.
uniqueEquivEquivUnique definition
(α : Sort u) (β : Sort v) [Unique β] : Unique α ≃ (α ≃ β)
Full source
/-- If `Unique β`, then `Unique α` is equivalent to `α ≃ β`. -/
def uniqueEquivEquivUnique (α : Sort u) (β : Sort v) [Unique β] : UniqueUnique α ≃ (α ≃ β) :=
  equivOfSubsingletonOfSubsingleton (fun _ => Equiv.ofUnique _ _) Equiv.unique
Equivalence between uniqueness and bijection to a unique type
Informal description
Given a type $\beta$ with a unique element, there is an equivalence between the type `Unique α` (the type of unique instances of $\alpha$) and the type of equivalences $\alpha \simeq \beta$. This means that having a unique element in $\alpha$ is equivalent to having a bijection between $\alpha$ and $\beta$ when $\beta$ has exactly one element.
Function.update_comp_equiv theorem
[DecidableEq α'] [DecidableEq α] (f : α → β) (g : α' ≃ α) (a : α) (v : β) : update f a v ∘ g = update (f ∘ g) (g.symm a) v
Full source
theorem update_comp_equiv [DecidableEq α'] [DecidableEq α] (f : α → β)
    (g : α' ≃ α) (a : α) (v : β) :
    updateupdate f a v ∘ g = update (f ∘ g) (g.symm a) v := by
  rw [← update_comp_eq_of_injective _ g.injective, g.apply_symm_apply]
Function Update Commutes with Composition via Equivalence
Informal description
Let $f : \alpha \to \beta$ be a function, $g : \alpha' \simeq \alpha$ an equivalence between types $\alpha'$ and $\alpha$, $a \in \alpha$, and $v \in \beta$. Then the composition of the updated function $\text{update } f \, a \, v$ with $g$ is equal to the function obtained by updating $f \circ g$ at $g^{-1}(a)$ with $v$, i.e., \[ (\text{update } f \, a \, v) \circ g = \text{update } (f \circ g) \, (g^{-1}(a)) \, v. \]
Function.update_apply_equiv_apply theorem
[DecidableEq α'] [DecidableEq α] (f : α → β) (g : α' ≃ α) (a : α) (v : β) (a' : α') : update f a v (g a') = update (f ∘ g) (g.symm a) v a'
Full source
theorem update_apply_equiv_apply [DecidableEq α'] [DecidableEq α] (f : α → β)
    (g : α' ≃ α) (a : α) (v : β) (a' : α') : update f a v (g a') = update (f ∘ g) (g.symm a) v a' :=
  congr_fun (update_comp_equiv f g a v) a'
Equality of Updated Function Values via Equivalence
Informal description
Let $f : \alpha \to \beta$ be a function, $g : \alpha' \simeq \alpha$ an equivalence between types $\alpha'$ and $\alpha$, $a \in \alpha$, $v \in \beta$, and $a' \in \alpha'$. Then the value of the updated function $\text{update } f \, a \, v$ at $g(a')$ is equal to the value of the updated function $\text{update } (f \circ g) \, g^{-1}(a) \, v$ at $a'$, i.e., \[ \text{update } f \, a \, v \, (g(a')) = \text{update } (f \circ g) \, g^{-1}(a) \, v \, a'. \]
Function.piCongrLeft'_update theorem
[DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β) (f : ∀ a, P a) (b : β) (x : P (e.symm b)) : e.piCongrLeft' P (update f (e.symm b) x) = update (e.piCongrLeft' P f) b x
Full source
theorem piCongrLeft'_update [DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β)
    (f : ∀ a, P a) (b : β) (x : P (e.symm b)) :
    e.piCongrLeft' P (update f (e.symm b) x) = update (e.piCongrLeft' P f) b x := by
  ext b'
  rcases eq_or_ne b' b with (rfl | h) <;> simp_all
Compatibility of Dependent Function Update with Equivalence Transport
Informal description
Let $P : \alpha \to \text{Sort}*$ be a family of types, $e : \alpha \simeq \beta$ an equivalence between types $\alpha$ and $\beta$, $f : \forall a, P a$ a dependent function, $b \in \beta$, and $x \in P(e^{-1}b)$. Then the equivalence $e.\text{piCongrLeft}' P$ applied to the updated function $\text{update } f \, (e^{-1}b) \, x$ is equal to the updated function $\text{update } (e.\text{piCongrLeft}' P f) \, b \, x$.
Function.piCongrLeft'_symm_update theorem
[DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β) (f : ∀ b, P (e.symm b)) (b : β) (x : P (e.symm b)) : (e.piCongrLeft' P).symm (update f b x) = update ((e.piCongrLeft' P).symm f) (e.symm b) x
Full source
theorem piCongrLeft'_symm_update [DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β)
    (f : ∀ b, P (e.symm b)) (b : β) (x : P (e.symm b)) :
    (e.piCongrLeft' P).symm (update f b x) = update ((e.piCongrLeft' P).symm f) (e.symm b) x := by
  simp [(e.piCongrLeft' P).symm_apply_eq, piCongrLeft'_update]
Inverse Equivalence Commutes with Dependent Function Update: $(e.\text{piCongrLeft}' P)^{-1}(\text{update } f \, b \, x) = \text{update } \big((e.\text{piCongrLeft}' P)^{-1} f\big) \, (e^{-1}b) \, x$
Informal description
Let $P : \alpha \to \text{Type}$ be a family of types, $e : \alpha \simeq \beta$ an equivalence between types $\alpha$ and $\beta$, $f : \forall b, P(e^{-1}b)$ a dependent function, $b \in \beta$, and $x \in P(e^{-1}b)$. Then the inverse of the equivalence $e.\text{piCongrLeft}' P$ applied to the updated function $\text{update } f \, b \, x$ is equal to the updated function $\text{update } \big((e.\text{piCongrLeft}' P)^{-1} f\big) \, (e^{-1}b) \, x$.