doc-next-gen

Mathlib.Logic.Equiv.Sum

Module docstring

{"# Equivalence between sum types

In this file we continue the work on equivalences begun in Mathlib/Logic/Equiv/Defs.lean, defining

  • canonical isomorphisms between various types: e.g.,

    • Equiv.sumEquivSigmaBool is the canonical equivalence between the sum of two types α ⊕ β and the sigma-type Σ b, bif b then β else α;

    • Equiv.prodSumDistrib : α × (β ⊕ γ) ≃ (α × β) ⊕ (α × γ) shows that type product and type sum satisfy the distributive law up to a canonical equivalence;

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.psumEquivSum definition
(α β) : α ⊕' β ≃ α ⊕ β
Full source
/-- `PSum` is equivalent to `Sum`. -/
def psumEquivSum (α β) : α ⊕' βα ⊕' β ≃ α ⊕ β where
  toFun s := PSum.casesOn s inl inr
  invFun := Sum.elim PSum.inl PSum.inr
  left_inv s := by cases s <;> rfl
  right_inv s := by cases s <;> rfl
Equivalence between parallel sum and sum types
Informal description
The equivalence between the `PSum` (parallel sum) type and the regular `Sum` type for any two types $\alpha$ and $\beta$. The forward direction maps `PSum.inl` to `Sum.inl` and `PSum.inr` to `Sum.inr`, while the inverse direction maps `Sum.inl` to `PSum.inl` and `Sum.inr` to `PSum.inr`. Both compositions of these mappings yield the identity function.
Equiv.sumCongr definition
{α₁ α₂ β₁ β₂} (ea : α₁ ≃ α₂) (eb : β₁ ≃ β₂) : α₁ ⊕ β₁ ≃ α₂ ⊕ β₂
Full source
/-- If `α ≃ α'` and `β ≃ β'`, then `α ⊕ β ≃ α' ⊕ β'`. This is `Sum.map` as an equivalence. -/
@[simps apply]
def sumCongr {α₁ α₂ β₁ β₂} (ea : α₁ ≃ α₂) (eb : β₁ ≃ β₂) : α₁ ⊕ β₁α₁ ⊕ β₁ ≃ α₂ ⊕ β₂ :=
  ⟨Sum.map ea eb, Sum.map ea.symm eb.symm, fun x => by simp, fun x => by simp⟩
Equivalence of sum types under componentwise equivalences
Informal description
Given equivalences $e_\alpha : \alpha_1 \simeq \alpha_2$ and $e_\beta : \beta_1 \simeq \beta_2$, there is an equivalence $\alpha_1 \oplus \beta_1 \simeq \alpha_2 \oplus \beta_2$ between the sum types, where the forward map applies $e_\alpha$ to left components and $e_\beta$ to right components, and the inverse map applies the inverses $e_\alpha^{-1}$ and $e_\beta^{-1}$ similarly.
Equiv.sumCongr_trans theorem
{α₁ α₂ β₁ β₂ γ₁ γ₂} (e : α₁ ≃ β₁) (f : α₂ ≃ β₂) (g : β₁ ≃ γ₁) (h : β₂ ≃ γ₂) : (Equiv.sumCongr e f).trans (Equiv.sumCongr g h) = Equiv.sumCongr (e.trans g) (f.trans h)
Full source
@[simp]
theorem sumCongr_trans {α₁ α₂ β₁ β₂ γ₁ γ₂} (e : α₁ ≃ β₁) (f : α₂ ≃ β₂) (g : β₁ ≃ γ₁) (h : β₂ ≃ γ₂) :
    (Equiv.sumCongr e f).trans (Equiv.sumCongr g h) = Equiv.sumCongr (e.trans g) (f.trans h) := by
  ext i
  cases i <;> rfl
Composition of Sum Equivalences via Componentwise Composition
Informal description
Given equivalences $e : \alpha_1 \simeq \beta_1$, $f : \alpha_2 \simeq \beta_2$, $g : \beta_1 \simeq \gamma_1$, and $h : \beta_2 \simeq \gamma_2$, the composition of the sum equivalences $\text{sumCongr}(e, f)$ and $\text{sumCongr}(g, h)$ is equal to the sum equivalence of the composed equivalences $\text{sumCongr}(e \circ g, f \circ h)$. In other words, the following diagram commutes: $$(\alpha_1 \oplus \alpha_2 \simeq \beta_1 \oplus \beta_2) \circ (\beta_1 \oplus \beta_2 \simeq \gamma_1 \oplus \gamma_2) = \alpha_1 \oplus \alpha_2 \simeq \gamma_1 \oplus \gamma_2$$ where all arrows represent equivalences.
Equiv.sumCongr_symm theorem
{α β γ δ} (e : α ≃ β) (f : γ ≃ δ) : (Equiv.sumCongr e f).symm = Equiv.sumCongr e.symm f.symm
Full source
@[simp]
theorem sumCongr_symm {α β γ δ} (e : α ≃ β) (f : γ ≃ δ) :
    (Equiv.sumCongr e f).symm = Equiv.sumCongr e.symm f.symm :=
  rfl
Inverse of Sum Equivalence is Sum of Inverses
Informal description
Given equivalences $e : \alpha \simeq \beta$ and $f : \gamma \simeq \delta$, the inverse of the sum equivalence $\text{sumCongr}(e, f) : \alpha \oplus \gamma \simeq \beta \oplus \delta$ is equal to the sum equivalence of the inverses, i.e., $\text{sumCongr}(e^{-1}, f^{-1})$.
Equiv.sumCongr_refl theorem
{α β} : Equiv.sumCongr (Equiv.refl α) (Equiv.refl β) = Equiv.refl (α ⊕ β)
Full source
@[simp]
theorem sumCongr_refl {α β} :
    Equiv.sumCongr (Equiv.refl α) (Equiv.refl β) = Equiv.refl (α ⊕ β) := by
  ext i
  cases i <;> rfl
Sum of Identity Equivalences is Identity on Sum Type
Informal description
For any types $\alpha$ and $\beta$, the equivalence $\text{sumCongr}(\text{refl}(\alpha), \text{refl}(\beta))$ between the sum type $\alpha \oplus \beta$ and itself is equal to the identity equivalence $\text{refl}(\alpha \oplus \beta)$.
Equiv.psumCongr definition
(e₁ : α ≃ β) (e₂ : γ ≃ δ) : α ⊕' γ ≃ β ⊕' δ
Full source
/-- If `α ≃ α'` and `β ≃ β'`, then `α ⊕' β ≃ α' ⊕' β'`. -/
def psumCongr (e₁ : α ≃ β) (e₂ : γ ≃ δ) : α ⊕' γα ⊕' γ ≃ β ⊕' δ where
  toFun x := PSum.casesOn x (PSum.inlPSum.inl ∘ e₁) (PSum.inrPSum.inr ∘ e₂)
  invFun x := PSum.casesOn x (PSum.inlPSum.inl ∘ e₁.symm) (PSum.inrPSum.inr ∘ e₂.symm)
  left_inv := by rintro (x | x) <;> simp
  right_inv := by rintro (x | x) <;> simp
Equivalence of sum types under component-wise equivalences
Informal description
Given equivalences $e₁ : α ≃ β$ and $e₂ : γ ≃ δ$, the function constructs an equivalence between the sum types $α ⊕' γ$ and $β ⊕' δ$ by applying $e₁$ to left components and $e₂$ to right components.
Equiv.psumSum definition
{α₂ β₂} (ea : α₁ ≃ α₂) (eb : β₁ ≃ β₂) : α₁ ⊕' β₁ ≃ α₂ ⊕ β₂
Full source
/-- Combine two `Equiv`s using `PSum` in the domain and `Sum` in the codomain. -/
def psumSum {α₂ β₂} (ea : α₁ ≃ α₂) (eb : β₁ ≃ β₂) :
    α₁ ⊕' β₁α₁ ⊕' β₁ ≃ α₂ ⊕ β₂ :=
  (ea.psumCongr eb).trans (psumEquivSum _ _)
Equivalence between parallel sum and regular sum under component-wise equivalences
Informal description
Given equivalences $e_a : α₁ ≃ α₂$ and $e_b : β₁ ≃ β₂$, the function constructs an equivalence between the parallel sum type $α₁ ⊕' β₁$ and the regular sum type $α₂ ⊕ β₂$ by first applying the component-wise equivalence $e_a.psumCongr e_b$ and then composing with the canonical equivalence between parallel sum and regular sum types.
Equiv.sumPSum definition
{α₁ β₁} (ea : α₁ ≃ α₂) (eb : β₁ ≃ β₂) : α₁ ⊕ β₁ ≃ α₂ ⊕' β₂
Full source
/-- Combine two `Equiv`s using `Sum` in the domain and `PSum` in the codomain. -/
def sumPSum {α₁ β₁} (ea : α₁ ≃ α₂) (eb : β₁ ≃ β₂) :
    α₁ ⊕ β₁α₁ ⊕ β₁ ≃ α₂ ⊕' β₂ :=
  (ea.symm.psumSum eb.symm).symm
Equivalence between sum and parallel sum under component-wise equivalences
Informal description
Given equivalences $e_a : α₁ ≃ α₂$ and $e_b : β₁ ≃ β₂$, the function constructs an equivalence between the sum type $α₁ ⊕ β₁$ and the parallel sum type $α₂ ⊕' β₂$ by first taking the symmetric equivalences $e_a^{-1} : α₂ ≃ α₁$ and $e_b^{-1} : β₂ ≃ β₁$, constructing an equivalence between $α₂ ⊕' β₂$ and $α₁ ⊕ β₁$ via `psumSum`, and then taking the symmetric equivalence again.
Equiv.subtypeSum definition
{α β} {p : α ⊕ β → Prop} : { c // p c } ≃ { a // p (Sum.inl a) } ⊕ { b // p (Sum.inr b) }
Full source
/-- A subtype of a sum is equivalent to a sum of subtypes. -/
def subtypeSum {α β} {p : α ⊕ β → Prop} :
    {c // p c}{c // p c} ≃ {a // p (Sum.inl a)} ⊕ {b // p (Sum.inr b)} where
  toFun
    | ⟨.inl a, h⟩ => .inl ⟨a, h⟩
    | ⟨.inr b, h⟩ => .inr ⟨b, h⟩
  invFun
    | .inl a => ⟨.inl a, a.2⟩
    | .inr b => ⟨.inr b, b.2⟩
  left_inv := by rintro ⟨a | b, h⟩ <;> rfl
  right_inv := by rintro (a | b) <;> rfl
Subtype of a sum as a sum of subtypes
Informal description
Given types $\alpha$ and $\beta$ and a predicate $p$ on $\alpha \oplus \beta$, the subtype $\{c \mid p(c)\}$ is equivalent to the sum of subtypes $\{a \mid p(\text{Sum.inl } a)\} \oplus \{b \mid p(\text{Sum.inr } b)\}$. The equivalence maps an element $\langle \text{Sum.inl } a, h \rangle$ to $\text{Sum.inl } \langle a, h \rangle$ and similarly for $\text{Sum.inr } b$, with the inverse mapping in the reverse direction.
Equiv.Perm.sumCongr abbrev
{α β} (ea : Equiv.Perm α) (eb : Equiv.Perm β) : Equiv.Perm (α ⊕ β)
Full source
/-- Combine a permutation of `α` and of `β` into a permutation of `α ⊕ β`. -/
abbrev sumCongr {α β} (ea : Equiv.Perm α) (eb : Equiv.Perm β) : Equiv.Perm (α ⊕ β) :=
  Equiv.sumCongr ea eb
Permutation of Sum Types via Componentwise Permutations
Informal description
Given permutations $e_\alpha$ of a type $\alpha$ and $e_\beta$ of a type $\beta$, there exists a permutation of the sum type $\alpha \oplus \beta$ obtained by applying $e_\alpha$ to left components and $e_\beta$ to right components.
Equiv.Perm.sumCongr_apply theorem
{α β} (ea : Equiv.Perm α) (eb : Equiv.Perm β) (x : α ⊕ β) : sumCongr ea eb x = Sum.map (⇑ea) (⇑eb) x
Full source
@[simp]
theorem sumCongr_apply {α β} (ea : Equiv.Perm α) (eb : Equiv.Perm β) (x : α ⊕ β) :
    sumCongr ea eb x = Sum.map (⇑ea) (⇑eb) x :=
  Equiv.sumCongr_apply ea eb x
Action of Sum Permutation via Componentwise Permutations
Informal description
Given permutations $e_\alpha$ of a type $\alpha$ and $e_\beta$ of a type $\beta$, the application of the permutation $\text{sumCongr}(e_\alpha, e_\beta)$ to an element $x$ of the sum type $\alpha \oplus \beta$ is equal to applying $\text{Sum.map}$ with $e_\alpha$ and $e_\beta$ to $x$.
Equiv.Perm.sumCongr_trans theorem
{α β} (e : Equiv.Perm α) (f : Equiv.Perm β) (g : Equiv.Perm α) (h : Equiv.Perm β) : (sumCongr e f).trans (sumCongr g h) = sumCongr (e.trans g) (f.trans h)
Full source
theorem sumCongr_trans {α β} (e : Equiv.Perm α) (f : Equiv.Perm β) (g : Equiv.Perm α)
    (h : Equiv.Perm β) : (sumCongr e f).trans (sumCongr g h) = sumCongr (e.trans g) (f.trans h) :=
  Equiv.sumCongr_trans e f g h
Composition of Sum Permutations via Componentwise Composition
Informal description
For any permutations $e, g$ of a type $\alpha$ and $f, h$ of a type $\beta$, the composition of the sum permutations $\text{sumCongr}(e, f)$ and $\text{sumCongr}(g, h)$ is equal to the sum permutation of the composed permutations $\text{sumCongr}(e \circ g, f \circ h)$. In other words, the following diagram commutes: $$(\alpha \oplus \beta \simeq \alpha \oplus \beta) \circ (\alpha \oplus \beta \simeq \alpha \oplus \beta) = \alpha \oplus \beta \simeq \alpha \oplus \beta$$ where all arrows represent permutations.
Equiv.Perm.sumCongr_symm theorem
{α β} (e : Equiv.Perm α) (f : Equiv.Perm β) : (sumCongr e f).symm = sumCongr e.symm f.symm
Full source
theorem sumCongr_symm {α β} (e : Equiv.Perm α) (f : Equiv.Perm β) :
    (sumCongr e f).symm = sumCongr e.symm f.symm :=
  Equiv.sumCongr_symm e f
Inverse of Sum Permutation Equals Sum of Inverses
Informal description
For any permutations $e$ of type $\alpha$ and $f$ of type $\beta$, the inverse of the permutation $\text{sumCongr}(e, f)$ of the sum type $\alpha \oplus \beta$ is equal to the permutation obtained by applying the inverses componentwise, i.e., $\text{sumCongr}(e^{-1}, f^{-1})$.
Equiv.Perm.sumCongr_refl theorem
{α β} : sumCongr (Equiv.refl α) (Equiv.refl β) = Equiv.refl (α ⊕ β)
Full source
theorem sumCongr_refl {α β} : sumCongr (Equiv.refl α) (Equiv.refl β) = Equiv.refl (α ⊕ β) :=
  Equiv.sumCongr_refl
Identity Permutation on Sum Type via Componentwise Identities
Informal description
For any types $\alpha$ and $\beta$, the permutation $\text{sumCongr}(\text{refl}(\alpha), \text{refl}(\beta))$ of the sum type $\alpha \oplus \beta$ is equal to the identity permutation $\text{refl}(\alpha \oplus \beta)$.
Equiv.boolEquivPUnitSumPUnit definition
: Bool ≃ PUnit.{u + 1} ⊕ PUnit.{v + 1}
Full source
/-- `Bool` is equivalent the sum of two `PUnit`s. -/
def boolEquivPUnitSumPUnit : BoolBool ≃ PUnit.{u + 1} ⊕ PUnit.{v + 1} :=
  ⟨fun b => b.casesOn (inl PUnit.unit) (inr PUnit.unit) , Sum.elim (fun _ => false) fun _ => true,
    fun b => by cases b <;> rfl, fun s => by rcases s with (⟨⟨⟩⟩ | ⟨⟨⟩⟩) <;> rfl⟩
Equivalence between Boolean and sum of unit types
Informal description
The type `Bool` is equivalent to the sum of two unit types `PUnit ⊕ PUnit`. The equivalence is given by mapping `false` to the left summand and `true` to the right summand, with the inverse mapping the left summand to `false` and the right summand to `true`.
Equiv.sumComm definition
(α β) : α ⊕ β ≃ β ⊕ α
Full source
/-- Sum of types is commutative up to an equivalence. This is `Sum.swap` as an equivalence. -/
@[simps -fullyApplied apply]
def sumComm (α β) : α ⊕ βα ⊕ β ≃ β ⊕ α :=
  ⟨Sum.swap, Sum.swap, Sum.swap_swap, Sum.swap_swap⟩
Commutativity of sum types
Informal description
The equivalence `Equiv.sumComm α β` provides a canonical bijection between the sum types `α ⊕ β` and `β ⊕ α`, realized by the function `Sum.swap` which swaps the order of the summands. This equivalence is its own inverse, as applying `Sum.swap` twice returns the original sum type.
Equiv.sumComm_symm theorem
(α β) : (sumComm α β).symm = sumComm β α
Full source
@[simp]
theorem sumComm_symm (α β) : (sumComm α β).symm = sumComm β α :=
  rfl
Inverse of Sum Commutativity Equivalence is Commutativity Equivalence in Reverse
Informal description
For any types $\alpha$ and $\beta$, the inverse of the equivalence $\alpha \oplus \beta \simeq \beta \oplus \alpha$ (given by swapping the summands) is equal to the equivalence $\beta \oplus \alpha \simeq \alpha \oplus \beta$ (also given by swapping the summands).
Equiv.sumAssoc definition
(α β γ) : (α ⊕ β) ⊕ γ ≃ α ⊕ (β ⊕ γ)
Full source
/-- Sum of types is associative up to an equivalence. -/
def sumAssoc (α β γ) : (α ⊕ β) ⊕ γ(α ⊕ β) ⊕ γ ≃ α ⊕ (β ⊕ γ) :=
  ⟨Sum.elim (Sum.elim Sum.inl (Sum.inr ∘ Sum.inl)) (Sum.inr ∘ Sum.inr),
    Sum.elim (Sum.inl ∘ Sum.inl) <| Sum.elim (Sum.inl ∘ Sum.inr) Sum.inr,
      by rintro (⟨_ | _⟩ | _) <;> rfl, by
    rintro (_ | ⟨_ | _⟩) <;> rfl⟩
Associativity of sum types
Informal description
The equivalence `Equiv.sumAssoc α β γ` provides a canonical bijection between the sum types `(α ⊕ β) ⊕ γ` and `α ⊕ (β ⊕ γ)`, demonstrating that sum of types is associative up to equivalence. The bijection is constructed by appropriately nesting the left and right injections of the sum types.
Equiv.sumAssoc_apply_inl_inl theorem
{α β γ} (a) : sumAssoc α β γ (inl (inl a)) = inl a
Full source
@[simp]
theorem sumAssoc_apply_inl_inl {α β γ} (a) : sumAssoc α β γ (inl (inl a)) = inl a :=
  rfl
Associativity Equivalence Preserves Leftmost Injection
Informal description
For any types $\alpha$, $\beta$, $\gamma$ and any element $a \in \alpha$, the associativity equivalence maps $\text{inl}(\text{inl}(a))$ in $(\alpha \oplus \beta) \oplus \gamma$ to $\text{inl}(a)$ in $\alpha \oplus (\beta \oplus \gamma)$. That is, the equivalence satisfies $f(\text{inl}(\text{inl}(a))) = \text{inl}(a)$.
Equiv.sumAssoc_apply_inl_inr theorem
{α β γ} (b) : sumAssoc α β γ (inl (inr b)) = inr (inl b)
Full source
@[simp]
theorem sumAssoc_apply_inl_inr {α β γ} (b) : sumAssoc α β γ (inl (inr b)) = inr (inl b) :=
  rfl
Associativity Equivalence Maps Left-Right Injection to Right-Left Injection
Informal description
For any types $\alpha$, $\beta$, $\gamma$ and any element $b \in \beta$, the associativity equivalence maps $\text{inl}(\text{inr}(b))$ in $(\alpha \oplus \beta) \oplus \gamma$ to $\text{inr}(\text{inl}(b))$ in $\alpha \oplus (\beta \oplus \gamma)$. That is, the equivalence satisfies $f(\text{inl}(\text{inr}(b))) = \text{inr}(\text{inl}(b))$.
Equiv.sumAssoc_apply_inr theorem
{α β γ} (c) : sumAssoc α β γ (inr c) = inr (inr c)
Full source
@[simp]
theorem sumAssoc_apply_inr {α β γ} (c) : sumAssoc α β γ (inr c) = inr (inr c) :=
  rfl
Associativity Equivalence Maps Right Injection to Nested Right Injection
Informal description
For any types $\alpha$, $\beta$, $\gamma$ and any element $c \in \gamma$, the associativity equivalence maps $\text{inr}(c)$ in $(\alpha \oplus \beta) \oplus \gamma$ to $\text{inr}(\text{inr}(c))$ in $\alpha \oplus (\beta \oplus \gamma)$. That is, the equivalence satisfies $f(\text{inr}(c)) = \text{inr}(\text{inr}(c))$.
Equiv.sumAssoc_symm_apply_inl theorem
{α β γ} (a) : (sumAssoc α β γ).symm (inl a) = inl (inl a)
Full source
@[simp]
theorem sumAssoc_symm_apply_inl {α β γ} (a) : (sumAssoc α β γ).symm (inl a) = inl (inl a) :=
  rfl
Inverse Associativity Equivalence on Left Injection
Informal description
For any types $\alpha, \beta, \gamma$ and any element $a \in \alpha$, the inverse of the associativity equivalence applied to $\text{inl}(a)$ equals $\text{inl}(\text{inl}(a))$. That is, $(\alpha \oplus \beta \oplus \gamma)^{-1}(\text{inl}(a)) = \text{inl}(\text{inl}(a))$.
Equiv.sumAssoc_symm_apply_inr_inl theorem
{α β γ} (b) : (sumAssoc α β γ).symm (inr (inl b)) = inl (inr b)
Full source
@[simp]
theorem sumAssoc_symm_apply_inr_inl {α β γ} (b) :
    (sumAssoc α β γ).symm (inr (inl b)) = inl (inr b) :=
  rfl
Inverse Associativity Equivalence Maps Nested Right-Left Injection to Left-Right Injection
Informal description
For any types $\alpha, \beta, \gamma$ and any element $b \in \beta$, the inverse of the associativity equivalence $\text{sumAssoc}\ \alpha\ \beta\ \gamma$ applied to $\text{inr}(\text{inl}(b))$ equals $\text{inl}(\text{inr}(b))$.
Equiv.sumAssoc_symm_apply_inr_inr theorem
{α β γ} (c) : (sumAssoc α β γ).symm (inr (inr c)) = inr c
Full source
@[simp]
theorem sumAssoc_symm_apply_inr_inr {α β γ} (c) : (sumAssoc α β γ).symm (inr (inr c)) = inr c :=
  rfl
Inverse Associativity Equivalence on Nested Right Injection
Informal description
For any types $\alpha, \beta, \gamma$ and any element $c \in \gamma$, the inverse of the associativity equivalence applied to $\text{inr}(\text{inr}(c))$ equals $\text{inr}(c)$. That is, $(\text{sumAssoc}\ \alpha\ \beta\ \gamma)^{-1}(\text{inr}(\text{inr}(c))) = \text{inr}(c)$.
Equiv.sumSumSumComm definition
(α β γ δ) : (α ⊕ β) ⊕ γ ⊕ δ ≃ (α ⊕ γ) ⊕ β ⊕ δ
Full source
/-- Four-way commutativity of `sum`. The name matches `add_add_add_comm`. -/
@[simps apply]
def sumSumSumComm (α β γ δ) : (α ⊕ β) ⊕ γ ⊕ δ(α ⊕ β) ⊕ γ ⊕ δ ≃ (α ⊕ γ) ⊕ β ⊕ δ where
  toFun :=
    (sumAssoc (α ⊕ γ) β δ) ∘ (Sum.map (sumAssoc α γ β).symm (@id δ))
      ∘ (Sum.map (Sum.map (@id α) (sumComm β γ)) (@id δ))
      ∘ (Sum.map (sumAssoc α β γ) (@id δ))
      ∘ (sumAssoc (α ⊕ β) γ δ).symm
  invFun :=
    (sumAssoc (α ⊕ β) γ δ) ∘ (Sum.map (sumAssoc α β γ).symm (@id δ))
      ∘ (Sum.map (Sum.map (@id α) (sumComm β γ).symm) (@id δ))
      ∘ (Sum.map (sumAssoc α γ β) (@id δ))
      ∘ (sumAssoc (α ⊕ γ) β δ).symm
  left_inv x := by rcases x with ((a | b) | (c | d)) <;> simp
  right_inv x := by rcases x with ((a | c) | (b | d)) <;> simp
Four-way commutativity of sum types
Informal description
The equivalence `Equiv.sumSumSumComm α β γ δ` provides a canonical bijection between the sum types `(α ⊕ β) ⊕ γ ⊕ δ` and `(α ⊕ γ) ⊕ β ⊕ δ`. This demonstrates a four-way commutativity property of sum types, analogous to the commutativity of addition in arithmetic. The bijection is constructed by composing several simpler equivalences involving associativity (`sumAssoc`) and commutativity (`sumComm`) of sum types, appropriately rearranging the components.
Equiv.sumSumSumComm_symm theorem
(α β γ δ) : (sumSumSumComm α β γ δ).symm = sumSumSumComm α γ β δ
Full source
@[simp]
theorem sumSumSumComm_symm (α β γ δ) : (sumSumSumComm α β γ δ).symm = sumSumSumComm α γ β δ :=
  rfl
Inverse of Four-Way Sum Commutativity Equivalence
Informal description
For any types $\alpha, \beta, \gamma, \delta$, the inverse of the four-way sum commutativity equivalence $\text{sumSumSumComm}_{\alpha\beta\gamma\delta}$ is equal to the four-way sum commutativity equivalence $\text{sumSumSumComm}_{\alpha\gamma\beta\delta}$.
Equiv.sumEmpty definition
(α β) [IsEmpty β] : α ⊕ β ≃ α
Full source
/-- Sum with `IsEmpty` is equivalent to the original type. -/
@[simps symm_apply]
def sumEmpty (α β) [IsEmpty β] : α ⊕ βα ⊕ β ≃ α where
  toFun := Sum.elim id isEmptyElim
  invFun := inl
  left_inv s := by
    rcases s with (_ | x)
    · rfl
    · exact isEmptyElim x
  right_inv _ := rfl
Equivalence between sum type and left component when right is empty
Informal description
For any types $\alpha$ and $\beta$ where $\beta$ is empty (i.e., `IsEmpty β` holds), the sum type $\alpha \oplus \beta$ is equivalent to $\alpha$. The equivalence is given by the function that maps $\text{inl}(a)$ to $a$ for any $a \in \alpha$ and is undefined on $\text{inr}(b)$ (since $\beta$ is empty).
Equiv.sumEmpty_apply_inl theorem
{α β} [IsEmpty β] (a : α) : sumEmpty α β (Sum.inl a) = a
Full source
@[simp]
theorem sumEmpty_apply_inl {α β} [IsEmpty β] (a : α) : sumEmpty α β (Sum.inl a) = a :=
  rfl
Application of sum-empty equivalence to left injection
Informal description
For any types $\alpha$ and $\beta$ where $\beta$ is empty, the equivalence `sumEmpty α β` maps the left injection $\text{inl}(a)$ of an element $a \in \alpha$ to $a$ itself.
Equiv.emptySum definition
(α β) [IsEmpty α] : α ⊕ β ≃ β
Full source
/-- The sum of `IsEmpty` with any type is equivalent to that type. -/
@[simps! symm_apply]
def emptySum (α β) [IsEmpty α] : α ⊕ βα ⊕ β ≃ β :=
  (sumComm _ _).trans <| sumEmpty _ _
Equivalence between sum type and right component when left is empty
Informal description
For any types $\alpha$ and $\beta$ where $\alpha$ is empty (i.e., `IsEmpty α` holds), the sum type $\alpha \oplus \beta$ is equivalent to $\beta$. The equivalence is constructed by first swapping the summands via `sumComm` and then applying `sumEmpty` to eliminate the now-empty right component.
Equiv.emptySum_apply_inr theorem
{α β} [IsEmpty α] (b : β) : emptySum α β (Sum.inr b) = b
Full source
@[simp]
theorem emptySum_apply_inr {α β} [IsEmpty α] (b : β) : emptySum α β (Sum.inr b) = b :=
  rfl
Application of Empty-Sum Equivalence to Right Injection
Informal description
For any types $\alpha$ and $\beta$ where $\alpha$ is empty, the equivalence $\text{emptySum} \alpha \beta$ maps the right injection $\text{inr}(b)$ of an element $b \in \beta$ to $b$ itself.
Equiv.sumEquivSigmaBool definition
(α β) : α ⊕ β ≃ Σ b, bif b then β else α
Full source
/-- `α ⊕ β` is equivalent to a `Sigma`-type over `Bool`. Note that this definition assumes `α` and
`β` to be types from the same universe, so it cannot be used directly to transfer theorems about
sigma types to theorems about sum types. In many cases one can use `ULift` to work around this
difficulty. -/
def sumEquivSigmaBool (α β) : α ⊕ βα ⊕ β ≃ Σ b, bif b then β else α :=
  ⟨fun s => s.elim (fun x => ⟨false, x⟩) fun x => ⟨true, x⟩, fun s =>
    match s with
    | ⟨false, a⟩ => inl a
    | ⟨true, b⟩ => inr b,
    fun s => by cases s <;> rfl, fun s => by rcases s with ⟨_ | _, _⟩ <;> rfl⟩
Equivalence between sum type and boolean-indexed sigma type
Informal description
The equivalence between the sum type $\alpha \oplus \beta$ and the sigma type $\Sigma b, \text{bif } b \text{ then } \beta \text{ else } \alpha$, where $\text{bif}$ is the boolean conditional. Concretely: - The forward map sends $\text{inl } x$ to $\langle \text{false}, x \rangle$ and $\text{inr } y$ to $\langle \text{true}, y \rangle$. - The inverse map sends $\langle \text{false}, a \rangle$ to $\text{inl } a$ and $\langle \text{true}, b \rangle$ to $\text{inr } b$.
Equiv.sigmaFiberEquiv definition
{α β : Type*} (f : α → β) : (Σ y : β, { x // f x = y }) ≃ α
Full source
/-- `sigmaFiberEquiv f` for `f : α → β` is the natural equivalence between
the type of all fibres of `f` and the total space `α`. -/
@[simps]
def sigmaFiberEquiv {α β : Type*} (f : α → β) : (Σ y : β, { x // f x = y }) ≃ α :=
  ⟨fun x => ↑x.2, fun x => ⟨f x, x, rfl⟩, fun ⟨_, _, rfl⟩ => rfl, fun _ => rfl⟩
Equivalence between fibers and total space
Informal description
For any function \( f : \alpha \to \beta \), the equivalence \(\text{sigmaFiberEquiv} f\) establishes a natural bijection between the type of all fibers of \( f \) (i.e., the dependent pair type \(\Sigma y : \beta, \{ x \mid f x = y \}\)) and the total space \(\alpha\). Concretely, the equivalence maps a pair \((y, x)\) where \( f x = y \) to the element \( x \), and its inverse maps an element \( x \) to the pair \((f x, x)\) with the trivial proof \( f x = f x \).
Equiv.sigmaEquivOptionOfInhabited definition
(α : Type u) [Inhabited α] [DecidableEq α] : Σ β : Type u, α ≃ Option β
Full source
/-- Inhabited types are equivalent to `Option β` for some `β` by identifying `default` with `none`.
-/
def sigmaEquivOptionOfInhabited (α : Type u) [Inhabited α] [DecidableEq α] :
    Σ β : Type u, α ≃ Option β where
  fst := {a // a ≠ default}
  snd.toFun a := if h : a = default then none else some ⟨a, h⟩
  snd.invFun := Option.elim' default (↑)
  snd.left_inv a := by dsimp only; split_ifs <;> simp [*]
  snd.right_inv
    | none => by simp
    | some ⟨_, ha⟩ => dif_neg ha
Equivalence between inhabited type and option of non-default elements
Informal description
For any inhabited type $\alpha$ with decidable equality, there exists a type $\beta$ (specifically, the subtype of elements of $\alpha$ not equal to the default value) such that $\alpha$ is equivalent to $\text{Option}\ \beta$. The equivalence is constructed as follows: - The forward map sends an element $a \in \alpha$ to $\text{some}\ \langle a, h\rangle$ if $a \neq \text{default}$, where $h$ is the proof of $a \neq \text{default}$, and to $\text{none}$ if $a = \text{default}$. - The inverse map is the elimination function for $\text{Option}\ \beta$, which returns the default value when the input is $\text{none}$ and the underlying value when the input is $\text{some}\ b$.
Equiv.sumCompl definition
{α : Type*} (p : α → Prop) [DecidablePred p] : { a // p a } ⊕ { a // ¬p a } ≃ α
Full source
/-- For any predicate `p` on `α`,
the sum of the two subtypes `{a // p a}` and its complement `{a // ¬ p a}`
is naturally equivalent to `α`.

See `subtypeOrEquiv` for sum types over subtypes `{x // p x}` and `{x // q x}`
that are not necessarily `IsCompl p q`. -/
def sumCompl {α : Type*} (p : α → Prop) [DecidablePred p] :
    { a // p a }{ a // p a } ⊕ { a // ¬p a }{ a // p a } ⊕ { a // ¬p a } ≃ α where
  toFun := Sum.elim Subtype.val Subtype.val
  invFun a := if h : p a then Sum.inl ⟨a, h⟩ else Sum.inr ⟨a, h⟩
  left_inv := by
    rintro (⟨x, hx⟩ | ⟨x, hx⟩) <;> dsimp
    · rw [dif_pos]
    · rw [dif_neg]
  right_inv a := by
    dsimp
    split_ifs <;> rfl
Equivalence between sum of subtypes and base type
Informal description
For any type $\alpha$ and decidable predicate $p$ on $\alpha$, the sum type $\{a \mid p a\} \oplus \{a \mid \neg p a\}$ is naturally equivalent to $\alpha$ via the following bijection: - The forward map sends $\text{inl}(x)$ (where $x \in \{a \mid p a\}$) to $x$ and $\text{inr}(x)$ (where $x \in \{a \mid \neg p a\}$) to $x$. - The inverse map sends $a \in \alpha$ to $\text{inl}(a)$ if $p a$ holds, and to $\text{inr}(a)$ otherwise.
Equiv.sumCompl_apply_inl theorem
{α} (p : α → Prop) [DecidablePred p] (x : { a // p a }) : sumCompl p (Sum.inl x) = x
Full source
@[simp]
theorem sumCompl_apply_inl {α} (p : α → Prop) [DecidablePred p] (x : { a // p a }) :
    sumCompl p (Sum.inl x) = x :=
  rfl
Equivalence maps left injection to element in subtype
Informal description
For any type $\alpha$ and decidable predicate $p$ on $\alpha$, the equivalence `sumCompl p` maps the left injection $\text{inl}(x)$ of an element $x$ in the subtype $\{a \mid p a\}$ to $x$ itself.
Equiv.sumCompl_apply_inr theorem
{α} (p : α → Prop) [DecidablePred p] (x : { a // ¬p a }) : sumCompl p (Sum.inr x) = x
Full source
@[simp]
theorem sumCompl_apply_inr {α} (p : α → Prop) [DecidablePred p] (x : { a // ¬p a }) :
    sumCompl p (Sum.inr x) = x :=
  rfl
Equivalence maps right injection to element in complement subtype
Informal description
For any type $\alpha$ and decidable predicate $p$ on $\alpha$, the equivalence `sumCompl p` maps the right injection $\text{inr}(x)$ of an element $x$ in the subtype $\{a \mid \neg p a\}$ to $x$ itself.
Equiv.sumCompl_apply_symm_of_pos theorem
{α} (p : α → Prop) [DecidablePred p] (a : α) (h : p a) : (sumCompl p).symm a = Sum.inl ⟨a, h⟩
Full source
@[simp]
theorem sumCompl_apply_symm_of_pos {α} (p : α → Prop) [DecidablePred p] (a : α) (h : p a) :
    (sumCompl p).symm a = Sum.inl ⟨a, h⟩ :=
  dif_pos h
Inverse of Sum-Complement Equivalence Maps Positive Predicate to Left Injection
Informal description
For any type $\alpha$ and decidable predicate $p$ on $\alpha$, the inverse of the equivalence `sumCompl p` maps an element $a \in \alpha$ satisfying $p(a)$ to the left injection $\text{inl}(\langle a, h \rangle)$, where $h$ is the proof that $p(a)$ holds.
Equiv.sumCompl_apply_symm_of_neg theorem
{α} (p : α → Prop) [DecidablePred p] (a : α) (h : ¬p a) : (sumCompl p).symm a = Sum.inr ⟨a, h⟩
Full source
@[simp]
theorem sumCompl_apply_symm_of_neg {α} (p : α → Prop) [DecidablePred p] (a : α) (h : ¬p a) :
    (sumCompl p).symm a = Sum.inr ⟨a, h⟩ :=
  dif_neg h
Inverse of Sum-Complement Equivalence Maps Negated Predicate to Right Injection
Informal description
For any type $\alpha$ and decidable predicate $p$ on $\alpha$, the inverse of the equivalence `sumCompl p` maps an element $a \in \alpha$ satisfying $\neg p(a)$ to the right injection $\text{inr}(\langle a, h \rangle)$, where $h$ is the proof that $\neg p(a)$ holds.
Equiv.prodSumDistrib definition
(α β γ) : α × (β ⊕ γ) ≃ (α × β) ⊕ (α × γ)
Full source
/-- Type product is left distributive with respect to type sum up to an equivalence. -/
def prodSumDistrib (α β γ) : α × (β ⊕ γ)α × (β ⊕ γ) ≃ (α × β) ⊕ (α × γ) :=
  calc
    α × (β ⊕ γ) ≃ (β ⊕ γ) × α := prodComm _ _
    _ ≃ (β × α) ⊕ (γ × α)calc
    α × (β ⊕ γ) ≃ (β ⊕ γ) × α := prodComm _ _
    _ ≃ (β × α) ⊕ (γ × α) := sumProdDistrib _ _ _
    _ ≃ (α × β) ⊕ (α × γ) := sumCongr (prodComm _ _) (prodComm _ _)
Left distributivity of product over sum via equivalence
Informal description
The equivalence $\alpha \times (\beta \oplus \gamma) \simeq (\alpha \times \beta) \oplus (\alpha \times \gamma)$ shows that the product type is left distributive with respect to the sum type. It maps a pair $(a, x)$ where $x$ is either in $\beta$ or $\gamma$ to either $(a, b)$ if $x = \text{inl } b$ or $(a, c)$ if $x = \text{inr } c$.
Equiv.prodSumDistrib_apply_left theorem
{α β γ} (a : α) (b : β) : prodSumDistrib α β γ (a, Sum.inl b) = Sum.inl (a, b)
Full source
@[simp]
theorem prodSumDistrib_apply_left {α β γ} (a : α) (b : β) :
    prodSumDistrib α β γ (a, Sum.inl b) = Sum.inl (a, b) :=
  rfl
Left injection case of product-sum distributivity equivalence
Informal description
For any types $\alpha$, $\beta$, and $\gamma$, the equivalence $\text{prodSumDistrib} \colon \alpha \times (\beta \oplus \gamma) \simeq (\alpha \times \beta) \oplus (\alpha \times \gamma)$ maps a pair $(a, \text{inl } b)$ to $\text{inl } (a, b)$, where $a \in \alpha$ and $b \in \beta$.
Equiv.prodSumDistrib_apply_right theorem
{α β γ} (a : α) (c : γ) : prodSumDistrib α β γ (a, Sum.inr c) = Sum.inr (a, c)
Full source
@[simp]
theorem prodSumDistrib_apply_right {α β γ} (a : α) (c : γ) :
    prodSumDistrib α β γ (a, Sum.inr c) = Sum.inr (a, c) :=
  rfl
Right component application of product-sum distributivity equivalence
Informal description
For any types $\alpha$, $\beta$, and $\gamma$, given an element $a \in \alpha$ and $c \in \gamma$, the equivalence $\text{prodSumDistrib}$ maps the pair $(a, \text{inr } c)$ to $\text{inr } (a, c)$.
Equiv.prodSumDistrib_symm_apply_left theorem
{α β γ} (a : α × β) : (prodSumDistrib α β γ).symm (inl a) = (a.1, inl a.2)
Full source
@[simp]
theorem prodSumDistrib_symm_apply_left {α β γ} (a : α × β) :
    (prodSumDistrib α β γ).symm (inl a) = (a.1, inl a.2) :=
  rfl
Inverse of Product-Sum Distributivity Equivalence on Left Injection
Informal description
For any types $\alpha$, $\beta$, and $\gamma$, and any pair $(a, b) \in \alpha \times \beta$, the inverse of the distributivity equivalence $\text{prodSumDistrib}_{\alpha,\beta,\gamma}^{-1}$ maps the left injection $\text{inl}(a, b)$ to the pair $(a, \text{inl}(b)) \in \alpha \times (\beta \oplus \gamma)$.
Equiv.prodSumDistrib_symm_apply_right theorem
{α β γ} (a : α × γ) : (prodSumDistrib α β γ).symm (inr a) = (a.1, inr a.2)
Full source
@[simp]
theorem prodSumDistrib_symm_apply_right {α β γ} (a : α × γ) :
    (prodSumDistrib α β γ).symm (inr a) = (a.1, inr a.2) :=
  rfl
Inverse of product-sum distributivity equivalence on right summand: $(a, c) \mapsto (a, \text{inr}(c))$
Informal description
For any types $\alpha$, $\beta$, and $\gamma$, and any pair $(a, c) \in \alpha \times \gamma$, the inverse of the distributivity equivalence $\text{prodSumDistrib}$ maps the right summand $\text{inr}(a, c)$ to the pair $(a, \text{inr}(c))$.
Equiv.sigmaSumDistrib definition
{ι} (α β : ι → Type*) : (Σ i, α i ⊕ β i) ≃ (Σ i, α i) ⊕ (Σ i, β i)
Full source
/-- An indexed sum of disjoint sums of types is equivalent to the sum of the indexed sums. Compare
with `Equiv.sumSigmaDistrib` which is indexed by sums. -/
@[simps]
def sigmaSumDistrib {ι} (α β : ι → Type*) :
    (Σ i, α i ⊕ β i) ≃ (Σ i, α i) ⊕ (Σ i, β i) :=
  ⟨fun p => p.2.map (Sigma.mk p.1) (Sigma.mk p.1),
    Sum.elim (Sigma.map id fun _ => Sum.inl) (Sigma.map id fun _ => Sum.inr), fun p => by
    rcases p with ⟨i, a | b⟩ <;> rfl, fun p => by rcases p with (⟨i, a⟩ | ⟨i, b⟩) <;> rfl⟩
Distributivity of Sigma over Sum Types
Informal description
For an index type $\iota$ and type families $\alpha, \beta : \iota \to \text{Type}$, the dependent sum type $\Sigma i, (\alpha i \oplus \beta i)$ is equivalent to the sum type $(\Sigma i, \alpha i) \oplus (\Sigma i, \beta i)$. Concretely, this means: 1. Any pair $(i, \text{inl } a)$ where $a \in \alpha i$ corresponds to $\text{inl } (i, a)$ in the right-hand side. 2. Any pair $(i, \text{inr } b)$ where $b \in \beta i$ corresponds to $\text{inr } (i, b)$ in the right-hand side.
Equiv.sumSigmaDistrib definition
{α β} (t : α ⊕ β → Type*) : (Σ i, t i) ≃ (Σ i, t (.inl i)) ⊕ (Σ i, t (.inr i))
Full source
/-- A type indexed by  disjoint sums of types is equivalent to the sum of the sums. Compare with
`Equiv.sigmaSumDistrib` which has the sums as the output type. -/
@[simps]
def sumSigmaDistrib {α β} (t : α ⊕ β → Type*) :
    (Σ i, t i) ≃ (Σ i, t (.inl i)) ⊕ (Σ i, t (.inr i)) :=
  ⟨(match · with
   | .mk (.inl x) y => .inl ⟨x, y⟩
   | .mk (.inr x) y => .inr ⟨x, y⟩),
  Sum.elim (fun a ↦ ⟨.inl a.1, a.2⟩) (fun b ↦ ⟨.inr b.1, b.2⟩),
  by rintro ⟨x|x,y⟩ <;> simp,
  by rintro (⟨x,y⟩|⟨x,y⟩) <;> simp⟩
Distributivity of Sigma over Sum Types
Informal description
Given types $\alpha$ and $\beta$, and a type family $t$ indexed by $\alpha \oplus \beta$, the sigma type $\Sigma i, t i$ is equivalent to the sum of the sigma types $(\Sigma i, t (\text{inl } i)) \oplus (\Sigma i, t (\text{inr } i))$. More concretely, this equivalence maps a pair $(i, x)$ where $i$ is in $\alpha \oplus \beta$ and $x$ is in $t i$ to either $\text{inl } (i, x)$ if $i$ is in $\alpha$ or $\text{inr } (i, x)$ if $i$ is in $\beta$. The inverse maps $\text{inl } (i, x)$ to $(\text{inl } i, x)$ and $\text{inr } (i, x)$ to $(\text{inr } i, x)$.