doc-next-gen

Init.Core

Module docstring

{"# definitions ","# set notation ","# collections ","# Boolean operators ","# Logical connectives and equality ","# Exists ","# Decidable ","# if-then-else expression theorems ","# Inhabited ","# Subsingleton ","# Subtype ","# Sum ","# Product ","# Dependent products ","# Universe polymorphic unit ","# Setoid ","# Propositional extensionality ","# Prop lemmas ","## implies ","# Quotients ","# Function extensionality ","# Squash ","# Kernel reduction hints "}

inline definition
{α : Sort u} (a : α) : α
Full source
/--
`inline (f x)` is an indication to the compiler to inline the definition of `f`
at the application site itself (by comparison to the `@[inline]` attribute,
which applies to all applications of the function).
-/
@[simp] def inline {α : Sort u} (a : α) : α := a
Inline function hint
Informal description
The function `inline` takes an element `a` of type `α` and returns `a` unchanged. It serves as a compiler hint to inline the definition at the call site.
id_def theorem
{α : Sort u} (a : α) : id a = a
Full source
theorem id_def {α : Sort u} (a : α) : id a = a := rfl
Identity Function Definition: $\mathrm{id}(a) = a$
Informal description
For any element $a$ of type $\alpha$, the identity function applied to $a$ is equal to $a$ itself, i.e., $\mathrm{id}(a) = a$.
flip definition
{α : Sort u} {β : Sort v} {φ : Sort w} (f : α → β → φ) : β → α → φ
Full source
/--
`flip f a b` is `f b a`. It is useful for "point-free" programming,
since it can sometimes be used to avoid introducing variables.
For example, `(·<·)` is the less-than relation,
and `flip (·<·)` is the greater-than relation.
-/
@[inline] def flip {α : Sort u} {β : Sort v} {φ : Sort w} (f : α → β → φ) : β → α → φ :=
  fun b a => f a b
Argument-flipping function
Informal description
Given a function \( f : \alpha \to \beta \to \varphi \), the function `flip f` is defined as \( \lambda b \, a, f a b \), which reverses the order of the arguments of \( f \). This is particularly useful for point-free programming, where explicit variable declarations can be avoided. For example, if \( f \) is the less-than relation \( (<) \), then `flip f` represents the greater-than relation \( (>) \).
Function.const_apply theorem
{y : β} {x : α} : const α y x = y
Full source
@[simp] theorem Function.const_apply {y : β} {x : α} : const α y x = y := rfl
Evaluation of Constant Function: $\text{const}_\alpha(y)(x) = y$
Informal description
For any element $y$ of type $\beta$ and any element $x$ of type $\alpha$, the constant function $\text{const}_\alpha(y)$ evaluated at $x$ equals $y$, i.e., $\text{const}_\alpha(y)(x) = y$.
Function.comp_apply theorem
{f : β → δ} {g : α → β} {x : α} : comp f g x = f (g x)
Full source
@[simp] theorem Function.comp_apply {f : β → δ} {g : α → β} {x : α} : comp f g x = f (g x) := rfl
Function Composition Evaluation: $(f \circ g)(x) = f(g(x))$
Informal description
For any functions $f \colon \beta \to \delta$ and $g \colon \alpha \to \beta$, and any element $x \in \alpha$, the composition $(f \circ g)(x)$ is equal to $f(g(x))$.
Function.comp_def theorem
{α β δ} (f : β → δ) (g : α → β) : f ∘ g = fun x => f (g x)
Full source
theorem Function.comp_def {α β δ} (f : β → δ) (g : α → β) : f ∘ g = fun x => f (g x) := rfl
Definition of Function Composition: $f \circ g = \lambda x, f(g(x))$
Informal description
For any functions $f \colon \beta \to \delta$ and $g \colon \alpha \to \beta$, the composition $f \circ g$ is equal to the function $\lambda x, f(g(x))$.
Function.const_comp theorem
{f : α → β} {c : γ} : (Function.const β c ∘ f) = Function.const α c
Full source
@[simp] theorem Function.const_comp {f : α → β} {c : γ} :
    (Function.constFunction.const β c ∘ f) = Function.const α c := by
  rfl
Composition of Constant Function with Any Function Yields Constant Function
Informal description
For any function $f \colon \alpha \to \beta$ and any element $c \in \gamma$, the composition of the constant function $\text{const}_\beta(c)$ (which maps every element of $\beta$ to $c$) with $f$ is equal to the constant function $\text{const}_\alpha(c)$ (which maps every element of $\alpha$ to $c$). In other words, $\text{const}_\beta(c) \circ f = \text{const}_\alpha(c)$.
Function.comp_const theorem
{f : β → γ} {b : β} : (f ∘ Function.const α b) = Function.const α (f b)
Full source
@[simp] theorem Function.comp_const {f : β → γ} {b : β} :
    (f ∘ Function.const α b) = Function.const α (f b) := by
  rfl
Composition with Constant Function Yields Constant Function
Informal description
For any function $f : \beta \to \gamma$ and any element $b \in \beta$, the composition of $f$ with the constant function that maps every element of $\alpha$ to $b$ is equal to the constant function that maps every element of $\alpha$ to $f(b)$. In other words, $f \circ (\text{const}_\alpha b) = \text{const}_\alpha (f(b))$.
Function.true_comp theorem
{f : α → β} : ((fun _ => true) ∘ f) = fun _ => true
Full source
@[simp] theorem Function.true_comp {f : α → β} : ((fun _ => true) ∘ f) = fun _ => true := by
  rfl
Composition with Constant True Function Preserves True
Informal description
For any function $f : \alpha \to \beta$, the composition of the constant true function with $f$ is equal to the constant true function, i.e., $(\lambda \_, \text{true}) \circ f = \lambda \_, \text{true}$.
Function.false_comp theorem
{f : α → β} : ((fun _ => false) ∘ f) = fun _ => false
Full source
@[simp] theorem Function.false_comp {f : α → β} : ((fun _ => false) ∘ f) = fun _ => false := by
  rfl
Composition with Constant False Function Preserves False
Informal description
For any function $f : \alpha \to \beta$, the composition of the constant false function with $f$ is equal to the constant false function, i.e., $(\lambda \_, \text{false}) \circ f = \lambda \_, \text{false}$.
Empty.elim definition
{C : Sort u} : Empty → C
Full source
/--
`Empty.elim : Empty → C` says that a value of any type can be constructed from
`Empty`. This can be thought of as a compiler-checked assertion that a code path is unreachable.
-/
@[macro_inline] def Empty.elim {C : Sort u} : Empty → C := Empty.rec
Elimination rule for the empty type
Informal description
The function `Empty.elim` states that from a value of the empty type `Empty`, one can construct a value of any type `C`. This serves as a compiler-verified assertion that a particular code path is unreachable, since there are no possible values of type `Empty` to begin with.
instDecidableEqEmpty instance
: DecidableEq Empty
Full source
/-- Decidable equality for Empty -/
instance : DecidableEq Empty := fun a => a.elim
Decidable Equality for the Empty Type
Informal description
The empty type has decidable equality, meaning that for any two elements of the empty type, the equality between them can be constructively determined (trivially, since there are no elements in the empty type).
PEmpty.elim definition
{C : Sort _} : PEmpty → C
Full source
/--
`PEmpty.elim : Empty → C` says that a value of any type can be constructed from
`PEmpty`. This can be thought of as a compiler-checked assertion that a code path is unreachable.
-/
@[macro_inline] def PEmpty.elim {C : Sort _} : PEmpty → C := fun a => nomatch a
Elimination rule for the empty type
Informal description
The function `PEmpty.elim` states that from a value of the empty type `PEmpty`, one can construct a value of any type `C`. This serves as a compiler-verified assertion that a particular code path is unreachable, since there are no possible values of type `PEmpty` to begin with.
instDecidableEqPEmpty instance
: DecidableEq PEmpty
Full source
/-- Decidable equality for PEmpty -/
instance : DecidableEq PEmpty := fun a => a.elim
Decidable Equality for the Polymorphic Empty Type
Informal description
The polymorphic empty type `PEmpty` has decidable equality, meaning that for any two elements of `PEmpty`, the equality between them can be constructively determined (trivially, since there are no elements in `PEmpty`).
Thunk structure
(α : Type u)
Full source
/--
Delays evaluation. The delayed code is evaluated at most once.

A thunk is code that constructs a value when it is requested via `Thunk.get`, `Thunk.map`, or
`Thunk.bind`. The resulting value is cached, so the code is executed at most once. This is also
known as lazy or call-by-need evaluation.

The Lean runtime has special support for the `Thunk` type in order to implement the caching
behavior.
-/
structure Thunk (α : Type u) : Type u where
  /--
  Constructs a new thunk from a function `Unit → α` that will be called when the thunk is first
  forced.

  The result is cached. It is re-used when the thunk is forced again.
  -/
  mk ::
  /-- Extract the getter function out of a thunk. Use `Thunk.get` instead. -/
  private fn : Unit → α
Lazy value (Thunk)
Informal description
A structure representing delayed evaluation of code that produces a value of type $\alpha$. The code is evaluated at most once when the value is requested, and the result is cached for subsequent requests. This implements lazy evaluation (also known as call-by-need).
Thunk.pure definition
(a : α) : Thunk α
Full source
/--
Stores an already-computed value in a thunk.

Because the value has already been computed, there is no laziness.
-/
@[extern "lean_thunk_pure"] protected def Thunk.pure (a : α) : Thunk α :=
  ⟨fun _ => a⟩
Pure thunk constructor
Informal description
The function `Thunk.pure` takes a value `a` of type `α` and returns a thunk that, when evaluated, always yields `a`. This thunk does not perform any computation since the value is already known.
Thunk.get definition
(x : @& Thunk α) : α
Full source
/--
Gets the thunk's value. If the value is cached, it is returned in constant time; if not, it is
computed.

Computed values are cached, so the value is not recomputed.
-/
-- NOTE: we use `Thunk.get` instead of `Thunk.fn` as the accessor primitive as the latter has an additional `Unit` argument
@[extern "lean_thunk_get_own"] protected def Thunk.get (x : @& Thunk α) : α :=
  x.fn ()
Retrieve value of a thunk
Informal description
The function retrieves the value of a thunk (a lazily evaluated computation). If the value has already been computed and cached, it is returned immediately; otherwise, the computation is performed and the result is cached for future calls.
Thunk.map definition
(f : α → β) (x : Thunk α) : Thunk β
Full source
/--
Constructs a new thunk that forces `x` and then applies `x` to the result. Upon forcing, the result
of `f` is cached and the reference to the thunk `x` is dropped.
-/
@[inline] protected def Thunk.map (f : α → β) (x : Thunk α) : Thunk β :=
  ⟨fun _ => f x.get⟩
Mapping a function over a thunk
Informal description
Given a function $f : \alpha \to \beta$ and a thunk $x$ (a lazily evaluated computation producing a value of type $\alpha$), the function `Thunk.map` constructs a new thunk that, when forced, applies $f$ to the result of forcing $x$. The result of $f$ is cached and the reference to the original thunk $x$ is dropped.
Thunk.bind definition
(x : Thunk α) (f : α → Thunk β) : Thunk β
Full source
/--
Constructs a new thunk that applies `f` to the result of `x` when forced.
-/
@[inline] protected def Thunk.bind (x : Thunk α) (f : α → Thunk β) : Thunk β :=
  ⟨fun _ => (f x.get).get⟩
Binding operation for thunks
Informal description
Given a thunk `x` (a lazily evaluated computation producing a value of type `α`) and a function `f : α → Thunk β`, the function `Thunk.bind` constructs a new thunk that, when forced, first forces `x` to obtain a value `a : α`, then forces the thunk `f a` to obtain the final result of type `β`.
Thunk.sizeOf_eq theorem
[SizeOf α] (a : Thunk α) : sizeOf a = 1 + sizeOf a.get
Full source
@[simp] theorem Thunk.sizeOf_eq [SizeOf α] (a : Thunk α) : sizeOf a = 1 + sizeOf a.get := by
   cases a; rfl
Size of Thunk Equals One Plus Size of Its Value: $\text{sizeOf}(a) = 1 + \text{sizeOf}(a.\text{get})$
Informal description
For any type $\alpha$ with a size function, the size of a thunk $a$ (a lazily evaluated computation producing a value of type $\alpha$) is equal to $1$ plus the size of its forced value $a.\text{get}$.
thunkCoe instance
: CoeTail α (Thunk α)
Full source
instance thunkCoe : CoeTail α (Thunk α) where
  -- Since coercions are expanded eagerly, `a` is evaluated lazily.
  coe a := ⟨fun _ => a⟩
Tail Coercion to Thunk Type
Informal description
For any type $\alpha$, there is a tail coercion from $\alpha$ to `Thunk α`, which represents a lazily evaluated value of type $\alpha$.
Eq.ndrecOn abbrev
{α : Sort u2} {a : α} {motive : α → Sort u1} {b : α} (h : a = b) (m : motive a) : motive b
Full source
/-- A variation on `Eq.ndrec` with the equality argument first. -/
abbrev Eq.ndrecOn.{u1, u2} {α : Sort u2} {a : α} {motive : α → Sort u1} {b : α} (h : a = b) (m : motive a) : motive b :=
  Eq.ndrec m h
Transport Along Equality (Non-dependent Recursor, Equality-First Variant)
Informal description
Given a type $\alpha$, elements $a, b \in \alpha$, and a dependent type family $\text{motive} : \alpha \to \text{Sort } u_1$, if we have a proof $h : a = b$ and a term $m : \text{motive } a$, then we can construct a term of type $\text{motive } b$. This is the non-dependent eliminator for equality that allows transporting a term along an equality proof, with the equality argument appearing first.
Iff structure
(a b : Prop)
Full source
/--
If and only if, or logical bi-implication. `a ↔ b` means that `a` implies `b` and vice versa.
By `propext`, this implies that `a` and `b` are equal and hence any expression involving `a`
is equivalent to the corresponding expression with `b` instead.
-/
structure Iff (a b : Prop) : Prop where
  /-- If `a → b` and `b → a` then `a` and `b` are equivalent. -/
  intro ::
  /-- Modus ponens for if and only if. If `a ↔ b` and `a`, then `b`. -/
  mp : a → b
  /-- Modus ponens for if and only if, reversed. If `a ↔ b` and `b`, then `a`. -/
  mpr : b → a
Logical bi-implication (if and only if)
Informal description
The logical connective representing bi-implication between two propositions $a$ and $b$, meaning that $a$ implies $b$ and $b$ implies $a$. By propositional extensionality, this implies that $a$ and $b$ are equivalent and can be substituted for each other in any context.
term_<->_ definition
: Lean.TrailingParserDescr✝
Full source
@[inherit_doc] infix:20 " <-> " => Iff
If-and-only-if notation
Informal description
The infix notation `a <-> b` is defined as syntactic sugar for the logical bi-implication `Iff a b`, meaning "$a$ if and only if $b$".
term_↔_ definition
: Lean.TrailingParserDescr✝
Full source
@[inherit_doc] infix:20 " ↔ "   => Iff
Logical equivalence (Iff) notation
Informal description
The infix notation `↔` represents logical equivalence (if and only if) between two propositions, with a precedence level of 20.
Sum inductive
(α : Type u) (β : Type v)
Full source
/--
The disjoint union of types `α` and `β`, ordinarily written `α ⊕ β`.

An element of `α ⊕ β` is either an `a : α` wrapped in `Sum.inl` or a `b : β` wrapped in `Sum.inr`.
`α ⊕ β` is not equivalent to the set-theoretic union of `α` and `β` because its values include an
indication of which of the two types was chosen. The union of a singleton set with itself contains
one element, while `Unit ⊕ Unit` contains distinct values `inl ()` and `inr ()`.
-/
inductive Sum (α : Type u) (β : Type v) where
  /-- Left injection into the sum type `α ⊕ β`. -/
  | inl (val : α) : Sum α β
  /-- Right injection into the sum type `α ⊕ β`. -/
  | inr (val : β) : Sum α β
Disjoint union of types
Informal description
The disjoint union (or sum type) of types $\alpha$ and $\beta$, denoted $\alpha \oplus \beta$. An element of $\alpha \oplus \beta$ is either an element of $\alpha$ tagged with `inl` or an element of $\beta$ tagged with `inr`. This differs from the set-theoretic union in that it preserves information about which type the element originated from (e.g., $\text{Unit} \oplus \text{Unit}$ has two distinct elements: $\text{inl} ()$ and $\text{inr} ()$).
term_⊕_ definition
: Lean.TrailingParserDescr✝
Full source
@[inherit_doc] infixr:30 " ⊕ " => Sum
Disjoint union notation
Informal description
The infix notation `⊕` represents the disjoint union (sum type) of two types, with right associativity and precedence level 30.
PSum inductive
(α : Sort u) (β : Sort v)
Full source
/--
The disjoint union of arbitrary sorts `α` `β`, or `α ⊕' β`.

It differs from `α ⊕ β` in that it allows `α` and `β` to have arbitrary sorts `Sort u` and `Sort v`,
instead of restricting them to `Type u` and `Type v`. This means that it can be used in situations
where one side is a proposition, like `True ⊕' Nat`. However, the resulting universe level
constraints are often more difficult to solve than those that result from `Sum`.
-/
inductive PSum (α : Sort u) (β : Sort v) where
  /-- Left injection into the sum type `α ⊕' β`.-/
  | inl (val : α) : PSum α β
  /-- Right injection into the sum type `α ⊕' β`. -/
  | inr (val : β) : PSum α β
Disjoint union of arbitrary sorts
Informal description
The disjoint union of arbitrary sorts `α` and `β`, denoted as `α ⊕' β`. This generalizes the usual sum type `α ⊕ β` by allowing `α` and `β` to be of arbitrary sorts (including propositions), rather than restricting them to types. For example, it can represent cases like `True ⊕' Nat` where one side is a proposition.
term_⊕'_ definition
: Lean.TrailingParserDescr✝
Full source
@[inherit_doc] infixr:30 " ⊕' " => PSum
Disjoint union notation for arbitrary sorts (`⊕'`)
Informal description
The notation `⊕'` is an infix operator with precedence 30, representing the disjoint union of arbitrary sorts (including propositions) via the `PSum` type. It generalizes the usual sum type `⊕` by allowing its operands to be of any sort.
PSum.inhabitedLeft definition
{α β} [Inhabited α] : Inhabited (PSum α β)
Full source
/--
If the left type in a sum is inhabited then the sum is inhabited.

This is not an instance to avoid non-canonical instances when both the left and right types are
inhabited.
-/
@[reducible] def PSum.inhabitedLeft {α β} [Inhabited α] : Inhabited (PSum α β) := ⟨PSum.inl default⟩
Inhabited left component of disjoint union
Informal description
Given types $\alpha$ and $\beta$, if $\alpha$ is inhabited (i.e., has a designated element), then the disjoint union $\alpha \oplus' \beta$ is also inhabited, with the default element being the injection of the default element of $\alpha$ into the left component of the sum.
PSum.inhabitedRight definition
{α β} [Inhabited β] : Inhabited (PSum α β)
Full source
/--
If the right type in a sum is inhabited then the sum is inhabited.

This is not an instance to avoid non-canonical instances when both the left and right types are
inhabited.
-/
@[reducible] def PSum.inhabitedRight {α β} [Inhabited β] : Inhabited (PSum α β) := ⟨PSum.inr default⟩
Inhabited right component of disjoint union
Informal description
Given types $\alpha$ and $\beta$, if $\beta$ is inhabited (i.e., has a designated element), then the disjoint union $\alpha \oplus' \beta$ is also inhabited, with the default element being the injection of the default element of $\beta$ into the right component of the sum.
PSum.nonemptyLeft instance
[h : Nonempty α] : Nonempty (PSum α β)
Full source
instance PSum.nonemptyLeft [h : Nonempty α] : Nonempty (PSum α β) :=
  Nonempty.elim h (fun a => ⟨PSum.inl a⟩)
Nonempty Left Component Implies Nonempty Disjoint Union
Informal description
For any types $\alpha$ and $\beta$, if $\alpha$ is nonempty, then the disjoint union $\alpha \oplus' \beta$ is also nonempty.
PSum.nonemptyRight instance
[h : Nonempty β] : Nonempty (PSum α β)
Full source
instance PSum.nonemptyRight [h : Nonempty β] : Nonempty (PSum α β) :=
  Nonempty.elim h (fun b => ⟨PSum.inr b⟩)
Nonempty Right Component Implies Nonempty Disjoint Union
Informal description
For any types $\alpha$ and $\beta$, if $\beta$ is nonempty, then the disjoint union $\alpha \oplus' \beta$ is also nonempty.
Sigma structure
{α : Type u} (β : α → Type v)
Full source
/--
Dependent pairs, in which the second element's type depends on the value of the first element. The
type `Sigma β` is typically written `Σ a : α, β a` or `(a : α) × β a`.

Although its values are pairs, `Sigma` is sometimes known as the *dependent sum type*, since it is
the type level version of an indexed summation.
-/
@[pp_using_anonymous_constructor]
structure Sigma {α : Type u} (β : α → Type v) where
  /--
  Constructs a dependent pair.

  Using this constructor in a context in which the type is not known usually requires a type
  ascription to determine `β`. This is because the desired relationship between the two values can't
  generally be determined automatically.
  -/
  mk ::
  /--
  The first component of a dependent pair.
  -/
  fst : α
  /--
  The second component of a dependent pair. Its type depends on the first component.
  -/
  snd : β fst
Dependent sum type
Informal description
The structure `Sigma` represents dependent pairs, where the type of the second component depends on the value of the first component. It is typically denoted as $\Sigma a : \alpha, \beta a$ or $(a : \alpha) \times \beta a$, where $\alpha$ is a type and $\beta$ is a type-valued function on $\alpha$. This structure is also known as the *dependent sum type* since it generalizes the notion of an indexed summation to the type level.
PSigma structure
{α : Sort u} (β : α → Sort v)
Full source
/--
Fully universe-polymorphic dependent pairs, in which the second element's type depends on the value
of the first element and both types are allowed to be propositions. The type `PSigma β` is typically
written `Σ' a : α, β a` or `(a : α) ×' β a`.

In practice, this generality leads to universe level constraints that are difficult to solve, so
`PSigma` is rarely used in manually-written code. It is usually only used in automation that
constructs pairs of arbitrary types.

To pair a value with a proof that a predicate holds for it, use `Subtype`. To demonstrate that a
value exists that satisfies a predicate, use `Exists`. A dependent pair with a proposition as its
first component is not typically useful due to proof irrelevance: there's no point in depending on a
specific proof because all proofs are equal anyway.
-/
@[pp_using_anonymous_constructor]
structure PSigma {α : Sort u} (β : α → Sort v) where
  /-- Constructs a fully universe-polymorphic dependent pair. -/
  mk ::
  /--
  The first component of a dependent pair.
  -/
  fst : α
  /--
  The second component of a dependent pair. Its type depends on the first component.
  -/
  snd : β fst
Universe-polymorphic dependent pair
Informal description
The structure `PSigma` represents a fully universe-polymorphic dependent pair, where the type of the second component depends on the value of the first component. Both components can be propositions. This is typically written as $\Sigma' a : \alpha, \beta a$ or $(a : \alpha) \times' \beta a$. Due to universe level constraints, `PSigma` is rarely used in manual code and is mainly employed in automation that constructs pairs of arbitrary types. For practical purposes, use `Subtype` to pair a value with a proof of a predicate, or `Exists` to demonstrate the existence of a value satisfying a predicate. Note that dependent pairs with a proposition as the first component are generally not useful because of proof irrelevance.
Exists inductive
{α : Sort u} (p : α → Prop) : Prop
Full source
/--
Existential quantification. If `p : α → Prop` is a predicate, then `∃ x : α, p x`
asserts that there is some `x` of type `α` such that `p x` holds.
To create an existential proof, use the `exists` tactic,
or the anonymous constructor notation `⟨x, h⟩`.
To unpack an existential, use `cases h` where `h` is a proof of `∃ x : α, p x`,
or `let ⟨x, hx⟩ := h` where `.

Because Lean has proof irrelevance, any two proofs of an existential are
definitionally equal. One consequence of this is that it is impossible to recover the
witness of an existential from the mere fact of its existence.
For example, the following does not compile:
```
example (h : ∃ x : Nat, x = x) : Nat :=
  let ⟨x, _⟩ := h  -- fail, because the goal is `Nat : Type`
  x
```
The error message `recursor 'Exists.casesOn' can only eliminate into Prop` means
that this only works when the current goal is another proposition:
```
example (h : ∃ x : Nat, x = x) : True :=
  let ⟨x, _⟩ := h  -- ok, because the goal is `True : Prop`
  trivial
```
-/
inductive Exists {α : Sort u} (p : α → Prop) : Prop where
  /-- Existential introduction. If `a : α` and `h : p a`,
  then `⟨a, h⟩` is a proof that `∃ x : α, p x`. -/
  | intro (w : α) (h : p w) : Exists p
Existential Quantifier
Informal description
The existential quantifier. Given a type $\alpha$ and a predicate $p : \alpha \to \text{Prop}$, the expression $\exists x : \alpha, p x$ asserts that there exists some element $x$ of type $\alpha$ for which $p x$ holds. To construct a proof of an existential statement, one can use the `exists` tactic or the anonymous constructor notation $\langle x, h \rangle$ where $x$ is the witness and $h$ is a proof of $p x$. To deconstruct an existential proof $h : \exists x : \alpha, p x$, one can use pattern matching with `cases h` or `let ⟨x, hx⟩ := h`. Due to proof irrelevance in Lean, any two proofs of the same existential statement are definitionally equal. This implies that the witness cannot be extracted from the existential proof unless the goal is another proposition. For example, attempting to extract a natural number from $h : \exists x : \mathbb{N}, x = x$ will fail unless the goal is a proposition.
ForInStep inductive
(α : Type u)
Full source
/--
An indication of whether a loop's body terminated early that's used to compile the `for x in xs`
notation.

A collection's `ForIn` or `ForIn'` instance describe's how to iterate over its elements. The monadic
action that represents the body of the loop returns a `ForInStep α`, where `α` is the local state
used to implement features such as `let mut`.
-/
inductive ForInStep (α : Type u) where
  /--
  The loop should terminate early.

  `ForInStep.done` is produced by uses of `break` or `return` in the loop body.
  -/
  | done  : α → ForInStep α
  /--
  The loop should continue with the next iteration, using the returned state.

  `ForInStep.yield` is produced by `continue` and by reaching the bottom of the loop body.
  -/
  | yield : α → ForInStep α
  deriving Inhabited
Loop control indicator for iteration
Informal description
An inductive type used to indicate whether a loop's body terminated early during iteration over a collection. It is primarily used in the implementation of the `for x in xs` notation, where the monadic action representing the loop body returns a value of type `ForInStep α`, with `α` being the local state used for features like mutable variables. The type has two constructors: 1. `yield (a : α)` - indicates the loop should continue with the new state `a` 2. `done (a : α)` - indicates the loop should terminate early with final state `a`
instInhabitedForInStep instance
{a✝} [Inhabited✝ a✝] : Inhabited✝ (@ForInStep a✝)
Full source
Inhabited
Default Element for Loop Control Type
Informal description
For any type $\alpha$ with a default element, the type `ForInStep α` (used to control loop iteration) also has a default element.
ForIn structure
(m : Type u₁ → Type u₂) (ρ : Type u) (α : outParam (Type v))
Full source
/--
Monadic iteration in `do`-blocks, using the `for x in xs` notation.

The parameter `m` is the monad of the `do`-block in which iteration is performed, `ρ` is the type of
the collection being iterated over, and `α` is the type of elements.
-/
class ForIn (m : Type u₁ → Type u₂) (ρ : Type u) (α : outParam (Type v)) where
  /--
  Monadically iterates over the contents of a collection `xs`, with a local state `b` and the
  possibility of early termination.

  Because a `do` block supports local mutable bindings along with `return`, and `break`, the monadic
  action passed to `ForIn.forIn` takes a starting state in addition to the current element of the
  collection and returns an updated state together with an indication of whether iteration should
  continue or terminate. If the action returns `ForInStep.done`, then `ForIn.forIn` should stop
  iteration and return the updated state. If the action returns `ForInStep.yield`, then
  `ForIn.forIn` should continue iterating if there are further elements, passing the updated state
  to the action.

  More information about the translation of `for` loops into `ForIn.forIn` is available in [the Lean
  reference manual](lean-manual://section/monad-iteration-syntax).
  -/
  forIn {β} [Monad m] (xs : ρ) (b : β) (f : α → β → m (ForInStep β)) : m β
Monadic iteration structure
Informal description
The structure `ForIn` represents the monadic iteration capability for `do`-blocks using the `for x in xs` notation. Here: - `m` is the monad type constructor in which the iteration is performed - `ρ` is the type of the collection being iterated over - `α` is the type of elements in the collection (marked as an output parameter) This structure enables monadic iteration over collections of type `ρ` in the monad `m`, where each element has type `α`.
ForIn' structure
(m : Type u₁ → Type u₂) (ρ : Type u) (α : outParam (Type v)) (d : outParam (Membership α ρ))
Full source
/--
Monadic iteration in `do`-blocks with a membership proof, using the `for h : x in xs` notation.

The parameter `m` is the monad of the `do`-block in which iteration is performed, `ρ` is the type of
the collection being iterated over, `α` is the type of elements, and `d` is the specific membership
predicate to provide.
-/
class ForIn' (m : Type u₁ → Type u₂) (ρ : Type u) (α : outParam (Type v)) (d : outParam (Membership α ρ)) where
  /--
  Monadically iterates over the contents of a collection `xs`, with a local state `b` and the
  possibility of early termination. At each iteration, the body of the loop is provided with a proof
  that the current element is in the collection.

  Because a `do` block supports local mutable bindings along with `return`, and `break`, the monadic
  action passed to `ForIn'.forIn'` takes a starting state in addition to the current element of the
  collection with its membership proof. The action returns an updated state together with an
  indication of whether iteration should continue or terminate. If the action returns
  `ForInStep.done`, then `ForIn'.forIn'` should stop iteration and return the updated state. If the
  action returns `ForInStep.yield`, then `ForIn'.forIn'` should continue iterating if there are
  further elements, passing the updated state to the action.

  More information about the translation of `for` loops into `ForIn'.forIn'` is available in [the
  Lean reference manual](lean-manual://section/monad-iteration-syntax).
  -/
  forIn' {β} [Monad m] (x : ρ) (b : β) (f : (a : α) → a ∈ x → β → m (ForInStep β)) : m β
Monadic iteration with membership proofs
Informal description
The structure `ForIn'` represents monadic iteration in `do`-blocks with a membership proof, supporting the `for h : x in xs` notation. Here: - `m` is the monad type constructor in which iteration is performed - `ρ` is the type of the collection being iterated over - `α` is the type of elements in the collection (marked as an output parameter) - `d` is the specific membership predicate that provides proofs of element membership This structure enables monadic iteration over collections of type `ρ` in the monad `m`, where each element has type `α` and comes with a membership proof.
DoResultPRBC inductive
(α β σ : Type u)
Full source
/--
Auxiliary type used to compile `do` notation. It is used when compiling a do block
nested inside a combinator like `tryCatch`. It encodes the possible ways the
block can exit:
* `pure (a : α) s` means that the block exited normally with return value `a`.
* `return (b : β) s` means that the block exited via a `return b` early-exit command.
* `break s` means that `break` was called, meaning that we should exit
  from the containing loop.
* `continue s` means that `continue` was called, meaning that we should continue
  to the next iteration of the containing loop.

All cases return a value `s : σ` which bundles all the mutable variables of the do-block.
-/
inductive DoResultPRBC (α β σ : Type u) where
  /-- `pure (a : α) s` means that the block exited normally with return value `a` -/
  | pure : α → σ → DoResultPRBC α β σ
  /-- `return (b : β) s` means that the block exited via a `return b` early-exit command -/
  | return : β → σ → DoResultPRBC α β σ
  /-- `break s` means that `break` was called, meaning that we should exit
  from the containing loop -/
  | break : σ → DoResultPRBC α β σ
  /-- `continue s` means that `continue` was called, meaning that we should continue
  to the next iteration of the containing loop -/
  | continue : σ → DoResultPRBC α β σ
Possible exits of a nested `do` block
Informal description
The inductive type `DoResultPRBC` represents the possible ways a `do` block can exit when nested inside a combinator like `tryCatch`. It has four constructors: 1. `pure (a : α) s`: The block exited normally with return value `a` and state `s`. 2. `return (b : β) s`: The block exited via an early `return b` command with state `s`. 3. `break s`: The block exited via a `break` command with state `s`, indicating exit from the containing loop. 4. `continue s`: The block exited via a `continue` command with state `s`, indicating continuation to the next iteration of the containing loop. Here, `α` is the return type of the normal exit, `β` is the return type of the early exit, and `σ` is the type of the mutable state carried through the computation.
DoResultPR inductive
(α β σ : Type u)
Full source
/--
Auxiliary type used to compile `do` notation. It is the same as
`DoResultPRBC α β σ` except that `break` and `continue` are not available
because we are not in a loop context.
-/
inductive DoResultPR (α β σ : Type u) where
  /-- `pure (a : α) s` means that the block exited normally with return value `a` -/
  | pure   : α → σ → DoResultPR α β σ
  /-- `return (b : β) s` means that the block exited via a `return b` early-exit command -/
  | return : β → σ → DoResultPR α β σ
`do` Block Result Type (Pure/Return Variant)
Informal description
The inductive type `DoResultPR` represents possible outcomes of a `do` block computation, parameterized by types `α`, `β`, and `σ`. It is used to compile `do` notation and is similar to `DoResultPRBC` but without support for `break` and `continue` operations since it is not in a loop context.
DoResultBC inductive
(σ : Type u)
Full source
/--
Auxiliary type used to compile `do` notation. It is an optimization of
`DoResultPRBC PEmpty PEmpty σ` to remove the impossible cases,
used when neither `pure` nor `return` are possible exit paths.
-/
inductive DoResultBC (σ : Type u) where
  /-- `break s` means that `break` was called, meaning that we should exit
  from the containing loop -/
  | break    : σ → DoResultBC σ
  /-- `continue s` means that `continue` was called, meaning that we should continue
  to the next iteration of the containing loop -/
  | continue : σ → DoResultBC σ
Do-block result type (basic continuation case)
Informal description
The inductive type `DoResultBC` is an auxiliary type used in the compilation of `do` notation in Lean. It represents possible results of a `do` block where neither `pure` nor `return` are possible exit paths, with a single type parameter `σ` representing the state type.
DoResultSBC inductive
(α σ : Type u)
Full source
/--
Auxiliary type used to compile `do` notation. It is an optimization of
either `DoResultPRBC α PEmpty σ` or `DoResultPRBC PEmpty α σ` to remove the
impossible case, used when either `pure` or `return` is never used.
-/
inductive DoResultSBC (α σ : Type u) where
  /-- This encodes either `pure (a : α)` or `return (a : α)`:
  * `pure (a : α) s` means that the block exited normally with return value `a`
  * `return (b : β) s` means that the block exited via a `return b` early-exit command

  The one that is actually encoded depends on the context of use. -/
  | pureReturn : α → σ → DoResultSBC α σ
  /-- `break s` means that `break` was called, meaning that we should exit
  from the containing loop -/
  | break    : σ → DoResultSBC α σ
  /-- `continue s` means that `continue` was called, meaning that we should continue
  to the next iteration of the containing loop -/
  | continue   : σ → DoResultSBC α σ
Do-notation result type (single branch case)
Informal description
The inductive type `DoResultSBC` is an auxiliary type used in the compilation of `do` notation, representing a result with two type parameters `α` and `σ`. It serves as an optimization for cases where either `pure` or `return` operations are never used in the computation.
HasEquiv structure
(α : Sort u)
Full source
/-- `HasEquiv α` is the typeclass which supports the notation `x ≈ y` where `x y : α`.-/
class HasEquiv (α : Sort u) where
  /-- `x ≈ y` says that `x` and `y` are equivalent. Because this is a typeclass,
  the notion of equivalence is type-dependent. -/
  Equiv : α → α → Sort v
Equivalence Relation Typeclass
Informal description
The structure `HasEquiv α` is a typeclass that enables the notation `x ≈ y` for elements `x, y : α`, representing an equivalence relation on the type `α`.
term_≈_ definition
: Lean.TrailingParserDescr✝
Full source
@[inherit_doc] infix:50 " ≈ "  => HasEquiv.Equiv
Equivalence relation notation (`≈`)
Informal description
The notation `x ≈ y` is defined as an infix operator with precedence 50, representing the equivalence relation `HasEquiv.Equiv` between elements `x` and `y` of a type that has an instance of the `HasEquiv` typeclass.
HasSubset structure
(α : Type u)
Full source
/-- Notation type class for the subset relation `⊆`. -/
class HasSubset (α : Type u) where
  /-- Subset relation: `a ⊆ b`  -/
  Subset : α → α → Prop
Subset notation type class
Informal description
The type class `HasSubset` provides notation for the subset relation `⊆` on a type `α`.
HasSSubset structure
(α : Type u)
Full source
/-- Notation type class for the strict subset relation `⊂`. -/
class HasSSubset (α : Type u) where
  /-- Strict subset relation: `a ⊂ b`  -/
  SSubset : α → α → Prop
Strict subset notation
Informal description
The type class `HasSSubset` provides notation for the strict subset relation `⊂` on a type `α`. This is used to denote that one set is strictly contained within another, meaning it is a subset but not equal.
Superset abbrev
[HasSubset α] (a b : α)
Full source
/-- Superset relation: `a ⊇ b`  -/
abbrev Superset [HasSubset α] (a b : α) := Subset b a
Superset Relation: $a \supseteq b$
Informal description
For a type $\alpha$ with a subset relation $\subseteq$, the superset relation $\supseteq$ is defined such that $a \supseteq b$ if and only if $b \subseteq a$.
SSuperset abbrev
[HasSSubset α] (a b : α)
Full source
/-- Strict superset relation: `a ⊃ b`  -/
abbrev SSuperset [HasSSubset α] (a b : α) := SSubset b a
Strict Superset Relation: $a \supset b$
Informal description
For a type $\alpha$ with a strict subset relation $\subset$, the strict superset relation $\supset$ is defined such that $a \supset b$ if and only if $b \subset a$.
Union structure
(α : Type u)
Full source
/-- Notation type class for the union operation `∪`. -/
class Union (α : Type u) where
  /-- `a ∪ b` is the union of`a` and `b`. -/
  union : α → α → α
Union operation
Informal description
The structure representing the union operation `∪` on a type `α`, which combines two sets into a new set containing all elements from either of the original sets.
Inter structure
(α : Type u)
Full source
/-- Notation type class for the intersection operation `∩`. -/
class Inter (α : Type u) where
  /-- `a ∩ b` is the intersection of`a` and `b`. -/
  inter : α → α → α
Set Intersection
Informal description
The structure representing the intersection operation `∩` on a type `α`. This is used to define the notation for set intersection.
SDiff structure
(α : Type u)
Full source
/-- Notation type class for the set difference `\`. -/
class SDiff (α : Type u) where
  /--
  `a \ b` is the set difference of `a` and `b`,
  consisting of all elements in `a` that are not in `b`.
  -/
  sdiff : α → α → α
Set Difference Operation
Informal description
The structure representing the set difference operation `\` on a type `α`. This is a type class that provides notation for the set difference between two sets of elements of type `α`.
EmptyCollection structure
(α : Type u)
Full source
/-- `EmptyCollection α` is the typeclass which supports the notation `∅`, also written as `{}`. -/
class EmptyCollection (α : Type u) where
  /-- `∅` or `{}` is the empty set or empty collection.
  It is supported by the `EmptyCollection` typeclass. -/
  emptyCollection : α
Empty Collection Typeclass
Informal description
The structure `EmptyCollection α` is a typeclass that provides support for the empty collection notation `∅` (or `{}`) for a type `α`.
Insert structure
(α : outParam <| Type u) (γ : Type v)
Full source
/--
Type class for the `insert` operation.
Used to implement the `{ a, b, c }` syntax.
-/
class Insert (α : outParam <| Type u) (γ : Type v) where
  /-- `insert x xs` inserts the element `x` into the collection `xs`. -/
  insert : α → γ → γ
Insert operation type class
Informal description
The structure `Insert` is a type class for the `insert` operation, which is used to implement the syntax `{a, b, c}` for inserting elements into a collection of type `γ`. Here, `α` is an output parameter representing the type of elements being inserted.
Singleton structure
(α : outParam <| Type u) (β : Type v)
Full source
/--
Type class for the `singleton` operation.
Used to implement the `{ a, b, c }` syntax.
-/
class Singleton (α : outParam <| Type u) (β : Type v) where
  /-- `singleton x` is a collection with the single element `x` (notation: `{x}`). -/
  singleton : α → β
Singleton collection type class
Informal description
The structure `Singleton` is a type class for the operation that creates a singleton collection containing a single element of type `α` in a collection type `β`. This is used to implement the syntax `{a}` for singleton sets.
LawfulSingleton structure
(α : Type u) (β : Type v) [EmptyCollection β] [Insert α β] [Singleton α β]
Full source
/-- `insert x ∅ = {x}` -/
class LawfulSingleton (α : Type u) (β : Type v) [EmptyCollection β] [Insert α β] [Singleton α β] :
    Prop where
  /-- `insert x ∅ = {x}` -/
  insert_empty_eq (x : α) : (insert x  : β) = singleton x
Lawful Singleton Collection
Informal description
The structure `LawfulSingleton` is a type class that ensures the consistency between the operations `insert`, `singleton`, and the empty collection `∅` for a type `β` with elements of type `α`. Specifically, it guarantees that inserting an element `x` into the empty collection `∅` results in the singleton collection `{x}`.
insert_emptyc_eq theorem
[EmptyCollection β] [Insert α β] [Singleton α β] [LawfulSingleton α β] (x : α) : (insert x ∅ : β) = singleton x
Full source
@[deprecated insert_empty_eq (since := "2025-03-12")]
theorem insert_emptyc_eq [EmptyCollection β] [Insert α β] [Singleton α β]
    [LawfulSingleton α β] (x : α) : (insert x  : β) = singleton x :=
  insert_empty_eq _
Insertion into Empty Collection Yields Singleton: $\text{insert}(x, \emptyset) = \{x\}$
Informal description
For any type $\beta$ with an empty collection $\emptyset$ and insertion operation, if $\beta$ has a lawful singleton structure, then inserting an element $x$ of type $\alpha$ into the empty collection yields the singleton set $\{x\}$, i.e., $\text{insert}(x, \emptyset) = \{x\}$.
LawfulSingleton.insert_emptyc_eq theorem
[EmptyCollection β] [Insert α β] [Singleton α β] [LawfulSingleton α β] (x : α) : (insert x ∅ : β) = singleton x
Full source
@[deprecated insert_empty_eq (since := "2025-03-12")]
theorem LawfulSingleton.insert_emptyc_eq [EmptyCollection β] [Insert α β] [Singleton α β]
    [LawfulSingleton α β] (x : α) : (insert x  : β) = singleton x :=
  insert_empty_eq _
Insertion into Empty Collection Yields Singleton: $\text{insert}(x, \emptyset) = \{x\}$
Informal description
For any type $\beta$ with an empty collection $\emptyset$, an insertion operation, and a lawful singleton structure, inserting an element $x$ of type $\alpha$ into the empty collection yields the singleton set $\{x\}$, i.e., $\text{insert}(x, \emptyset) = \{x\}$.
Sep structure
(α : outParam <| Type u) (γ : Type v)
Full source
/-- Type class used to implement the notation `{ a ∈ c | p a }` -/
class Sep (α : outParam <| Type u) (γ : Type v) where
  /-- Computes `{ a ∈ c | p a }`. -/
  sep : (α → Prop) → γ → γ
Set-builder notation type class
Informal description
The structure `Sep` is used to implement the notation `{ a ∈ c | p a }` for set-builder notation, where `α` is an output parameter representing the type of elements in the collection `γ`.
Task structure
(α : Type u)
Full source
/--
`Task α` is a primitive for asynchronous computation.
It represents a computation that will resolve to a value of type `α`,
possibly being computed on another thread. This is similar to `Future` in Scala,
`Promise` in Javascript, and `JoinHandle` in Rust.

The tasks have an overridden representation in the runtime.
-/
structure Task (α : Type u) : Type u where
  /-- `Task.pure (a : α)` constructs a task that is already resolved with value `a`. -/
  pure ::
  /--
  Blocks the current thread until the given task has finished execution, and then returns the result
  of the task. If the current thread is itself executing a (non-dedicated) task, the maximum
  threadpool size is temporarily increased by one while waiting so as to ensure the process cannot
  be deadlocked by threadpool starvation. Note that when the current thread is unblocked, more tasks
  than the configured threadpool size may temporarily be running at the same time until sufficiently
  many tasks have finished.

  `Task.map` and `Task.bind` should be preferred over `Task.get` for setting up task dependencies
  where possible as they do not require temporarily growing the threadpool in this way.
  -/
  get : α
  deriving Inhabited, Nonempty
Asynchronous Task
Informal description
The structure `Task α` represents an asynchronous computation that will eventually produce a value of type `α`. This computation may be performed on a separate thread, similar to `Future` in Scala, `Promise` in JavaScript, or `JoinHandle` in Rust.
instInhabitedTask instance
{a✝} [Inhabited✝ a✝] : Inhabited✝ (@Task a✝)
Full source
Inhabited, Nonempty
Inhabitedness of Task Types from Inhabited Base Types
Informal description
For any inhabited type `α`, the type `Task α` of asynchronous computations producing values of type `α` is also inhabited, with a default task that produces the default value of `α`.
instNonemptyTask instance
: Nonempty✝ (@Task✝ α✝)
Full source
Nonempty
Nonemptiness of Task Types
Informal description
For any type $\alpha$, the type `Task α` of asynchronous computations producing values of type $\alpha$ is nonempty.
Task.Priority abbrev
Full source
/--
Task priority.

Tasks with higher priority will always be scheduled before tasks with lower priority. Tasks with a
priority greater than `Task.Priority.max` are scheduled on dedicated threads.
-/
abbrev Priority := Nat
Task Priority Abstraction
Informal description
Task priority is an abstraction representing the scheduling priority of tasks. Tasks with higher priority values are scheduled before those with lower priority. The priority values range from a default value up to a maximum value (`Task.Priority.max`), with priorities above this maximum being scheduled on dedicated threads.
Task.Priority.default definition
: Priority
Full source
/-- The default priority for spawned tasks, also the lowest priority: `0`. -/
def Priority.default : Priority := 0
Default task priority
Informal description
The default priority value for spawned tasks, which is also the lowest priority value: $0$.
Task.Priority.max definition
: Priority
Full source
/--
The highest regular priority for spawned tasks: `8`.

Spawning a task with a priority higher than `Task.Priority.max` is not an error but will spawn a
dedicated worker for the task. This is indicated using `Task.Priority.dedicated`. Regular priority
tasks are placed in a thread pool and worked on according to their priority order.
-/
-- see `LEAN_MAX_PRIO`
def Priority.max : Priority := 8
Maximum task priority
Informal description
The maximum priority value for regular tasks, set to $8$. Tasks with priority higher than this value are scheduled on dedicated threads.
Task.Priority.dedicated definition
: Priority
Full source
/--
Indicates that a task should be scheduled on a dedicated thread.

Any priority higher than `Task.Priority.max` will result in the task being scheduled
immediately on a dedicated thread. This is particularly useful for long-running and/or
I/O-bound tasks since Lean will, by default, allocate no more non-dedicated workers
than the number of cores to reduce context switches.
-/
def Priority.dedicated : Priority := 9
Dedicated thread task priority
Informal description
The priority value for tasks that should be scheduled on a dedicated thread, set to $9$. Any task with priority higher than the maximum regular priority (`Task.Priority.max`) will be scheduled immediately on a dedicated thread, which is particularly useful for long-running or I/O-bound tasks.
NonScalar structure
Full source
/--
`NonScalar` is a type that is not a scalar value in our runtime.
It is used as a stand-in for an arbitrary boxed value to avoid excessive
monomorphization, and it is only created using `unsafeCast`. It is somewhat
analogous to C `void*` in usage, but the type itself is not special.
-/
structure NonScalar where
  /-- You should not use this function -/ mk ::
  /-- You should not use this function -/ val : Nat
Non-scalar runtime value placeholder
Informal description
The structure `NonScalar` represents a type that is not a scalar value in the runtime system. It serves as a placeholder for arbitrary boxed values to prevent excessive monomorphization and is only created using unsafe casting operations. Its usage is somewhat analogous to C's `void*` pointer type, though the type itself is not specially treated by the system.
PNonScalar inductive
: Type u
Full source
/--
`PNonScalar` is a type that is not a scalar value in our runtime.
It is used as a stand-in for an arbitrary boxed value to avoid excessive
monomorphization, and it is only created using `unsafeCast`. It is somewhat
analogous to C `void*` in usage, but the type itself is not special.

This is the universe-polymorphic version of `PNonScalar`; it is preferred to use
`NonScalar` instead where applicable.
-/
inductive PNonScalar : Type u where
  /-- You should not use this function -/
  | mk (v : Nat) : PNonScalar
Universe-polymorphic non-scalar type
Informal description
The inductive type `PNonScalar` represents a type that is not a scalar value in the runtime. It serves as a placeholder for arbitrary boxed values to prevent excessive monomorphization and is only created using `unsafeCast`. This type is analogous to `void*` in C but is not treated specially in the type system. The universe-polymorphic version is preferred to be used as `NonScalar` where applicable.
Nat.add_zero theorem
(n : Nat) : n + 0 = n
Full source
@[simp] protected theorem Nat.add_zero (n : Nat) : n + 0 = n := rfl
Right Additive Identity for Natural Numbers
Informal description
For any natural number $n$, the sum of $n$ and $0$ is equal to $n$, i.e., $n + 0 = n$.
optParam_eq theorem
(α : Sort u) (default : α) : optParam α default = α
Full source
theorem optParam_eq (α : Sort u) (default : α) : optParam α default = α := rfl
Equality of Optional Parameter Type with Base Type
Informal description
For any type $\alpha$ and any default value `default` of type $\alpha$, the type `optParam α default` is equal to $\alpha$.
strictOr definition
(b₁ b₂ : Bool)
Full source
/--
`strictOr` is the same as `or`, but it does not use short-circuit evaluation semantics:
both sides are evaluated, even if the first value is `true`.
-/
@[extern "lean_strict_or"] def strictOr  (b₁ b₂ : Bool) := b₁ || b₂
Strict Boolean OR
Informal description
The function `strictOr` takes two Boolean values `b₁` and `b₂` and returns their disjunction `b₁ ∨ b₂`. Unlike the standard Boolean `or` operation, `strictOr` evaluates both arguments even if the first one is `true`.
strictAnd definition
(b₁ b₂ : Bool)
Full source
/--
`strictAnd` is the same as `and`, but it does not use short-circuit evaluation semantics:
both sides are evaluated, even if the first value is `false`.
-/
@[extern "lean_strict_and"] def strictAnd (b₁ b₂ : Bool) := b₁ && b₂
Strict Boolean AND
Informal description
The function `strictAnd` takes two Boolean values `b₁` and `b₂` and returns their conjunction `b₁ && b₂`. Unlike the standard Boolean `and` operation, `strictAnd` evaluates both arguments even if the first one is `false`.
bne definition
{α : Type u} [BEq α] (a b : α) : Bool
Full source
/--
`x != y` is boolean not-equal. It is the negation of `x == y` which is supplied by
the `BEq` typeclass.

Unlike `x ≠ y` (which is notation for `Ne x y`), this is `Bool` valued instead of
`Prop` valued. It is mainly intended for programming applications.
-/
@[inline] def bne {α : Type u} [BEq α] (a b : α) : Bool :=
  !(a == b)
Boolean not-equal operation
Informal description
The function `bne` takes two elements `a` and `b` of type `α` equipped with a boolean equality relation `==` (via the `BEq` typeclass), and returns the boolean negation of `a == b`. This provides a boolean-valued not-equal operation, distinct from the propositional inequality `≠`.
term_!=_ definition
: Lean.TrailingParserDescr✝
Full source
@[inherit_doc] infix:50 " != " => bne
Boolean not-equal operator (`!=`)
Informal description
The infix notation `!=` is defined as the boolean not-equal operation `bne`, which checks if two elements are not equal according to the `BEq` typeclass and returns a boolean result.
LawfulBEq structure
(α : Type u) [BEq α]
Full source
/--
A Boolean equality test coincides with propositional equality.

In other words:
 * `a == b` implies `a = b`.
 * `a == a` is true.
-/
class LawfulBEq (α : Type u) [BEq α] : Prop where
  /-- If `a == b` evaluates to `true`, then `a` and `b` are equal in the logic. -/
  eq_of_beq : {a b : α} → a == b → a = b
  /-- `==` is reflexive, that is, `(a == a) = true`. -/
  protected rfl : {a : α} → a == a
Lawful Boolean Equality
Informal description
A structure `LawfulBEq α` asserts that the boolean equality test `==` on a type `α` coincides with propositional equality `=`. Specifically: 1. If `a == b` evaluates to `true`, then `a = b` holds. 2. For any `a : α`, the test `a == a` evaluates to `true`.
instLawfulBEqBool instance
: LawfulBEq Bool
Full source
instance : LawfulBEq Bool where
  eq_of_beq {a b} h := by cases a <;> cases b <;> first | rfl | contradiction
  rfl {a} := by cases a <;> decide
Lawful Boolean Equality for the Boolean Type
Informal description
The boolean type $\mathtt{Bool}$ has a lawful boolean equality structure, meaning that the boolean equality operator `==` coincides with propositional equality `=`. Specifically: 1. For any boolean values $a$ and $b$, if $a == b$ evaluates to $\mathtt{true}$, then $a = b$ holds. 2. For any boolean value $a$, the test $a == a$ evaluates to $\mathtt{true}$.
instLawfulBEq instance
[DecidableEq α] : LawfulBEq α
Full source
instance [DecidableEq α] : LawfulBEq α where
  eq_of_beq := of_decide_eq_true
  rfl := of_decide_eq_self_eq_true _
Lawful Boolean Equality for Types with Decidable Equality
Informal description
For any type $\alpha$ with decidable equality, the boolean equality operator `==` on $\alpha$ is lawful, meaning it coincides with propositional equality. Specifically: 1. If `a == b` evaluates to `true`, then `a = b` holds. 2. For any `a : α`, the test `a == a` evaluates to `true`.
instLawfulBEqChar instance
: LawfulBEq Char
Full source
instance : LawfulBEq Char := inferInstance
Lawful Boolean Equality for Unicode Characters
Informal description
The boolean equality operator `==` on Unicode characters is lawful, meaning it coincides with propositional equality. Specifically: 1. For any characters $c$ and $d$, if $c == d$ evaluates to `true`, then $c = d$ holds. 2. For any character $c$, the test $c == c$ evaluates to `true$.
instLawfulBEqString instance
: LawfulBEq String
Full source
instance : LawfulBEq String := inferInstance
Lawful Boolean Equality for Strings
Informal description
The boolean equality operator `==` on strings is lawful, meaning it coincides with propositional equality. Specifically: 1. For any strings $s_1$ and $s_2$, if $s_1 == s_2$ evaluates to `true`, then $s_1 = s_2$ holds. 2. For any string $s$, the test $s == s$ evaluates to `true$.
trivial theorem
: True
Full source
@[inherit_doc True.intro] theorem trivial : True := ⟨⟩
Trivial Truth ($\text{True}$)
Informal description
The proposition $\text{True}$ holds.
mt theorem
{a b : Prop} (h₁ : a → b) (h₂ : ¬b) : ¬a
Full source
theorem mt {a b : Prop} (h₁ : a → b) (h₂ : ¬b) : ¬a :=
  fun ha => h₂ (h₁ ha)
Modus Tollens: $\neg b$ from $a \to b$ and $\neg a$
Informal description
For any propositions $a$ and $b$, if $a$ implies $b$ ($a \to b$) and $b$ is false ($\neg b$), then $a$ is false ($\neg a$).
not_false theorem
: ¬False
Full source
theorem not_false : ¬False := id
Negation of False Holds ($\neg \text{False}$)
Informal description
The negation of the false proposition holds, i.e., $\neg \text{False}$.
not_not_intro theorem
{p : Prop} (h : p) : ¬¬p
Full source
theorem not_not_intro {p : Prop} (h : p) : ¬ ¬ p :=
  fun hn : ¬ p => hn h
Double Negation Introduction: $p \to \neg \neg p$
Informal description
For any proposition $p$, if $p$ holds, then the double negation of $p$ holds, i.e., $\neg \neg p$.
Eq.mp definition
{α β : Sort u} (h : α = β) (a : α) : β
Full source
/--
If `h : α = β` is a proof of type equality, then `h.mp : α → β` is the induced
"cast" operation, mapping elements of `α` to elements of `β`.

You can prove theorems about the resulting element by induction on `h`, since
`rfl.mp` is definitionally the identity function.
-/
@[macro_inline] def Eq.mp {α β : Sort u} (h : α = β) (a : α) : β :=
  h ▸ a
Type cast via equality proof
Informal description
Given a proof $h : \alpha = \beta$ of type equality, the function $\text{Eq.mp}\ h$ maps an element $a$ of type $\alpha$ to the corresponding element of type $\beta$ by casting along $h$.
Eq.mpr definition
{α β : Sort u} (h : α = β) (b : β) : α
Full source
/--
If `h : α = β` is a proof of type equality, then `h.mpr : β → α` is the induced
"cast" operation in the reverse direction, mapping elements of `β` to elements of `α`.

You can prove theorems about the resulting element by induction on `h`, since
`rfl.mpr` is definitionally the identity function.
-/
@[macro_inline] def Eq.mpr {α β : Sort u} (h : α = β) (b : β) : α :=
  h ▸ b
Reverse type cast via equality proof
Informal description
Given a proof $h : \alpha = \beta$ of type equality, the function $\text{Eq.mpr}\ h$ maps an element $b$ of type $\beta$ to the corresponding element of type $\alpha$ by casting along $h$ in the reverse direction. This is the inverse operation of $\text{Eq.mp}\ h$.
Eq.substr theorem
{α : Sort u} {p : α → Prop} {a b : α} (h₁ : b = a) (h₂ : p a) : p b
Full source
@[elab_as_elim]
theorem Eq.substr {α : Sort u} {p : α → Prop} {a b : α} (h₁ : b = a) (h₂ : p a) : p b :=
  h₁ ▸ h₂
Substitution Property of Equality: $b = a \land p(a) \implies p(b)$
Informal description
For any type $\alpha$, property $p$ on $\alpha$, and elements $a, b \in \alpha$, if $b = a$ and $p(a)$ holds, then $p(b)$ holds.
cast_eq theorem
{α : Sort u} (h : α = α) (a : α) : cast h a = a
Full source
@[simp] theorem cast_eq {α : Sort u} (h : α = α) (a : α) : cast h a = a :=
  rfl
Identity Cast Preserves Equality
Informal description
For any type $\alpha$, given a proof $h$ that $\alpha$ is equal to itself and an element $a : \alpha$, the cast of $a$ along $h$ is equal to $a$ itself, i.e., $\text{cast}(h, a) = a$.
Ne definition
{α : Sort u} (a b : α)
Full source
/--
`a ≠ b`, or `Ne a b` is defined as `¬ (a = b)` or `a = b → False`,
and asserts that `a` and `b` are not equal.
-/
@[reducible] def Ne {α : Sort u} (a b : α) :=
  ¬(a = b)
Inequality relation
Informal description
For elements \( a \) and \( b \) of a type \( \alpha \), the relation \( a \neq b \) is defined as the negation of \( a = b \), meaning \( a \neq b \) holds if and only if \( a = b \) implies a contradiction.
term_≠_ definition
: Lean.TrailingParserDescr✝
Full source
@[inherit_doc] infix:50 " ≠ "  => Ne
Inequality notation
Informal description
The notation `≠` is defined as the infix operator for the inequality relation `Ne`, meaning `a ≠ b` is equivalent to `¬(a = b)`.
Ne.intro theorem
(h : a = b → False) : a ≠ b
Full source
theorem Ne.intro (h : a = b → False) : a ≠ b := h
Introduction Rule for Inequality: $a = b \to \text{False}$ implies $a \neq b$
Informal description
For any elements $a$ and $b$ of a type $\alpha$, if the assumption $a = b$ leads to a contradiction, then $a \neq b$.
Ne.elim theorem
(h : a ≠ b) : a = b → False
Full source
theorem Ne.elim (h : a ≠ b) : a = b → False := h
Inequality Implies Contradiction from Equality
Informal description
For any elements $a$ and $b$ of a type $\alpha$, if $a \neq b$, then the equality $a = b$ implies a contradiction (i.e., $\text{False}$).
Ne.irrefl theorem
(h : a ≠ a) : False
Full source
theorem Ne.irrefl (h : a ≠ a) : False := h rfl
Irreflexivity of Inequality: $a \neq a$ is False
Informal description
For any element $a$ of a type $\alpha$, the assumption $a \neq a$ leads to a contradiction (i.e., $\text{False}$).
Ne.symm theorem
(h : a ≠ b) : b ≠ a
Full source
@[symm] theorem Ne.symm (h : a ≠ b) : b ≠ a := fun h₁ => h (h₁.symm)
Symmetry of Inequality: $a \neq b \implies b \neq a$
Informal description
For any elements $a$ and $b$ of a type $\alpha$, if $a \neq b$, then $b \neq a$.
ne_comm theorem
{α} {a b : α} : a ≠ b ↔ b ≠ a
Full source
theorem ne_comm {α} {a b : α} : a ≠ ba ≠ b ↔ b ≠ a := ⟨Ne.symm, Ne.symm⟩
Commutativity of Inequality: $a \neq b \leftrightarrow b \neq a$
Informal description
For any elements $a$ and $b$ of a type $\alpha$, the inequality $a \neq b$ holds if and only if $b \neq a$ holds.
false_of_ne theorem
: a ≠ a → False
Full source
theorem false_of_ne : a ≠ aFalse := Ne.irrefl
Irreflexivity of Inequality: $a \neq a \to \text{False}$
Informal description
For any element $a$ of a type $\alpha$, the inequality $a \neq a$ implies a contradiction (i.e., $\text{False}$).
ne_false_of_self theorem
: p → p ≠ False
Full source
theorem ne_false_of_self : p → p ≠ False :=
  fun (hp : p) (h : p = False) => h ▸ hp
Truth Implies Inequality with False: $p \to p \neq \text{False}$
Informal description
For any proposition $p$, if $p$ holds, then $p$ is not equal to $\text{False}$.
ne_true_of_not theorem
: ¬p → p ≠ True
Full source
theorem ne_true_of_not : ¬pp ≠ True :=
  fun (hnp : ¬p) (h : p = True) =>
    have : ¬True := h ▸ hnp
    this trivial
Negation Implies Inequality with True: $\neg p \to p \neq \text{True}$
Informal description
For any proposition $p$, if $\neg p$ holds, then $p$ is not equal to $\text{True}$.
true_ne_false theorem
: ¬True = False
Full source
theorem true_ne_false : ¬True = False := ne_false_of_self trivial
Inequality of True and False: $\text{True} \neq \text{False}$
Informal description
The proposition $\text{True}$ is not equal to $\text{False}$, i.e., $\text{True} \neq \text{False}$.
false_ne_true theorem
: False ≠ True
Full source
theorem false_ne_true : FalseFalse ≠ True := fun h => h.symmtrivial
Inequality of False and True: $\text{False} \neq \text{True}$
Informal description
The proposition $\text{False}$ is not equal to $\text{True}$, i.e., $\text{False} \neq \text{True}$.
Bool.of_not_eq_true theorem
: {b : Bool} → ¬(b = true) → b = false
Full source
theorem Bool.of_not_eq_true : {b : Bool} → ¬ (b = true) → b = false
  | true,  h => absurd rfl h
  | false, _ => rfl
Boolean Negation Implies Falsity: $\neg(b = \text{true}) \to b = \text{false}$
Informal description
For any Boolean value $b$, if $b$ is not equal to `true`, then $b$ must be equal to `false$.
Bool.of_not_eq_false theorem
: {b : Bool} → ¬(b = false) → b = true
Full source
theorem Bool.of_not_eq_false : {b : Bool} → ¬ (b = false) → b = true
  | true,  _ => rfl
  | false, h => absurd rfl h
Boolean Negation Implies Truth: $\neg(b = \text{false}) \to b = \text{true}$
Informal description
For any Boolean value $b$, if $b$ is not equal to `false`, then $b$ must be equal to `true`.
ne_of_beq_false theorem
[BEq α] [LawfulBEq α] {a b : α} (h : (a == b) = false) : a ≠ b
Full source
theorem ne_of_beq_false [BEq α] [LawfulBEq α] {a b : α} (h : (a == b) = false) : a ≠ b := by
  intro h'; subst h'; have : true = false := Eq.trans LawfulBEq.rfl.symm h; contradiction
False Boolean Equality Implies Inequality: $(a == b) = \text{false} \to a \neq b$
Informal description
For any type $\alpha$ with a boolean equality relation `==` that is lawful (i.e., agrees with propositional equality), and for any elements $a, b \in \alpha$ such that the boolean equality test evaluates to `false`, i.e., $(a == b) = \text{false}$, it follows that $a \neq b$.
beq_false_of_ne theorem
[BEq α] [LawfulBEq α] {a b : α} (h : a ≠ b) : (a == b) = false
Full source
theorem beq_false_of_ne [BEq α] [LawfulBEq α] {a b : α} (h : a ≠ b) : (a == b) = false :=
  have : ¬ (a == b) = true := by
    intro h'; rw [eq_of_beq h'] at h; contradiction
  Bool.of_not_eq_true this
Boolean Inequality Implies False Equality: $a \neq b \to (a == b) = \text{false}$
Informal description
For any type $\alpha$ with a boolean equality relation `==` that is lawful (i.e., agrees with propositional equality), and for any elements $a, b \in \alpha$ such that $a \neq b$, the boolean equality test evaluates to `false`, i.e., $(a == b) = \text{false}$.
HEq.ndrec definition
{α : Sort u2} {a : α} {motive : {β : Sort u2} → β → Sort u1} (m : motive a) {β : Sort u2} {b : β} (h : HEq a b) : motive b
Full source
/-- Non-dependent recursor for `HEq` -/
noncomputable def HEq.ndrec.{u1, u2} {α : Sort u2} {a : α} {motive : {β : Sort u2} → β → Sort u1} (m : motive a) {β : Sort u2} {b : β} (h : HEq a b) : motive b :=
  h.rec m
Non-dependent recursor for heterogeneous equality
Informal description
Given a type $\alpha$, an element $a : \alpha$, a motive (dependent type family) $\text{motive} : \{\beta : \text{Sort } u_2\} \to \beta \to \text{Sort } u_1$, and an element $m : \text{motive } a$, if $b : \beta$ is heterogeneously equal to $a$ (i.e., $a \approx b$), then the element $m$ can be transported to $\text{motive } b$.
HEq.ndrecOn definition
{α : Sort u2} {a : α} {motive : {β : Sort u2} → β → Sort u1} {β : Sort u2} {b : β} (h : HEq a b) (m : motive a) : motive b
Full source
/-- `HEq.ndrec` variant -/
noncomputable def HEq.ndrecOn.{u1, u2} {α : Sort u2} {a : α} {motive : {β : Sort u2} → β → Sort u1} {β : Sort u2} {b : β} (h : HEq a b) (m : motive a) : motive b :=
  h.rec m
Non-dependent recursor for heterogeneous equality
Informal description
Given a type $\alpha$, an element $a : \alpha$, a dependent type family $\text{motive} : \{\beta : \text{Sort } u_2\} \to \beta \to \text{Sort } u_1$, and an element $m : \text{motive } a$, if $b : \beta$ is heterogeneously equal to $a$ (i.e., $a \approx b$), then the element $m$ can be transported to $\text{motive } b$. This is the non-dependent version of the recursor for heterogeneous equality.
HEq.elim definition
{α : Sort u} {a : α} {p : α → Sort v} {b : α} (h₁ : HEq a b) (h₂ : p a) : p b
Full source
/-- `HEq.ndrec` variant -/
noncomputable def HEq.elim {α : Sort u} {a : α} {p : α → Sort v} {b : α} (h₁ : HEq a b) (h₂ : p a) : p b :=
  eq_of_heq h₁ ▸ h₂
Elimination rule for heterogeneous equality
Informal description
Given a predicate $p$ on elements of type $\alpha$, if $a$ and $b$ are heterogeneously equal (i.e., $a \approx b$) and $p(a)$ holds, then $p(b)$ also holds.
HEq.subst theorem
{p : (T : Sort u) → T → Prop} (h₁ : HEq a b) (h₂ : p α a) : p β b
Full source
/-- Substitution with heterogeneous equality. -/
theorem HEq.subst {p : (T : Sort u) → T → Prop} (h₁ : HEq a b) (h₂ : p α a) : p β b :=
  HEq.ndrecOn h₁ h₂
Substitution Property for Heterogeneous Equality
Informal description
Given a predicate $p$ on elements of arbitrary types, if $a : \alpha$ and $b : \beta$ are heterogeneously equal (denoted $a \approx b$), and $p(\alpha, a)$ holds, then $p(\beta, b)$ also holds.
HEq.symm theorem
(h : HEq a b) : HEq b a
Full source
/-- Heterogeneous equality is symmetric. -/
@[symm] theorem HEq.symm (h : HEq a b) : HEq b a :=
  h.rec (HEq.refl a)
Symmetry of Heterogeneous Equality
Informal description
For any elements $a$ and $b$ of potentially different types, if $a$ is heterogeneously equal to $b$ (denoted $a \approx b$), then $b$ is heterogeneously equal to $a$ (denoted $b \approx a$).
heq_of_eq theorem
(h : a = a') : HEq a a'
Full source
/-- Propositionally equal terms are also heterogeneously equal. -/
theorem heq_of_eq (h : a = a') : HEq a a' :=
  Eq.subst h (HEq.refl a)
Homogeneous Equality Implies Heterogeneous Equality ($a = a' \to a \approx a'$)
Informal description
For any elements $a$ and $a'$ of the same type, if $a = a'$ holds, then $a$ and $a'$ are also heterogeneously equal, denoted $a \approx a'$.
HEq.trans theorem
(h₁ : HEq a b) (h₂ : HEq b c) : HEq a c
Full source
/-- Heterogeneous equality is transitive. -/
theorem HEq.trans (h₁ : HEq a b) (h₂ : HEq b c) : HEq a c :=
  HEq.subst h₂ h₁
Transitivity of Heterogeneous Equality: $a \approx b \approx c \implies a \approx c$
Informal description
For any elements $a$, $b$, and $c$ of potentially different types, if $a$ is heterogeneously equal to $b$ (denoted $a \approx b$) and $b$ is heterogeneously equal to $c$ (denoted $b \approx c$), then $a$ is heterogeneously equal to $c$ (denoted $a \approx c$).
heq_of_heq_of_eq theorem
(h₁ : HEq a b) (h₂ : b = b') : HEq a b'
Full source
/-- Heterogeneous equality precomposes with propositional equality. -/
theorem heq_of_heq_of_eq (h₁ : HEq a b) (h₂ : b = b') : HEq a b' :=
  HEq.trans h₁ (heq_of_eq h₂)
Heterogeneous Equality Preservation under Homogeneous Equality ($a \approx b \land b = b' \implies a \approx b'$)
Informal description
Given elements $a$, $b$, and $b'$ where $a$ and $b$ are heterogeneously equal (denoted $a \approx b$) and $b$ is homogeneously equal to $b'$ (denoted $b = b'$), then $a$ is heterogeneously equal to $b'$ (denoted $a \approx b'$).
heq_of_eq_of_heq theorem
(h₁ : a = a') (h₂ : HEq a' b) : HEq a b
Full source
/-- Heterogeneous equality postcomposes with propositional equality. -/
theorem heq_of_eq_of_heq (h₁ : a = a') (h₂ : HEq a' b) : HEq a b :=
  HEq.trans (heq_of_eq h₁) h₂
Heterogeneous Equality via Homogeneous Equality: $a = a' \approx b \implies a \approx b$
Informal description
For any elements $a$, $a'$, and $b$ of potentially different types, if $a = a'$ holds and $a'$ is heterogeneously equal to $b$ (denoted $a' \approx b$), then $a$ is heterogeneously equal to $b$ (denoted $a \approx b$).
type_eq_of_heq theorem
(h : HEq a b) : α = β
Full source
/-- If two terms are heterogeneously equal then their types are propositionally equal. -/
theorem type_eq_of_heq (h : HEq a b) : α = β :=
  h.rec (Eq.refl α)
Type Equality from Heterogeneous Equality
Informal description
Given a heterogeneous equality `h : a ≈ b` between elements `a : α` and `b : β`, the types `α` and `β` are propositionally equal, i.e., $\alpha = \beta$.
eqRec_heq theorem
{α : Sort u} {φ : α → Sort v} {a a' : α} : (h : a = a') → (p : φ a) → HEq (Eq.recOn (motive := fun x _ => φ x) h p) p
Full source
/--
Rewriting inside `φ` using `Eq.recOn` yields a term that's heterogeneously equal to the original
term.
-/
theorem eqRec_heq {α : Sort u} {φ : α → Sort v} {a a' : α} : (h : a = a') → (p : φ a) → HEq (Eq.recOn (motive := fun x _ => φ x) h p) p
  | rfl, p => HEq.refl p
Heterogeneous Equality Preservation under Dependent Recursion
Informal description
For any type $\alpha$ and type family $\varphi : \alpha \to \text{Sort } v$, given elements $a, a' \in \alpha$ and a proof $h : a = a'$, for any term $p : \varphi(a)$, the term obtained by rewriting $p$ using $h$ via `Eq.recOn` is heterogeneously equal to $p$.
heq_of_eqRec_eq theorem
{α β : Sort u} {a : α} {b : β} (h₁ : α = β) (h₂ : Eq.rec (motive := fun α _ => α) a h₁ = b) : HEq a b
Full source
/--
If casting a term with `Eq.rec` to another type makes it equal to some other term, then the two
terms are heterogeneously equal.
-/
theorem heq_of_eqRec_eq {α β : Sort u} {a : α} {b : β} (h₁ : α = β) (h₂ : Eq.rec (motive := fun α _ => α) a h₁ = b) : HEq a b := by
  subst h₁
  apply heq_of_eq
  exact h₂
Heterogeneous Equality from Cast Equality via `Eq.rec`
Informal description
For any types $\alpha$ and $\beta$, and elements $a : \alpha$ and $b : \beta$, if $\alpha = \beta$ and the result of casting $a$ to type $\beta$ via `Eq.rec` equals $b$, then $a$ and $b$ are heterogeneously equal, denoted $a \approx b$.
cast_heq theorem
{α β : Sort u} : (h : α = β) → (a : α) → HEq (cast h a) a
Full source
/--
The result of casting a term with `cast` is heterogeneously equal to the original term.
-/
theorem cast_heq {α β : Sort u} : (h : α = β) → (a : α) → HEq (cast h a) a
  | rfl, a => HEq.refl a
Heterogeneous Equality of Cast Elements
Informal description
Given types $\alpha$ and $\beta$ and a proof $h : \alpha = \beta$, for any element $a : \alpha$, the cast of $a$ to type $\beta$ is heterogeneously equal to $a$ itself. That is, $\text{cast}(h, a) \approx a$.
iff_iff_implies_and_implies theorem
{a b : Prop} : (a ↔ b) ↔ (a → b) ∧ (b → a)
Full source
theorem iff_iff_implies_and_implies {a b : Prop} : (a ↔ b) ↔ (a → b) ∧ (b → a) :=
  Iff.intro (fun h => And.intro h.mp h.mpr) (fun h => Iff.intro h.left h.right)
Bi-implication Equivalence: $a \leftrightarrow b \iff (a \rightarrow b) \land (b \rightarrow a)$
Informal description
For any two propositions $a$ and $b$, the bi-implication $a \leftrightarrow b$ holds if and only if both $a \rightarrow b$ and $b \rightarrow a$ hold.
Iff.refl theorem
(a : Prop) : a ↔ a
Full source
@[refl] theorem Iff.refl (a : Prop) : a ↔ a :=
  Iff.intro (fun h => h) (fun h => h)
Reflexivity of Bi-implication
Informal description
For any proposition $a$, the bi-implication $a \leftrightarrow a$ holds.
Iff.rfl theorem
{a : Prop} : a ↔ a
Full source
protected theorem Iff.rfl {a : Prop} : a ↔ a :=
  Iff.refl a
Reflexivity of Bi-implication ($a \leftrightarrow a$)
Informal description
For any proposition $a$, the bi-implication $a \leftrightarrow a$ holds.
Iff.of_eq theorem
(h : a = b) : a ↔ b
Full source
theorem Iff.of_eq (h : a = b) : a ↔ b := h ▸ Iff.rfl
Equality Implies Logical Equivalence ($a = b \Rightarrow a \leftrightarrow b$)
Informal description
For any propositions $a$ and $b$, if $a = b$ then $a \leftrightarrow b$.
Iff.trans theorem
(h₁ : a ↔ b) (h₂ : b ↔ c) : a ↔ c
Full source
theorem Iff.trans (h₁ : a ↔ b) (h₂ : b ↔ c) : a ↔ c :=
  Iff.intro (h₂.mp ∘ h₁.mp) (h₁.mpr ∘ h₂.mpr)
Transitivity of Logical Equivalence ($a \leftrightarrow b \leftrightarrow c \Rightarrow a \leftrightarrow c$)
Informal description
For any propositions $a$, $b$, and $c$, if $a \leftrightarrow b$ and $b \leftrightarrow c$, then $a \leftrightarrow c$.
instTransIff instance
: Trans Iff Iff Iff
Full source
instance : Trans Iff Iff Iff where
  trans := Iff.trans
Transitivity of Logical Equivalence (`Iff`)
Informal description
The logical bi-implication relation `Iff` is transitive. That is, for any propositions $a$, $b$, and $c$, if $a \leftrightarrow b$ and $b \leftrightarrow c$, then $a \leftrightarrow c$.
Eq.comm theorem
{a b : α} : a = b ↔ b = a
Full source
theorem Eq.comm {a b : α} : a = b ↔ b = a := Iff.intro Eq.symm Eq.symm
Commutativity of Equality: $a = b \leftrightarrow b = a$
Informal description
For any elements $a$ and $b$ of a type $\alpha$, the equality $a = b$ holds if and only if $b = a$ holds.
HEq.comm theorem
{a : α} {b : β} : HEq a b ↔ HEq b a
Full source
theorem HEq.comm {a : α} {b : β} : HEqHEq a b ↔ HEq b a := Iff.intro HEq.symm HEq.symm
Symmetry of Heterogeneous Equality: $a \approx b \leftrightarrow b \approx a$
Informal description
For any elements $a$ of type $\alpha$ and $b$ of type $\beta$, the heterogeneous equality $a \approx b$ holds if and only if $b \approx a$ holds.
heq_comm theorem
{a : α} {b : β} : HEq a b ↔ HEq b a
Full source
theorem heq_comm {a : α} {b : β} : HEqHEq a b ↔ HEq b a := HEq.comm
Symmetry of Heterogeneous Equality: $a \approx b \leftrightarrow b \approx a$
Informal description
For any elements $a$ of type $\alpha$ and $b$ of type $\beta$, the heterogeneous equality $a \approx b$ holds if and only if $b \approx a$ holds.
Iff.symm theorem
(h : a ↔ b) : b ↔ a
Full source
@[symm] theorem Iff.symm (h : a ↔ b) : b ↔ a := Iff.intro h.mpr h.mp
Symmetry of Logical Equivalence
Informal description
Given a proof $h$ that propositions $a$ and $b$ are equivalent ($a \leftrightarrow b$), we can conclude that $b$ and $a$ are equivalent ($b \leftrightarrow a$).
Iff.comm theorem
: (a ↔ b) ↔ (b ↔ a)
Full source
theorem Iff.comm: (a ↔ b) ↔ (b ↔ a) := Iff.intro Iff.symm Iff.symm
Commutativity of Logical Equivalence: $(a \leftrightarrow b) \leftrightarrow (b \leftrightarrow a)$
Informal description
For any two propositions $a$ and $b$, the equivalence $a \leftrightarrow b$ holds if and only if the equivalence $b \leftrightarrow a$ holds.
iff_comm theorem
: (a ↔ b) ↔ (b ↔ a)
Full source
theorem iff_comm : (a ↔ b) ↔ (b ↔ a) := Iff.comm
Commutativity of Logical Equivalence: $(a \leftrightarrow b) \leftrightarrow (b \leftrightarrow a)$
Informal description
For any two propositions $a$ and $b$, the equivalence $a \leftrightarrow b$ holds if and only if the equivalence $b \leftrightarrow a$ holds.
And.symm theorem
: a ∧ b → b ∧ a
Full source
@[symm] theorem And.symm : a ∧ bb ∧ a := fun ⟨ha, hb⟩ => ⟨hb, ha⟩
Commutativity of Logical Conjunction: $a \land b \to b \land a$
Informal description
For any two propositions $a$ and $b$, if $a \land b$ holds, then $b \land a$ holds.
And.comm theorem
: a ∧ b ↔ b ∧ a
Full source
theorem And.comm : a ∧ ba ∧ b ↔ b ∧ a := Iff.intro And.symm And.symm
Commutativity of Logical Conjunction: $a \land b \leftrightarrow b \land a$
Informal description
For any two propositions $a$ and $b$, the conjunction $a \land b$ is logically equivalent to $b \land a$.
and_comm theorem
: a ∧ b ↔ b ∧ a
Full source
theorem and_comm : a ∧ ba ∧ b ↔ b ∧ a := And.comm
Commutativity of Logical Conjunction: $a \land b \leftrightarrow b \land a$
Informal description
For any two propositions $a$ and $b$, the conjunction $a \land b$ is logically equivalent to $b \land a$.
Or.symm theorem
: a ∨ b → b ∨ a
Full source
@[symm] theorem Or.symm : a ∨ bb ∨ a := .rec .inr .inl
Symmetry of Logical Disjunction
Informal description
For any two propositions $a$ and $b$, if $a \lor b$ holds, then $b \lor a$ holds.
Or.comm theorem
: a ∨ b ↔ b ∨ a
Full source
theorem Or.comm : a ∨ ba ∨ b ↔ b ∨ a := Iff.intro Or.symm Or.symm
Commutativity of Logical Disjunction: $a \lor b \leftrightarrow b \lor a$
Informal description
For any two propositions $a$ and $b$, the disjunction $a \lor b$ is logically equivalent to $b \lor a$.
or_comm theorem
: a ∨ b ↔ b ∨ a
Full source
theorem or_comm : a ∨ ba ∨ b ↔ b ∨ a := Or.comm
Commutativity of Logical Disjunction: $a \lor b \leftrightarrow b \lor a$
Informal description
For any two propositions $a$ and $b$, the disjunction $a \lor b$ is logically equivalent to $b \lor a$.
Exists.elim theorem
{α : Sort u} {p : α → Prop} {b : Prop} (h₁ : Exists (fun x => p x)) (h₂ : ∀ (a : α), p a → b) : b
Full source
theorem Exists.elim {α : Sort u} {p : α → Prop} {b : Prop}
   (h₁ : Exists (fun x => p x)) (h₂ : ∀ (a : α), p a → b) : b :=
  match h₁ with
  | intro a h => h₂ a h
Existential Elimination Rule
Informal description
Given a type $\alpha$, a predicate $p : \alpha \to \text{Prop}$, and a proposition $b$, if there exists an element $x$ in $\alpha$ such that $p(x)$ holds, and for every element $a$ in $\alpha$, $p(a)$ implies $b$, then $b$ holds.
decide_false theorem
(h : Decidable False) : @decide False h = false
Full source
@[simp] theorem decide_false (h : Decidable False) : @decide False h = false :=
  match h with
  | isFalseisFalse _ => rfl
  | isTrueisTrue h  => False.elim h
Decidable False evaluates to false
Informal description
For any decidable instance `h` of the proposition `False`, the boolean evaluation `decide False` (with respect to `h`) is equal to `false`.
decide_true_eq_true abbrev
Full source
@[deprecated decide_true (since := "2024-11-05")] abbrev decide_true_eq_true := decide_true
Boolean Evaluation of Decidable True is True
Informal description
For any instance `h` of `Decidable True`, the boolean evaluation of the proposition `True` is equal to `true`, i.e., `decide True = true`.
decide_false_eq_false abbrev
Full source
@[deprecated decide_false (since := "2024-11-05")] abbrev decide_false_eq_false := decide_false
Decidable False evaluates to false
Informal description
For any decidable instance of the proposition `False`, the boolean evaluation `decide False` is equal to `false`.
toBoolUsing definition
{p : Prop} (d : Decidable p) : Bool
Full source
/-- Similar to `decide`, but uses an explicit instance -/
@[inline] def toBoolUsing {p : Prop} (d : Decidable p) : Bool :=
  decide (h := d)
Explicit decision to boolean conversion
Informal description
Given a decidable proposition $p$ with an explicit decision procedure $d$, the function returns `true` if $p$ is true and `false` if $p$ is false.
toBoolUsing_eq_true theorem
{p : Prop} (d : Decidable p) (h : p) : toBoolUsing d = true
Full source
theorem toBoolUsing_eq_true {p : Prop} (d : Decidable p) (h : p) : toBoolUsing d = true :=
  decide_eq_true (inst := d) h
Decidable Proposition to Boolean Conversion Yields True When Proposition Holds
Informal description
For any decidable proposition $p$ with decision procedure $d$, if $p$ holds, then the boolean value obtained by converting $d$ to a boolean is `true`.
ofBoolUsing_eq_true theorem
{p : Prop} {d : Decidable p} (h : toBoolUsing d = true) : p
Full source
theorem ofBoolUsing_eq_true {p : Prop} {d : Decidable p} (h : toBoolUsing d = true) : p :=
  of_decide_eq_true (inst := d) h
Decidable Proposition from Boolean True Evaluation: $\text{toBoolUsing}(d) = \text{true} \to p$
Informal description
For any decidable proposition $p$ with decision procedure $d$, if the boolean conversion of $d$ evaluates to `true`, then $p$ holds.
ofBoolUsing_eq_false theorem
{p : Prop} {d : Decidable p} (h : toBoolUsing d = false) : ¬p
Full source
theorem ofBoolUsing_eq_false {p : Prop} {d : Decidable p} (h : toBoolUsing d = false) : ¬ p :=
  of_decide_eq_false (inst := d) h
False Boolean Evaluation Implies Negation: $\text{toBoolUsing}(d) = \text{false} \to \neg p$
Informal description
For any decidable proposition $p$ with decision procedure $d$, if the boolean evaluation of $p$ (via `toBoolUsing d`) is `false`, then $\neg p$ holds.
instDecidableTrue instance
: Decidable True
Full source
instance : Decidable True :=
  isTrue trivial
Decidability of True
Informal description
The proposition $\text{True}$ is decidable, meaning there is a constructive proof that $\text{True}$ is either true or false (in this case, always true).
instDecidableFalse instance
: Decidable False
Full source
instance : Decidable False :=
  isFalse not_false
Decidability of False
Informal description
The proposition `False` is decidable, meaning there is a constructive proof that `False` is either true or false (in this case, always false).
Decidable.byCases definition
{q : Sort u} [dec : Decidable p] (h1 : p → q) (h2 : ¬p → q) : q
Full source
/--
Construct a `q` if some proposition `p` is decidable, and both the truth and falsity of `p` are
sufficient to construct a `q`.

This is a synonym for `dite`, the dependent if-then-else operator.
-/
@[macro_inline] def byCases {q : Sort u} [dec : Decidable p] (h1 : p → q) (h2 : ¬p → q) : q :=
  match dec with
  | isTrue h  => h1 h
  | isFalse h => h2 h
Case analysis on a decidable proposition
Informal description
Given a decidable proposition \( p \) and two functions \( h_1 \) and \( h_2 \) that produce a term of type \( q \) from a proof of \( p \) and a proof of \( \neg p \) respectively, this function constructs a term of type \( q \) by cases on the decidability of \( p \). If \( p \) is true, it applies \( h_1 \) to the proof; if \( p \) is false, it applies \( h_2 \) to the proof.
Decidable.em theorem
(p : Prop) [Decidable p] : p ∨ ¬p
Full source
theorem em (p : Prop) [Decidable p] : p ∨ ¬p :=
  byCases Or.inl Or.inr
Law of Excluded Middle for Decidable Propositions
Informal description
For any proposition $p$ with a decidable instance, either $p$ holds or its negation $\neg p$ holds.
Decidable.byContradiction theorem
[dec : Decidable p] (h : ¬p → False) : p
Full source
theorem byContradiction [dec : Decidable p] (h : ¬pFalse) : p :=
  byCases id (fun np => False.elim (h np))
Proof by Contradiction for Decidable Propositions
Informal description
For any decidable proposition $p$, if assuming $\neg p$ leads to a contradiction, then $p$ holds.
Decidable.of_not_not theorem
[Decidable p] : ¬¬p → p
Full source
theorem of_not_not [Decidable p] : ¬ ¬ p → p :=
  fun hnn => byContradiction (fun hn => absurd hn hnn)
Double Negation Elimination for Decidable Propositions
Informal description
For any decidable proposition $p$, if the negation of the negation of $p$ holds (i.e., $\neg\neg p$), then $p$ holds.
Decidable.not_and_iff_or_not theorem
{p q : Prop} [d₁ : Decidable p] [d₂ : Decidable q] : ¬(p ∧ q) ↔ ¬p ∨ ¬q
Full source
theorem not_and_iff_or_not {p q : Prop} [d₁ : Decidable p] [d₂ : Decidable q] : ¬ (p ∧ q)¬ (p ∧ q) ↔ ¬ p ∨ ¬ q :=
  Iff.intro
    (fun h => match d₁, d₂ with
      | isTrue h₁,  isTrue h₂   => absurd (And.intro h₁ h₂) h
      | _,           isFalse h₂ => Or.inr h₂
      | isFalse h₁, _           => Or.inl h₁)
    (fun (h) ⟨hp, hq⟩ => match h with
      | Or.inl h => h hp
      | Or.inr h => h hq)
De Morgan's Law for Conjunction: $\neg(p \land q) \leftrightarrow \neg p \lor \neg q$
Informal description
For any two propositions $p$ and $q$ with decidable truth values, the negation of their conjunction is equivalent to the disjunction of their negations. That is, $\neg(p \land q) \leftrightarrow (\neg p \lor \neg q)$.
decidable_of_decidable_of_iff definition
[Decidable p] (h : p ↔ q) : Decidable q
Full source
/-- Transfer a decidability proof across an equivalence of propositions. -/
@[inline] def decidable_of_decidable_of_iff [Decidable p] (h : p ↔ q) : Decidable q :=
  if hp : p then
    isTrue (Iff.mp h hp)
  else
    isFalse fun hq => absurd (Iff.mpr h hq) hp
Decidability transfer via bi-implication
Informal description
Given a decidable proposition $p$ and a bi-implication $p \leftrightarrow q$, the decidability of $q$ can be inferred. Specifically, if $p$ is decidable and $p$ is equivalent to $q$, then $q$ is also decidable.
decidable_of_decidable_of_eq definition
[Decidable p] (h : p = q) : Decidable q
Full source
/-- Transfer a decidability proof across an equality of propositions. -/
@[inline] def decidable_of_decidable_of_eq [Decidable p] (h : p = q) : Decidable q :=
  decidable_of_decidable_of_iff (p := p) (h ▸ Iff.rfl)
Decidability transfer via propositional equality
Informal description
Given a decidable proposition $p$ and an equality $p = q$ between propositions, the decidability of $q$ can be inferred. Specifically, if $p$ is decidable and $p$ is equal to $q$, then $q$ is also decidable.
instDecidableIff instance
{p q} [Decidable p] [Decidable q] : Decidable (p ↔ q)
Full source
instance {p q} [Decidable p] [Decidable q] : Decidable (p ↔ q) :=
  if hp : p then
    if hq : q then
      isTrue ⟨fun _ => hq, fun _ => hp⟩
    else
      isFalse fun h => hq (h.1 hp)
  else
    if hq : q then
      isFalse fun h => hp (h.2 hq)
    else
      isTrue ⟨fun h => absurd h hp, fun h => absurd h hq⟩
Decidability of Logical Equivalence
Informal description
For any two propositions $p$ and $q$ with decidable truth values, the bi-implication $p \leftrightarrow q$ is also decidable.
if_pos theorem
{c : Prop} {h : Decidable c} (hc : c) {α : Sort u} {t e : α} : (ite c t e) = t
Full source
theorem if_pos {c : Prop} {h : Decidable c} (hc : c) {α : Sort u} {t e : α} : (ite c t e) = t :=
  match h with
  | isTrue  _   => rfl
  | isFalse hnc => absurd hc hnc
If-then-else evaluates to true branch when condition holds
Informal description
For any proposition $c$ with a decidable instance, if $c$ holds, then the if-then-else expression `if c then t else e` evaluates to $t$.
if_neg theorem
{c : Prop} {h : Decidable c} (hnc : ¬c) {α : Sort u} {t e : α} : (ite c t e) = e
Full source
theorem if_neg {c : Prop} {h : Decidable c} (hnc : ¬c) {α : Sort u} {t e : α} : (ite c t e) = e :=
  match h with
  | isTrue hc   => absurd hc hnc
  | isFalse _   => rfl
Conditional Evaluation Under Negation: `if ¬c then t else e = e`
Informal description
For any proposition $c$ with a decidable instance, if $\neg c$ holds, then the conditional expression `if c then t else e` evaluates to $e$.
iteInduction definition
{c} [inst : Decidable c] {motive : α → Sort _} {t e : α} (hpos : c → motive t) (hneg : ¬c → motive e) : motive (ite c t e)
Full source
/-- Split an if-then-else into cases. The `split` tactic is generally easier to use than this theorem. -/
def iteInduction {c} [inst : Decidable c] {motive : α → Sort _} {t e : α}
    (hpos : c → motive t) (hneg : ¬c → motive e) : motive (ite c t e) :=
  match inst with
  | isTrue h => hpos h
  | isFalse h => hneg h
Induction principle for if-then-else expressions
Informal description
Given a decidable proposition \( c \), a type family \( \text{motive} \) on \( \alpha \), and terms \( t, e : \alpha \), the induction principle for the if-then-else expression states that to prove \( \text{motive}(\text{if } c \text{ then } t \text{ else } e) \), it suffices to prove \( \text{motive}(t) \) under the assumption that \( c \) holds and \( \text{motive}(e) \) under the assumption that \( \neg c \) holds.
dif_pos theorem
{c : Prop} {h : Decidable c} (hc : c) {α : Sort u} {t : c → α} {e : ¬c → α} : (dite c t e) = t hc
Full source
theorem dif_pos {c : Prop} {h : Decidable c} (hc : c) {α : Sort u} {t : c → α} {e : ¬ c → α} : (dite c t e) = t hc :=
  match h with
  | isTrue  _   => rfl
  | isFalse hnc => absurd hc hnc
Dependent if-then-else evaluates to true branch when condition holds
Informal description
For any decidable proposition $c$ and type $\alpha$, if $c$ holds with proof $hc$, then the dependent if-then-else expression `dite c t e` evaluates to $t(hc)$, where $t$ is a function producing a result when given a proof of $c$, and $e$ is a function producing a result when given a proof of $\neg c$.
dif_neg theorem
{c : Prop} {h : Decidable c} (hnc : ¬c) {α : Sort u} {t : c → α} {e : ¬c → α} : (dite c t e) = e hnc
Full source
theorem dif_neg {c : Prop} {h : Decidable c} (hnc : ¬c) {α : Sort u} {t : c → α} {e : ¬ c → α} : (dite c t e) = e hnc :=
  match h with
  | isTrue hc   => absurd hc hnc
  | isFalse _   => rfl
Dependent If-Then-Else Evaluates to Else Branch When Condition is False
Informal description
For any decidable proposition $c$ and type $\alpha$, if $\neg c$ holds, then the dependent if-then-else expression `dite c t e` evaluates to the result of applying the function $e$ to the proof of $\neg c$. In other words, if $c$ is false, then `dite c t e = e hnc` where `hnc` is the proof of $\neg c$.
dif_eq_if theorem
(c : Prop) {h : Decidable c} {α : Sort u} (t : α) (e : α) : dite c (fun _ => t) (fun _ => e) = ite c t e
Full source
theorem dif_eq_if (c : Prop) {h : Decidable c} {α : Sort u} (t : α) (e : α) : dite c (fun _ => t) (fun _ => e) = ite c t e :=
  match h with
  | isTrue _    => rfl
  | isFalse _   => rfl
Equivalence of Dependent and Standard If-Then-Else for Constant Branches
Informal description
For any proposition $c$ with a decidable instance, and for any terms $t, e$ of type $\alpha$, the dependent if-then-else expression `dite c (fun _ => t) (fun _ => e)` is equal to the standard if-then-else expression `ite c t e`.
instDecidableIte instance
{c t e : Prop} [dC : Decidable c] [dT : Decidable t] [dE : Decidable e] : Decidable (if c then t else e)
Full source
instance {c t e : Prop} [dC : Decidable c] [dT : Decidable t] [dE : Decidable e] : Decidable (if c then t else e)  :=
  match dC with
  | isTrue _   => dT
  | isFalse _  => dE
Decidability of Conditional Propositions
Informal description
For any propositions $c$, $t$, and $e$, if $c$ is decidable and both $t$ and $e$ are decidable, then the proposition "if $c$ then $t$ else $e$" is also decidable.
instDecidableDite instance
{c : Prop} {t : c → Prop} {e : ¬c → Prop} [dC : Decidable c] [dT : ∀ h, Decidable (t h)] [dE : ∀ h, Decidable (e h)] : Decidable (if h : c then t h else e h)
Full source
instance {c : Prop} {t : c → Prop} {e : ¬c → Prop} [dC : Decidable c] [dT : ∀ h, Decidable (t h)] [dE : ∀ h, Decidable (e h)] : Decidable (if h : c then t h else e h)  :=
  match dC with
  | isTrue hc  => dT hc
  | isFalse hc => dE hc
Decidability of Dependent If-Then-Else Expressions
Informal description
For any proposition $c$ and dependent functions $t : c \to \text{Prop}$ and $e : \neg c \to \text{Prop}$, if $c$ is decidable and both $t$ and $e$ are decidable for all inputs, then the dependent if-then-else expression `if h : c then t h else e h` is decidable.
noConfusionTypeEnum abbrev
{α : Sort u} {β : Sort v} [inst : DecidableEq β] (f : α → β) (P : Sort w) (x y : α) : Sort w
Full source
/-- Auxiliary definition for generating compact `noConfusion` for enumeration types -/
abbrev noConfusionTypeEnum {α : Sort u} {β : Sort v} [inst : DecidableEq β] (f : α → β) (P : Sort w) (x y : α) : Sort w :=
  (inst (f x) (f y)).casesOn
    (fun _ => P)
    (fun _ => P → P)
Discrimination Type Constructor for Enumeration Types via Decidable Equality
Informal description
Given types $\alpha$ and $\beta$ with $\beta$ having decidable equality, and a function $f \colon \alpha \to \beta$, the type `noConfusionTypeEnum f P x y` is defined for any type $P$ and elements $x, y \in \alpha$ to assist in generating compact proofs of discrimination for enumeration types.
noConfusionEnum abbrev
{α : Sort u} {β : Sort v} [inst : DecidableEq β] (f : α → β) {P : Sort w} {x y : α} (h : x = y) : noConfusionTypeEnum f P x y
Full source
/-- Auxiliary definition for generating compact `noConfusion` for enumeration types -/
abbrev noConfusionEnum {α : Sort u} {β : Sort v} [inst : DecidableEq β] (f : α → β) {P : Sort w} {x y : α} (h : x = y) : noConfusionTypeEnum f P x y :=
  Decidable.casesOn
    (motive := fun (inst : Decidable (f x = f y)) => Decidable.casesOn (motive := fun _ => Sort w) inst (fun _ => P) (fun _ => P → P))
    (inst (f x) (f y))
    (fun h' => False.elim (h' (congrArg f h)))
    (fun _ => fun x => x)
Discrimination Constructor for Enumeration Types via Decidable Equality
Informal description
Given types $\alpha$ and $\beta$ with $\beta$ having decidable equality, a function $f \colon \alpha \to \beta$, a type $P$, and elements $x, y \in \alpha$ with a proof $h$ that $x = y$, the term `noConfusionEnum f h` constructs an element of the discrimination type `noConfusionTypeEnum f P x y`, which assists in generating compact proofs of discrimination for enumeration types.
instInhabitedProp instance
: Inhabited Prop
Full source
instance : Inhabited Prop where
  default := True
Inhabited Type of Propositions
Informal description
The type of propositions `Prop` is inhabited, with a default element.
instInhabitedNonScalar instance
: Inhabited✝ (@NonScalar)
Full source
Inhabited for NonScalar, PNonScalar, True, ForInStep
Inhabited Instance for Non-Scalar Type
Informal description
The type `NonScalar` is inhabited, meaning it has a designated default element.
instInhabitedPNonScalar instance
: Inhabited✝ (@PNonScalar)
Full source
Inhabited for NonScalar, PNonScalar, True, ForInStep
Inhabited Instance for Non-Scalar Type
Informal description
The type `PNonScalar` is inhabited, meaning it has a designated default element.
instInhabitedTrue instance
: Inhabited✝ (@True)
Full source
Inhabited for NonScalar, PNonScalar, True, ForInStep
Inhabited Instance for True Proposition
Informal description
The proposition `True` is inhabited, with its default element being the canonical proof `True.intro`.
instInhabitedForInStep_1 instance
{a✝} [Inhabited✝ a✝] : Inhabited✝ (@ForInStep a✝)
Full source
Inhabited for NonScalar, PNonScalar, True, ForInStep
Default Loop Control Indicator for Inhabited Types
Informal description
For any type $\alpha$ with a default element, the type `ForInStep α` of loop control indicators for iteration over $\alpha$ also has a default element.
nonempty_of_exists theorem
{α : Sort u} {p : α → Prop} : Exists (fun x => p x) → Nonempty α
Full source
theorem nonempty_of_exists {α : Sort u} {p : α → Prop} : Exists (fun x => p x) → Nonempty α
  | ⟨w, _⟩ => ⟨w⟩
Existence Implies Nonemptiness
Informal description
For any type $\alpha$ and predicate $p : \alpha \to \text{Prop}$, if there exists an element $x \in \alpha$ such that $p(x)$ holds, then $\alpha$ is nonempty.
Subsingleton structure
(α : Sort u)
Full source
/--
A _subsingleton_ is a type with at most one element. It is either empty or has a unique element.

All propositions are subsingletons because of proof irrelevance: false propositions are empty, and
all proofs of a true proposition are equal to one another. Some non-propositional types are also
subsingletons.
-/
class Subsingleton (α : Sort u) : Prop where
  /-- Prove that `α` is a subsingleton by showing that any two elements are equal. -/
  intro ::
  /-- Any two elements of a subsingleton are equal. -/
  allEq : (a b : α) → a = b
Subsingleton type
Informal description
A *subsingleton* is a type with at most one element. In other words, a type is a subsingleton if it is either empty or contains exactly one element. All propositions are subsingletons due to proof irrelevance: false propositions are empty, and all proofs of a true proposition are equal to each other. Some non-propositional types can also be subsingletons.
Subsingleton.elim theorem
{α : Sort u} [h : Subsingleton α] : (a b : α) → a = b
Full source
/--
If a type is a subsingleton, then all of its elements are equal.
-/
protected theorem Subsingleton.elim {α : Sort u} [h : Subsingleton α] : (a b : α) → a = b :=
  h.allEq
Equality of Elements in a Subsingleton
Informal description
For any subsingleton type $\alpha$ (i.e., a type with at most one element), any two elements $a, b \in \alpha$ are equal: $a = b$.
Subsingleton.helim theorem
{α β : Sort u} [h₁ : Subsingleton α] (h₂ : α = β) (a : α) (b : β) : HEq a b
Full source
/--
If two types are equal and one of them is a subsingleton, then all of their elements are
[heterogeneously equal](lean-manual://section/HEq).
-/
protected theorem Subsingleton.helim {α β : Sort u} [h₁ : Subsingleton α] (h₂ : α = β) (a : α) (b : β) : HEq a b := by
  subst h₂
  apply heq_of_eq
  apply Subsingleton.elim
Heterogeneous Equality in Subsingleton Types
Informal description
Let $\alpha$ and $\beta$ be types in the same universe, with $\alpha$ being a subsingleton. If $\alpha = \beta$, then for any elements $a \in \alpha$ and $b \in \beta$, we have $a \approx b$ (heterogeneous equality).
instSubsingleton instance
(p : Prop) : Subsingleton p
Full source
instance (p : Prop) : Subsingleton p := ⟨fun a b => proof_irrel a b⟩
Propositions are Subsingletons
Informal description
Every proposition is a subsingleton, meaning it has at most one element (due to proof irrelevance).
instSubsingletonPEmpty instance
: Subsingleton PEmpty
Full source
instance : Subsingleton PEmpty := ⟨(·.elim)⟩
Polymorphic Empty Type is a Subsingleton
Informal description
The polymorphic empty type `PEmpty` is a subsingleton, meaning it has at most one element (in fact, it has none).
instSubsingletonDecidable instance
(p : Prop) : Subsingleton (Decidable p)
Full source
instance (p : Prop) : Subsingleton (Decidable p) :=
  Subsingleton.intro fun
    | isTrue t₁ => fun
      | isTrue _   => rfl
      | isFalse f₂ => absurd t₁ f₂
    | isFalse f₁ => fun
      | isTrue t₂  => absurd t₂ f₁
      | isFalse _  => rfl
Decidable Propositions are Subsingletons
Informal description
For any proposition $p$, the type `Decidable p` is a subsingleton, meaning it has at most one element up to definitional equality.
recSubsingleton theorem
{p : Prop} [h : Decidable p] {h₁ : p → Sort u} {h₂ : ¬p → Sort u} [h₃ : ∀ (h : p), Subsingleton (h₁ h)] [h₄ : ∀ (h : ¬p), Subsingleton (h₂ h)] : Subsingleton (h.casesOn h₂ h₁)
Full source
theorem recSubsingleton
     {p : Prop} [h : Decidable p]
     {h₁ : p → Sort u}
     {h₂ : ¬p → Sort u}
     [h₃ : ∀ (h : p), Subsingleton (h₁ h)]
     [h₄ : ∀ (h : ¬p), Subsingleton (h₂ h)]
     : Subsingleton (h.casesOn h₂ h₁) :=
  match h with
  | isTrue h  => h₃ h
  | isFalse h => h₄ h
Subsingleton Property of Decidable Case Analysis
Informal description
Let $p$ be a proposition with a decidable instance $h : \text{Decidable } p$. For any type families $h_1 : p \to \text{Sort } u$ and $h_2 : \neg p \to \text{Sort } u$, if for every proof $h_p$ of $p$, the type $h_1(h_p)$ is a subsingleton, and for every proof $h_{\neg p}$ of $\neg p$, the type $h_2(h_{\neg p})$ is a subsingleton, then the type obtained by case analysis on $h$ (i.e., $h.\text{casesOn } h_2 h_1$) is also a subsingleton.
Equivalence structure
{α : Sort u} (r : α → α → Prop)
Full source
/--
An equivalence relation `r : α → α → Prop` is a relation that is

* reflexive: `r x x`,
* symmetric: `r x y` implies `r y x`, and
* transitive: `r x y` and `r y z` implies `r x z`.

Equality is an equivalence relation, and equivalence relations share many of the properties of
equality.
-/
structure Equivalence {α : Sort u} (r : α → α → Prop) : Prop where
  /-- An equivalence relation is reflexive: `r x x` -/
  refl  : ∀ x, r x x
  /-- An equivalence relation is symmetric: `r x y` implies `r y x` -/
  symm  : ∀ {x y}, r x y → r y x
  /-- An equivalence relation is transitive: `r x y` and `r y z` implies `r x z` -/
  trans : ∀ {x y z}, r x y → r y z → r x z
Equivalence Relation
Informal description
An equivalence relation on a type $\alpha$ is a binary relation $r : \alpha \to \alpha \to \text{Prop}$ that is: 1. Reflexive: $r(x, x)$ holds for all $x \in \alpha$, 2. Symmetric: $r(x, y)$ implies $r(y, x)$ for all $x, y \in \alpha$, 3. Transitive: $r(x, y)$ and $r(y, z)$ imply $r(x, z)$ for all $x, y, z \in \alpha$. Equality is an example of an equivalence relation, and equivalence relations share many properties with equality.
emptyRelation definition
{α : Sort u} (_ _ : α) : Prop
Full source
/-- The empty relation is the relation on `α` which is always `False`. -/
def emptyRelation {α : Sort u} (_ _ : α) : Prop :=
  False
Empty relation
Informal description
The empty relation on a type $\alpha$ is the binary relation that always evaluates to `False`, meaning it never holds for any pair of elements in $\alpha$.
Subrelation definition
{α : Sort u} (q r : α → α → Prop)
Full source
/--
`Subrelation q r` means that `q ⊆ r` or `∀ x y, q x y → r x y`.
It is the analogue of the subset relation on relations.
-/
def Subrelation {α : Sort u} (q r : α → α → Prop) :=
  ∀ {x y}, q x y → r x y
Subrelation of binary relations
Informal description
Given a type $\alpha$ and two binary relations $q, r$ on $\alpha$, we say that $q$ is a subrelation of $r$ if for all $x, y \in \alpha$, whenever $q(x, y)$ holds, then $r(x, y)$ also holds.
InvImage definition
{α : Sort u} {β : Sort v} (r : β → β → Prop) (f : α → β) : α → α → Prop
Full source
/--
The inverse image of `r : β → β → Prop` by a function `α → β` is the relation
`s : α → α → Prop` defined by `s a b = r (f a) (f b)`.
-/
def InvImage {α : Sort u} {β : Sort v} (r : β → β → Prop) (f : α → β) : α → α → Prop :=
  fun a₁ a₂ => r (f a₁) (f a₂)
Inverse image of a relation under a function
Informal description
Given a binary relation \( r \) on a type \( \beta \) and a function \( f : \alpha \to \beta \), the inverse image of \( r \) under \( f \) is the binary relation on \( \alpha \) defined by \( s(a_1, a_2) = r(f(a_1), f(a_2)) \) for any \( a_1, a_2 \in \alpha \).
Relation.TransGen inductive
{α : Sort u} (r : α → α → Prop) : α → α → Prop
Full source
/--
The transitive closure `TransGen r` of a relation `r` is the smallest relation which is
transitive and contains `r`. `TransGen r a z` if and only if there exists a sequence
`a r b r ... r z` of length at least 1 connecting `a` to `z`.
-/
inductive Relation.TransGen {α : Sort u} (r : α → α → Prop) : α → α → Prop
  /-- If `r a b`, then `TransGen r a b`. This is the base case of the transitive closure. -/
  | single {a b} : r a b → TransGen r a b
  /-- If `TransGen r a b` and `r b c`, then `TransGen r a c`.
  This is the inductive case of the transitive closure. -/
  | tail {a b c} : TransGen r a b → r b c → TransGen r a c
Transitive closure of a relation
Informal description
The transitive closure $\text{TransGen}(r)$ of a binary relation $r$ on a type $\alpha$ is the smallest transitive relation that contains $r$. For elements $a, z \in \alpha$, $\text{TransGen}(r)(a, z)$ holds if and only if there exists a finite sequence of elements $a = b_0, b_1, \dots, b_n = z$ with $n \geq 1$ such that $r(b_i, b_{i+1})$ holds for each $i = 0, \dots, n-1$.
Relation.TransGen.trans theorem
{α : Sort u} {r : α → α → Prop} {a b c} : TransGen r a b → TransGen r b c → TransGen r a c
Full source
/-- The transitive closure is transitive. -/
theorem Relation.TransGen.trans {α : Sort u} {r : α → α → Prop} {a b c} :
    TransGen r a b → TransGen r b c → TransGen r a c := by
  intro hab hbc
  induction hbc with
  | single h => exact TransGen.tail hab h
  | tail _ h ih => exact TransGen.tail ih h
Transitivity of the Transitive Closure
Informal description
For any type $\alpha$ and binary relation $r$ on $\alpha$, if $\text{TransGen}(r)(a, b)$ and $\text{TransGen}(r)(b, c)$ hold for elements $a, b, c \in \alpha$, then $\text{TransGen}(r)(a, c)$ also holds. In other words, the transitive closure $\text{TransGen}(r)$ is itself transitive.
Subtype.existsOfSubtype theorem
{α : Type u} {p : α → Prop} : { x // p x } → Exists (fun x => p x)
Full source
theorem existsOfSubtype {α : Type u} {p : α → Prop} : { x // p x }Exists (fun x => p x)
  | ⟨a, h⟩ => ⟨a, h⟩
Existence of Witness from Subtype
Informal description
For any type $\alpha$ and predicate $p : \alpha \to \text{Prop}$, given an element of the subtype $\{x \mid p x\}$, there exists an element $x \in \alpha$ such that $p x$ holds.
Subtype.eq theorem
: ∀ {a1 a2 : { x // p x }}, val a1 = val a2 → a1 = a2
Full source
protected theorem eq : ∀ {a1 a2 : {x // p x}}, val a1 = val a2 → a1 = a2
  | ⟨_, _⟩, ⟨_, _⟩, rfl => rfl
Equality of Subtypes via Underlying Values
Informal description
For any subtype $\{x \mid p x\}$ of a type $\alpha$, if two elements $a_1$ and $a_2$ in the subtype have equal underlying values (i.e., $\text{val}(a_1) = \text{val}(a_2)$), then $a_1 = a_2$.
Subtype.eta theorem
(a : { x // p x }) (h : p (val a)) : mk (val a) h = a
Full source
theorem eta (a : {x // p x}) (h : p (val a)) : mk (val a) h = a := by
  cases a
  exact rfl
Subtype Eta Rule: $\text{mk}(\text{val}(a), h) = a$
Informal description
For any element $a$ of the subtype $\{x \mid p(x)\}$ and any proof $h$ that $p(\text{val}(a))$ holds, the term $\text{mk}(\text{val}(a), h)$ is equal to $a$.
Subtype.instDecidableEq instance
{α : Type u} {p : α → Prop} [DecidableEq α] : DecidableEq { x : α // p x }
Full source
instance {α : Type u} {p : α → Prop} [DecidableEq α] : DecidableEq {x : α // p x} :=
  fun ⟨a, h₁⟩ ⟨b, h₂⟩ =>
    if h : a = b then isTrue (by subst h; exact rfl)
    else isFalse (fun h' => Subtype.noConfusion h' (fun h' => absurd h' h))
Decidable Equality for Subtypes
Informal description
For any type $\alpha$ with decidable equality and any predicate $p$ on $\alpha$, the subtype $\{x \mid p x\}$ also has decidable equality.
Sum.inhabitedLeft definition
[Inhabited α] : Inhabited (Sum α β)
Full source
@[reducible, inherit_doc PSum.inhabitedLeft]
def Sum.inhabitedLeft [Inhabited α] : Inhabited (Sum α β) where
  default := Sum.inl default
Inhabited left sum type
Informal description
Given an inhabited type $\alpha$ and any type $\beta$, the sum type $\alpha \oplus \beta$ is inhabited, with the default element being the left injection of the default element of $\alpha$.
Sum.inhabitedRight definition
[Inhabited β] : Inhabited (Sum α β)
Full source
@[reducible, inherit_doc PSum.inhabitedRight]
def Sum.inhabitedRight [Inhabited β] : Inhabited (Sum α β) where
  default := Sum.inr default
Inhabited right sum type
Informal description
Given any type $\alpha$ and an inhabited type $\beta$, the sum type $\alpha \oplus \beta$ is inhabited, with the default element being the right injection of the default element of $\beta$.
Sum.nonemptyLeft instance
[h : Nonempty α] : Nonempty (Sum α β)
Full source
instance Sum.nonemptyLeft [h : Nonempty α] : Nonempty (Sum α β) :=
  Nonempty.elim h (fun a => ⟨Sum.inl a⟩)
Nonempty Left Sum Type
Informal description
For any types $\alpha$ and $\beta$, if $\alpha$ is nonempty, then the sum type $\alpha \oplus \beta$ is also nonempty.
Sum.nonemptyRight instance
[h : Nonempty β] : Nonempty (Sum α β)
Full source
instance Sum.nonemptyRight [h : Nonempty β] : Nonempty (Sum α β) :=
  Nonempty.elim h (fun b => ⟨Sum.inr b⟩)
Nonempty Right Sum Type
Informal description
For any types $\alpha$ and $\beta$, if $\beta$ is nonempty, then the sum type $\alpha \oplus \beta$ is also nonempty.
instDecidableEqSum instance
{α : Type u} {β : Type v} [DecidableEq α] [DecidableEq β] : DecidableEq (Sum α β)
Full source
instance {α : Type u} {β : Type v} [DecidableEq α] [DecidableEq β] : DecidableEq (Sum α β) := fun a b =>
  match a, b with
  | Sum.inl a, Sum.inl b =>
    if h : a = b then isTrue (h ▸ rfl)
    else isFalse fun h' => Sum.noConfusion h' fun h' => absurd h' h
  | Sum.inr a, Sum.inr b =>
    if h : a = b then isTrue (h ▸ rfl)
    else isFalse fun h' => Sum.noConfusion h' fun h' => absurd h' h
  | Sum.inr _, Sum.inl _ => isFalse fun h => Sum.noConfusion h
  | Sum.inl _, Sum.inr _ => isFalse fun h => Sum.noConfusion h
Decidable Equality for Sum Types
Informal description
For any types $\alpha$ and $\beta$ with decidable equality, the sum type $\alpha \oplus \beta$ also has decidable equality.
instNonemptyProd instance
[h1 : Nonempty α] [h2 : Nonempty β] : Nonempty (α × β)
Full source
instance [h1 : Nonempty α] [h2 : Nonempty β] : Nonempty (α × β) :=
  Nonempty.elim h1 fun x =>
    Nonempty.elim h2 fun y =>
      ⟨(x, y)⟩
Nonempty Product Type
Informal description
For any types $\alpha$ and $\beta$, if $\alpha$ is nonempty and $\beta$ is nonempty, then their product type $\alpha \times \beta$ is also nonempty.
instNonemptyMProd instance
[h1 : Nonempty α] [h2 : Nonempty β] : Nonempty (MProd α β)
Full source
instance [h1 : Nonempty α] [h2 : Nonempty β] : Nonempty (MProd α β) :=
  Nonempty.elim h1 fun x =>
    Nonempty.elim h2 fun y =>
      ⟨⟨x, y⟩⟩
Nonempty Monomorphic Product Type
Informal description
For any types $\alpha$ and $\beta$ in the same universe, if both $\alpha$ and $\beta$ are nonempty, then their monomorphic product type $\alpha \times \beta$ is also nonempty.
instNonemptyPProd instance
[h1 : Nonempty α] [h2 : Nonempty β] : Nonempty (PProd α β)
Full source
instance [h1 : Nonempty α] [h2 : Nonempty β] : Nonempty (PProd α β) :=
  Nonempty.elim h1 fun x =>
    Nonempty.elim h2 fun y =>
      ⟨⟨x, y⟩⟩
Nonempty Propositional Product Type
Informal description
For any types $\alpha$ and $\beta$, if both $\alpha$ and $\beta$ are nonempty, then their propositional product type $\alpha \times' \beta$ is also nonempty.
instInhabitedProd instance
[Inhabited α] [Inhabited β] : Inhabited (α × β)
Full source
instance [Inhabited α] [Inhabited β] : Inhabited (α × β) where
  default := (default, default)
Inhabitedness of Product Types
Informal description
For any inhabited types $\alpha$ and $\beta$, their product type $\alpha \times \beta$ is also inhabited. Specifically, the default element of $\alpha \times \beta$ is the pair consisting of the default elements of $\alpha$ and $\beta$.
instInhabitedMProd instance
[Inhabited α] [Inhabited β] : Inhabited (MProd α β)
Full source
instance [Inhabited α] [Inhabited β] : Inhabited (MProd α β) where
  default := ⟨default, default⟩
Inhabitedness of Monomorphic Product Types
Informal description
For any types $\alpha$ and $\beta$ that are inhabited (i.e., have default elements), their monomorphic product type $MProd\ \alpha\ \beta$ is also inhabited.
instInhabitedPProd instance
[Inhabited α] [Inhabited β] : Inhabited (PProd α β)
Full source
instance [Inhabited α] [Inhabited β] : Inhabited (PProd α β) where
  default := ⟨default, default⟩
Inhabitedness of Propositional Product Types
Informal description
For any inhabited types $\alpha$ and $\beta$, their propositional product type $\alpha \times' \beta$ is also inhabited.
instDecidableEqProd instance
[DecidableEq α] [DecidableEq β] : DecidableEq (α × β)
Full source
instance [DecidableEq α] [DecidableEq β] : DecidableEq (α × β) :=
  fun (a, b) (a', b') =>
    match decEq a a' with
    | isTrue e₁ =>
      match decEq b b' with
      | isTrue e₂  => isTrue (e₁ ▸ e₂ ▸ rfl)
      | isFalse n₂ => isFalse fun h => Prod.noConfusion h fun _   e₂' => absurd e₂' n₂
    | isFalse n₁ => isFalse fun h => Prod.noConfusion h fun e₁' _   => absurd e₁' n₁
Decidable Equality for Product Types
Informal description
For any types $\alpha$ and $\beta$ with decidable equality, the product type $\alpha \times \beta$ also has decidable equality. That is, given two pairs $(a_1, b_1)$ and $(a_2, b_2)$ in $\alpha \times \beta$, it is constructively decidable whether they are equal.
instBEqProd instance
[BEq α] [BEq β] : BEq (α × β)
Full source
instance [BEq α] [BEq β] : BEq (α × β) where
  beq := fun (a₁, b₁) (a₂, b₂) => a₁ == a₂ && b₁ == b₂
Boolean Equality on Product Types
Informal description
For any types $\alpha$ and $\beta$ equipped with boolean equality relations, the product type $\alpha \times \beta$ also has a boolean equality relation. This relation compares pairs component-wise using the boolean equality of $\alpha$ and $\beta$.
Prod.lexLt definition
[LT α] [LT β] (s : α × β) (t : α × β) : Prop
Full source
/--
Lexicographical order for products.

Two pairs are lexicographically ordered if their first elements are ordered or if their first
elements are equal and their second elements are ordered.
-/
def Prod.lexLt [LT α] [LT β] (s : α × β) (t : α × β) : Prop :=
  s.1 < t.1 ∨ (s.1 = t.1 ∧ s.2 < t.2)
Lexicographic order on pairs
Informal description
Given two ordered pairs $(a_1, b_1)$ and $(a_2, b_2)$ in $\alpha \times \beta$, where $\alpha$ and $\beta$ are types equipped with a "less than" relation, the lexicographic order relation $(a_1, b_1) <_{\text{lex}} (a_2, b_2)$ holds if either $a_1 < a_2$ or ($a_1 = a_2$ and $b_1 < b_2$).
Prod.lexLtDec instance
[LT α] [LT β] [DecidableEq α] [(a b : α) → Decidable (a < b)] [(a b : β) → Decidable (a < b)] : (s t : α × β) → Decidable (Prod.lexLt s t)
Full source
instance Prod.lexLtDec
    [LT α] [LT β] [DecidableEq α]
    [(a b : α) → Decidable (a < b)] [(a b : β) → Decidable (a < b)]
    : (s t : α × β) → Decidable (Prod.lexLt s t) :=
  fun _ _ => inferInstanceAs (Decidable (_ ∨ _))
Decidability of Lexicographic Order on Pairs
Informal description
For any types $\alpha$ and $\beta$ equipped with a decidable equality and decidable "less than" relations, the lexicographic order on pairs $(a_1, b_1) <_{\text{lex}} (a_2, b_2)$ in $\alpha \times \beta$ is also decidable. This means that for any two pairs $s$ and $t$ in $\alpha \times \beta$, it can be constructively determined whether $s <_{\text{lex}} t$ holds or not.
Prod.lexLt_def theorem
[LT α] [LT β] (s t : α × β) : (Prod.lexLt s t) = (s.1 < t.1 ∨ (s.1 = t.1 ∧ s.2 < t.2))
Full source
theorem Prod.lexLt_def [LT α] [LT β] (s t : α × β) : (Prod.lexLt s t) = (s.1 < t.1 ∨ (s.1 = t.1 ∧ s.2 < t.2)) :=
  rfl
Definition of Lexicographic Order on Pairs
Informal description
For any types $\alpha$ and $\beta$ equipped with a "less than" relation, and for any ordered pairs $s = (a_1, b_1)$ and $t = (a_2, b_2)$ in $\alpha \times \beta$, the lexicographic order relation $s <_{\text{lex}} t$ holds if and only if either $a_1 < a_2$ or ($a_1 = a_2$ and $b_1 < b_2$).
Prod.eta theorem
(p : α × β) : (p.1, p.2) = p
Full source
theorem Prod.eta (p : α × β) : (p.1, p.2) = p := rfl
Eta Reduction for Ordered Pairs: $(p.1, p.2) = p$
Informal description
For any ordered pair $p = (a, b)$ in $\alpha \times \beta$, the pair $(p.1, p.2)$ is equal to $p$ itself, where $p.1$ and $p.2$ denote the first and second components of $p$ respectively.
Prod.map definition
{α₁ : Type u₁} {α₂ : Type u₂} {β₁ : Type v₁} {β₂ : Type v₂} (f : α₁ → α₂) (g : β₁ → β₂) : α₁ × β₁ → α₂ × β₂
Full source
/--
Transforms a pair by applying functions to both elements.

Examples:
 * `(1, 2).map (· + 1) (· * 3) = (2, 6)`
 * `(1, 2).map toString (· * 3) = ("1", 6)`
-/
def Prod.map {α₁ : Type u₁} {α₂ : Type u₂} {β₁ : Type v₁} {β₂ : Type v₂}
    (f : α₁ → α₂) (g : β₁ → β₂) : α₁ × β₁α₂ × β₂
  | (a, b) => (f a, g b)
Mapping of ordered pairs component-wise
Informal description
Given functions $f : \alpha_1 \to \alpha_2$ and $g : \beta_1 \to \beta_2$, the function $\text{Prod.map}$ applies $f$ to the first component and $g$ to the second component of an ordered pair $(a, b) \in \alpha_1 \times \beta_1$, resulting in the pair $(f(a), g(b)) \in \alpha_2 \times \beta_2$.
Prod.map_apply theorem
(f : α → β) (g : γ → δ) (x) (y) : Prod.map f g (x, y) = (f x, g y)
Full source
@[simp] theorem Prod.map_apply (f : α → β) (g : γ → δ) (x) (y) :
    Prod.map f g (x, y) = (f x, g y) := rfl
Component-wise Mapping of Ordered Pairs: $\text{Prod.map}\,f\,g\,(x, y) = (f(x), g(y))$
Informal description
For any functions $f : \alpha \to \beta$ and $g : \gamma \to \delta$, and any elements $x \in \alpha$ and $y \in \gamma$, the mapping of the pair $(x, y)$ under $\text{Prod.map}\,f\,g$ is equal to the pair $(f(x), g(y))$.
Prod.map_fst theorem
(f : α → β) (g : γ → δ) (x) : (Prod.map f g x).1 = f x.1
Full source
@[simp] theorem Prod.map_fst (f : α → β) (g : γ → δ) (x) : (Prod.map f g x).1 = f x.1 := rfl
First Component Preservation under Product Mapping: $(\text{map}\,f\,g\,x).1 = f(x_1)$
Informal description
For any functions $f : \alpha \to \beta$ and $g : \gamma \to \delta$, and any pair $x = (x_1, x_2) \in \alpha \times \gamma$, the first component of the mapped pair $\text{Prod.map}\,f\,g\,x$ is equal to $f$ applied to the first component of $x$, i.e., $(\text{Prod.map}\,f\,g\,x).1 = f(x_1)$.
Prod.map_snd theorem
(f : α → β) (g : γ → δ) (x) : (Prod.map f g x).2 = g x.2
Full source
@[simp] theorem Prod.map_snd (f : α → β) (g : γ → δ) (x) : (Prod.map f g x).2 = g x.2 := rfl
Second Component Preservation under Product Mapping
Informal description
For any functions $f : \alpha \to \beta$ and $g : \gamma \to \delta$, and any pair $x = (x_1, x_2) \in \alpha \times \gamma$, the second component of the mapped pair $\text{Prod.map}\,f\,g\,x$ is equal to $g$ applied to the second component of $x$, i.e., $(\text{Prod.map}\,f\,g\,x).2 = g(x_2)$.
Exists.of_psigma_prop theorem
{α : Sort u} {p : α → Prop} : (PSigma (fun x => p x)) → Exists (fun x => p x)
Full source
theorem Exists.of_psigma_prop {α : Sort u} {p : α → Prop} : (PSigma (fun x => p x)) → Exists (fun x => p x)
  | ⟨x, hx⟩ => ⟨x, hx⟩
Construction of Existential from Dependent Pair
Informal description
For any type $\alpha$ and predicate $p : \alpha \to \text{Prop}$, given a dependent pair $(x, h_x)$ where $x : \alpha$ and $h_x : p x$, there exists an element $x$ of type $\alpha$ such that $p x$ holds.
PSigma.eta theorem
{α : Sort u} {β : α → Sort v} {a₁ a₂ : α} {b₁ : β a₁} {b₂ : β a₂} (h₁ : a₁ = a₂) (h₂ : Eq.ndrec b₁ h₁ = b₂) : PSigma.mk a₁ b₁ = PSigma.mk a₂ b₂
Full source
protected theorem PSigma.eta {α : Sort u} {β : α → Sort v} {a₁ a₂ : α} {b₁ : β a₁} {b₂ : β a₂}
    (h₁ : a₁ = a₂) (h₂ : Eq.ndrec b₁ h₁ = b₂) : PSigma.mk a₁ b₁ = PSigma.mk a₂ b₂ := by
  subst h₁
  subst h₂
  exact rfl
Dependent Pair Equality via Component Equality
Informal description
For any type $\alpha$ and type family $\beta : \alpha \to \text{Sort } v$, given elements $a_1, a_2 \in \alpha$ and elements $b_1 \in \beta a_1$, $b_2 \in \beta a_2$, if $a_1 = a_2$ and $b_1$ transported along this equality equals $b_2$, then the dependent pairs $\langle a_1, b_1 \rangle$ and $\langle a_2, b_2 \rangle$ are equal.
PUnit.subsingleton theorem
(a b : PUnit) : a = b
Full source
theorem PUnit.subsingleton (a b : PUnit) : a = b := by
  cases a; cases b; exact rfl
Uniqueness of Elements in the Unit Type
Informal description
For any two elements $a$ and $b$ of the unit type $\text{PUnit}$, we have $a = b$.
instSubsingletonPUnit instance
: Subsingleton PUnit
Full source
instance : Subsingleton PUnit :=
  Subsingleton.intro PUnit.subsingleton
Universe-Polymorphic Unit Type is a Subsingleton
Informal description
The universe-polymorphic unit type `PUnit` is a subsingleton, meaning any two elements of `PUnit` are equal.
instInhabitedPUnit instance
: Inhabited PUnit
Full source
instance : Inhabited PUnit where
  default := ⟨⟩
Inhabited Universe-Polymorphic Unit Type
Informal description
The universe-polymorphic unit type `PUnit` is inhabited, with a designated default element.
instDecidableEqPUnit instance
: DecidableEq PUnit
Full source
instance : DecidableEq PUnit :=
  fun a b => isTrue (PUnit.subsingleton a b)
Decidable Equality for the Unit Type
Informal description
The universe-polymorphic unit type $\text{PUnit}$ has decidable equality. That is, for any two elements $a, b \in \text{PUnit}$, the equality $a = b$ is decidable.
Setoid structure
(α : Sort u)
Full source
/--
A setoid is a type with a distinguished equivalence relation, denoted `≈`.

The `Quotient` type constructor requires a `Setoid` instance.
-/
class Setoid (α : Sort u) where
  /-- `x ≈ y` is the distinguished equivalence relation of a setoid. -/
  r : α → α → Prop
  /-- The relation `x ≈ y` is an equivalence relation. -/
  iseqv : Equivalence r
Setoid (Type with Equivalence Relation)
Informal description
A setoid is a type $\alpha$ equipped with a distinguished equivalence relation $\approx$ on $\alpha$. This structure is used to define quotient types, where the quotient construction requires an underlying setoid instance to specify the equivalence relation being quotiented by.
instHasEquivOfSetoid instance
{α : Sort u} [Setoid α] : HasEquiv α
Full source
instance {α : Sort u} [Setoid α] : HasEquiv α :=
  ⟨Setoid.r⟩
Setoid Induces Equivalence Relation
Informal description
For any type $\alpha$ equipped with a setoid structure (an equivalence relation $\approx$), there is a canonical way to view $\alpha$ as having an equivalence relation, enabling the notation $x \approx y$ for $x, y \in \alpha$.
Setoid.refl theorem
(a : α) : a ≈ a
Full source
/-- A setoid's equivalence relation is reflexive. -/
theorem refl (a : α) : a ≈ a :=
  iseqv.refl a
Reflexivity of Setoid Equivalence Relation
Informal description
For any element $a$ of a type $\alpha$ equipped with a setoid structure (i.e., an equivalence relation $\approx$), the relation $a \approx a$ holds.
Setoid.symm theorem
{a b : α} (hab : a ≈ b) : b ≈ a
Full source
/-- A setoid's equivalence relation is symmetric. -/
theorem symm {a b : α} (hab : a ≈ b) : b ≈ a :=
  iseqv.symm hab
Symmetry of Setoid Equivalence Relation
Informal description
For any elements $a$ and $b$ of a type $\alpha$ equipped with a setoid structure (i.e., an equivalence relation $\approx$), if $a \approx b$, then $b \approx a$.
Setoid.trans theorem
{a b c : α} (hab : a ≈ b) (hbc : b ≈ c) : a ≈ c
Full source
/-- A setoid's equivalence relation is transitive. -/
theorem trans {a b c : α} (hab : a ≈ b) (hbc : b ≈ c) : a ≈ c :=
  iseqv.trans hab hbc
Transitivity of Setoid Equivalence Relation
Informal description
For any elements $a, b, c$ of a type $\alpha$ equipped with a setoid structure (i.e., an equivalence relation $\approx$), if $a \approx b$ and $b \approx c$, then $a \approx c$.
propext axiom
{a b : Prop} : (a ↔ b) → a = b
Full source
/--
The axiom of **propositional extensionality**. It asserts that if propositions
`a` and `b` are logically equivalent (i.e. we can prove `a` from `b` and vice versa),
then `a` and `b` are *equal*, meaning that we can replace `a` with `b` in all
contexts.

For simple expressions like `a ∧ c ∨ d → e` we can prove that because all the logical
connectives respect logical equivalence, we can replace `a` with `b` in this expression
without using `propext`. However, for higher order expressions like `P a` where
`P : Prop → Prop` is unknown, or indeed for `a = b` itself, we cannot replace `a` with `b`
without an axiom which says exactly this.

This is a relatively uncontroversial axiom, which is intuitionistically valid.
It does however block computation when using `#reduce` to reduce proofs directly
(which is not recommended), meaning that canonicity,
the property that all closed terms of type `Nat` normalize to numerals,
fails to hold when this (or any) axiom is used:
```
set_option pp.proofs true

def foo : Nat := by
  have : (True → True) ↔ True := ⟨λ _ => trivial, λ _ _ => trivial⟩
  have := propext this ▸ (2 : Nat)
  exact this

#reduce foo
-- propext { mp := fun x x => True.intro, mpr := fun x => True.intro } ▸ 2

#eval foo -- 2
```
`#eval` can evaluate it to a numeral because the compiler erases casts and
does not evaluate proofs, so `propext`, whose return type is a proposition,
can never block it.
-/
axiom propext {a b : Prop} : (a ↔ b) → a = b
Axiom of Propositional Extensionality: $(a \leftrightarrow b) \to a = b$
Informal description
For any two propositions $a$ and $b$, if $a$ is logically equivalent to $b$ (i.e., $a \leftrightarrow b$ holds), then $a$ and $b$ are equal (i.e., $a = b$ holds).
Eq.propIntro theorem
{a b : Prop} (h₁ : a → b) (h₂ : b → a) : a = b
Full source
theorem Eq.propIntro {a b : Prop} (h₁ : a → b) (h₂ : b → a) : a = b :=
  propext <| Iff.intro h₁ h₂
Propositional Equality via Mutual Implication
Informal description
For any two propositions $a$ and $b$, if $a$ implies $b$ and $b$ implies $a$, then $a$ and $b$ are equal, i.e., $a = b$.
instDecidableEqOfIff instance
{p q : Prop} [d : Decidable (p ↔ q)] : Decidable (p = q)
Full source
instance {p q : Prop} [d : Decidable (p ↔ q)] : Decidable (p = q) :=
  match d with
  | isTrue h => isTrue (propext h)
  | isFalse h => isFalse fun heq => h (heq ▸ Iff.rfl)
Decidability of Propositional Equality via Bi-implication
Informal description
For any two propositions $p$ and $q$, if there exists a constructive proof that $p \leftrightarrow q$ is decidable, then there exists a constructive proof that $p = q$ is decidable.
Nat.succ.inj theorem
{m n : Nat} : m.succ = n.succ → m = n
Full source
theorem Nat.succ.inj {m n : Nat} : m.succ = n.succ → m = n :=
  fun x => Nat.noConfusion x id
Injectivity of Successor Function on Natural Numbers
Informal description
For any natural numbers $m$ and $n$, if the successor of $m$ equals the successor of $n$, then $m$ equals $n$.
Nat.succ.injEq theorem
(u v : Nat) : (u.succ = v.succ) = (u = v)
Full source
theorem Nat.succ.injEq (u v : Nat) : (u.succ = v.succ) = (u = v) :=
  Eq.propIntro Nat.succ.inj (congrArg Nat.succ)
Equivalence of Successor Equality: $(u+1 = v+1) ↔ (u = v)$
Informal description
For any natural numbers $u$ and $v$, the equality $u+1 = v+1$ holds if and only if $u = v$ holds.
beq_iff_eq theorem
[BEq α] [LawfulBEq α] {a b : α} : a == b ↔ a = b
Full source
@[simp] theorem beq_iff_eq [BEq α] [LawfulBEq α] {a b : α} : a == b ↔ a = b :=
  ⟨eq_of_beq, by intro h; subst h; exact LawfulBEq.rfl⟩
Equivalence of Boolean and Propositional Equality in Lawful Types
Informal description
For any type $\alpha$ with a boolean equality operation `==` that is lawful (i.e., agrees with propositional equality), and for any elements $a, b \in \alpha$, the boolean equality test $a == b$ holds if and only if $a = b$.
Not.elim definition
{α : Sort _} (H1 : ¬a) (H2 : a) : α
Full source
/-- *Ex falso* for negation: from `¬a` and `a` anything follows. This is the same as `absurd` with
the arguments flipped, but it is in the `Not` namespace so that projection notation can be used. -/
def Not.elim {α : Sort _} (H1 : ¬a) (H2 : a) : α := absurd H2 H1
Negation elimination (ex falso)
Informal description
Given a type $\alpha$, a proof $H_1$ of $\neg a$, and a proof $H_2$ of $a$, the term $\text{Not.elim}\, H_1\, H_2$ produces an element of type $\alpha$. This is equivalent to the principle of explosion (ex falso quodlibet), where a contradiction allows deriving any term.
And.elim abbrev
(f : a → b → α) (h : a ∧ b) : α
Full source
/-- Non-dependent eliminator for `And`. -/
abbrev And.elim (f : a → b → α) (h : a ∧ b) : α := f h.left h.right
Conjunction Eliminator
Informal description
Given a function $f : a \to b \to \alpha$ and a proof $h$ of the conjunction $a \land b$, the eliminator produces an element of type $\alpha$ by applying $f$ to the left and right components of $h$.
Iff.elim definition
(f : (a → b) → (b → a) → α) (h : a ↔ b) : α
Full source
/-- Non-dependent eliminator for `Iff`. -/
def Iff.elim (f : (a → b) → (b → a) → α) (h : a ↔ b) : α := f h.mp h.mpr
Bi-implication Eliminator
Informal description
Given a function $f : (a \to b) \to (b \to a) \to \alpha$ and a proof $h$ of the bi-implication $a \leftrightarrow b$, the eliminator produces an element of type $\alpha$ by applying $f$ to the forward and backward implications extracted from $h$.
Iff.subst theorem
{a b : Prop} {p : Prop → Prop} (h₁ : a ↔ b) (h₂ : p a) : p b
Full source
/-- Iff can now be used to do substitutions in a calculation -/
theorem Iff.subst {a b : Prop} {p : Prop → Prop} (h₁ : a ↔ b) (h₂ : p a) : p b :=
  Eq.subst (propext h₁) h₂
Substitution Property of Logical Equivalence
Informal description
For any propositions $a$ and $b$ and any predicate $p$ on propositions, if $a \leftrightarrow b$ holds and $p(a)$ holds, then $p(b)$ also holds.
Not.intro theorem
{a : Prop} (h : a → False) : ¬a
Full source
theorem Not.intro {a : Prop} (h : a → False) : ¬a := h
Introduction Rule for Negation
Informal description
For any proposition $a$, if assuming $a$ leads to a contradiction (i.e., $a \to \text{False}$), then $\neg a$ holds.
Not.imp theorem
{a b : Prop} (H2 : ¬b) (H1 : a → b) : ¬a
Full source
theorem Not.imp {a b : Prop} (H2 : ¬b) (H1 : a → b) : ¬a := mt H1 H2
Modus Tollens: $\neg a$ from $a \to b$ and $\neg b$
Informal description
For any propositions $a$ and $b$, if $a$ implies $b$ ($a \to b$) and $b$ is false ($\neg b$), then $a$ is false ($\neg a$).
not_congr theorem
(h : a ↔ b) : ¬a ↔ ¬b
Full source
theorem not_congr (h : a ↔ b) : ¬a¬a ↔ ¬b := ⟨mt h.2, mt h.1⟩
Negation Preserves Logical Equivalence: $\neg a \leftrightarrow \neg b$ from $a \leftrightarrow b$
Informal description
For any propositions $a$ and $b$, if $a$ is equivalent to $b$ ($a \leftrightarrow b$), then the negation of $a$ is equivalent to the negation of $b$ ($\neg a \leftrightarrow \neg b$).
not_not_not theorem
: ¬¬¬a ↔ ¬a
Full source
theorem not_not_not : ¬¬¬a¬¬¬a ↔ ¬a := ⟨mt not_not_intro, not_not_intro⟩
Triple Negation Equivalence: $\neg \neg \neg a \leftrightarrow \neg a$
Informal description
For any proposition $a$, the triple negation $\neg \neg \neg a$ is equivalent to the single negation $\neg a$, i.e., $\neg \neg \neg a \leftrightarrow \neg a$.
iff_of_true theorem
(ha : a) (hb : b) : a ↔ b
Full source
theorem iff_of_true (ha : a) (hb : b) : a ↔ b := Iff.intro (fun _ => hb) (fun _ => ha)
Logical Equivalence from Truth of Both Propositions
Informal description
Given two propositions $a$ and $b$ such that $a$ holds and $b$ holds, then $a$ is logically equivalent to $b$, i.e., $a \leftrightarrow b$.
iff_of_false theorem
(ha : ¬a) (hb : ¬b) : a ↔ b
Full source
theorem iff_of_false (ha : ¬a) (hb : ¬b) : a ↔ b := Iff.intro ha.elim hb.elim
Logical Equivalence from Falsity of Both Propositions: $\neg a \land \neg b \to (a \leftrightarrow b)$
Informal description
For any propositions $a$ and $b$, if both $\neg a$ and $\neg b$ hold, then $a$ is logically equivalent to $b$, i.e., $a \leftrightarrow b$.
iff_true_left theorem
(ha : a) : (a ↔ b) ↔ b
Full source
theorem iff_true_left  (ha : a) : (a ↔ b) ↔ b := Iff.intro (·.mp ha) (iff_of_true ha)
Equivalence of Biconditional with True Left Proposition
Informal description
Given a proposition $a$ that holds, the statement "$a$ if and only if $b$" is equivalent to $b$ itself, i.e., $(a \leftrightarrow b) \leftrightarrow b$.
iff_true_right theorem
(ha : a) : (b ↔ a) ↔ b
Full source
theorem iff_true_right (ha : a) : (b ↔ a) ↔ b := Iff.comm.trans (iff_true_left ha)
Equivalence of Biconditional with True Right Proposition: $(b \leftrightarrow a) \leftrightarrow b$ when $a$ holds
Informal description
Given a proposition $a$ that holds, the statement "$b$ if and only if $a$" is equivalent to $b$ itself, i.e., $(b \leftrightarrow a) \leftrightarrow b$.
iff_false_left theorem
(ha : ¬a) : (a ↔ b) ↔ ¬b
Full source
theorem iff_false_left  (ha : ¬a) : (a ↔ b) ↔ ¬b := Iff.intro (mt ·.mpr ha) (iff_of_false ha)
Equivalence of Biconditional with False Left Proposition: $(a \leftrightarrow b) \leftrightarrow \neg b$ when $\neg a$ holds
Informal description
For any propositions $a$ and $b$, if $\neg a$ holds, then the statement "$a$ if and only if $b$" is equivalent to $\neg b$, i.e., $(a \leftrightarrow b) \leftrightarrow \neg b$.
iff_false_right theorem
(ha : ¬a) : (b ↔ a) ↔ ¬b
Full source
theorem iff_false_right (ha : ¬a) : (b ↔ a) ↔ ¬b := Iff.comm.trans (iff_false_left ha)
Equivalence of Biconditional with False Right Proposition: $(b \leftrightarrow a) \leftrightarrow \neg b$ when $\neg a$ holds
Informal description
For any propositions $a$ and $b$, if $\neg a$ holds, then the statement "$b$ if and only if $a$" is equivalent to $\neg b$, i.e., $(b \leftrightarrow a) \leftrightarrow \neg b$.
of_iff_true theorem
(h : a ↔ True) : a
Full source
theorem of_iff_true    (h : a ↔ True) : a := h.mpr trivial
Implication from Equivalence with True: $a \leftrightarrow \text{True} \implies a$
Informal description
Given a proposition $a$ such that $a$ is equivalent to $\text{True}$ (i.e., $a \leftrightarrow \text{True}$), then $a$ holds.
iff_true_intro theorem
(h : a) : a ↔ True
Full source
theorem iff_true_intro (h : a) : a ↔ True := iff_of_true h trivial
Equivalence with True from Proof of Proposition
Informal description
For any proposition $a$, if $a$ holds, then $a$ is logically equivalent to the true proposition $\text{True}$, i.e., $a \leftrightarrow \text{True}$.
not_of_iff_false theorem
: (p ↔ False) → ¬p
Full source
theorem not_of_iff_false : (p ↔ False) → ¬p := Iff.mp
Negation from False Equivalence
Informal description
For any proposition $p$, if $p$ is equivalent to $\text{False}$, then $\neg p$ holds.
iff_false_intro theorem
(h : ¬a) : a ↔ False
Full source
theorem iff_false_intro (h : ¬a) : a ↔ False := iff_of_false h id
Equivalence of False Proposition to False: $\neg a \to (a \leftrightarrow \text{False})$
Informal description
For any proposition $a$, if $\neg a$ holds, then $a$ is logically equivalent to $\text{False}$, i.e., $a \leftrightarrow \text{False}$.
not_iff_false_intro theorem
(h : a) : ¬a ↔ False
Full source
theorem not_iff_false_intro (h : a) : ¬a¬a ↔ False := iff_false_intro (not_not_intro h)
Negation of True Proposition is False: $a \to (\neg a \leftrightarrow \text{False})$
Informal description
For any proposition $a$, if $a$ holds, then the negation of $a$ is equivalent to $\text{False}$, i.e., $\neg a \leftrightarrow \text{False}$.
not_true theorem
: (¬True) ↔ False
Full source
theorem not_true : (¬True) ↔ False := iff_false_intro (not_not_intro trivial)
Negation of True is False ($\neg \text{True} \leftrightarrow \text{False}$)
Informal description
The negation of the true proposition is equivalent to false, i.e., $\neg \text{True} \leftrightarrow \text{False}$.
not_false_iff theorem
: (¬False) ↔ True
Full source
theorem not_false_iff : (¬False) ↔ True := iff_true_intro not_false
Negation of False is Equivalent to True
Informal description
The negation of the false proposition is equivalent to the true proposition, i.e., $\neg \text{False} \leftrightarrow \text{True}$.
Eq.to_iff theorem
: a = b → (a ↔ b)
Full source
theorem Eq.to_iff : a = b → (a ↔ b) := Iff.of_eq
Equality Implies Logical Equivalence ($a = b \Rightarrow a \leftrightarrow b$)
Informal description
For any propositions $a$ and $b$, if $a = b$ then $a \leftrightarrow b$.
iff_of_eq theorem
: a = b → (a ↔ b)
Full source
theorem iff_of_eq : a = b → (a ↔ b) := Iff.of_eq
Equality Implies Logical Equivalence ($a = b \Rightarrow a \leftrightarrow b$)
Informal description
For any propositions $a$ and $b$, if $a = b$ then $a \leftrightarrow b$.
neq_of_not_iff theorem
: ¬(a ↔ b) → a ≠ b
Full source
theorem neq_of_not_iff : ¬(a ↔ b)a ≠ b := mt Iff.of_eq
Non-equivalence Implies Non-equality: $\neg (a \leftrightarrow b) \Rightarrow a \neq b$
Informal description
For any propositions $a$ and $b$, if $a$ is not equivalent to $b$ (i.e., $\neg (a \leftrightarrow b)$), then $a$ is not equal to $b$ (i.e., $a \neq b$).
iff_iff_eq theorem
: (a ↔ b) ↔ a = b
Full source
theorem iff_iff_eq : (a ↔ b) ↔ a = b := Iff.intro propext Iff.of_eq
Propositional Equivalence Equals Equality ($a \leftrightarrow b \iff a = b$)
Informal description
For any two propositions $a$ and $b$, the logical equivalence $a \leftrightarrow b$ holds if and only if $a$ and $b$ are equal, i.e., $a \leftrightarrow b \iff a = b$.
ne_self_iff_false theorem
(a : α) : a ≠ a ↔ False
Full source
theorem ne_self_iff_false (a : α) : a ≠ aa ≠ a ↔ False := not_iff_false_intro rfl
Inequality with Self is False: $a \neq a \leftrightarrow \text{False}$
Informal description
For any element $a$ of type $\alpha$, the statement $a \neq a$ is equivalent to $\text{False}$.
false_of_true_iff_false theorem
(h : True ↔ False) : False
Full source
theorem false_of_true_iff_false (h : TrueTrue ↔ False) : False := h.mp trivial
Contradiction from $\text{True} \leftrightarrow \text{False}$
Informal description
Given a bi-implication between the propositions $\text{True}$ and $\text{False}$, i.e., $\text{True} \leftrightarrow \text{False}$, we can derive a contradiction ($\text{False}$).
false_of_true_eq_false theorem
(h : True = False) : False
Full source
theorem false_of_true_eq_false  (h : True = False) : False := false_of_true_iff_false (Iff.of_eq h)
Contradiction from $\text{True} = \text{False}$
Informal description
Given an equality between the propositions $\text{True}$ and $\text{False}$, i.e., $\text{True} = \text{False}$, we can derive a contradiction ($\text{False}$).
true_eq_false_of_false theorem
: False → (True = False)
Full source
theorem true_eq_false_of_false : False → (True = False) := False.elim
Contradiction Implies True Equals False
Informal description
Given a contradiction (a proof of `False`), it follows that the proposition `True` is equal to `False`, i.e., $\text{True} = \text{False}$.
iff_def theorem
: (a ↔ b) ↔ (a → b) ∧ (b → a)
Full source
theorem iff_def  : (a ↔ b) ↔ (a → b) ∧ (b → a) := iff_iff_implies_and_implies
Bi-implication Equivalence: $a \leftrightarrow b \iff (a \rightarrow b) \land (b \rightarrow a)$
Informal description
For any two propositions $a$ and $b$, the bi-implication $a \leftrightarrow b$ holds if and only if both $a \rightarrow b$ and $b \rightarrow a$ hold.
iff_def' theorem
: (a ↔ b) ↔ (b → a) ∧ (a → b)
Full source
theorem iff_def' : (a ↔ b) ↔ (b → a) ∧ (a → b) := Iff.trans iff_def And.comm
Bi-implication Equivalence: $a \leftrightarrow b \iff (b \rightarrow a) \land (a \rightarrow b)$
Informal description
For any two propositions $a$ and $b$, the bi-implication $a \leftrightarrow b$ holds if and only if both $b \rightarrow a$ and $a \rightarrow b$ hold.
false_iff_true theorem
: (False ↔ True) ↔ False
Full source
theorem false_iff_true : (False ↔ True) ↔ False := iff_false_intro (·.mpr True.intro)
False Implication with True is False
Informal description
The bi-implication between the false proposition $\text{False}$ and the true proposition $\text{True}$ is equivalent to $\text{False}$, i.e., $(\text{False} \leftrightarrow \text{True}) \leftrightarrow \text{False}$.
iff_not_self theorem
: ¬(a ↔ ¬a)
Full source
theorem iff_not_self : ¬(a ↔ ¬a) | H => let f h := H.1 h h; f (H.2 f)
Non-equivalence of a Proposition with its Negation
Informal description
For any proposition $a$, it is not the case that $a$ is equivalent to its negation, i.e., $\neg (a \leftrightarrow \neg a)$.
heq_self_iff_true theorem
(a : α) : HEq a a ↔ True
Full source
theorem heq_self_iff_true (a : α) : HEqHEq a a ↔ True := iff_true_intro HEq.rfl
Heterogeneous Reflexivity is Equivalent to True
Informal description
For any element $a$ of type $\alpha$, the heterogeneous equality $a \equiv a$ holds if and only if the true proposition $\text{True}$ holds.
not_not_of_not_imp theorem
: ¬(a → b) → ¬¬a
Full source
theorem not_not_of_not_imp : ¬(a → b)¬¬a := mt Not.elim
Double Negation from Negated Implication: $\neg(a \to b) \to \neg\neg a$
Informal description
For any propositions $a$ and $b$, if the implication $a \to b$ is false ($\neg(a \to b)$), then the double negation of $a$ holds ($\neg\neg a$).
not_of_not_imp theorem
{a : Prop} : ¬(a → b) → ¬b
Full source
theorem not_of_not_imp {a : Prop} : ¬(a → b)¬b := mt fun h _ => h
Negation of Implication Implies Negation of Consequent
Informal description
For any proposition $a$, if the implication $a \to b$ is false ($\neg(a \to b)$), then $b$ is false ($\neg b$).
imp_not_self theorem
: (a → ¬a) ↔ ¬a
Full source
@[simp] theorem imp_not_self : (a → ¬a) ↔ ¬a := Iff.intro (fun h ha => h ha ha) (fun h _ => h)
Implication of Self-Negation: $(a \to \neg a) \leftrightarrow \neg a$
Informal description
For any proposition $a$, the implication $(a \to \neg a)$ holds if and only if $\neg a$ holds.
imp_intro theorem
{α β : Prop} (h : α) : β → α
Full source
theorem imp_intro {α β : Prop} (h : α) : β → α := fun _ => h
Implication Introduction: $\beta \to \alpha$ from $\alpha$
Informal description
For any propositions $\alpha$ and $\beta$, given a proof $h$ of $\alpha$, the implication $\beta \to \alpha$ holds.
imp_imp_imp theorem
{a b c d : Prop} (h₀ : c → a) (h₁ : b → d) : (a → b) → (c → d)
Full source
theorem imp_imp_imp {a b c d : Prop} (h₀ : c → a) (h₁ : b → d) : (a → b) → (c → d) := (h₁ ∘ · ∘ h₀)
Implication Chain: $(c \to a) \to (b \to d) \to (a \to b) \to (c \to d)$
Informal description
For any propositions $a, b, c, d$, given implications $c \to a$ and $b \to d$, the implication $(a \to b) \to (c \to d)$ holds.
imp_iff_right theorem
{a : Prop} (ha : a) : (a → b) ↔ b
Full source
theorem imp_iff_right {a : Prop} (ha : a) : (a → b) ↔ b := Iff.intro (· ha) (fun a _ => a)
Implication Equivalence: $(a \to b) \leftrightarrow b$ given $a$
Informal description
For any proposition $a$ with a proof $ha : a$, the implication $(a \to b)$ is equivalent to $b$.
imp_true_iff theorem
(α : Sort u) : (α → True) ↔ True
Full source
theorem imp_true_iff (α : Sort u) : (α → True) ↔ True := iff_true_intro (fun _ => trivial)
Implication to True is Trivially True
Informal description
For any type $\alpha$, the implication $(\alpha \to \text{True})$ is equivalent to $\text{True}$.
false_imp_iff theorem
(a : Prop) : (False → a) ↔ True
Full source
theorem false_imp_iff (a : Prop) : (False → a) ↔ True := iff_true_intro False.elim
Implication from False: $(\text{False} \to a) \leftrightarrow \text{True}$
Informal description
For any proposition $a$, the implication $(\text{False} \to a)$ is equivalent to $\text{True}$.
true_imp_iff theorem
{α : Prop} : (True → α) ↔ α
Full source
theorem true_imp_iff {α : Prop} : (True → α) ↔ α := imp_iff_right True.intro
Implication from True: $(\text{True} \to \alpha) \leftrightarrow \alpha$
Informal description
For any proposition $\alpha$, the implication $(\text{True} \to \alpha)$ holds if and only if $\alpha$ holds.
imp_self theorem
: (a → a) ↔ True
Full source
@[simp high] theorem imp_self : (a → a) ↔ True := iff_true_intro id
Implication Reflexivity: $(a \to a) \leftrightarrow \text{True}$
Informal description
For any proposition $a$, the implication $a \to a$ is equivalent to the true proposition $\text{True}$, i.e., $(a \to a) \leftrightarrow \text{True}$.
imp_false theorem
: (a → False) ↔ ¬a
Full source
@[simp] theorem imp_false : (a → False) ↔ ¬a := Iff.rfl
Implication to False is Equivalent to Negation: $(a \to \text{False}) \leftrightarrow \neg a$
Informal description
For any proposition $a$, the implication $(a \to \text{False})$ holds if and only if $\neg a$ holds.
imp.swap theorem
: (a → b → c) ↔ (b → a → c)
Full source
theorem imp.swap : (a → b → c) ↔ (b → a → c) := Iff.intro flip flip
Implication Order Swap: $(a \to b \to c) \leftrightarrow (b \to a \to c)$
Informal description
For any propositions $a$, $b$, and $c$, the implication $a \to (b \to c)$ is equivalent to the implication $b \to (a \to c)$.
imp_not_comm theorem
: (a → ¬b) ↔ (b → ¬a)
Full source
theorem imp_not_comm : (a → ¬b) ↔ (b → ¬a) := imp.swap
Implication-Negation Commutation: $(a \to \neg b) \leftrightarrow (b \to \neg a)$
Informal description
For any propositions $a$ and $b$, the implication $a \to \neg b$ is equivalent to the implication $b \to \neg a$.
imp_congr_left theorem
(h : a ↔ b) : (a → c) ↔ (b → c)
Full source
theorem imp_congr_left (h : a ↔ b) : (a → c) ↔ (b → c) := Iff.intro (· ∘ h.mpr) (· ∘ h.mp)
Implication Equivalence under Propositional Equivalence
Informal description
Given propositions $a$, $b$, and $c$, and a proof $h$ that $a \leftrightarrow b$, then the implication $a \to c$ is equivalent to the implication $b \to c$. In other words, $(a \to c) \leftrightarrow (b \to c)$.
imp_congr_right theorem
(h : a → (b ↔ c)) : (a → b) ↔ (a → c)
Full source
theorem imp_congr_right (h : a → (b ↔ c)) : (a → b) ↔ (a → c) :=
  Iff.intro (fun hab ha => (h ha).mp (hab ha)) (fun hcd ha => (h ha).mpr (hcd ha))
Implication Equivalence under Conditional Bi-implication
Informal description
Given propositions $a$, $b$, and $c$, and a proof $h$ that $a$ implies the equivalence $b \leftrightarrow c$, then the implication $a \to b$ is equivalent to the implication $a \to c$. In other words, $(a \to b) \leftrightarrow (a \to c)$.
imp_congr_ctx theorem
(h₁ : a ↔ c) (h₂ : c → (b ↔ d)) : (a → b) ↔ (c → d)
Full source
theorem imp_congr_ctx (h₁ : a ↔ c) (h₂ : c → (b ↔ d)) : (a → b) ↔ (c → d) :=
  Iff.trans (imp_congr_left h₁) (imp_congr_right h₂)
Implication Equivalence under Contextual Bi-implication
Informal description
Given propositions $a$, $b$, $c$, and $d$, and proofs $h_1$ that $a \leftrightarrow c$ and $h_2$ that $c$ implies $b \leftrightarrow d$, then the implication $a \to b$ is equivalent to the implication $c \to d$. In other words, $(a \to b) \leftrightarrow (c \to d)$.
imp_congr theorem
(h₁ : a ↔ c) (h₂ : b ↔ d) : (a → b) ↔ (c → d)
Full source
theorem imp_congr (h₁ : a ↔ c) (h₂ : b ↔ d) : (a → b) ↔ (c → d) := imp_congr_ctx h₁ fun _ => h₂
Implication Equivalence under Bi-implication
Informal description
Given propositions $a$, $b$, $c$, and $d$, and proofs $h_1$ that $a \leftrightarrow c$ and $h_2$ that $b \leftrightarrow d$, then the implication $a \to b$ is equivalent to the implication $c \to d$. In other words, $(a \to b) \leftrightarrow (c \to d)$.
imp_iff_not theorem
(hb : ¬b) : a → b ↔ ¬a
Full source
theorem imp_iff_not (hb : ¬b) : a → b ↔ ¬a := imp_congr_right fun _ => iff_false_intro hb
Implication Equivalence under False Conclusion: $(a \to b) \leftrightarrow \neg a$ when $\neg b$
Informal description
For any propositions $a$ and $b$, if $\neg b$ holds, then the implication $a \to b$ is equivalent to $\neg a$. That is, $(a \to b) \leftrightarrow \neg a$.
Quot.sound axiom
: ∀ {α : Sort u} {r : α → α → Prop} {a b : α}, r a b → Quot.mk r a = Quot.mk r b
Full source
/--
The **quotient axiom**, which asserts the equality of elements related by the quotient's relation.

The relation `r` does not need to be an equivalence relation to use this axiom. When `r` is not an
equivalence relation, the quotient is with respect to the equivalence relation generated by `r`.

`Quot.sound` is part of the built-in primitive quotient type:
 * `Quot` is the built-in quotient type.
 * `Quot.mk` places elements of the underlying type `α` into the quotient.
 * `Quot.lift` allows the definition of functions from the quotient to some other type.
 * `Quot.ind` is used to write proofs about quotients by assuming that all elements are constructed
   with `Quot.mk`; it is analogous to the [recursor](lean-manual://section/recursors) for a
   structure.

[Quotient types](lean-manual://section/quotients) are described in more detail in the Lean Language
Reference.
-/
axiom sound : ∀ {α : Sort u} {r : α → α → Prop} {a b : α}, r a b → Quot.mk r a = Quot.mk r b
Quotient Soundness Axiom
Informal description
For any type $\alpha$ and any binary relation $r$ on $\alpha$, if two elements $a, b \in \alpha$ are related by $r$ (i.e., $r(a, b)$ holds), then their images under the quotient map $\operatorname{Quot.mk}_r$ are equal, i.e., $\operatorname{Quot.mk}_r(a) = \operatorname{Quot.mk}_r(b)$.
Quot.liftBeta theorem
{α : Sort u} {r : α → α → Prop} {β : Sort v} (f : α → β) (c : (a b : α) → r a b → f a = f b) (a : α) : lift f c (Quot.mk r a) = f a
Full source
protected theorem liftBeta {α : Sort u} {r : α → α → Prop} {β : Sort v}
    (f : α → β)
    (c : (a b : α) → r a b → f a = f b)
    (a : α)
    : lift f c (Quot.mk r a) = f a :=
  rfl
Computation Rule for Quotient Lifting
Informal description
For any type $\alpha$ with a relation $r : \alpha \to \alpha \to \mathrm{Prop}$, any type $\beta$, any function $f : \alpha \to \beta$, and any proof $c$ that $f$ respects $r$ (i.e., for all $a, b \in \alpha$, $r(a, b)$ implies $f(a) = f(b)$), the lifting of $f$ to the quotient $\mathrm{Quot}\,r$ satisfies $\mathrm{lift}\,f\,c\,(\mathrm{Quot.mk}_r\,a) = f(a)$ for any $a \in \alpha$.
Quot.indBeta theorem
{α : Sort u} {r : α → α → Prop} {motive : Quot r → Prop} (p : (a : α) → motive (Quot.mk r a)) (a : α) : (ind p (Quot.mk r a) : motive (Quot.mk r a)) = p a
Full source
protected theorem indBeta {α : Sort u} {r : α → α → Prop} {motive : Quot r → Prop}
    (p : (a : α) → motive (Quot.mk r a))
    (a : α)
    : (ind p (Quot.mk r a) : motive (Quot.mk r a)) = p a :=
  rfl
Computation Rule for Quotient Induction
Informal description
For any type $\alpha$ with a relation $r : \alpha \to \alpha \to \mathrm{Prop}$, a property $\mathrm{motive}$ on the quotient $\mathrm{Quot}\,r$, and a function $p : \alpha \to \mathrm{motive}(\mathrm{Quot.mk}_r(a))$, the application of the induction principle $\mathrm{ind}\,p$ to the quotient element $\mathrm{Quot.mk}_r(a)$ is equal to $p(a)$.
Quot.liftOn abbrev
{α : Sort u} {β : Sort v} {r : α → α → Prop} (q : Quot r) (f : α → β) (c : (a b : α) → r a b → f a = f b) : β
Full source
/--
Lifts a function from an underlying type to a function on a quotient, requiring that it respects the
quotient's relation.

Given a relation `r : α → α → Prop` and a quotient's value `q : Quot r`, applying a `f : α → β`
requires a proof `c` that `f` respects `r`. In this case, `Quot.liftOn q f h : β` evaluates
to the result of applying `f` to the underlying value in `α` from `q`.

`Quot.liftOn` is a version of the built-in primitive `Quot.lift` with its parameters re-ordered.

[Quotient types](lean-manual://section/quotients) are described in more detail in the Lean Language
Reference.
-/
protected abbrev liftOn {α : Sort u} {β : Sort v} {r : α → α → Prop}
  (q : Quot r) (f : α → β) (c : (a b : α) → r a b → f a = f b) : β :=
  lift f c q
Lifting a Function to a Quotient via Respect for the Relation
Informal description
Given a type $\alpha$ with a relation $r : \alpha \to \alpha \to \mathrm{Prop}$, a quotient value $q : \mathrm{Quot}\,r$, a function $f : \alpha \to \beta$, and a proof $c$ that $f$ respects $r$ (i.e., for any $a, b \in \alpha$, if $r\,a\,b$ holds then $f\,a = f\,b$), the operation $\mathrm{Quot.liftOn}\,q\,f\,c$ lifts $f$ to the quotient, yielding an element of type $\beta$.
Quot.inductionOn theorem
{α : Sort u} {r : α → α → Prop} {motive : Quot r → Prop} (q : Quot r) (h : (a : α) → motive (Quot.mk r a)) : motive q
Full source
@[elab_as_elim]
protected theorem inductionOn {α : Sort u} {r : α → α → Prop} {motive : Quot r → Prop}
    (q : Quot r)
    (h : (a : α) → motive (Quot.mk r a))
    : motive q :=
  ind h q
Induction Principle for Quotient Types
Informal description
For any type $\alpha$ with a relation $r : \alpha \to \alpha \to \mathrm{Prop}$, a property $\mathrm{motive}$ on the quotient $\mathrm{Quot}\,r$, and a quotient element $q : \mathrm{Quot}\,r$, if the property holds for every equivalence class $\mathrm{Quot.mk}_r(a)$ where $a : \alpha$, then the property holds for $q$.
Quot.exists_rep theorem
{α : Sort u} {r : α → α → Prop} (q : Quot r) : Exists (fun a => (Quot.mk r a) = q)
Full source
theorem exists_rep {α : Sort u} {r : α → α → Prop} (q : Quot r) : Exists (fun a => (Quot.mk r a) = q) :=
  q.inductionOn (fun a => ⟨a, rfl⟩)
Existence of Representative for Quotient Elements
Informal description
For any type $\alpha$ with a relation $r : \alpha \to \alpha \to \mathrm{Prop}$ and any element $q$ of the quotient $\mathrm{Quot}\,r$, there exists an element $a \in \alpha$ such that the equivalence class of $a$ under $r$ is equal to $q$, i.e., $\mathrm{Quot.mk}_r(a) = q$.
Quot.indep definition
(f : (a : α) → motive (Quot.mk r a)) (a : α) : PSigma motive
Full source
/-- Auxiliary definition for `Quot.rec`. -/
@[reducible, macro_inline]
protected def indep (f : (a : α) → motive (Quot.mk r a)) (a : α) : PSigma motive :=
  ⟨Quot.mk r a, f a⟩
Dependent pair construction for quotient induction
Informal description
Given a type $\alpha$ with a relation $r$ on $\alpha$, a family of types $\text{motive}$ indexed by the quotient $\text{Quot } r$, and a function $f$ that assigns to each $a : \alpha$ an element of $\text{motive}$ applied to the equivalence class of $a$, the function $\text{Quot.indep}$ constructs a dependent pair consisting of the equivalence class of $a$ and the value $f a$. In other words, for each $a : \alpha$, $\text{Quot.indep } f a$ is the pair $(\text{Quot.mk } r a, f a)$.
Quot.indepCoherent theorem
(f : (a : α) → motive (Quot.mk r a)) (h : (a b : α) → (p : r a b) → Eq.ndrec (f a) (sound p) = f b) : (a b : α) → r a b → Quot.indep f a = Quot.indep f b
Full source
protected theorem indepCoherent
    (f : (a : α) → motive (Quot.mk r a))
    (h : (a b : α) → (p : r a b) → Eq.ndrec (f a) (sound p) = f b)
    : (a b : α) → r a b → Quot.indep f a = Quot.indep f b  :=
  fun a b e => PSigma.eta (sound e) (h a b e)
Coherence of Dependent Pairs under Quotient Relation
Informal description
Given a type $\alpha$ with a relation $r$ on $\alpha$, a family of types $\text{motive}$ indexed by the quotient $\text{Quot } r$, and a function $f : (a : \alpha) \to \text{motive}(\text{Quot.mk } r a)$ such that for any $a, b \in \alpha$ related by $r$, the value $f a$ transported along the equality $\text{Quot.mk } r a = \text{Quot.mk } r b$ equals $f b$, then for any $a, b \in \alpha$ related by $r$, the dependent pairs $\text{Quot.indep } f a$ and $\text{Quot.indep } f b$ are equal.
Quot.liftIndepPr1 theorem
(f : (a : α) → motive (Quot.mk r a)) (h : ∀ (a b : α) (p : r a b), Eq.ndrec (f a) (sound p) = f b) (q : Quot r) : (lift (Quot.indep f) (Quot.indepCoherent f h) q).1 = q
Full source
protected theorem liftIndepPr1
    (f : (a : α) → motive (Quot.mk r a))
    (h : ∀ (a b : α) (p : r a b), Eq.ndrec (f a) (sound p) = f b)
    (q : Quot r)
    : (lift (Quot.indep f) (Quot.indepCoherent f h) q).1 = q := by
 induction q using Quot.ind
 exact rfl
First Projection of Lifted Dependent Pair Equals Original Quotient Element
Informal description
Given a type $\alpha$ with a relation $r$ on $\alpha$, a family of types $\text{motive}$ indexed by the quotient $\text{Quot } r$, and a function $f : (a : \alpha) \to \text{motive}(\text{Quot.mk } r a)$ such that for any $a, b \in \alpha$ related by $r$, the value $f a$ transported along the equality $\text{Quot.mk } r a = \text{Quot.mk } r b$ equals $f b$, then for any element $q$ of the quotient $\text{Quot } r$, the first projection of the lifted dependent pair $\text{lift}(\text{Quot.indep } f, \text{Quot.indepCoherent } f h) q$ equals $q$. In other words, the function $\text{lift}$ applied to the dependent pair construction $\text{Quot.indep } f$ and its coherence proof $\text{Quot.indepCoherent } f h$ yields a pair whose first component is the original quotient element $q$.
Quot.rec abbrev
(f : (a : α) → motive (Quot.mk r a)) (h : (a b : α) → (p : r a b) → Eq.ndrec (f a) (sound p) = f b) (q : Quot r) : motive q
Full source
/--
A dependent recursion principle for `Quot`. It is analogous to the
[recursor](lean-manual://section/recursors) for a structure, and can be used when the resulting type
is not necessarily a proposition.

While it is very general, this recursor can be tricky to use. The following simpler alternatives may
be easier to use:
 * `Quot.lift` is useful for defining non-dependent functions.
 * `Quot.ind` is useful for proving theorems about quotients.
 * `Quot.recOnSubsingleton` can be used whenever the target type is a `Subsingleton`.
 * `Quot.hrecOn` uses [heterogeneous equality](lean-manual://section/HEq) instead of rewriting with
   `Quot.sound`.

`Quot.recOn` is a version of this recursor that takes the quotient parameter first.
-/
@[elab_as_elim] protected abbrev rec
    (f : (a : α) → motive (Quot.mk r a))
    (h : (a b : α) → (p : r a b) → Eq.ndrec (f a) (sound p) = f b)
    (q : Quot r) : motive q :=
  Eq.ndrecOn (Quot.liftIndepPr1 f h q) ((lift (Quot.indep f) (Quot.indepCoherent f h) q).2)
Dependent Recursion Principle for Quotients
Informal description
Given a type $\alpha$ with a relation $r$ on $\alpha$, a family of types $\text{motive}$ indexed by the quotient $\text{Quot } r$, and a function $f : (a : \alpha) \to \text{motive}(\text{Quot.mk } r a)$ such that for any $a, b \in \alpha$ related by $r$, the value $f a$ transported along the equality $\text{Quot.mk } r a = \text{Quot.mk } r b$ equals $f b$, then for any element $q$ of the quotient $\text{Quot } r$, we can construct an element of type $\text{motive } q$.
Quot.recOn abbrev
(q : Quot r) (f : (a : α) → motive (Quot.mk r a)) (h : (a b : α) → (p : r a b) → Eq.ndrec (f a) (sound p) = f b) : motive q
Full source
/--
A dependent recursion principle for `Quot` that takes the quotient first. It is analogous to the
[recursor](lean-manual://section/recursors) for a structure, and can be used when the resulting type
is not necessarily a proposition.

While it is very general, this recursor can be tricky to use. The following simpler alternatives may
be easier to use:
 * `Quot.lift` is useful for defining non-dependent functions.
 * `Quot.ind` is useful for proving theorems about quotients.
 * `Quot.recOnSubsingleton` can be used whenever the target type is a `Subsingleton`.
 * `Quot.hrecOn` uses [heterogeneous equality](lean-manual://section/HEq) instead of rewriting with
   `Quot.sound`.

`Quot.rec` is a version of this recursor that takes the quotient parameter last.
-/
@[elab_as_elim] protected abbrev recOn
    (q : Quot r)
    (f : (a : α) → motive (Quot.mk r a))
    (h : (a b : α) → (p : r a b) → Eq.ndrec (f a) (sound p) = f b)
    : motive q :=
 q.rec f h
Dependent Recursion Principle for Quotients (Element-First Variant)
Informal description
Given a type $\alpha$ with a relation $r$ on $\alpha$, a family of types $\text{motive}$ indexed by the quotient $\text{Quot } r$, and an element $q$ of $\text{Quot } r$, if there exists a function $f : (a : \alpha) \to \text{motive}(\text{Quot.mk } r a)$ such that for any $a, b \in \alpha$ related by $r$, the value $f a$ transported along the equality $\text{Quot.mk } r a = \text{Quot.mk } r b$ equals $f b$, then we can construct an element of type $\text{motive } q$.
Quot.recOnSubsingleton abbrev
[h : (a : α) → Subsingleton (motive (Quot.mk r a))] (q : Quot r) (f : (a : α) → motive (Quot.mk r a)) : motive q
Full source
/--
An alternative induction principle for quotients that can be used when the target type is a
subsingleton, in which all elements are equal.

In these cases, the proof that the function respects the quotient's relation is trivial, so any
function can be lifted.

`Quot.rec` does not assume that the type is a subsingleton.
-/
@[elab_as_elim] protected abbrev recOnSubsingleton
    [h : (a : α) → Subsingleton (motive (Quot.mk r a))]
    (q : Quot r)
    (f : (a : α) → motive (Quot.mk r a))
    : motive q := by
  induction q using Quot.rec
  apply f
  apply Subsingleton.elim
Subsingleton Recursion Principle for Quotients
Informal description
Given a type $\alpha$ with a relation $r$, a family of types $\text{motive}$ indexed by the quotient $\text{Quot } r$, and a function $f : \alpha \to \text{motive}(\text{Quot.mk } r a)$, if for every $a \in \alpha$ the type $\text{motive}(\text{Quot.mk } r a)$ is a subsingleton (has at most one element), then for any element $q$ of the quotient $\text{Quot } r$, we can construct an element of type $\text{motive } q$ using $f$.
Quot.hrecOn abbrev
(q : Quot r) (f : (a : α) → motive (Quot.mk r a)) (c : (a b : α) → (p : r a b) → HEq (f a) (f b)) : motive q
Full source
/--
A dependent recursion principle for `Quot` that uses [heterogeneous
equality](lean-manual://section/HEq), analogous to a [recursor](lean-manual://section/recursors) for
a structure.

`Quot.recOn` is a version of this recursor that uses `Eq` instead of `HEq`.
-/
protected abbrev hrecOn
    (q : Quot r)
    (f : (a : α) → motive (Quot.mk r a))
    (c : (a b : α) → (p : r a b) → HEq (f a) (f b))
    : motive q :=
  Quot.recOn q f fun a b p => eq_of_heq <|
    have p₁ : HEq (Eq.ndrec (f a) (sound p)) (f a) := eqRec_heq (sound p) (f a)
    HEq.trans p₁ (c a b p)
Heterogeneous Recursion Principle for Quotients
Informal description
Given a type $\alpha$ with a relation $r$, a family of types $\text{motive}$ indexed by the quotient $\text{Quot } r$, and an element $q$ of $\text{Quot } r$, if there exists a function $f : (a : \alpha) \to \text{motive}(\text{Quot.mk } r a)$ such that for any $a, b \in \alpha$ related by $r$, the values $f a$ and $f b$ are heterogeneously equal (i.e., $\text{HEq} (f a) (f b)$), then we can construct an element of type $\text{motive } q$.
Quotient definition
{α : Sort u} (s : Setoid α)
Full source
/--
Quotient types coarsen the propositional equality for a type so that terms related by some
equivalence relation are considered equal. The equivalence relation is given by an instance of
`Setoid`.

Set-theoretically, `Quotient s` can seen as the set of equivalence classes of `α` modulo the
`Setoid` instance's relation `s.r`. Functions from `Quotient s` must prove that they respect `s.r`:
to define a function `f : Quotient s → β`, it is necessary to provide `f' : α → β` and prove that
for all `x : α` and `y : α`, `s.r x y → f' x = f' y`. `Quotient.lift` implements this operation.

The key quotient operators are:
 * `Quotient.mk` places elements of the underlying type `α` into the quotient.
 * `Quotient.lift` allows the definition of functions from the quotient to some other type.
 * `Quotient.sound` asserts the equality of elements related by `r`
 * `Quotient.ind` is used to write proofs about quotients by assuming that all elements are
   constructed with `Quotient.mk`.

`Quotient` is built on top of the primitive quotient type `Quot`, which does not require a proof
that the relation is an equivalence relation. `Quotient` should be used instead of `Quot` for
relations that actually are equivalence relations.
-/
def Quotient {α : Sort u} (s : Setoid α) :=
  @Quot α Setoid.r
Quotient Type by Equivalence Relation
Informal description
Given a type $\alpha$ equipped with an equivalence relation $\approx$ (represented by a `Setoid` instance $s$), the quotient type $\text{Quotient}\, s$ is the type of equivalence classes of $\alpha$ modulo $\approx$. The quotient construction provides: - $\text{Quotient.mk}$ which maps elements of $\alpha$ to their equivalence classes - $\text{Quotient.lift}$ for defining functions from the quotient to another type while respecting the equivalence relation - $\text{Quotient.sound}$ which proves that related elements become equal in the quotient - $\text{Quotient.ind}$ for proving properties about the quotient by considering only representative elements This should be used instead of the primitive `Quot` when working with proper equivalence relations.
Quotient.mk definition
{α : Sort u} (s : Setoid α) (a : α) : Quotient s
Full source
/--
Places an element of a type into the quotient that equates terms according to an equivalence
relation.

The setoid instance is provided explicitly. `Quotient.mk'` uses instance synthesis instead.

Given `v : α`, `Quotient.mk s v : Quotient s` is like `v`, except all observations of `v`'s value
must respect `s.r`. `Quotient.lift` allows values in a quotient to be mapped to other types, so long
as the mapping respects `s.r`.
-/
@[inline]
protected def mk {α : Sort u} (s : Setoid α) (a : α) : Quotient s :=
  Quot.mk Setoid.r a
Quotient map (explicit setoid version)
Informal description
Given a type $\alpha$ with an equivalence relation $\approx$ (represented by a setoid $s$), the function $\text{Quotient.mk}\, s$ maps an element $a : \alpha$ to its equivalence class in the quotient type $\text{Quotient}\, s$, where elements related by $\approx$ are identified.
Quotient.mk' definition
{α : Sort u} [s : Setoid α] (a : α) : Quotient s
Full source
/--
Places an element of a type into the quotient that equates terms according to an equivalence
relation.

The equivalence relation is found by synthesizing a `Setoid` instance. `Quotient.mk` instead expects
the instance to be provided explicitly.

Given `v : α`, `Quotient.mk' v : Quotient s` is like `v`, except all observations of `v`'s value
must respect `s.r`. `Quotient.lift` allows values in a quotient to be mapped to other types, so long
as the mapping respects `s.r`.

-/
protected def mk' {α : Sort u} [s : Setoid α] (a : α) : Quotient s :=
  Quotient.mk s a
Quotient map (implicit setoid version)
Informal description
Given a type $\alpha$ with an equivalence relation $\approx$ (represented by an implicit setoid instance $s$), the function $\text{Quotient.mk'}$ maps an element $a : \alpha$ to its equivalence class in the quotient type $\text{Quotient}\, s$, where elements related by $\approx$ are identified. This is the implicit setoid version of $\text{Quotient.mk}$.
Quotient.sound theorem
{α : Sort u} {s : Setoid α} {a b : α} : a ≈ b → Quotient.mk s a = Quotient.mk s b
Full source
/--
The **quotient axiom**, which asserts the equality of elements related in the setoid.

Because `Quotient` is built on a lower-level type `Quot`, `Quotient.sound` is implemented as a
theorem. It is derived from `Quot.sound`, the soundness axiom for the lower-level quotient type
`Quot`.
-/
theorem sound {α : Sort u} {s : Setoid α} {a b : α} : a ≈ bQuotient.mk s a = Quotient.mk s b :=
  Quot.sound
Quotient Soundness: Related Elements Map to Equal Equivalence Classes
Informal description
For any type $\alpha$ equipped with an equivalence relation $\approx$ (represented by a setoid $s$), and for any two elements $a, b \in \alpha$ that are related by $\approx$, their images under the quotient map $\operatorname{Quotient.mk}_s$ are equal, i.e., $\operatorname{Quotient.mk}_s(a) = \operatorname{Quotient.mk}_s(b)$.
Quotient.lift abbrev
{α : Sort u} {β : Sort v} {s : Setoid α} (f : α → β) : ((a b : α) → a ≈ b → f a = f b) → Quotient s → β
Full source
/--
Lifts a function from an underlying type to a function on a quotient, requiring that it respects the
quotient's equivalence relation.

Given `s : Setoid α` and a quotient `Quotient s`, applying a function `f : α → β` requires a proof
`h` that `f` respects the equivalence relation `s.r`. In this case, the function
`Quotient.lift f h : Quotient s → β` computes the same values as `f`.

`Quotient.liftOn` is a version of this operation that takes the quotient value as its first explicit
parameter.
-/
protected abbrev lift {α : Sort u} {β : Sort v} {s : Setoid α} (f : α → β) : ((a b : α) → a ≈ b → f a = f b) → Quotient s → β :=
  Quot.lift f
Lifting a Function to a Quotient via Respect for the Equivalence Relation
Informal description
Given a type $\alpha$ with an equivalence relation $\approx$ (represented by a setoid $s$), a function $f : \alpha \to \beta$, and a proof that $f$ respects $\approx$ (i.e., for any $a, b \in \alpha$, if $a \approx b$ then $f(a) = f(b)$), the operation $\mathrm{lift}$ defines a function from the quotient $\alpha / \approx$ to $\beta$ by applying $f$ to representatives of equivalence classes.
Quotient.ind theorem
{α : Sort u} {s : Setoid α} {motive : Quotient s → Prop} : ((a : α) → motive (Quotient.mk s a)) → (q : Quotient s) → motive q
Full source
/--
A reasoning principle for quotients that allows proofs about quotients to assume that all values are
constructed with `Quotient.mk`.
-/
protected theorem ind {α : Sort u} {s : Setoid α} {motive : Quotient s → Prop} : ((a : α) → motive (Quotient.mk s a)) → (q : Quotient s) → motive q :=
  Quot.ind
Induction Principle for Quotient Types
Informal description
Let $\alpha$ be a type with an equivalence relation $\approx$ (represented by a setoid $s$), and let $P$ be a predicate on the quotient type $\text{Quotient}\, s$. If $P$ holds for all equivalence classes $\text{Quotient.mk}\, s\, a$ where $a \in \alpha$, then $P$ holds for every element of the quotient $\text{Quotient}\, s$. In other words, to prove a property $P$ about all elements of the quotient $\alpha / \approx$, it suffices to prove $P$ for all equivalence classes represented by elements of $\alpha$.
Quotient.liftOn abbrev
{α : Sort u} {β : Sort v} {s : Setoid α} (q : Quotient s) (f : α → β) (c : (a b : α) → a ≈ b → f a = f b) : β
Full source
/--
Lifts a function from an underlying type to a function on a quotient, requiring that it respects the
quotient's equivalence relation.

Given `s : Setoid α` and a quotient value `q : Quotient s`, applying a function `f : α → β` requires
a proof `c` that `f` respects the equivalence relation `s.r`. In this case, the term
`Quotient.liftOn q f h : β` reduces to the result of applying `f` to the underlying `α` value.

`Quotient.lift` is a version of this operation that takes the quotient value last, rather than
first.
-/
protected abbrev liftOn {α : Sort u} {β : Sort v} {s : Setoid α} (q : Quotient s) (f : α → β) (c : (a b : α) → a ≈ b → f a = f b) : β :=
  Quot.liftOn q f c
Lifting a Function to a Quotient via Respect for the Equivalence Relation
Informal description
Given a type $\alpha$ with an equivalence relation $\approx$ (represented by a setoid $s$), a quotient value $q$ of $\alpha$ by $\approx$, a function $f : \alpha \to \beta$, and a proof $c$ that $f$ respects $\approx$ (i.e., for any $a, b \in \alpha$, if $a \approx b$ then $f(a) = f(b)$), the operation $\mathrm{liftOn}$ applies $f$ to a representative of $q$ to produce an element of $\beta$.
Quotient.inductionOn theorem
{α : Sort u} {s : Setoid α} {motive : Quotient s → Prop} (q : Quotient s) (h : (a : α) → motive (Quotient.mk s a)) : motive q
Full source
/-- The analogue of `Quot.inductionOn`: every element of `Quotient s` is of the form `Quotient.mk s a`. -/
@[elab_as_elim]
protected theorem inductionOn {α : Sort u} {s : Setoid α} {motive : Quotient s → Prop}
    (q : Quotient s)
    (h : (a : α) → motive (Quotient.mk s a))
    : motive q :=
  Quot.inductionOn q h
Induction Principle for Quotient Types via Representatives
Informal description
Let $\alpha$ be a type equipped with an equivalence relation $\approx$ (represented by a setoid $s$), and let $P$ be a property on the quotient type $\text{Quotient}\, s$. For any element $q$ of $\text{Quotient}\, s$, if $P$ holds for every equivalence class $\text{Quotient.mk}\, s\, a$ where $a \in \alpha$, then $P$ holds for $q$.
Quotient.exists_rep theorem
{α : Sort u} {s : Setoid α} (q : Quotient s) : Exists (fun (a : α) => Quotient.mk s a = q)
Full source
theorem exists_rep {α : Sort u} {s : Setoid α} (q : Quotient s) : Exists (fun (a : α) => Quotient.mk s a = q) :=
  Quot.exists_rep q
Existence of Representatives in Quotient Types
Informal description
For any type $\alpha$ with an equivalence relation $\approx$ (represented by a setoid $s$) and any element $q$ of the quotient type $\mathrm{Quotient}\,s$, there exists an element $a \in \alpha$ such that the equivalence class of $a$ is equal to $q$, i.e., $\mathrm{Quotient.mk}_s(a) = q$.
Quotient.rec definition
(f : (a : α) → motive (Quotient.mk s a)) (h : (a b : α) → (p : a ≈ b) → Eq.ndrec (f a) (Quotient.sound p) = f b) (q : Quotient s) : motive q
Full source
/--
A dependent recursion principle for `Quotient`. It is analogous to the
[recursor](lean-manual://section/recursors) for a structure, and can be used when the resulting type
is not necessarily a proposition.

While it is very general, this recursor can be tricky to use. The following simpler alternatives may
be easier to use:

 * `Quotient.lift` is useful for defining non-dependent functions.
 * `Quotient.ind` is useful for proving theorems about quotients.
 * `Quotient.recOnSubsingleton` can be used whenever the target type is a `Subsingleton`.
 * `Quotient.hrecOn` uses heterogeneous equality instead of rewriting with `Quotient.sound`.

`Quotient.recOn` is a version of this recursor that takes the quotient parameter first.
-/
@[inline, elab_as_elim]
protected def rec
    (f : (a : α) → motive (Quotient.mk s a))
    (h : (a b : α) → (p : a ≈ b) → Eq.ndrec (f a) (Quotient.sound p) = f b)
    (q : Quotient s)
    : motive q :=
  Quot.rec f h q
Dependent Recursion Principle for Quotient Types
Informal description
Given a type $\alpha$ with an equivalence relation $\approx$ (represented by a setoid $s$), a family of types $\text{motive}$ indexed by the quotient $\text{Quotient}\, s$, and a function $f : (a : \alpha) \to \text{motive}(\text{Quotient.mk}\, s\, a)$ such that for any $a, b \in \alpha$ related by $\approx$, the value $f a$ transported along the equality $\text{Quotient.mk}\, s\, a = \text{Quotient.mk}\, s\, b$ equals $f b$, then for any element $q$ of the quotient $\text{Quotient}\, s$, we can construct an element of type $\text{motive}\, q$.
Quotient.recOn abbrev
(q : Quotient s) (f : (a : α) → motive (Quotient.mk s a)) (h : (a b : α) → (p : a ≈ b) → Eq.ndrec (f a) (Quotient.sound p) = f b) : motive q
Full source
/--
A dependent recursion principle for `Quotient`. It is analogous to the
[recursor](lean-manual://section/recursors) for a structure, and can be used when the resulting type
is not necessarily a proposition.

While it is very general, this recursor can be tricky to use. The following simpler alternatives may
be easier to use:

 * `Quotient.lift` is useful for defining non-dependent functions.
 * `Quotient.ind` is useful for proving theorems about quotients.
 * `Quotient.recOnSubsingleton` can be used whenever the target type is a `Subsingleton`.
 * `Quotient.hrecOn` uses heterogeneous equality instead of rewriting with `Quotient.sound`.

`Quotient.rec` is a version of this recursor that takes the quotient parameter last.
-/
@[elab_as_elim]
protected abbrev recOn
    (q : Quotient s)
    (f : (a : α) → motive (Quotient.mk s a))
    (h : (a b : α) → (p : a ≈ b) → Eq.ndrec (f a) (Quotient.sound p) = f b)
    : motive q :=
  Quot.recOn q f h
Dependent Recursion Principle for Quotient Types (Element-First Variant)
Informal description
Given a type $\alpha$ with an equivalence relation $\approx$ (represented by a setoid $s$), a family of types $\text{motive}$ indexed by the quotient $\text{Quotient}\, s$, and an element $q$ of $\text{Quotient}\, s$, if there exists a function $f : (a : \alpha) \to \text{motive}(\text{Quotient.mk}\, s\, a)$ such that for any $a, b \in \alpha$ related by $\approx$, the value $f a$ transported along the equality $\text{Quotient.mk}\, s\, a = \text{Quotient.mk}\, s\, b$ equals $f b$, then we can construct an element of type $\text{motive}\, q$.
Quotient.recOnSubsingleton abbrev
[h : (a : α) → Subsingleton (motive (Quotient.mk s a))] (q : Quotient s) (f : (a : α) → motive (Quotient.mk s a)) : motive q
Full source
/--
An alternative recursion or induction principle for quotients that can be used when the target type
is a subsingleton, in which all elements are equal.

In these cases, the proof that the function respects the quotient's equivalence relation is trivial,
so any function can be lifted.

`Quotient.rec` does not assume that the target type is a subsingleton.
-/
@[elab_as_elim]
protected abbrev recOnSubsingleton
    [h : (a : α) → Subsingleton (motive (Quotient.mk s a))]
    (q : Quotient s)
    (f : (a : α) → motive (Quotient.mk s a))
    : motive q :=
  Quot.recOnSubsingleton (h := h) q f
Subsingleton Recursion Principle for Quotient Types
Informal description
Given a type $\alpha$ with an equivalence relation $\approx$ (represented by a setoid $s$), a family of types $\text{motive}$ indexed by the quotient $\alpha/\!\approx$, and an element $q \in \alpha/\!\approx$, if for every $a \in \alpha$ the type $\text{motive}([a])$ is a subsingleton (has at most one element), then any function $f : (a : \alpha) \to \text{motive}([a])$ induces an element of $\text{motive}(q)$.
Quotient.hrecOn abbrev
(q : Quotient s) (f : (a : α) → motive (Quotient.mk s a)) (c : (a b : α) → (p : a ≈ b) → HEq (f a) (f b)) : motive q
Full source
/--
A dependent recursion principle for `Quotient` that uses [heterogeneous
equality](lean-manual://section/HEq), analogous to a [recursor](lean-manual://section/recursors) for
a structure.

`Quotient.recOn` is a version of this recursor that uses `Eq` instead of `HEq`.
-/
@[elab_as_elim]
protected abbrev hrecOn
    (q : Quotient s)
    (f : (a : α) → motive (Quotient.mk s a))
    (c : (a b : α) → (p : a ≈ b) → HEq (f a) (f b))
    : motive q :=
  Quot.hrecOn q f c
Heterogeneous Recursion Principle for Quotient Types
Informal description
Given a type $\alpha$ with an equivalence relation $\approx$ (represented by a setoid $s$), a family of types $\text{motive}$ indexed by the quotient $\alpha/\!\approx$, and an element $q \in \alpha/\!\approx$, if there exists a function $f : (a : \alpha) \to \text{motive}([a])$ such that for any $a, b \in \alpha$ related by $\approx$, the values $f(a)$ and $f(b)$ are heterogeneously equal (i.e., $\text{HEq}(f(a), f(b))$), then we can construct an element of type $\text{motive}(q)$.
Quotient.lift₂ abbrev
(f : α → β → φ) (c : (a₁ : α) → (b₁ : β) → (a₂ : α) → (b₂ : β) → a₁ ≈ a₂ → b₁ ≈ b₂ → f a₁ b₁ = f a₂ b₂) (q₁ : Quotient s₁) (q₂ : Quotient s₂) : φ
Full source
/--
Lifts a binary function from the underlying types to a binary function on quotients. The function
must respect both quotients' equivalence relations.

`Quotient.lift` is a version of this operation for unary functions. `Quotient.liftOn₂` is a version
that take the quotient parameters first.
-/
protected abbrev lift₂
    (f : α → β → φ)
    (c : (a₁ : α) → (b₁ : β) → (a₂ : α) → (b₂ : β) → a₁ ≈ a₂b₁ ≈ b₂ → f a₁ b₁ = f a₂ b₂)
    (q₁ : Quotient s₁) (q₂ : Quotient s₂)
    : φ := by
  apply Quotient.lift (fun (a₁ : α) => Quotient.lift (f a₁) (fun (a b : β) => c a₁ a a₁ b (Setoid.refl a₁)) q₂) _ q₁
  intros
  induction q₂ using Quotient.ind
  apply c; assumption; apply Setoid.refl
Lifting a Binary Function to Quotients Respecting Equivalence Relations
Informal description
Given types $\alpha$, $\beta$, and $\varphi$ with equivalence relations $\approx_1$ on $\alpha$ and $\approx_2$ on $\beta$, a binary function $f : \alpha \to \beta \to \varphi$ that respects both equivalence relations (i.e., for any $a_1, a_2 \in \alpha$ and $b_1, b_2 \in \beta$, if $a_1 \approx_1 a_2$ and $b_1 \approx_2 b_2$, then $f(a_1, b_1) = f(a_2, b_2)$), and two elements $q_1$ and $q_2$ in the quotient types $\alpha/\!\approx_1$ and $\beta/\!\approx_2$ respectively, then $\mathrm{lift}_2$ defines a function that lifts $f$ to operate on the quotient elements $q_1$ and $q_2$ to produce an element of $\varphi$.
Quotient.liftOn₂ abbrev
(q₁ : Quotient s₁) (q₂ : Quotient s₂) (f : α → β → φ) (c : (a₁ : α) → (b₁ : β) → (a₂ : α) → (b₂ : β) → a₁ ≈ a₂ → b₁ ≈ b₂ → f a₁ b₁ = f a₂ b₂) : φ
Full source
/--
Lifts a binary function from the underlying types to a binary function on quotients. The function
must respect both quotients' equivalence relations.

`Quotient.liftOn` is a version of this operation for unary functions. `Quotient.lift₂` is a version
that take the quotient parameters last.
-/
protected abbrev liftOn₂
    (q₁ : Quotient s₁)
    (q₂ : Quotient s₂)
    (f : α → β → φ)
    (c : (a₁ : α) → (b₁ : β) → (a₂ : α) → (b₂ : β) → a₁ ≈ a₂b₁ ≈ b₂ → f a₁ b₁ = f a₂ b₂)
    : φ :=
  Quotient.lift₂ f c q₁ q₂
Lifting Binary Functions to Quotients Respecting Equivalence Relations
Informal description
Given two quotient types $\alpha/\!\approx_1$ and $\beta/\!\approx_2$ with equivalence relations $\approx_1$ on $\alpha$ and $\approx_2$ on $\beta$, a binary function $f : \alpha \to \beta \to \varphi$, and a proof that $f$ respects both equivalence relations (i.e., for any $a_1, a_2 \in \alpha$ and $b_1, b_2 \in \beta$, if $a_1 \approx_1 a_2$ and $b_1 \approx_2 b_2$, then $f(a_1, b_1) = f(a_2, b_2)$), then $\mathrm{liftOn}_2$ defines a function that lifts $f$ to operate on the quotient elements $q_1 \in \alpha/\!\approx_1$ and $q_2 \in \beta/\!\approx_2$ to produce an element of $\varphi$.
Quotient.ind₂ theorem
{motive : Quotient s₁ → Quotient s₂ → Prop} (h : (a : α) → (b : β) → motive (Quotient.mk s₁ a) (Quotient.mk s₂ b)) (q₁ : Quotient s₁) (q₂ : Quotient s₂) : motive q₁ q₂
Full source
@[elab_as_elim]
protected theorem ind₂
    {motive : Quotient s₁ → Quotient s₂ → Prop}
    (h : (a : α) → (b : β) → motive (Quotient.mk s₁ a) (Quotient.mk s₂ b))
    (q₁ : Quotient s₁)
    (q₂ : Quotient s₂)
    : motive q₁ q₂ := by
  induction q₁ using Quotient.ind
  induction q₂ using Quotient.ind
  apply h
Double Induction Principle for Quotient Types
Informal description
Let $\alpha$ and $\beta$ be types with equivalence relations $\approx_1$ and $\approx_2$ (represented by setoids $s_1$ and $s_2$ respectively), and let $P$ be a predicate on pairs of elements from the quotient types $\text{Quotient}\, s_1$ and $\text{Quotient}\, s_2$. If $P$ holds for all pairs of equivalence classes $(\text{Quotient.mk}\, s_1\, a, \text{Quotient.mk}\, s_2\, b)$ where $a \in \alpha$ and $b \in \beta$, then $P$ holds for every pair $(q_1, q_2)$ with $q_1 \in \text{Quotient}\, s_1$ and $q_2 \in \text{Quotient}\, s_2$. In other words, to prove a property $P$ about all pairs of elements from two quotient types $\alpha/\!\approx_1$ and $\beta/\!\approx_2$, it suffices to prove $P$ for all pairs represented by elements of $\alpha$ and $\beta$.
Quotient.inductionOn₂ theorem
{motive : Quotient s₁ → Quotient s₂ → Prop} (q₁ : Quotient s₁) (q₂ : Quotient s₂) (h : (a : α) → (b : β) → motive (Quotient.mk s₁ a) (Quotient.mk s₂ b)) : motive q₁ q₂
Full source
@[elab_as_elim]
protected theorem inductionOn₂
    {motive : Quotient s₁ → Quotient s₂ → Prop}
    (q₁ : Quotient s₁)
    (q₂ : Quotient s₂)
    (h : (a : α) → (b : β) → motive (Quotient.mk s₁ a) (Quotient.mk s₂ b))
    : motive q₁ q₂ := by
  induction q₁ using Quotient.ind
  induction q₂ using Quotient.ind
  apply h
Double Induction Principle for Quotient Types
Informal description
Let $s₁$ and $s₂$ be equivalence relations on types $\alpha$ and $\beta$ respectively, and let $P$ be a predicate on $\text{Quotient}\, s₁ \times \text{Quotient}\, s₂$. Given two elements $q₁ \in \text{Quotient}\, s₁$ and $q₂ \in \text{Quotient}\, s₂$, if $P$ holds for all pairs $(\text{Quotient.mk}\, s₁\, a, \text{Quotient.mk}\, s₂\, b)$ where $a \in \alpha$ and $b \in \beta$, then $P$ holds for $(q₁, q₂)$.
Quotient.inductionOn₃ theorem
{s₃ : Setoid φ} {motive : Quotient s₁ → Quotient s₂ → Quotient s₃ → Prop} (q₁ : Quotient s₁) (q₂ : Quotient s₂) (q₃ : Quotient s₃) (h : (a : α) → (b : β) → (c : φ) → motive (Quotient.mk s₁ a) (Quotient.mk s₂ b) (Quotient.mk s₃ c)) : motive q₁ q₂ q₃
Full source
@[elab_as_elim]
protected theorem inductionOn₃
    {s₃ : Setoid φ}
    {motive : Quotient s₁ → Quotient s₂ → Quotient s₃ → Prop}
    (q₁ : Quotient s₁)
    (q₂ : Quotient s₂)
    (q₃ : Quotient s₃)
    (h : (a : α) → (b : β) → (c : φ) → motive (Quotient.mk s₁ a) (Quotient.mk s₂ b) (Quotient.mk s₃ c))
    : motive q₁ q₂ q₃ := by
  induction q₁ using Quotient.ind
  induction q₂ using Quotient.ind
  induction q₃ using Quotient.ind
  apply h
Triple Induction Principle for Quotient Types
Informal description
Let $\alpha$, $\beta$, and $\varphi$ be types equipped with equivalence relations (represented by setoids $s_1$, $s_2$, and $s_3$ respectively). Given a predicate $P$ on the product of quotient types $\text{Quotient}\, s_1 \times \text{Quotient}\, s_2 \times \text{Quotient}\, s_3$, if $P$ holds for all triples of equivalence classes represented by elements $(a, b, c) \in \alpha \times \beta \times \varphi$, then $P$ holds for every triple $(q_1, q_2, q_3)$ in the product of the quotient types. In other words, to prove a property $P$ about all triples in the product of three quotient types, it suffices to prove $P$ for all triples represented by elements of the original types.
Quotient.exact theorem
{s : Setoid α} {a b : α} : Quotient.mk s a = Quotient.mk s b → a ≈ b
Full source
/--
If two values are equal in a quotient, then they are related by its equivalence relation.
-/
theorem exact {s : Setoid α} {a b : α} : Quotient.mk s a = Quotient.mk s b → a ≈ b :=
  fun h => rel_of_eq h
Equality in Quotient Implies Equivalence Relation Holds
Informal description
Let $\alpha$ be a type equipped with an equivalence relation $\approx$ (represented by a setoid $s$). For any two elements $a, b \in \alpha$, if their equivalence classes in the quotient $\text{Quotient}\, s$ are equal (i.e., $\text{Quotient.mk}\, s\, a = \text{Quotient.mk}\, s\, b$), then $a$ and $b$ are related by $\approx$ (i.e., $a \approx b$).
Quotient.recOnSubsingleton₂ abbrev
{motive : Quotient s₁ → Quotient s₂ → Sort uC} [s : (a : α) → (b : β) → Subsingleton (motive (Quotient.mk s₁ a) (Quotient.mk s₂ b))] (q₁ : Quotient s₁) (q₂ : Quotient s₂) (g : (a : α) → (b : β) → motive (Quotient.mk s₁ a) (Quotient.mk s₂ b)) : motive q₁ q₂
Full source
/--
An alternative induction or recursion operator for defining binary operations on quotients that can
be used when the target type is a subsingleton.

In these cases, the proof that the function respects the quotient's equivalence relation is trivial,
so any function can be lifted.
-/
@[elab_as_elim]
protected abbrev recOnSubsingleton₂
    {motive : Quotient s₁ → Quotient s₂ → Sort uC}
    [s : (a : α) → (b : β) → Subsingleton (motive (Quotient.mk s₁ a) (Quotient.mk s₂ b))]
    (q₁ : Quotient s₁)
    (q₂ : Quotient s₂)
    (g : (a : α) → (b : β) → motive (Quotient.mk s₁ a) (Quotient.mk s₂ b))
    : motive q₁ q₂ := by
  induction q₁ using Quot.recOnSubsingleton
  induction q₂ using Quot.recOnSubsingleton
  apply g
  intro a; apply s
  induction q₂ using Quot.recOnSubsingleton
  intro a; apply s
  infer_instance
Subsingleton Recursion Principle for Binary Operations on Quotients
Informal description
Given two quotient types $\text{Quotient}\, s₁$ and $\text{Quotient}\, s₂$ with equivalence relations on types $\alpha$ and $\beta$ respectively, and a family of types $\text{motive}$ indexed by pairs of quotient elements, if for every $a \in \alpha$ and $b \in \beta$ the type $\text{motive}(\text{Quotient.mk}\, s₁\, a, \text{Quotient.mk}\, s₂\, b)$ is a subsingleton (has at most one element), then for any elements $q₁$ of $\text{Quotient}\, s₁$ and $q₂$ of $\text{Quotient}\, s₂$, and any function $g$ that constructs elements of $\text{motive}$ from representatives, we can construct an element of type $\text{motive}(q₁, q₂)$.
Quotient.decidableEq instance
{α : Sort u} {s : Setoid α} [d : ∀ (a b : α), Decidable (a ≈ b)] : DecidableEq (Quotient s)
Full source
instance Quotient.decidableEq {α : Sort u} {s : Setoid α} [d : ∀ (a b : α), Decidable (a ≈ b)]
    : DecidableEq (Quotient s) :=
  fun (q₁ q₂ : Quotient s) =>
    Quotient.recOnSubsingleton₂ q₁ q₂
      fun a₁ a₂ =>
        match d a₁ a₂ with
        | isTrue h₁  => isTrue (Quotient.sound h₁)
        | isFalse h₂ => isFalse fun h => absurd (Quotient.exact h) h₂
Decidability of Equality in Quotient Types with Decidable Equivalence Relations
Informal description
For any type $\alpha$ equipped with an equivalence relation $\approx$ (represented by a setoid $s$), if the relation $\approx$ is decidable (i.e., for any $a, b \in \alpha$, we can determine whether $a \approx b$ holds), then the equality relation on the quotient type $\text{Quotient}\, s$ is also decidable.
funext theorem
{α : Sort u} {β : α → Sort v} {f g : (x : α) → β x} (h : ∀ x, f x = g x) : f = g
Full source
/--
**Function extensionality.** If two functions return equal results for all possible arguments, then
they are equal.

It is called “extensionality” because it provides a way to prove two objects equal based on the
properties of the underlying mathematical functions, rather than based on the syntax used to denote
them. Function extensionality is a theorem that can be [proved using quotient
types](lean-manual://section/quotient-funext).
-/
theorem funext {α : Sort u} {β : α → Sort v} {f g : (x : α) → β x}
    (h : ∀ x, f x = g x) : f = g := by
  let eqv (f g : (x : α) → β x) := ∀ x, f x = g x
  let extfunApp (f : Quot eqv) (x : α) : β x :=
    Quot.liftOn f
      (fun (f : ∀ (x : α), β x) => f x)
      (fun _ _ h => h x)
  show extfunApp (Quot.mk eqv f) = extfunApp (Quot.mk eqv g)
  exact congrArg extfunApp (Quot.sound h)
Function Extensionality: $(\forall x, f(x) = g(x)) \to f = g$
Informal description
For any types $\alpha$ and $\beta$, and any functions $f, g : \alpha \to \beta$, if $f(x) = g(x)$ for all $x \in \alpha$, then $f = g$.
Pi.instSubsingleton instance
{α : Sort u} {β : α → Sort v} [∀ a, Subsingleton (β a)] : Subsingleton (∀ a, β a)
Full source
instance Pi.instSubsingleton {α : Sort u} {β : α → Sort v} [∀ a, Subsingleton (β a)] :
    Subsingleton (∀ a, β a) where
  allEq f g := funext fun a => Subsingleton.elim (f a) (g a)
Dependent Function Type is Subsingleton When Codomains Are
Informal description
For any family of types $\beta$ indexed by $\alpha$, if each $\beta(a)$ is a subsingleton (i.e., has at most one element), then the type of dependent functions $\forall a, \beta(a)$ is also a subsingleton.
Squash definition
(α : Sort u)
Full source
/--
The quotient of `α` by the universal relation. The elements of `Squash α` are those of `α`, but all
of them are equal and cannot be distinguished.

`Squash α` is a `Subsingleton`: it is empty if `α` is empty, otherwise it has just one element. It
is the “universal `Subsingleton`” mapped from `α`.

`Nonempty α` also has these properties. It is a proposition, which means that its elements (i.e.
proofs) are erased from compiled code and represented by a dummy value. `Squash α` is a `Type u`,
and its representation in compiled code is identical to that of `α`.

Consequently, `Squash.lift` may extract an `α` value into any subsingleton type `β`, while
`Nonempty.rec` can only do the same when `β` is a proposition.
-/
def Squash (α : Sort u) := Quot (fun (_ _ : α) => True)
Universal subsingleton quotient
Informal description
The type `Squash α` is the quotient of `α` by the universal relation where all elements are considered equal. It represents a subsingleton type derived from `α`: if `α` is nonempty, `Squash α` has exactly one element; otherwise, it is empty. Unlike `Nonempty α`, which is a proposition, `Squash α` is a `Type u` with the same runtime representation as `α`, allowing extraction of an `α` value into any subsingleton type.
Squash.mk definition
{α : Sort u} (x : α) : Squash α
Full source
/--
Places a value into its squash type, in which it cannot be distinguished from any other.
-/
def Squash.mk {α : Sort u} (x : α) : Squash α := Quot.mk _ x
Inclusion into squash type
Informal description
The function takes an element $x$ of type $\alpha$ and returns its image in the squash type $\text{Squash } \alpha$, where all elements of $\alpha$ are considered equal.
Squash.ind theorem
{α : Sort u} {motive : Squash α → Prop} (h : ∀ (a : α), motive (Squash.mk a)) : ∀ (q : Squash α), motive q
Full source
/--
A reasoning principle that allows proofs about squashed types to assume that all values are
constructed with `Squash.mk`.
-/
theorem Squash.ind {α : Sort u} {motive : Squash α → Prop} (h : ∀ (a : α), motive (Squash.mk a)) : ∀ (q : Squash α), motive q :=
  Quot.ind h
Induction Principle for Squash Types
Informal description
For any type $\alpha$ and property $P$ on $\text{Squash } \alpha$, if $P$ holds for all elements of the form $\text{Squash.mk } a$ where $a : \alpha$, then $P$ holds for all elements of $\text{Squash } \alpha$.
Squash.lift definition
{α β} [Subsingleton β] (s : Squash α) (f : α → β) : β
Full source
/--
Extracts a squashed value into any subsingleton type.

If `β` is a subsingleton, a function `α → β` cannot distinguish between elements of `α` and thus
automatically respects the universal relation that `Squash` quotients with.
-/
@[inline] def Squash.lift {α β} [Subsingleton β] (s : Squash α) (f : α → β) : β :=
  Quot.lift f (fun _ _ _ => Subsingleton.elim _ _) s
Lifting from squash type to subsingleton
Informal description
Given a subsingleton type $\beta$ and a function $f : \alpha \to \beta$, the function `Squash.lift` maps an element of the squash type $\text{Squash } \alpha$ to an element of $\beta$ by applying $f$ to any representative of the equivalence class. Since $\beta$ is a subsingleton, the result is independent of the choice of representative.
instSubsingletonSquash instance
: Subsingleton (Squash α)
Full source
instance : Subsingleton (Squash α) where
  allEq a b := by
    induction a using Squash.ind
    induction b using Squash.ind
    apply Quot.sound
    trivial
Squash Types are Subsingletons
Informal description
The squash type $\text{Squash } \alpha$ is a subsingleton for any type $\alpha$.
Lean.trustCompiler axiom
: True
Full source
/--
Depends on the correctness of the Lean compiler, interpreter, and all `[implemented_by ...]` and `[extern ...]` annotations.
-/
axiom trustCompiler : True
Compiler Trust Axiom
Informal description
The proposition `True` holds by trusting the correctness of the Lean compiler and interpreter, including all `[implemented_by ...]` and `[extern ...]` annotations.
Lean.reduceBool opaque
(b : Bool) : Bool
Full source
/--
When the kernel tries to reduce a term `Lean.reduceBool c`, it will invoke the Lean interpreter to evaluate `c`.
The kernel will not use the interpreter if `c` is not a constant.
This feature is useful for performing proofs by reflection.

Remark: the Lean frontend allows terms of the from `Lean.reduceBool t` where `t` is a term not containing
free variables. The frontend automatically declares a fresh auxiliary constant `c` and replaces the term with
`Lean.reduceBool c`. The main motivation is that the code for `t` will be pre-compiled.

Warning: by using this feature, the Lean compiler and interpreter become part of your trusted code base.
This is extra 30k lines of code. More importantly, you will probably not be able to check your development using
external type checkers that do not implement this feature.
Keep in mind that if you are using Lean as programming language, you are already trusting the Lean compiler and interpreter.
So, you are mainly losing the capability of type checking your development using external checkers.

Recall that the compiler trusts the correctness of all `[implemented_by ...]` and `[extern ...]` annotations.
If an extern function is executed, then the trusted code base will also include the implementation of the associated
foreign function.
-/
opaque reduceBool (b : Bool) : Bool :=
  -- This ensures that `#print axioms` will track use of `reduceBool`.
  have := trustCompiler
  b
Boolean Compile-Time Reduction via Interpreter
Informal description
The function `Lean.reduceBool` evaluates a Boolean expression `b` at compile time by invoking the Lean interpreter, returning the resulting Boolean value. This is used for proofs by reflection, where the kernel reduces `Lean.reduceBool c` only when `c` is a constant.
Lean.reduceNat opaque
(n : Nat) : Nat
Full source
/--
Similar to `Lean.reduceBool` for closed `Nat` terms.

Remark: we do not have plans for supporting a generic `reduceValue {α} (a : α) : α := a`.
The main issue is that it is non-trivial to convert an arbitrary runtime object back into a Lean expression.
We believe `Lean.reduceBool` enables most interesting applications (e.g., proof by reflection).
-/
opaque reduceNat (n : Nat) : Nat :=
  -- This ensures that `#print axioms` will track use of `reduceNat`.
  have := trustCompiler
  n
Runtime reduction for closed natural number terms
Informal description
The function `Lean.reduceNat` takes a natural number `n` and returns a natural number, performing runtime reduction on closed terms of type `Nat`.
Lean.ofReduceBool axiom
(a b : Bool) (h : reduceBool a = b) : a = b
Full source
/--
The axiom `ofReduceBool` is used to perform proofs by reflection. See `reduceBool`.

This axiom is usually not used directly, because it has some syntactic restrictions.
Instead, the `native_decide` tactic can be used to prove any proposition whose
decidability instance can be evaluated to `true` using the lean compiler / interpreter.

Warning: by using this feature, the Lean compiler and interpreter become part of your trusted code base.
This is extra 30k lines of code. More importantly, you will probably not be able to check your development using
external type checkers that do not implement this feature.
Keep in mind that if you are using Lean as programming language, you are already trusting the Lean compiler and interpreter.
So, you are mainly losing the capability of type checking your development using external checkers.
-/
axiom ofReduceBool (a b : Bool) (h : reduceBool a = b) : a = b
Boolean Reflection Axiom: $\text{reduceBool}(a) = b \to a = b$
Informal description
For any Boolean values $a$ and $b$, if the compile-time reduction of $a$ equals $b$ (i.e., $\text{reduceBool}(a) = b$), then $a = b$.
Lean.ofReduceNat axiom
(a b : Nat) (h : reduceNat a = b) : a = b
Full source
/--
The axiom `ofReduceNat` is used to perform proofs by reflection. See `reduceBool`.

Warning: by using this feature, the Lean compiler and interpreter become part of your trusted code base.
This is extra 30k lines of code. More importantly, you will probably not be able to check your development using
external type checkers that do not implement this feature.
Keep in mind that if you are using Lean as programming language, you are already trusting the Lean compiler and interpreter.
So, you are mainly losing the capability of type checking your development using external checkers.
-/
axiom ofReduceNat (a b : Nat) (h : reduceNat a = b) : a = b
Natural Number Reflection Axiom: $\text{reduceNat}(a) = b \to a = b$
Informal description
For any natural numbers $a$ and $b$, if the compile-time reduction of $a$ equals $b$ (i.e., $\text{reduceNat}(a) = b$), then $a = b$.
Lean.opaqueId opaque
{α : Sort u} (x : α) : α
Full source
/--
The term `opaqueId x` will not be reduced by the kernel.
-/
opaque opaqueId {α : Sort u} (x : α) : α := x
Opaque Identity Function
Informal description
For any type `α` and any element `x : α`, the term `opaqueId x` is an element of type `α` that is definitionally equal to `x` but will not be reduced by the kernel during computation.
ge_iff_le theorem
[LE α] {x y : α} : x ≥ y ↔ y ≤ x
Full source
@[simp] theorem ge_iff_le [LE α] {x y : α} : x ≥ y ↔ y ≤ x := Iff.rfl
Greater Than or Equal to is Equivalent to Less Than or Equal to Flipped ($x \geq y \leftrightarrow y \leq x$)
Informal description
For any type $\alpha$ equipped with a "less than or equal to" relation $\leq$, and for any elements $x, y \in \alpha$, the statement $x \geq y$ holds if and only if $y \leq x$.
gt_iff_lt theorem
[LT α] {x y : α} : x > y ↔ y < x
Full source
@[simp] theorem gt_iff_lt [LT α] {x y : α} : x > y ↔ y < x := Iff.rfl
Greater Than is Equivalent to Less Than Flipped ($x > y \leftrightarrow y < x$)
Informal description
For any type $\alpha$ equipped with a "less than" relation $<$, and for any elements $x, y \in \alpha$, the statement $x > y$ holds if and only if $y < x$.
le_of_eq_of_le theorem
{a b c : α} [LE α] (h₁ : a = b) (h₂ : b ≤ c) : a ≤ c
Full source
theorem le_of_eq_of_le {a b c : α} [LE α] (h₁ : a = b) (h₂ : b ≤ c) : a ≤ c := h₁ ▸ h₂
Transitivity of $\leq$ with equality on the left
Informal description
For any elements $a, b, c$ of a type $\alpha$ equipped with a less-than-or-equal-to relation $\leq$, if $a = b$ and $b \leq c$, then $a \leq c$.
le_of_le_of_eq theorem
{a b c : α} [LE α] (h₁ : a ≤ b) (h₂ : b = c) : a ≤ c
Full source
theorem le_of_le_of_eq {a b c : α} [LE α] (h₁ : a ≤ b) (h₂ : b = c) : a ≤ c := h₂ ▸ h₁
Transitivity of $\leq$ with equality on the right
Informal description
For any elements $a, b, c$ of a type $\alpha$ equipped with a less-than-or-equal-to relation $\leq$, if $a \leq b$ and $b = c$, then $a \leq c$.
lt_of_eq_of_lt theorem
{a b c : α} [LT α] (h₁ : a = b) (h₂ : b < c) : a < c
Full source
theorem lt_of_eq_of_lt {a b c : α} [LT α] (h₁ : a = b) (h₂ : b < c) : a < c := h₁ ▸ h₂
Transitivity of $<$ with equality on the left
Informal description
For any elements $a, b, c$ of a type $\alpha$ equipped with a strict order relation $<$, if $a = b$ and $b < c$, then $a < c$.
lt_of_lt_of_eq theorem
{a b c : α} [LT α] (h₁ : a < b) (h₂ : b = c) : a < c
Full source
theorem lt_of_lt_of_eq {a b c : α} [LT α] (h₁ : a < b) (h₂ : b = c) : a < c := h₂ ▸ h₁
Transitivity of $<$ with equality on the right
Informal description
For any elements $a, b, c$ of a type $\alpha$ equipped with a strict order relation $<$, if $a < b$ and $b = c$, then $a < c$.
Std.Associative structure
(op : α → α → α)
Full source
/--
`Associative op` indicates `op` is an associative operation,
i.e. `(a ∘ b) ∘ c = a ∘ (b ∘ c)`.
-/
class Associative (op : α → α → α) : Prop where
  /-- An associative operation satisfies `(a ∘ b) ∘ c = a ∘ (b ∘ c)`. -/
  assoc : (a b c : α) → op (op a b) c = op a (op b c)
Associative Operation
Informal description
The structure `Associative op` asserts that the binary operation `op` is associative, meaning that for any elements `a`, `b`, and `c` of type `α`, the equality `(a ∘ b) ∘ c = a ∘ (b ∘ c)` holds, where `∘` denotes the operation `op`.
Std.Commutative structure
(op : α → α → α)
Full source
/--
`Commutative op` says that `op` is a commutative operation,
i.e. `a ∘ b = b ∘ a`.
-/
class Commutative (op : α → α → α) : Prop where
  /-- A commutative operation satisfies `a ∘ b = b ∘ a`. -/
  comm : (a b : α) → op a b = op b a
Commutative Operation
Informal description
The structure `Commutative op` asserts that the binary operation `op` is commutative, meaning that for any elements `a` and `b`, the equality `op a b = op b a` holds.
Std.IdempotentOp structure
(op : α → α → α)
Full source
/--
`IdempotentOp op` indicates `op` is an idempotent binary operation.
i.e. `a ∘ a = a`.
-/
class IdempotentOp (op : α → α → α) : Prop where
  /-- An idempotent operation satisfies `a ∘ a = a`. -/
  idempotent : (x : α) → op x x = x
Idempotent binary operation
Informal description
The structure `IdempotentOp op` asserts that the binary operation `op` on a type `α` is idempotent, meaning that for any element `a` of type `α`, applying `op` to `a` and `a` yields `a` again, i.e., $a \circ a = a$.
Std.LeftIdentity structure
(op : α → β → β) (o : outParam α)
Full source
/--
`LeftIdentify op o` indicates `o` is a left identity of `op`.

This class does not require a proof that `o` is an identity, and
is used primarily for inferring the identity using class resolution.
-/
class LeftIdentity (op : α → β → β) (o : outParam α) : Prop
Left identity element for a binary operation
Informal description
The structure `LeftIdentity op o` indicates that the element `o` is a left identity for the binary operation `op : α → β → β`, meaning that for any `b : β`, we have `op o b = b`. This class is primarily used for inferring the identity element via class resolution and does not require a proof that `o` is indeed an identity.
Std.LawfulLeftIdentity structure
(op : α → β → β) (o : outParam α) : Prop extends LeftIdentity op o
Full source
/--
`LawfulLeftIdentify op o` indicates `o` is a verified left identity of
`op`.
-/
class LawfulLeftIdentity (op : α → β → β) (o : outParam α) : Prop extends LeftIdentity op o where
  /-- Left identity `o` is an identity. -/
  left_id : ∀ a, op o a = a
Verified left identity element for a binary operation
Informal description
The structure `LawfulLeftIdentity op o` asserts that the element `o` is a verified left identity for the binary operation `op : α → β → β`, meaning that for all `b : β`, we have `op o b = b`.
Std.RightIdentity structure
(op : α → β → α) (o : outParam β)
Full source
/--
`RightIdentify op o` indicates `o` is a right identity `o` of `op`.

This class does not require a proof that `o` is an identity, and is used
primarily for inferring the identity using class resolution.
-/
class RightIdentity (op : α → β → α) (o : outParam β) : Prop
Right identity element for a binary operation
Informal description
The structure `RightIdentity op o` indicates that the element `o` is a right identity for the binary operation `op : α → β → α`, meaning that for any `a : α`, we have `op a o = a`. This class is primarily used for inferring the identity element via class resolution and does not require a proof that `o` is indeed an identity.
Std.LawfulRightIdentity structure
(op : α → β → α) (o : outParam β) : Prop extends RightIdentity op o
Full source
/--
`LawfulRightIdentify op o` indicates `o` is a verified right identity of
`op`.
-/
class LawfulRightIdentity (op : α → β → α) (o : outParam β) : Prop extends RightIdentity op o where
  /-- Right identity `o` is an identity. -/
  right_id : ∀ a, op a o = a
Verified right identity element for a binary operation
Informal description
The structure `LawfulRightIdentity op o` asserts that the element `o` is a verified right identity for the binary operation `op : α → β → α`, meaning that for all `a : α`, we have `op a o = a`.
Std.Identity structure
(op : α → α → α) (o : outParam α) : Prop extends LeftIdentity op o, RightIdentity op o
Full source
/--
`Identity op o` indicates `o` is a left and right identity of `op`.

This class does not require a proof that `o` is an identity, and is used
primarily for inferring the identity using class resolution.
-/
class Identity (op : α → α → α) (o : outParam α) : Prop extends LeftIdentity op o, RightIdentity op o
Identity element for a binary operation
Informal description
The structure `Identity op o` asserts that the element `o` is both a left and right identity for the binary operation `op` on type `α`. This means that for any element `x : α`, we have `op o x = x` and `op x o = x`. This class is primarily used for inferring the identity element through class resolution, without requiring explicit proofs of the identity properties.
Std.LawfulIdentity structure
(op : α → α → α) (o : outParam α) : Prop extends Identity op o, LawfulLeftIdentity op o, LawfulRightIdentity op o
Full source
/--
`LawfulIdentity op o` indicates `o` is a verified left and right
identity of `op`.
-/
class LawfulIdentity (op : α → α → α) (o : outParam α) : Prop extends Identity op o, LawfulLeftIdentity op o, LawfulRightIdentity op o
Verified identity element for a binary operation
Informal description
The structure `LawfulIdentity op o` asserts that the element `o` is a verified left and right identity for the binary operation `op`. This means that for all elements `x` of the appropriate type, both `op o x = x` and `op x o = x` hold.
Std.LawfulCommIdentity structure
(op : α → α → α) (o : outParam α) [hc : Commutative op] : Prop extends LawfulIdentity op o
Full source
/--
`LawfulCommIdentity` can simplify defining instances of `LawfulIdentity`
on commutative functions by requiring only a left or right identity
proof.

This class is intended for simplifying defining instances of
`LawfulIdentity` and functions needed commutative operations with
identity should just add a `LawfulIdentity` constraint.
-/
class LawfulCommIdentity (op : α → α → α) (o : outParam α) [hc : Commutative op] : Prop extends LawfulIdentity op o where
  left_id a := Eq.trans (hc.comm o a) (right_id a)
  right_id a := Eq.trans (hc.comm a o) (left_id a)
Lawful Commutative Identity
Informal description
The structure `LawfulCommIdentity op o` asserts that the binary operation `op` with identity element `o` is both commutative and satisfies the left and right identity laws. This means that for any elements `a` and `b`, the equality `op a b = op b a` holds (commutativity), and for any element `a`, the equalities `op o a = a` and `op a o = a` hold (identity laws). This structure is used to simplify the definition of lawful identity instances for commutative operations.
Std.Refl structure
(r : α → α → Prop)
Full source
/-- `Refl r` means the binary relation `r` is reflexive, that is, `r x x` always holds. -/
class Refl (r : α → α → Prop) : Prop where
  /-- A reflexive relation satisfies `r a a`. -/
  refl : ∀ a, r a a
Reflexive Relation
Informal description
The structure `Refl r` asserts that the binary relation `r` on a type `α` is reflexive, meaning that for every element `x` in `α`, the relation `r x x` holds.
Std.Antisymm structure
(r : α → α → Prop)
Full source
/-- `Antisymm r` says that `r` is antisymmetric, that is, `r a b → r b a → a = b`. -/
class Antisymm (r : α → α → Prop) : Prop where
  /-- An antisymmetric relation `r` satisfies `r a b → r b a → a = b`. -/
  antisymm (a b : α) : r a b → r b a → a = b
Antisymmetric Relation
Informal description
The structure `Antisymm r` asserts that the binary relation `r` on a type `α` is antisymmetric, meaning that for any elements `a` and `b` in `α`, if both `r a b` and `r b a` hold, then `a` must be equal to `b`.
Antisymm abbrev
(r : α → α → Prop) : Prop
Full source
@[deprecated Antisymm (since := "2024-10-16"), inherit_doc Antisymm]
abbrev _root_.Antisymm (r : α → α → Prop) : Prop := Std.Antisymm r
Antisymmetric Relation
Informal description
A binary relation $r$ on a type $\alpha$ is called *antisymmetric* if for any elements $a$ and $b$ in $\alpha$, whenever both $r(a, b)$ and $r(b, a)$ hold, it follows that $a = b$.
Std.Asymm structure
(r : α → α → Prop)
Full source
/-- `Asymm X r` means that the binary relation `r` on `X` is asymmetric, that is,
`r a b → ¬ r b a`. -/
class Asymm (r : α → α → Prop) : Prop where
  /-- An asymmetric relation satisfies `r a b → ¬ r b a`. -/
  asymm : ∀ a b, r a b → ¬r b a
Asymmetric binary relation
Informal description
The structure `Asymm X r` asserts that the binary relation `r$ on a type $X$ is asymmetric, meaning that for any elements $a$ and $b$ in $X$, if $r a b$ holds, then $r b a$ does not hold.
Std.Total structure
(r : α → α → Prop)
Full source
/-- `Total X r` means that the binary relation `r` on `X` is total, that is, that for any
`x y : X` we have `r x y` or `r y x`. -/
class Total (r : α → α → Prop) : Prop where
  /-- A total relation satisfies `r a b ∨ r b a`. -/
  total : ∀ a b, r a b ∨ r b a
Total binary relation
Informal description
The structure `Total X r` asserts that the binary relation `r` on the type `X` is total, meaning that for any two elements `x` and `y` in `X`, either `r x y` holds or `r y x` holds.
Std.Irrefl structure
(r : α → α → Prop)
Full source
/-- `Irrefl r` means the binary relation `r` is irreflexive, that is, `r x x` never
holds. -/
class Irrefl (r : α → α → Prop) : Prop where
  /-- An irreflexive relation satisfies `¬ r a a`. -/
  irrefl : ∀ a, ¬r a a
Irreflexive relation
Informal description
A binary relation \( r \) on a type \( \alpha \) is called irreflexive if \( r(x, x) \) never holds for any \( x \in \alpha \).