doc-next-gen

Init.Prelude

Module docstring

{"# Init.Prelude

This is the first file in the Lean import hierarchy. It is responsible for setting up basic definitions, most of which Lean already has \"built in knowledge\" about, so it is important that they be set up in exactly this way. (For example, Lean will use PUnit in the desugaring of do notation, or in the pattern match compiler.)

","Initialize the Quotient Module, which effectively adds the following definitions: ``` opaque Quot {α : Sort u} (r : α → α → Prop) : Sort u

opaque Quot.mk {α : Sort u} (r : α → α → Prop) (a : α) : Quot r

opaque Quot.lift {α : Sort u} {r : α → α → Prop} {β : Sort v} (f : α → β) : (∀ a b : α, r a b → Eq (f a) (f b)) → Quot r → β

opaque Quot.ind {α : Sort u} {r : α → α → Prop} {β : Quot r → Prop} : (∀ a : α, β (Quot.mk r a)) → ∀ q : Quot r, β q ","# if-then-else ","# Boolean operators ","# Syntax ","# Syntax AST ","# Builtin kinds ","# Parser descriptions ","Runtime support for making quotation terms auto-hygienic, by mangling identifiers introduced by them with a \"macro scope\" supplied by the context. Details to appear in a paper soon. ","We represent a name with macro scopes as .@.(.)*..hyg. Example: suppose the module name is `Init.Data.List.Basic`, and name is `foo.bla`, and macroscopes [2, 5] foo.bla.@.Init.Data.List.Basic.hyg.2.5 ```

We may have to combine scopes from different files/modules. The main modules being processed is always the right-most one. This situation may happen when we execute a macro generated in an imported file in the current file. [email protected]._hyg.4

The delimiter _hyg is used just to improve the hasMacroScopes performance. "}

id definition
{α : Sort u} (a : α) : α
Full source
/--
The identity function. `id` takes an implicit argument `α : Sort u`
(a type in any universe), and an argument `a : α`, and returns `a`.

Although this may look like a useless function, one application of the identity
function is to explicitly put a type on an expression. If `e` has type `T`,
and `T'` is definitionally equal to `T`, then `@id T' e` typechecks, and Lean
knows that this expression has type `T'` rather than `T`. This can make a
difference for typeclass inference, since `T` and `T'` may have different
typeclass instances on them. `show T' from e` is sugar for an `@id T' e`
expression.
-/
@[inline] def id {α : Sort u} (a : α) : α := a
Identity function
Informal description
The identity function, which takes an element $a$ of type $\alpha$ and returns $a$ itself.
Function.comp definition
{α : Sort u} {β : Sort v} {δ : Sort w} (f : β → δ) (g : α → β) : α → δ
Full source
/--
Function composition, usually written with the infix operator `∘`. A new function is created from
two existing functions, where one function's output is used as input to the other.

Examples:
 * `Function.comp List.reverse (List.drop 2) [3, 2, 4, 1] = [1, 4]`
 * `(List.reverse ∘ List.drop 2) [3, 2, 4, 1] = [1, 4]`
-/
@[inline] def Function.comp {α : Sort u} {β : Sort v} {δ : Sort w} (f : β → δ) (g : α → β) : α → δ :=
  fun x => f (g x)
Function composition
Informal description
Given functions \( f : \beta \to \delta \) and \( g : \alpha \to \beta \), the composition \( f \circ g \) is the function from \( \alpha \) to \( \delta \) defined by \( (f \circ g)(x) = f(g(x)) \) for any \( x \in \alpha \).
Function.const definition
{α : Sort u} (β : Sort v) (a : α) : β → α
Full source
/--
The constant function that ignores its argument.

If `a : α`, then `Function.const β a : β → α` is the “constant function with value `a`”. For all
arguments `b : β`, `Function.const β a b = a`.

Examples:
 * `Function.const Bool 10 true = 10`
 * `Function.const Bool 10 false = 10`
 * `Function.const String 10 "any string" = 10`
-/
@[inline] def Function.const {α : Sort u} (β : Sort v) (a : α) : β → α :=
  fun _ => a
Constant function
Informal description
The constant function that maps every element of type $\beta$ to a fixed element $a$ of type $\alpha$. For any input $b \in \beta$, the function returns $a$, i.e., $\text{const}_\beta(a)(b) = a$.
letFun definition
{α : Sort u} {β : α → Sort v} (v : α) (f : (x : α) → β x) : β v
Full source
/--
The encoding of `let_fun x := v; b` is `letFun v (fun x => b)`.
This is equal to `(fun x => b) v`, so the value of `x` is not accessible to `b`.
This is in contrast to `let x := v; b`, where the value of `x` is accessible to `b`.

There is special support for `letFun`.
Both WHNF and `simp` are aware of `letFun` and can reduce it when zeta reduction is enabled,
despite the fact it is marked `irreducible`.
For metaprogramming, the function `Lean.Expr.letFun?` can be used to recognize a `let_fun` expression
to extract its parts as if it were a `let` expression.
-/
@[irreducible] def letFun {α : Sort u} {β : α → Sort v} (v : α) (f : (x : α) → β x) : β v := f v
`let_fun` expression encoding
Informal description
The expression `letFun v (fun x => b)` encodes the `let_fun x := v; b` construct, which is equivalent to `(fun x => b) v`. Unlike a regular `let` expression, the value of `x` is not accessible within `b` itself.
inferInstance abbrev
{α : Sort u} [i : α] : α
Full source
/--
`inferInstance` synthesizes a value of any target type by typeclass
inference. This function has the same type signature as the identity
function, but the square brackets on the `[i : α]` argument means that it will
attempt to construct this argument by typeclass inference. (This will fail if
`α` is not a `class`.) Example:
```
#check (inferInstance : Inhabited Nat) -- Inhabited Nat

def foo : Inhabited (Nat × Nat) :=
  inferInstance

example : foo.default = (default, default) :=
  rfl
```
-/
abbrev inferInstance {α : Sort u} [i : α] : α := i
Typeclass Instance Synthesis
Informal description
Given a type $\alpha$ with a typeclass instance `[i : α]`, the term `inferInstance` synthesizes a value of type $\alpha$ by typeclass inference.
inferInstanceAs abbrev
(α : Sort u) [i : α] : α
Full source
/-- `inferInstanceAs α` synthesizes a value of any target type by typeclass
inference. This is just like `inferInstance` except that `α` is given
explicitly instead of being inferred from the target type. It is especially
useful when the target type is some `α'` which is definitionally equal to `α`,
but the instance we are looking for is only registered for `α` (because
typeclass search does not unfold most definitions, but definitional equality
does.) Example:
```
#check inferInstanceAs (Inhabited Nat) -- Inhabited Nat
```
-/
abbrev inferInstanceAs (α : Sort u) [i : α] : α := i
Typeclass Instance Synthesis for Explicit Type
Informal description
Given a type $\alpha$ (which may be in any universe level $u$) and an instance $i$ of $\alpha$, the term `inferInstanceAs α` synthesizes and returns a value of type $\alpha$ through typeclass inference. This is particularly useful when $\alpha$ is definitionally equal to another type $\alpha'$, but the desired instance is only registered for $\alpha$.
PUnit inductive
: Sort u
Full source
/--
The canonical universe-polymorphic type with just one element.

It should be used in contexts that require a type to be universe polymorphic, thus disallowing
`Unit`.
-/
inductive PUnit : Sort u where
  /-- The only element of the universe-polymorphic unit type. -/
  | unit : PUnit
Universe-polymorphic unit type
Informal description
The universe-polymorphic type `PUnit` is the canonical type with exactly one element, designed for contexts requiring a type that works across all universes.
Unit abbrev
: Type
Full source
/--
The canonical type with one element. This element is written `()`.

`Unit` has a number of uses:
 * It can be used to model control flow that returns from a function call without providing other
   information.
 * Monadic actions that return `Unit` have side effects without computing values.
 * In polymorphic types, it can be used to indicate that no data is to be stored in a particular
   field.
-/
abbrev Unit : Type := PUnit
Canonical Unit Type
Informal description
The type `Unit` is the canonical type with exactly one element, denoted as `()`. It is used in contexts where a function returns no meaningful value, in monadic actions with side effects, or to indicate the absence of data in polymorphic types.
Unit.unit abbrev
: Unit
Full source
/--
The only element of the unit type.

It can be written as an empty tuple: `()`.
-/
@[match_pattern] abbrev Unit.unit : Unit := PUnit.unit
Canonical Element of Unit Type
Informal description
The unique element of the unit type, denoted as `()`.
lcErased axiom
: Type
Full source
/-- Marker for information that has been erased by the code generator. -/
unsafe axiom lcErased : Type
Code Generator Erasure Marker Type
Informal description
The type `lcErased` is a marker type used by the Lean code generator to indicate information that has been erased during compilation.
lcAny axiom
: Type
Full source
/-- Marker for type dependency that has been erased by the code generator. -/
unsafe axiom lcAny : Type
Code Generator Erasure Marker Type
Informal description
The type `lcAny` is a marker type used by the Lean code generator to represent erased type dependencies.
lcProof axiom
{α : Prop} : α
Full source
/--
Auxiliary unsafe constant used by the Compiler when erasing proofs from code.

It may look strange to have an axiom that says "every proposition is true",
since this is obviously unsound, but the `unsafe` marker ensures that the
kernel will not let this through into regular proofs. The lower levels of the
code generator don't need proofs in terms, so this is used to stub the proofs
out.
-/
unsafe axiom lcProof {α : Prop} : α
Axiom of Proof Existence for All Propositions
Informal description
For any proposition $\alpha$, there exists a proof of $\alpha$.
lcCast axiom
{α : Sort u} {β : Sort v} (a : α) : β
Full source
/--
Auxiliary unsafe constant used by the Compiler when erasing casts.
-/
unsafe axiom lcCast {α : Sort u} {β : Sort v} (a : α) : β
Unsafe Type Casting Axiom
Informal description
Given any type $\alpha$ and any type $\beta$, there exists a function that takes an element of $\alpha$ and returns an element of $\beta$.
lcUnreachable axiom
{α : Sort u} : α
Full source
/--
Auxiliary unsafe constant used by the Compiler to mark unreachable code.

Like `lcProof`, this is an `unsafe axiom`, which means that even though it is
not sound, the kernel will not let us use it for regular proofs.

Executing this expression to actually synthesize a value of type `α` causes
**immediate undefined behavior**, and the compiler does take advantage of this
to optimize the code assuming that it is not called. If it is not optimized out,
it is likely to appear as a print message saying "unreachable code", but this
behavior is not guaranteed or stable in any way.
-/
unsafe axiom lcUnreachable {α : Sort u} : α
Unreachable Code Axiom
Informal description
The constant `lcUnreachable` is an unsafe axiom that represents unreachable code in the Lean compiler. For any type `α`, `lcUnreachable` purports to produce a term of type `α`, but executing this term results in undefined behavior. The compiler optimizes under the assumption that this term is never actually evaluated.
True inductive
: Prop
Full source
/--
`True` is a proposition and has only an introduction rule, `True.intro : True`.
In other words, `True` is simply true, and has a canonical proof, `True.intro`
For more information: [Propositional Logic](https://lean-lang.org/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
-/
inductive True : Prop where
  /-- `True` is true, and `True.intro` (or more commonly, `trivial`)
  is the proof. -/
  | intro : True
True proposition
Informal description
The proposition `True` is a trivial truth that has exactly one canonical proof, `True.intro`. It represents the always-true proposition in logic.
False inductive
: Prop
Full source
/--
`False` is the empty proposition. Thus, it has no introduction rules.
It represents a contradiction. `False` elimination rule, `False.rec`,
expresses the fact that anything follows from a contradiction.
This rule is sometimes called ex falso (short for ex falso sequitur quodlibet),
or the principle of explosion.
For more information: [Propositional Logic](https://lean-lang.org/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
-/
inductive False : Prop
False (contradiction)
Informal description
The proposition `False` represents a contradiction, with no introduction rules. The elimination rule `False.rec` (ex falso) states that anything can be derived from a contradiction.
Empty inductive
: Type
Full source
/--
The empty type. It has no constructors.

Use `Empty.elim` in contexts where a value of type `Empty` is in scope.
-/
inductive Empty : Type
Empty type
Informal description
The type `Empty` is an inductive type with no constructors, representing the empty type (a type with no elements). It is used in contexts where a contradiction or impossibility is derived, and can be eliminated using `Empty.elim` to derive any conclusion from an inhabitant of `Empty`.
PEmpty inductive
: Sort u
Full source
/--
The universe-polymorphic empty type, with no constructors.

`PEmpty` can be used in any universe, but this flexibility can lead to worse error messages and more
challenges with universe level unification. Prefer the type `Empty` or the proposition `False` when
possible.
-/
inductive PEmpty : Sort u where
Polymorphic Empty Type
Informal description
The polymorphic empty type, which has no constructors and can be used in any universe. It is similar to the type `Empty` or the proposition `False`, but with the flexibility of being universe-polymorphic.
Not definition
(a : Prop) : Prop
Full source
/--
`Not p`, or `¬p`, is the negation of `p`. It is defined to be `p → False`,
so if your goal is `¬p` you can use `intro h` to turn the goal into
`h : p ⊢ False`, and if you have `hn : ¬p` and `h : p` then `hn h : False`
and `(hn h).elim` will prove anything.
For more information: [Propositional Logic](https://lean-lang.org/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
-/
def Not (a : Prop) : Prop := a → False
Negation of a proposition
Informal description
The negation of a proposition \( p \), denoted \( \neg p \), is defined as the implication \( p \to \text{False} \). This means that if \( p \) holds, then a contradiction follows.
False.elim definition
{C : Sort u} (h : False) : C
Full source
/--
`False.elim : False → C` says that from `False`, any desired proposition
`C` holds. Also known as ex falso quodlibet (EFQ) or the principle of explosion.

The target type is actually `C : Sort u` which means it works for both
propositions and types. When executed, this acts like an "unreachable"
instruction: it is **undefined behavior** to run, but it will probably print
"unreachable code". (You would need to construct a proof of false to run it
anyway, which you can only do using `sorry` or unsound axioms.)
-/
@[macro_inline] def False.elim {C : Sort u} (h : False) : C :=
  h.rec
Principle of explosion (False elimination)
Informal description
The elimination rule for `False` states that from a contradiction (a proof of `False`), any desired proposition or type `C` can be derived. This is known as the principle of explosion (ex falso quodlibet).
absurd definition
{a : Prop} {b : Sort v} (h₁ : a) (h₂ : Not a) : b
Full source
/--
Anything follows from two contradictory hypotheses. Example:
```
example (hp : p) (hnp : ¬p) : q := absurd hp hnp
```
For more information: [Propositional Logic](https://lean-lang.org/theorem_proving_in_lean4/propositions_and_proofs.html#propositional-logic)
-/
@[macro_inline] def absurd {a : Prop} {b : Sort v} (h₁ : a) (h₂ : Not a) : b :=
  (h₂ h₁).rec
Principle of explosion (ex falso quodlibet)
Informal description
Given a proposition \( a \) and a type \( b \), if \( a \) holds and its negation \( \neg a \) also holds, then any term of type \( b \) can be derived. In other words, from a contradiction, anything follows.
Eq inductive
: α → α → Prop
Full source
/--
The equality relation. It has one introduction rule, `Eq.refl`.
We use `a = b` as notation for `Eq a b`.
A fundamental property of equality is that it is an equivalence relation.
```
variable (α : Type) (a b c d : α)
variable (hab : a = b) (hcb : c = b) (hcd : c = d)

example : a = d :=
  Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
```
Equality is much more than an equivalence relation, however. It has the important property that every assertion
respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value.
That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`.
Example:
```
example (α : Type) (a b : α) (p : α → Prop)
        (h1 : a = b) (h2 : p a) : p b :=
  Eq.subst h1 h2

example (α : Type) (a b : α) (p : α → Prop)
    (h1 : a = b) (h2 : p a) : p b :=
  h1 ▸ h2
```
The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`.
For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
inductive Eq : α → α → Prop where
  /-- `Eq.refl a : a = a` is reflexivity, the unique constructor of the
  equality type. See also `rfl`, which is usually used instead. -/
  | refl (a : α) : Eq a a
Equality Relation
Informal description
The equality relation on a type $\alpha$, denoted $a = b$ for $a, b \in \alpha$, is the smallest reflexive relation on $\alpha$. It satisfies the following properties: 1. Reflexivity: For any $a \in \alpha$, $a = a$. 2. Symmetry: For any $a, b \in \alpha$, if $a = b$ then $b = a$. 3. Transitivity: For any $a, b, c \in \alpha$, if $a = b$ and $b = c$ then $a = c$. 4. Substitution: For any property $p$ on $\alpha$ and any $a, b \in \alpha$, if $a = b$ and $p(a)$ holds, then $p(b)$ holds.
Eq.ndrec abbrev
{α : Sort u2} {a : α} {motive : α → Sort u1} (m : motive a) {b : α} (h : Eq a b) : motive b
Full source
/-- Non-dependent recursor for the equality type. -/
@[simp] abbrev Eq.ndrec.{u1, u2} {α : Sort u2} {a : α} {motive : α → Sort u1} (m : motive a) {b : α} (h : Eq a b) : motive b :=
  h.rec m
Transport Along Equality (Non-dependent Recursor)
Informal description
Given a type $\alpha$, an element $a \in \alpha$, and a dependent type family $\text{motive} : \alpha \to \text{Sort } u_1$, if we have a term $m : \text{motive } a$ and a proof $h : a = b$ for some $b \in \alpha$, then we can construct a term of type $\text{motive } b$. In other words, this is the non-dependent eliminator for equality that allows transporting a term along an equality proof.
rfl definition
{α : Sort u} {a : α} : Eq a a
Full source
/--
`rfl : a = a` is the unique constructor of the equality type. This is the
same as `Eq.refl` except that it takes `a` implicitly instead of explicitly.

This is a more powerful theorem than it may appear at first, because although
the statement of the theorem is `a = a`, Lean will allow anything that is
definitionally equal to that type. So, for instance, `2 + 2 = 4` is proven in
Lean by `rfl`, because both sides are the same up to definitional equality.
-/
@[match_pattern] def rfl {α : Sort u} {a : α} : Eq a a := Eq.refl a
Reflexivity of Equality
Informal description
The term `rfl` is the unique constructor of the equality type, representing reflexivity of equality. It proves that any element $a$ of type $\alpha$ is equal to itself, i.e., $a = a$. This holds definitionally, meaning it can prove any equality that reduces to $a = a$ by definitional equality (e.g., $2 + 2 = 4$).
id_eq theorem
(a : α) : Eq (id a) a
Full source
/-- `id x = x`, as a `@[simp]` lemma. -/
@[simp] theorem id_eq (a : α) : Eq (id a) a := rfl
Identity Function Property: $\mathrm{id}(a) = a$
Informal description
For any element $a$ of type $\alpha$, the identity function applied to $a$ is equal to $a$, i.e., $\mathrm{id}(a) = a$.
Eq.subst theorem
{α : Sort u} {motive : α → Prop} {a b : α} (h₁ : Eq a b) (h₂ : motive a) : motive b
Full source
/--
The substitution principle for equality. If `a = b ` and `P a` holds,
then `P b` also holds. We conventionally use the name `motive` for `P` here,
so that you can specify it explicitly using e.g.
`Eq.subst (motive := fun x => x < 5)` if it is not otherwise inferred correctly.

This theorem is the underlying mechanism behind the `rw` tactic, which is
essentially a fancy algorithm for finding good `motive` arguments to usefully
apply this theorem to replace occurrences of `a` with `b` in the goal or
hypotheses.

For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
theorem Eq.subst {α : Sort u} {motive : α → Prop} {a b : α} (h₁ : Eq a b) (h₂ : motive a) : motive b :=
  Eq.ndrec h₂ h₁
Substitution Property of Equality
Informal description
For any type $\alpha$, property $P : \alpha \to \mathrm{Prop}$, and elements $a, b \in \alpha$, if $a = b$ and $P(a)$ holds, then $P(b)$ also holds.
Eq.symm theorem
{α : Sort u} {a b : α} (h : Eq a b) : Eq b a
Full source
/--
Equality is symmetric: if `a = b` then `b = a`.

Because this is in the `Eq` namespace, if you have a variable `h : a = b`,
`h.symm` can be used as shorthand for `Eq.symm h` as a proof of `b = a`.

For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
@[symm] theorem Eq.symm {α : Sort u} {a b : α} (h : Eq a b) : Eq b a :=
  h ▸ rfl
Symmetry of Equality: $a = b \implies b = a$
Informal description
For any elements $a$ and $b$ of a type $\alpha$, if $a = b$ then $b = a$.
Eq.trans theorem
{α : Sort u} {a b c : α} (h₁ : Eq a b) (h₂ : Eq b c) : Eq a c
Full source
/--
Equality is transitive: if `a = b` and `b = c` then `a = c`.

Because this is in the `Eq` namespace, if you have variables or expressions
`h₁ : a = b` and `h₂ : b = c`, you can use `h₁.trans h₂ : a = c` as shorthand
for `Eq.trans h₁ h₂`.

For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
theorem Eq.trans {α : Sort u} {a b c : α} (h₁ : Eq a b) (h₂ : Eq b c) : Eq a c :=
  h₂ ▸ h₁
Transitivity of Equality
Informal description
For any elements $a$, $b$, and $c$ of a type $\alpha$, if $a = b$ and $b = c$, then $a = c$.
cast definition
{α β : Sort u} (h : Eq α β) (a : α) : β
Full source
/--
Cast across a type equality. If `h : α = β` is an equality of types, and
`a : α`, then `a : β` will usually not typecheck directly, but this function
will allow you to work around this and embed `a` in type `β` as `cast h a : β`.

It is best to avoid this function if you can, because it is more complicated
to reason about terms containing casts, but if the types don't match up
definitionally sometimes there isn't anything better you can do.

For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
@[macro_inline] def cast {α β : Sort u} (h : Eq α β) (a : α) : β :=
  h.rec a
Type casting via equality
Informal description
Given a type equality $h : \alpha = \beta$ and an element $a : \alpha$, the function $\text{cast}$ produces the corresponding element of type $\beta$. This allows working around type mismatches when $\alpha$ and $\beta$ are definitionally equal but not syntactically identical.
congrArg theorem
{α : Sort u} {β : Sort v} {a₁ a₂ : α} (f : α → β) (h : Eq a₁ a₂) : Eq (f a₁) (f a₂)
Full source
/--
Congruence in the function argument: if `a₁ = a₂` then `f a₁ = f a₂` for
any (nondependent) function `f`. This is more powerful than it might look at first, because
you can also use a lambda expression for `f` to prove that
`<something containing a₁> = <something containing a₂>`. This function is used
internally by tactics like `congr` and `simp` to apply equalities inside
subterms.

For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
theorem congrArg {α : Sort u} {β : Sort v} {a₁ a₂ : α} (f : α → β) (h : Eq a₁ a₂) : Eq (f a₁) (f a₂) :=
  h ▸ rfl
Function Application Preserves Equality (Congruence for Function Argument)
Informal description
For any types $\alpha$ and $\beta$, and any function $f : \alpha \to \beta$, if $a_1 = a_2$ for $a_1, a_2 \in \alpha$, then $f(a_1) = f(a_2)$.
congr theorem
{α : Sort u} {β : Sort v} {f₁ f₂ : α → β} {a₁ a₂ : α} (h₁ : Eq f₁ f₂) (h₂ : Eq a₁ a₂) : Eq (f₁ a₁) (f₂ a₂)
Full source
/--
Congruence in both function and argument. If `f₁ = f₂` and `a₁ = a₂` then
`f₁ a₁ = f₂ a₂`. This only works for nondependent functions; the theorem
statement is more complex in the dependent case.

For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality)
-/
theorem congr {α : Sort u} {β : Sort v} {f₁ f₂ : α → β} {a₁ a₂ : α} (h₁ : Eq f₁ f₂) (h₂ : Eq a₁ a₂) : Eq (f₁ a₁) (f₂ a₂) :=
  h₁ ▸ h₂ ▸ rfl
Congruence for Function Application: $f_1 = f_2 \land a_1 = a_2 \to f_1(a_1) = f_2(a_2)$
Informal description
For any types $\alpha$ and $\beta$, and any functions $f_1, f_2 : \alpha \to \beta$ and elements $a_1, a_2 \in \alpha$, if $f_1 = f_2$ and $a_1 = a_2$, then $f_1(a_1) = f_2(a_2)$.
congrFun theorem
{α : Sort u} {β : α → Sort v} {f g : (x : α) → β x} (h : Eq f g) (a : α) : Eq (f a) (g a)
Full source
/-- Congruence in the function part of an application: If `f = g` then `f a = g a`. -/
theorem congrFun {α : Sort u} {β : α → Sort v} {f g : (x : α) → β x} (h : Eq f g) (a : α) : Eq (f a) (g a) :=
  h ▸ rfl
Function Application Preserves Equality (Congruence for Functions)
Informal description
For any type $\alpha$ and any dependent type family $\beta : \alpha \to \text{Sort}\, v$, if two dependent functions $f, g : \prod_{x:\alpha} \beta(x)$ are equal (i.e., $f = g$), then for any $a : \alpha$, the applications $f(a)$ and $g(a)$ are also equal (i.e., $f(a) = g(a)$).
Quot.lcInv axiom
{α : Sort u} {r : α → α → Prop} (q : Quot r) : α
Full source
/--
Unsafe auxiliary constant used by the compiler to erase `Quot.lift`.
-/
unsafe axiom Quot.lcInv {α : Sort u} {r : α → α → Prop} (q : Quot r) : α
Lift Cancellation Inverse for Quotient Types
Informal description
For any type $\alpha$ and equivalence relation $r$ on $\alpha$, there exists a function $\text{lcInv}$ from the quotient type $\text{Quot}\, r$ back to $\alpha$.
HEq inductive
: {α : Sort u} → α → {β : Sort u} → β → Prop
Full source
/--
Heterogeneous equality. `HEq a b` asserts that `a` and `b` have the same
type, and casting `a` across the equality yields `b`, and vice versa.

You should avoid using this type if you can. Heterogeneous equality does not
have all the same properties as `Eq`, because the assumption that the types of
`a` and `b` are equal is often too weak to prove theorems of interest. One
important non-theorem is the analogue of `congr`: If `HEq f g` and `HEq x y`
and `f x` and `g y` are well typed it does not follow that `HEq (f x) (g y)`.
(This does follow if you have `f = g` instead.) However if `a` and `b` have
the same type then `a = b` and `HEq a b` are equivalent.
-/
inductive HEq : {α : Sort u} → α → {β : Sort u} → β → Prop where
  /-- Reflexivity of heterogeneous equality. -/
  | refl (a : α) : HEq a a
Heterogeneous equality
Informal description
The type `HEq a b` represents heterogeneous equality between elements `a : α` and `b : β`, asserting that `α` and `β` are equal types and that `a` and `b` are equal when cast to the same type. This is a weaker notion than homogeneous equality (`Eq`), as it does not satisfy all the same properties, such as the full congruence property for function application.
HEq.rfl definition
{α : Sort u} {a : α} : HEq a a
Full source
/-- A version of `HEq.refl` with an implicit argument. -/
@[match_pattern] protected def HEq.rfl {α : Sort u} {a : α} : HEq a a :=
  HEq.refl a
Reflexivity of heterogeneous equality
Informal description
The reflexive property of heterogeneous equality, stating that any element $a$ of type $\alpha$ is heterogeneously equal to itself.
Prod structure
(α : Type u) (β : Type v)
Full source
/--
The product type, usually written `α × β`. Product types are also called pair or tuple types.
Elements of this type are pairs in which the first element is an `α` and the second element is a
`β`.

Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`.
-/
structure Prod (α : Type u) (β : Type v) where
  /--
  Constructs a pair. This is usually written `(x, y)` instead of `Prod.mk x y`.
  -/
  mk ::
  /-- The first element of a pair. -/
  fst : α
  /-- The second element of a pair. -/
  snd : β
Product type (ordered pairs)
Informal description
The product type $\alpha \times \beta$ represents ordered pairs where the first component is of type $\alpha$ and the second component is of type $\beta$. Product types nest to the right, meaning that a triple $(x, y, z) \in \alpha \times \beta \times \gamma$ is equivalent to $(x, (y, z)) \in \alpha \times (\beta \times \gamma)$.
PProd structure
(α : Sort u) (β : Sort v)
Full source
/--
A product type in which the types may be propositions, usually written `α ×' β`.

This type is primarily used internally and as an implementation detail of proof automation. It is
rarely useful in hand-written code.
-/
structure PProd (α : Sort u) (β : Sort v) where
  /-- The first element of a pair. -/
  fst : α
  /-- The second element of a pair. -/
  snd : β
Propositional Product Type
Informal description
The structure `PProd` represents a product type where the components `α` and `β` can be propositions or types, typically written as `α ×' β`. This is primarily used internally for proof automation and is rarely useful in hand-written code.
MProd structure
(α β : Type u)
Full source
/--
A product type in which both `α` and `β` are in the same universe.

It is called `MProd` is because it is the *universe-monomorphic* product type.
-/
structure MProd (α β : Type u) where
  /-- The first element of a pair. -/
  fst : α
  /-- The second element of a pair. -/
  snd : β
Universe-monomorphic product type
Informal description
The structure `MProd` represents a product type where both components `α` and `β` are in the same universe. It is a universe-monomorphic version of the product type, meaning that both `α` and `β` must be types in the same universe level `u`.
And structure
(a b : Prop)
Full source
/--
`And a b`, or `a ∧ b`, is the conjunction of propositions. It can be
constructed and destructed like a pair: if `ha : a` and `hb : b` then
`⟨ha, hb⟩ : a ∧ b`, and if `h : a ∧ b` then `h.left : a` and `h.right : b`.
-/
@[pp_using_anonymous_constructor]
structure And (a b : Prop) : Prop where
  /-- `And.intro : a → b → a ∧ b` is the constructor for the And operation. -/
  intro ::
  /-- Extract the left conjunct from a conjunction. `h : a ∧ b` then
  `h.left`, also notated as `h.1`, is a proof of `a`. -/
  left : a
  /-- Extract the right conjunct from a conjunction. `h : a ∧ b` then
  `h.right`, also notated as `h.2`, is a proof of `b`. -/
  right : b
Logical Conjunction
Informal description
The logical conjunction of two propositions $a$ and $b$, denoted $a \land b$, is a proposition that is true if and only if both $a$ and $b$ are true. It can be constructed from proofs of $a$ and $b$, and decomposed into its left and right components.
Or inductive
(a b : Prop) : Prop
Full source
/--
`Or a b`, or `a ∨ b`, is the disjunction of propositions. There are two
constructors for `Or`, called `Or.inl : a → a ∨ b` and `Or.inr : b → a ∨ b`,
and you can use `match` or `cases` to destruct an `Or` assumption into the
two cases.
-/
inductive Or (a b : Prop) : Prop where
  /-- `Or.inl` is "left injection" into an `Or`. If `h : a` then `Or.inl h : a ∨ b`. -/
  | inl (h : a) : Or a b
  /-- `Or.inr` is "right injection" into an `Or`. If `h : b` then `Or.inr h : a ∨ b`. -/
  | inr (h : b) : Or a b
Logical disjunction
Informal description
The logical disjunction of two propositions $a$ and $b$, denoted $a \lor b$, is a proposition that is true if and only if at least one of $a$ or $b$ is true. It can be constructed from a proof of $a$ (via `Or.inl`) or a proof of $b$ (via `Or.inr`), and can be destructed into its two possible cases.
Or.intro_left theorem
(b : Prop) (h : a) : Or a b
Full source
/-- Alias for `Or.inl`. -/
theorem Or.intro_left (b : Prop) (h : a) : Or a b :=
  Or.inl h
Left Introduction for Logical Disjunction
Informal description
Given a proposition $b$ and a proof $h$ of proposition $a$, the disjunction $a \lor b$ holds.
Or.intro_right theorem
(a : Prop) (h : b) : Or a b
Full source
/-- Alias for `Or.inr`. -/
theorem Or.intro_right (a : Prop) (h : b) : Or a b :=
  Or.inr h
Right Introduction for Logical Disjunction
Informal description
Given a proposition $a$ and a proof $h$ of proposition $b$, the disjunction $a \lor b$ holds.
Or.elim theorem
{c : Prop} (h : Or a b) (left : a → c) (right : b → c) : c
Full source
/--
Proof by cases on an `Or`. If `a ∨ b`, and both `a` and `b` imply
proposition `c`, then `c` is true.
-/
theorem Or.elim {c : Prop} (h : Or a b) (left : a → c) (right : b → c) : c :=
  match h with
  | Or.inl h => left h
  | Or.inr h => right h
Proof by Cases on Disjunction
Informal description
Given a proposition $c$ and a disjunction $a \lor b$, if $a$ implies $c$ and $b$ implies $c$, then $c$ holds.
Or.resolve_left theorem
(h : Or a b) (na : Not a) : b
Full source
theorem Or.resolve_left  (h: Or a b) (na : Not a) : b := h.elim (absurd · na) id
Disjunctive Syllogism (Left)
Informal description
Given a disjunction $a \lor b$ and a proof $\neg a$ of the negation of $a$, we can conclude $b$.
Or.resolve_right theorem
(h : Or a b) (nb : Not b) : a
Full source
theorem Or.resolve_right (h: Or a b) (nb : Not b) : a := h.elim id (absurd · nb)
Disjunctive Syllogism (Right)
Informal description
Given a disjunction $a \lor b$ and a proof $\neg b$ of the negation of $b$, we can conclude $a$.
Or.neg_resolve_left theorem
(h : Or (Not a) b) (ha : a) : b
Full source
theorem Or.neg_resolve_left  (h : Or (Not a) b) (ha : a) : b := h.elim (absurd ha) id
Resolving Left Negation in Disjunction
Informal description
Given a disjunction $\neg a \lor b$ and a proof $ha : a$, we can conclude $b$.
Or.neg_resolve_right theorem
(h : Or a (Not b)) (nb : b) : a
Full source
theorem Or.neg_resolve_right (h : Or a (Not b)) (nb : b) : a := h.elim id (absurd nb)
Resolving Right Negation in Disjunction
Informal description
Given a disjunction $a \lor \neg b$ and a proof $b$, we can conclude $a$.
Bool inductive
: Type
Full source
/--
The Boolean values, `true` and `false`.

Logically speaking, this is equivalent to `Prop` (the type of propositions). The distinction is
important for programming: both propositions and their proofs are erased in the code generator,
while `Bool` corresponds to the Boolean type in most programming languages and carries precisely one
bit of run-time information.
-/
inductive Bool : Type where
  /-- The Boolean value `false`, not to be confused with the proposition `False`. -/
  | false : Bool
  /-- The Boolean value `true`, not to be confused with the proposition `True`. -/
  | true : Bool
Boolean type
Informal description
The type `Bool` represents the Boolean values `true` and `false`. While logically equivalent to `Prop` (the type of propositions), the distinction is important for programming: propositions and their proofs are erased during code generation, whereas `Bool` corresponds to the Boolean type in most programming languages and carries exactly one bit of runtime information.
Subtype structure
{α : Sort u} (p : α → Prop)
Full source
/--
All the elements of a type that satisfy a predicate.

`Subtype p`, usually written `{ x : α // p x }` or `{ x // p x }`, contains all elements `x : α` for
which `p x` is true. Its constructor is a pair of the value and the proof that it satisfies the
predicate. In run-time code, `{ x : α // p x }` is represented identically to `α`.

There is a coercion from `{ x : α // p x }` to `α`, so elements of a subtype may be used where the
underlying type is expected.

Examples:
 * `{ n : Nat // n % 2 = 0 }` is the type of even numbers.
 * `{ xs : Array String // xs.size = 5 }` is the type of arrays with five `String`s.
 * Given `xs : List α`, `List { x : α // x ∈ xs }` is the type of lists in which all elements are
   contained in `xs`.
-/
@[pp_using_anonymous_constructor]
structure Subtype {α : Sort u} (p : α → Prop) where
  /--
  The value in the underlying type that satisfies the predicate.
  -/
  val : α
  /--
  The proof that `val` satisfies the predicate `p`.
  -/
  property : p val
Subtype of a type with a predicate
Informal description
The structure `Subtype p` represents the subset of elements of type `α` that satisfy the predicate `p : α → \text{Prop}`. It is typically written as `\{x : α \mid p x\}` or `\{x \mid p x\}`. Elements of this type are pairs consisting of a value `x : α` and a proof that `p x` holds. At runtime, `Subtype p` is represented identically to `α`, and there is a coercion from `Subtype p` to `α`.
optParam definition
(α : Sort u) (default : α) : Sort u
Full source
/--
Gadget for optional parameter support.

A binder like `(x : α := default)` in a declaration is syntax sugar for
`x : optParam α default`, and triggers the elaborator to attempt to use
`default` to supply the argument if it is not supplied.
-/
@[reducible] def optParam (α : Sort u) (default : α) : Sort u := α
Optional Parameter Type
Informal description
The type `optParam α default` is used to represent optional parameters in function declarations. When a parameter is declared as `(x : α := default)`, it is syntactic sugar for `x : optParam α default`, indicating that if the argument is not provided, the default value should be used.
outParam definition
(α : Sort u) : Sort u
Full source
/--
Gadget for marking output parameters in type classes.

For example, the `Membership` class is defined as:
```
class Membership (α : outParam (Type u)) (γ : Type v)
```
This means that whenever a typeclass goal of the form `Membership ?α ?γ` comes
up, Lean will wait to solve it until `?γ` is known, but then it will run
typeclass inference, and take the first solution it finds, for any value of `?α`,
which thereby determines what `?α` should be.

This expresses that in a term like `a ∈ s`, `s` might be a `Set α` or
`List α` or some other type with a membership operation, and in each case
the "member" type `α` is determined by looking at the container type.
-/
@[reducible] def outParam (α : Sort u) : Sort u := α
Output parameter marker for type classes
Informal description
A type annotation used to mark output parameters in type classes. For example, in the `Membership` class, the type `α` is marked as an `outParam`, meaning that when solving a typeclass goal `Membership ?α ?γ`, Lean will wait until `?γ` is known and then determine `?α` from the first solution found during typeclass inference. This allows the member type `α` to be inferred from the container type `γ` in expressions like `a ∈ s`.
semiOutParam definition
(α : Sort u) : Sort u
Full source
/--
Gadget for marking semi output parameters in type classes.

Semi-output parameters influence the order in which arguments to type class
instances are processed.  Lean determines an order where all non-(semi-)output
parameters to the instance argument have to be figured out before attempting to
synthesize an argument (that is, they do not contain assignable metavariables
created during TC synthesis). This rules out instances such as `[Mul β] : Add
α` (because `β` could be anything). Marking a parameter as semi-output is a
promise that instances of the type class will always fill in a value for that
parameter.

For example, the `Coe` class is defined as:
```
class Coe (α : semiOutParam (Sort u)) (β : Sort v)
```
This means that all `Coe` instances should provide a concrete value for `α`
(i.e., not an assignable metavariable). An instance like `Coe Nat Int` or `Coe
α (Option α)` is fine, but `Coe α Nat` is not since it does not provide a value
for `α`.
-/
@[reducible] def semiOutParam (α : Sort u) : Sort u := α
Semi-output parameter marker
Informal description
A gadget for marking semi-output parameters in type classes. A semi-output parameter is one that influences the order of processing arguments in type class instance resolution, with the guarantee that instances will always provide a concrete value for this parameter (not an assignable metavariable during type class synthesis).
namedPattern definition
{α : Sort u} (x a : α) (h : Eq x a) : α
Full source
/-- Auxiliary declaration used to implement named patterns like `x@h:p`. -/
@[reducible] def namedPattern {α : Sort u} (x a : α) (h : Eq x a) : α := a
Named pattern auxiliary function
Informal description
The auxiliary function `namedPattern` is used to implement named patterns of the form `x@h:p` in pattern matching. Given elements `x` and `a` of type `α` and a proof `h` that `x = a`, it returns `a`. This allows binding both the matched value and the proof of its equality to names in a pattern match.
sorryAx axiom
(α : Sort u) (synthetic : Bool) : α
Full source
/--
Auxiliary axiom used to implement the `sorry` term and tactic.

The `sorry` term/tactic expands to `sorryAx _ (synthetic := false)`.
It is intended for stubbing-out incomplete parts of a value or proof while still having a syntactically correct skeleton.
Lean will give a warning whenever a declaration uses `sorry`, so you aren't likely to miss it,
but you can check if a declaration depends on `sorry` either directly or indirectly by looking for `sorryAx` in the output
of the `#print axioms my_thm` command.

The `synthetic` flag is false when a `sorry` is written explicitly by the user, but it is
set to `true` when a tactic fails to prove a goal, or if there is a type error
in the expression. A synthetic `sorry` acts like a regular one, except that it
suppresses follow-up errors in order to prevent an error from causing a cascade
of other errors because the desired term was not constructed.
-/
@[extern "lean_sorry", never_extract]
axiom sorryAx (α : Sort u) (synthetic : Bool) : α
Axiom for Incomplete Definitions and Proofs (`sorryAx`)
Informal description
The axiom `sorryAx` is a placeholder for incomplete definitions or proofs. Given a type `α` and a Boolean flag `synthetic`, it returns an element of type `α`. The `synthetic` flag distinguishes between explicit user-written `sorry` (when `false`) and automatically generated placeholders from failed tactics or type errors (when `true`), with the latter suppressing cascading errors.
ne_false_of_eq_true theorem
: {b : Bool} → Eq b true → Not (Eq b false)
Full source
theorem ne_false_of_eq_true : {b : Bool} → Eq b trueNot (Eq b false)
  | true, _  => fun h => Bool.noConfusion h
  | false, h => Bool.noConfusion h
$\mathtt{true} \neq \mathtt{false}$ for Booleans
Informal description
For any Boolean value $b$, if $b$ is equal to $\mathtt{true}$, then $b$ is not equal to $\mathtt{false}$.
ne_true_of_eq_false theorem
: {b : Bool} → Eq b false → Not (Eq b true)
Full source
theorem ne_true_of_eq_false : {b : Bool} → Eq b falseNot (Eq b true)
  | true, h  => Bool.noConfusion h
  | false, _ => fun h => Bool.noConfusion h
False Boolean is Not True
Informal description
For any Boolean value $b$, if $b$ is equal to $\text{false}$, then $b$ is not equal to $\text{true}$.
Inhabited structure
(α : Sort u)
Full source
/--
`Inhabited α` is a typeclass that says that `α` has a designated element,
called `(default : α)`. This is sometimes referred to as a "pointed type".

This class is used by functions that need to return a value of the type
when called "out of domain". For example, `Array.get! arr i : α` returns
a value of type `α` when `arr : Array α`, but if `i` is not in range of
the array, it reports a panic message, but this does not halt the program,
so it must still return a value of type `α` (and in fact this is required
for logical consistency), so in this case it returns `default`.
-/
class Inhabited (α : Sort u) where
  /-- `default` is a function that produces a "default" element of any
  `Inhabited` type. This element does not have any particular specified
  properties, but it is often an all-zeroes value. -/
  default : α
Inhabited type
Informal description
The typeclass `Inhabited α` asserts that the type `α` has a designated element called `default : α`. This is used by functions that need to return a value of type `α` even when called outside their intended domain, ensuring logical consistency.
Nonempty classInductive
(α : Sort u) : Prop
Full source
/--
`Nonempty α` is a typeclass that says that `α` is not an empty type,
that is, there exists an element in the type. It differs from `Inhabited α`
in that `Nonempty α` is a `Prop`, which means that it does not actually carry
an element of `α`, only a proof that *there exists* such an element.
Given `Nonempty α`, you can construct an element of `α` *nonconstructively*
using `Classical.choice`.
-/
class inductive Nonempty (α : Sort u) : Prop where
  /-- If `val : α`, then `α` is nonempty. -/
  | intro (val : α) : Nonempty α
Nonempty Type
Informal description
The typeclass `Nonempty α` asserts that the type `α` is not empty, meaning there exists at least one element in `α`. Unlike `Inhabited α`, which provides a specific element of `α`, `Nonempty α` only guarantees the existence of such an element and is a proposition (i.e., a `Prop`). Given `Nonempty α`, one can nonconstructively obtain an element of `α` using `Classical.choice`.
Classical.choice axiom
{α : Sort u} : Nonempty α → α
Full source
/--
**The axiom of choice**. `Nonempty α` is a proof that `α` has an element,
but the element itself is erased. The axiom `choice` supplies a particular
element of `α` given only this proof.

The textbook axiom of choice normally makes a family of choices all at once,
but that is implied from this formulation, because if `α : ι → Type` is a
family of types and `h : ∀ i, Nonempty (α i)` is a proof that they are all
nonempty, then `fun i => Classical.choice (h i) : ∀ i, α i` is a family of
chosen elements. This is actually a bit stronger than the ZFC choice axiom;
this is sometimes called "[global choice](https://en.wikipedia.org/wiki/Axiom_of_global_choice)".

In Lean, we use the axiom of choice to derive the law of excluded middle
(see `Classical.em`), so it will often show up in axiom listings where you
may not expect. You can use `#print axioms my_thm` to find out if a given
theorem depends on this or other axioms.

This axiom can be used to construct "data", but obviously there is no algorithm
to compute it, so Lean will require you to mark any definition that would
involve executing `Classical.choice` or other axioms as `noncomputable`, and
will not produce any executable code for such definitions.
-/
axiom Classical.choice {α : Sort u} : Nonempty α → α
Axiom of Choice (Global Version)
Informal description
Given a nonempty type $\alpha$ (i.e., a type for which we have a proof that it contains at least one element), the axiom of choice provides a function that selects an arbitrary element of $\alpha$.
Nonempty.elim theorem
{α : Sort u} {p : Prop} (h₁ : Nonempty α) (h₂ : α → p) : p
Full source
/--
The elimination principle for `Nonempty α`. If `Nonempty α`, and we can
prove `p` given any element `x : α`, then `p` holds. Note that it is essential
that `p` is a `Prop` here; the version with `p` being a `Sort u` is equivalent
to `Classical.choice`.
-/
protected theorem Nonempty.elim {α : Sort u} {p : Prop} (h₁ : Nonempty α) (h₂ : α → p) : p :=
  match h₁ with
  | intro a => h₂ a
Nonempty Elimination Principle
Informal description
For any type $\alpha$ and proposition $p$, if $\alpha$ is nonempty (i.e., $\text{Nonempty }\alpha$) and for every element $x \in \alpha$ we have $p$ holds (i.e., $x \rightarrow p$), then $p$ holds.
instNonemptyOfInhabited instance
{α : Sort u} [Inhabited α] : Nonempty α
Full source
instance {α : Sort u} [Inhabited α] : Nonempty α :=
  ⟨default⟩
Inhabited Types are Nonempty
Informal description
For any inhabited type $\alpha$ (i.e., a type with a designated default element), $\alpha$ is nonempty.
Classical.ofNonempty definition
{α : Sort u} [Nonempty α] : α
Full source
/--
A variation on `Classical.choice` that uses typeclass inference to
infer the proof of `Nonempty α`.
-/
noncomputable def Classical.ofNonempty {α : Sort u} [Nonempty α] : α :=
  Classical.choice inferInstance
Nonconstructive choice from a nonempty type
Informal description
Given a nonempty type $\alpha$ (i.e., `[Nonempty α]`), this function nonconstructively selects an element of $\alpha$ using typeclass inference to obtain the proof of nonemptiness.
instNonemptyForall instance
{α : Sort u} {β : Sort v} [Nonempty β] : Nonempty (α → β)
Full source
instance {α : Sort u} {β : Sort v} [Nonempty β] : Nonempty (α → β) :=
  Nonempty.intro fun _ => Classical.ofNonempty
Nonemptiness of Function Types from Nonempty Codomain
Informal description
For any types $\alpha$ and $\beta$, if $\beta$ is nonempty, then the function type $\alpha \to \beta$ is also nonempty.
Pi.instNonempty instance
{α : Sort u} {β : α → Sort v} [(a : α) → Nonempty (β a)] : Nonempty ((a : α) → β a)
Full source
instance Pi.instNonempty {α : Sort u} {β : α → Sort v} [(a : α) → Nonempty (β a)] :
    Nonempty ((a : α) → β a) :=
  Nonempty.intro fun _ => Classical.ofNonempty
Nonemptiness of Dependent Function Types
Informal description
For any family of types $\beta : \alpha \to \text{Sort } v$ indexed by $\alpha$, if each $\beta(a)$ is nonempty, then the dependent function type $\prod_{a : \alpha} \beta(a)$ is also nonempty.
instInhabitedSort instance
: Inhabited (Sort u)
Full source
instance : Inhabited (Sort u) where
  default := PUnit
Inhabitedness of Universe Types
Informal description
For any universe level $u$, the type `Sort u` is inhabited.
instInhabitedForall instance
(α : Sort u) {β : Sort v} [Inhabited β] : Inhabited (α → β)
Full source
instance (α : Sort u) {β : Sort v} [Inhabited β] : Inhabited (α → β) where
  default := fun _ => default
Inhabitedness of Function Types
Informal description
For any types $\alpha$ and $\beta$, if $\beta$ is inhabited, then the function type $\alpha \to \beta$ is also inhabited.
Pi.instInhabited instance
{α : Sort u} {β : α → Sort v} [(a : α) → Inhabited (β a)] : Inhabited ((a : α) → β a)
Full source
instance Pi.instInhabited {α : Sort u} {β : α → Sort v} [(a : α) → Inhabited (β a)] :
    Inhabited ((a : α) → β a) where
  default := fun _ => default
Inhabitedness of Dependent Function Types
Informal description
For any type family $\beta$ indexed by $\alpha$, if each fiber $\beta(a)$ is inhabited, then the dependent function type $(a : \alpha) \to \beta(a)$ is also inhabited.
instInhabitedBool instance
: Inhabited✝ (@Bool)
Full source
Inhabited for Bool
Inhabitedness of the Boolean Type
Informal description
The Boolean type $\mathtt{Bool}$ is inhabited, with $\mathtt{false}$ as its default element.
PLift structure
(α : Sort u)
Full source
/--
Lifts a proposition or type to a higher universe level.

`PLift α` wraps a proof or value of type `α`. The resulting type is in the next largest universe
after that of `α`. In particular, propositions become data.

The related type `ULift` can be used to lift a non-proposition type by any number of levels.

Examples:
 * `(False : Prop)`
 * `(PLift False : Type)`
 * `([.up (by trivial), .up (by simp), .up (by decide)] : List (PLift True))`
 * `(Nat : Type 0)`
 * `(PLift Nat : Type 1)`
-/
structure PLift (α : Sort u) : Type u where
  /-- Wraps a proof or value to increase its type's universe level by 1. -/
  up ::
  /-- Extracts a wrapped proof or value from a universe-lifted proposition or type. -/
  down : α
Universe lifting of propositions and types
Informal description
The structure `PLift α` lifts a proposition or type `α` to a higher universe level. It wraps a proof or value of type `α`, resulting in a type in the next largest universe after that of `α`. In particular, propositions become data when lifted with `PLift`.
PLift.up_down theorem
{α : Sort u} (b : PLift α) : Eq (up (down b)) b
Full source
/-- Bijection between `α` and `PLift α` -/
theorem PLift.up_down {α : Sort u} (b : PLift α) : Eq (up (down b)) b := rfl
Unlifting-Lifting Identity: $\mathrm{up}(\mathrm{down}(b)) = b$
Informal description
For any element $b$ of the lifted type $\mathrm{PLift}\,\alpha$, the composition of the unlifting operation $\mathrm{down}$ followed by the lifting operation $\mathrm{up}$ returns the original element $b$, i.e., $\mathrm{up}(\mathrm{down}(b)) = b$.
PLift.down_up theorem
{α : Sort u} (a : α) : Eq (down (up a)) a
Full source
/-- Bijection between `α` and `PLift α` -/
theorem PLift.down_up {α : Sort u} (a : α) : Eq (down (up a)) a := rfl
Lifting-Unlifting Identity: $\operatorname{down}(\operatorname{up}(a)) = a$
Informal description
For any element $a$ of type $\alpha$, the composition of the lifting operation $\operatorname{up}$ followed by the unlifting operation $\operatorname{down}$ returns the original element $a$, i.e., $\operatorname{down}(\operatorname{up}(a)) = a$.
NonemptyType definition
Full source
/--
`NonemptyType.{u}` is the type of nonempty types in universe `u`.
It is mainly used in constant declarations where we wish to introduce a type
and simultaneously assert that it is nonempty, but otherwise make the type
opaque.
-/
def NonemptyType := Subtype fun α : Type u => Nonempty α
Nonempty Type
Informal description
The type `NonemptyType.{u}` represents the collection of all nonempty types in universe `u`. It is defined as the subtype of `Type u` consisting of types `α` for which `Nonempty α` holds, meaning there exists at least one element in `α`. This is primarily used in constant declarations where we want to introduce a type and simultaneously assert its nonemptiness without exposing its specific structure.
NonemptyType.type abbrev
(type : NonemptyType.{u}) : Type u
Full source
/-- The underlying type of a `NonemptyType`. -/
abbrev NonemptyType.type (type : NonemptyTypeNonemptyType.{u}) : Type u :=
  type.val
Underlying Type of a Nonempty Type
Informal description
For any nonempty type `type` (an element of `NonemptyType.{u}`), the function `NonemptyType.type` returns the underlying type `Type u` associated with `type`.
instInhabitedNonemptyType instance
: Inhabited NonemptyType.{u}
Full source
/-- `NonemptyType` is inhabited, because `PUnit` is a nonempty type. -/
instance : Inhabited NonemptyTypeNonemptyType.{u} where
  default := ⟨PUnit, ⟨⟨⟩⟩⟩
Inhabited Nonempty Types
Informal description
The type `NonemptyType.{u}` of all nonempty types in universe `u` is itself inhabited, with the singleton type `PUnit` serving as a canonical example of a nonempty type.
ULift structure
(α : Type s)
Full source
/--
Lifts a type to a higher universe level.

`ULift α` wraps a value of type `α`. Instead of occupying the same universe as `α`, which would be
the minimal level, it takes a further level parameter and occupies their minimum. The resulting type
may occupy any universe that's at least as large as that of `α`.

The resulting universe of the lifting operator is the first parameter, and may be written explicitly
while allowing `α`'s level to be inferred.

The related type `PLift` can be used to lift a proposition or type by one level.

Examples:
 * `(Nat : Type 0)`
 * `(ULift Nat : Type 0)`
 * `(ULift Nat : Type 1)`
 * `(ULift Nat : Type 5)`
 * `(ULift.{7} (PUnit : Type 3) : Type 7)`
-/
-- The universe variable `r` is written first so that `ULift.{r} α` can be used
-- when `s` can be inferred from the type of `α`.
structure ULift.{r, s} (α : Type s) : Type (max s r) where
  /-- Wraps a value to increase its type's universe level. -/
  up ::
  /-- Extracts a wrapped value from a universe-lifted type. -/
  down : α
Universe Lift
Informal description
The structure `ULift α` represents a type that lifts a given type `α` to a higher universe level. It wraps a value of type `α` and allows it to exist in any universe level that is at least as large as the universe level of `α`. This is useful when working with types that need to be in a higher universe for certain operations or constructions.
ULift.up_down theorem
{α : Type u} (b : ULift.{v} α) : Eq (up (down b)) b
Full source
/-- Bijection between `α` and `ULift.{v} α` -/
theorem ULift.up_down {α : Type u} (b : ULift.{v} α) : Eq (up (down b)) b := rfl
Universe Lift-Unlift Identity: $\mathrm{up} \circ \mathrm{down} = \mathrm{id}$
Informal description
For any type $\alpha$ and any element $b$ in the universe-lifted type $\mathrm{ULift}_{\nu} \alpha$, the composition of the lifting and unlifting operations satisfies $\mathrm{up}(\mathrm{down}(b)) = b$.
ULift.down_up theorem
{α : Type u} (a : α) : Eq (down (up.{v} a)) a
Full source
/-- Bijection between `α` and `ULift.{v} α` -/
theorem ULift.down_up {α : Type u} (a : α) : Eq (down (up.{v} a)) a := rfl
Universe Lift-Unlift Identity: $\mathrm{down} \circ \mathrm{up} = \mathrm{id}$
Informal description
For any type $\alpha$ and any element $a \in \alpha$, the unlifting of the lifted element equals $a$, i.e., $\mathrm{down}(\mathrm{up}(a)) = a$.
Decidable classInductive
(p : Prop)
Full source
/--
Either a proof that `p` is true or a proof that `p` is false. This is equivalent to a `Bool` paired
with a proof that the `Bool` is `true` if and only if `p` is true.

`Decidable` instances are primarily used via `if`-expressions and the tactic `decide`. In
conditional expressions, the `Decidable` instance for the proposition is used to select a branch. At
run time, this case distinction code is identical to that which would be generated for a
`Bool`-based conditional. In proofs, the tactic `decide` synthesizes an instance of `Decidable p`,
attempts to reduce it to `isTrue h`, and then succeeds with the proof `h` if it can.

Because `Decidable` carries data, when writing `@[simp]` lemmas which include a `Decidable` instance
on the LHS, it is best to use `{_ : Decidable p}` rather than `[Decidable p]` so that non-canonical
instances can be found via unification rather than instance synthesis.
-/
class inductive Decidable (p : Prop) where
  /-- Proves that `p` is decidable by supplying a proof of `¬p` -/
  | isFalse (h : Not p) : Decidable p
  /-- Proves that `p` is decidable by supplying a proof of `p` -/
  | isTrue (h : p) : Decidable p
Decidable Proposition
Informal description
A typeclass `Decidable p` represents a constructive proof that a proposition `p` is either true or false. It consists of either a proof that `p` holds (`isTrue`) or a proof that `¬p` holds (`isFalse`). This is equivalent to having a boolean value together with a proof that the boolean is `true` if and only if `p` is true. Instances of `Decidable` are primarily used in `if`-expressions and the `decide` tactic. In conditional expressions, the `Decidable` instance for the proposition determines which branch to take. At runtime, this behaves like a standard boolean-based conditional. In proofs, the `decide` tactic synthesizes a `Decidable` instance, attempts to reduce it to `isTrue h`, and succeeds with proof `h` if possible.
Decidable.decide definition
(p : Prop) [h : Decidable p] : Bool
Full source
/--
Converts a decidable proposition into a `Bool`.

If `p : Prop` is decidable, then `decide p : Bool` is the Boolean value
that is `true` if `p` is true and `false` if `p` is false.
-/
@[inline_if_reduce, nospecialize] def Decidable.decide (p : Prop) [h : Decidable p] : Bool :=
  h.casesOn (fun _ => false) (fun _ => true)
Decidable proposition to boolean conversion
Informal description
Given a decidable proposition $p$, the function returns `true` if $p$ is true and `false` if $p$ is false.
DecidablePred abbrev
{α : Sort u} (r : α → Prop)
Full source
/--
A decidable predicate.

A predicate is decidable if the corresponding proposition is `Decidable` for each possible argument.
-/
abbrev DecidablePred {α : Sort u} (r : α → Prop) :=
  (a : α) → Decidable (r a)
Decidable Predicate
Informal description
A predicate $r$ on a type $\alpha$ is called *decidable* if for every element $x \in \alpha$, the proposition $r(x)$ is decidable (i.e., it can be constructively determined whether $r(x)$ holds or not).
DecidableRel abbrev
{α : Sort u} {β : Sort v} (r : α → β → Prop)
Full source
/--
A decidable relation.

A relation is decidable if the corresponding proposition is `Decidable` for all possible arguments.
-/
abbrev DecidableRel {α : Sort u} {β : Sort v} (r : α → β → Prop) :=
  (a : α) → (b : β) → Decidable (r a b)
Decidable Binary Relation
Informal description
A binary relation $r : \alpha \to \beta \to \mathrm{Prop}$ is called *decidable* if for every pair $(a, b) \in \alpha \times \beta$, the proposition $r(a, b)$ is decidable (i.e., it can be constructively determined whether $r(a, b)$ holds or not).
DecidableEq abbrev
(α : Sort u)
Full source
/--
Propositional equality is `Decidable` for all elements of a type.

In other words, an instance of `DecidableEq α` is a means of deciding the proposition `a = b` is
for all `a b : α`.
-/
abbrev DecidableEq (α : Sort u) :=
  (a b : α) → Decidable (Eq a b)
Decidable Equality Type
Informal description
A type $\alpha$ has decidable equality if for any two elements $a, b \in \alpha$, the proposition $a = b$ is decidable (i.e., it can be constructively determined whether $a = b$ holds or not).
decEq definition
{α : Sort u} [inst : DecidableEq α] (a b : α) : Decidable (Eq a b)
Full source
/--
Checks whether two terms of a type are equal using the type's `DecidableEq` instance.
-/
def decEq {α : Sort u} [inst : DecidableEq α] (a b : α) : Decidable (Eq a b) :=
  inst a b
Decidable equality check
Informal description
Given a type $\alpha$ with decidable equality and two elements $a, b \in \alpha$, the function `decEq` returns a `Decidable` instance for the proposition $a = b$, which can be used to constructively determine whether $a$ and $b$ are equal.
decide_eq_true theorem
: [inst : Decidable p] → p → Eq (decide p) true
Full source
theorem decide_eq_true : [inst : Decidable p] → p → Eq (decide p) true
  | isTrue  _, _   => rfl
  | isFalse h₁, h₂ => absurd h₂ h₁
Deciding a True Proposition Yields True
Informal description
For any decidable proposition $p$, if $p$ holds, then the boolean value obtained by deciding $p$ is equal to `true`.
decide_eq_false theorem
: [Decidable p] → Not p → Eq (decide p) false
Full source
theorem decide_eq_false : [Decidable p] → Not p → Eq (decide p) false
  | isTrue  h₁, h₂ => absurd h₁ h₂
  | isFalse _, _   => rfl
Decidable Proposition to False Evaluation: $\neg p \to \text{decide}(p) = \text{false}$
Informal description
For any decidable proposition $p$, if $\neg p$ holds, then the boolean evaluation of $p$ (via `decide p`) is equal to `false`.
of_decide_eq_true theorem
[inst : Decidable p] : Eq (decide p) true → p
Full source
theorem of_decide_eq_true [inst : Decidable p] : Eq (decide p) true → p := fun h =>
  match (generalizing := false) inst with
  | isTrue  h₁ => h₁
  | isFalse h₁ => absurd h (ne_true_of_eq_false (decide_eq_false h₁))
Decidable Proposition from True Evaluation: $\text{decide}(p) = \text{true} \to p$
Informal description
For any decidable proposition $p$, if the boolean evaluation of $p$ (via `decide p`) is equal to `true`, then $p$ holds.
of_decide_eq_false theorem
[inst : Decidable p] : Eq (decide p) false → Not p
Full source
theorem of_decide_eq_false [inst : Decidable p] : Eq (decide p) falseNot p := fun h =>
  match (generalizing := false) inst with
  | isTrue  h₁ => absurd h (ne_false_of_eq_true (decide_eq_true h₁))
  | isFalse h₁ => h₁
False Evaluation Implies Negation: $\text{decide}(p) = \text{false} \to \neg p$
Informal description
For any decidable proposition $p$, if the boolean evaluation of $p$ (via `decide p`) is equal to `false`, then $\neg p$ holds.
of_decide_eq_self_eq_true theorem
[inst : DecidableEq α] (a : α) : Eq (decide (Eq a a)) true
Full source
theorem of_decide_eq_self_eq_true [inst : DecidableEq α] (a : α) : Eq (decide (Eq a a)) true :=
  match (generalizing := false) inst a a with
  | isTrue  _  => rfl
  | isFalse h₁ => absurd rfl h₁
Decidable Equality Reflexivity Yields True
Informal description
For any type $\alpha$ with decidable equality and any element $a \in \alpha$, the decision procedure for the equality $a = a$ evaluates to `true`.
Bool.decEq definition
(a b : Bool) : Decidable (Eq a b)
Full source
/--
Decides whether two Booleans are equal.

This function should normally be called via the `DecidableEq Bool` instance that it exists to
support.
-/
@[inline] def Bool.decEq (a b : Bool) : Decidable (Eq a b) :=
   match a, b with
   | false, false => isTrue rfl
   | false, true  => isFalse (fun h => Bool.noConfusion h)
   | true, false  => isFalse (fun h => Bool.noConfusion h)
   | true, true   => isTrue rfl
Decidability of boolean equality
Informal description
The function `Bool.decEq` takes two boolean values `a` and `b` and returns a constructive proof that `a = b` is either true or false. Specifically: - If both `a` and `b` are `false`, it returns a proof that `false = false` (via `isTrue rfl`). - If one is `false` and the other is `true`, it returns a proof that `false = true` is false (via `isFalse`). - If both are `true`, it returns a proof that `true = true` (via `isTrue rfl`). This function is used to support the `DecidableEq Bool` instance, enabling boolean equality checks in `if` expressions and other decidability-based constructs.
instDecidableEqBool instance
: DecidableEq Bool
Full source
@[inline] instance : DecidableEq Bool :=
   Bool.decEq
Decidable Equality for Boolean Type
Informal description
The boolean type $\mathtt{Bool}$ has decidable equality, meaning that for any two boolean values $a$ and $b$, the equality $a = b$ can be constructively decided.
BEq structure
(α : Type u)
Full source
/--
`BEq α` is a typeclass for supplying a boolean-valued equality relation on
`α`, notated as `a == b`. Unlike `DecidableEq α` (which uses `a = b`), this
is `Bool` valued instead of `Prop` valued, and it also does not have any
axioms like being reflexive or agreeing with `=`. It is mainly intended for
programming applications. See `LawfulBEq` for a version that requires that
`==` and `=` coincide.

Typically we prefer to put the "more variable" term on the left,
and the "more constant" term on the right.
-/
class BEq (α : Type u) where
  /-- Boolean equality, notated as `a == b`. -/
  beq : α → α → Bool
Boolean Equality Structure
Informal description
The structure `BEq α` provides a boolean-valued equality relation `==` on the type `α`. Unlike the propositional equality `=`, this relation returns a boolean value (`true` or `false`) and does not require any axioms such as reflexivity or agreement with `=`. It is primarily intended for programming applications. A variant `LawfulBEq` enforces that `==` and `=` coincide.
instBEqOfDecidableEq instance
[DecidableEq α] : BEq α
Full source
instance [DecidableEq α] : BEq α where
  beq a b := decide (Eq a b)
Boolean Equality from Decidable Equality
Informal description
For any type $\alpha$ with decidable equality, there is a boolean equality structure on $\alpha$ where the boolean equality operator `==` coincides with the decidable equality.
dite definition
{α : Sort u} (c : Prop) [h : Decidable c] (t : c → α) (e : Not c → α) : α
Full source
/--
"Dependent" if-then-else, normally written via the notation `if h : c then t(h) else e(h)`,
is sugar for `dite c (fun h => t(h)) (fun h => e(h))`, and it is the same as
`if c then t else e` except that `t` is allowed to depend on a proof `h : c`,
and `e` can depend on `h : ¬c`. (Both branches use the same name for the hypothesis,
even though it has different types in the two cases.)

We use this to be able to communicate the if-then-else condition to the branches.
For example, `Array.get arr i h` expects a proof `h : i < arr.size` in order to
avoid a bounds check, so you can write `if h : i < arr.size then arr.get i h else ...`
to avoid the bounds check inside the if branch. (Of course in this case we have only
lifted the check into an explicit `if`, but we could also use this proof multiple times
or derive `i < arr.size` from some other proposition that we are checking in the `if`.)
-/
@[macro_inline] def dite {α : Sort u} (c : Prop) [h : Decidable c] (t : c → α) (e : Not c → α) : α :=
  h.casesOn e t
Dependent if-then-else
Informal description
The dependent if-then-else function, denoted `dite`, takes a decidable proposition `c`, a function `t` that produces a result given a proof of `c`, and a function `e` that produces a result given a proof of `¬c`. It returns the result of `t` applied to the proof of `c` if `c` is true, and the result of `e` applied to the proof of `¬c` otherwise. This allows the branches to depend on the proof of the condition.
ite definition
{α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α
Full source
/--
`if c then t else e` is notation for `ite c t e`, "if-then-else", which decides to
return `t` or `e` depending on whether `c` is true or false. The explicit argument
`c : Prop` does not have any actual computational content, but there is an additional
`[Decidable c]` argument synthesized by typeclass inference which actually
determines how to evaluate `c` to true or false. Write `if h : c then t else e`
instead for a "dependent if-then-else" `dite`, which allows `t`/`e` to use the fact
that `c` is true/false.
-/
/-
Because Lean uses a strict (call-by-value) evaluation strategy, the signature of this
function is problematic in that it would require `t` and `e` to be evaluated before
calling the `ite` function, which would cause both sides of the `if` to be evaluated.
Even if the result is discarded, this would be a big performance problem,
and is undesirable for users in any case. To resolve this, `ite` is marked as
`@[macro_inline]`, which means that it is unfolded during code generation, and
the definition of the function uses `fun _ => t` and `fun _ => e` so this recovers
the expected "lazy" behavior of `if`: the `t` and `e` arguments delay evaluation
until `c` is known.
-/
@[macro_inline] def ite {α : Sort u} (c : Prop) [h : Decidable c] (t e : α) : α :=
  h.casesOn (fun _ => e) (fun _ => t)
If-then-else conditional expression
Informal description
The expression `if c then t else e` is a conditional construct that evaluates to `t` when the proposition `c` is true and to `e` when `c` is false. The decision of which branch to take is determined by a typeclass instance `[Decidable c]`, which provides a constructive proof that `c` is either true or false. The proposition `c` itself does not carry computational content, but the `Decidable` instance is used to guide the evaluation.
instDecidableAnd instance
{p q} [dp : Decidable p] [dq : Decidable q] : Decidable (And p q)
Full source
@[macro_inline] instance {p q} [dp : Decidable p] [dq : Decidable q] : Decidable (And p q) :=
  match dp with
  | isTrue  hp =>
    match dq with
    | isTrue hq  => isTrue ⟨hp, hq⟩
    | isFalse hq => isFalse (fun h => hq (And.right h))
  | isFalse hp =>
    isFalse (fun h => hp (And.left h))
Decidability of Conjunction
Informal description
For any two propositions $p$ and $q$, if both $p$ and $q$ are decidable (i.e., there is a constructive proof that each is either true or false), then their conjunction $p \land q$ is also decidable.
instDecidableOr instance
[dp : Decidable p] [dq : Decidable q] : Decidable (Or p q)
Full source
@[macro_inline] instance [dp : Decidable p] [dq : Decidable q] : Decidable (Or p q) :=
  match dp with
  | isTrue  hp => isTrue (Or.inl hp)
  | isFalse hp =>
    match dq with
    | isTrue hq  => isTrue (Or.inr hq)
    | isFalse hq =>
      isFalse fun h => match h with
        | Or.inl h => hp h
        | Or.inr h => hq h
Decidability of Disjunction
Informal description
For any two propositions $p$ and $q$, if both $p$ and $q$ are decidable (i.e., there is a constructive proof that each is either true or false), then their disjunction $p \lor q$ is also decidable.
instDecidableNot instance
[dp : Decidable p] : Decidable (Not p)
Full source
instance [dp : Decidable p] : Decidable (Not p) :=
  match dp with
  | isTrue hp  => isFalse (absurd hp)
  | isFalse hp => isTrue hp
Decidability of Negation
Informal description
For any decidable proposition $p$, the negation $\neg p$ is also decidable.
cond definition
{α : Sort u} (c : Bool) (x y : α) : α
Full source
/--
The conditional function.

`cond c x y` is the same as `if c then x else y`, but optimized for a Boolean condition rather than
a decidable proposition. It can also be written using the notation `bif c then x else y`.

Just like `ite`, `cond` is declared `@[macro_inline]`, which causes applications of `cond` to be
unfolded. As a result, `x` and `y` are not evaluated at runtime until one of them is selected, and
only the selected branch is evaluated.
-/
@[macro_inline] def cond {α : Sort u} (c : Bool) (x y : α) : α :=
  match c with
  | true  => x
  | false => y
Boolean conditional function
Informal description
The function `cond` takes a Boolean condition `c` and two values `x` and `y` of the same type, and returns `x` if `c` is true and `y` if `c` is false. This is equivalent to `if c then x else y` but optimized for Boolean conditions rather than decidable propositions. The function is inlined, meaning that `x` and `y` are not evaluated until one of them is selected, and only the selected branch is evaluated.
Bool.dcond definition
{α : Sort u} (c : Bool) (x : Eq c true → α) (y : Eq c false → α) : α
Full source
/--
The dependent conditional function, in which each branch is provided with a local assumption about
the condition's value. This allows the value to be used in proofs as well as for control flow.

`dcond c (fun h => x) (fun h => y)` is the same as `if h : c then x else y`, but optimized for a
Boolean condition rather than a decidable proposition. Unlike the non-dependent version `cond`,
there is no special notation for `dcond`.

Just like `ite`, `dite`, and `cond`, `dcond` is declared `@[macro_inline]`, which causes
applications of `dcond` to be unfolded. As a result, `x` and `y` are not evaluated at runtime until
one of them is selected, and only the selected branch is evaluated. `dcond` is intended for
metaprogramming use, rather than for use in verified programs, so behavioral lemmas are not
provided.
-/
@[macro_inline]
protected def Bool.dcond {α : Sort u} (c : Bool) (x : Eq c true → α) (y : Eq c false → α) : α :=
  match c with
  | true  => x rfl
  | false => y rfl
Dependent Boolean conditional function
Informal description
The dependent conditional function `Bool.dcond` takes a Boolean condition `c` and two branches `x` and `y`, where each branch is provided with a proof that `c` is either `true` or `false`, respectively. It returns the result of evaluating `x` if `c` is `true` (with a proof that `c = true`) or `y` if `c` is `false` (with a proof that `c = false`). This function is optimized for Boolean conditions and is inlined during compilation, ensuring that only the selected branch is evaluated at runtime.
Bool.or definition
(x y : Bool) : Bool
Full source
/--
Boolean “or”, also known as disjunction. `or x y` can be written `x || y`.

The corresponding propositional connective is `Or : Prop → Prop → Prop`, written with the `∨`
operator.

The Boolean `or` is a `@[macro_inline]` function in order to give it short-circuiting evaluation:
if `x` is `true` then `y` is not evaluated at runtime.
-/
@[macro_inline] def Bool.or (x y : Bool) : Bool :=
  match x with
  | true  => true
  | false => y
Boolean disjunction (OR)
Informal description
The Boolean disjunction function, written as `x || y`, returns `true` if either `x` or `y` is `true`, and `false` otherwise. The function is short-circuiting: if `x` is `true`, `y` is not evaluated.
Bool.and definition
(x y : Bool) : Bool
Full source
/--
Boolean “and”, also known as conjunction. `and x y` can be written `x && y`.

The corresponding propositional connective is `And : Prop → Prop → Prop`, written with the `∧`
operator.

The Boolean `and` is a `@[macro_inline]` function in order to give it short-circuiting evaluation:
if `x` is `false` then `y` is not evaluated at runtime.
-/
@[macro_inline] def Bool.and (x y : Bool) : Bool :=
  match x with
  | false => false
  | true  => y
Boolean conjunction (AND)
Informal description
The Boolean conjunction function, written as `x && y`, returns `true` if both `x` and `y` are `true`, and `false` otherwise. The function is short-circuiting: if `x` is `false`, `y` is not evaluated.
Bool.not definition
: Bool → Bool
Full source
/--
Boolean negation, also known as Boolean complement. `not x` can be written `!x`.

This is a function that maps the value `true` to `false` and the value `false` to `true`. The
propositional connective is `Not : Prop → Prop`.
-/
@[inline] def Bool.not : BoolBool
  | true  => false
  | false => true
Boolean negation
Informal description
The Boolean negation function, denoted by `¬x` or `!x`, maps `true` to `false` and `false` to `true`.
Nat inductive
Full source
/--
The natural numbers, starting at zero.

This type is special-cased by both the kernel and the compiler, and overridden with an efficient
implementation. Both use a fast arbitrary-precision arithmetic library (usually
[GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.
-/
inductive Nat where
  /--
  Zero, the smallest natural number.

  Using `Nat.zero` explicitly should usually be avoided in favor of the literal `0`, which is the
  [simp normal form](lean-manual://section/simp-normal-forms).
  -/
  | zero : Nat
  /--
  The successor of a natural number `n`.

  Using `Nat.succ n` should usually be avoided in favor of `n + 1`, which is the [simp normal
  form](lean-manual://section/simp-normal-forms).
  -/
  | succ (n : Nat) : Nat
Natural numbers
Informal description
The type of natural numbers, starting at zero. This type is implemented with efficient arbitrary-precision arithmetic, and small values are unboxed for performance.
instInhabitedNat instance
: Inhabited Nat
Full source
instance : Inhabited Nat where
  default := Nat.zero
Natural Numbers are Inhabited
Informal description
The type of natural numbers $\mathbb{N}$ is inhabited, with a default element.
OfNat structure
(α : Type u) (_ : Nat)
Full source
/--
The class `OfNat α n` powers the numeric literal parser. If you write
`37 : α`, Lean will attempt to synthesize `OfNat α 37`, and will generate
the term `(OfNat.ofNat 37 : α)`.

There is a bit of infinite regress here since the desugaring apparently
still contains a literal `37` in it. The type of expressions contains a
primitive constructor for "raw natural number literals", which you can directly
access using the macro `nat_lit 37`. Raw number literals are always of type `Nat`.
So it would be more correct to say that Lean looks for an instance of
`OfNat α (nat_lit 37)`, and it generates the term `(OfNat.ofNat (nat_lit 37) : α)`.
-/
class OfNat (α : Type u) (_ : Nat) where
  /-- The `OfNat.ofNat` function is automatically inserted by the parser when
  the user writes a numeric literal like `1 : α`. Implementations of this
  typeclass can therefore customize the behavior of `n : α` based on `n` and
  `α`. -/
  ofNat : α
Numeric literal interpretation
Informal description
The class `OfNat α n` enables the interpretation of numeric literals as elements of type `α`. Specifically, when a numeric literal like `37` is written with an explicit type `α` (i.e., `37 : α`), Lean attempts to synthesize an instance of `OfNat α 37`, resulting in the term `(OfNat.ofNat 37 : α)`. This mechanism relies on raw natural number literals (internally represented as `nat_lit 37`), which are always of type `Nat`. Thus, Lean effectively looks for an instance of `OfNat α (nat_lit 37)` and generates `(OfNat.ofNat (nat_lit 37) : α)`.
instOfNatNat instance
(n : Nat) : OfNat Nat n
Full source
@[default_instance 100] /- low prio -/
instance instOfNatNat (n : Nat) : OfNat Nat n where
  ofNat := n
Natural Numbers as Numeric Literals
Informal description
For any natural number $n$, $n$ can be interpreted as an element of type $\mathbb{N}$ via the `OfNat` typeclass.
LE structure
(α : Type u)
Full source
/-- `LE α` is the typeclass which supports the notation `x ≤ y` where `x y : α`.-/
class LE (α : Type u) where
  /-- The less-equal relation: `x ≤ y` -/
  le : α → α → Prop
Less than or equal to typeclass
Informal description
The typeclass `LE α` provides support for the notation `x ≤ y` where `x, y` are elements of type `α`. This represents the "less than or equal to" relation on the type `α`.
LT structure
(α : Type u)
Full source
/-- `LT α` is the typeclass which supports the notation `x < y` where `x y : α`.-/
class LT (α : Type u) where
  /-- The less-than relation: `x < y` -/
  lt : α → α → Prop
Less Than Typeclass
Informal description
The typeclass `LT α` provides support for the notation `x < y` where `x` and `y` are elements of type `α`. This is used to define the "less than" relation on a type.
GE.ge definition
{α : Type u} [LE α] (a b : α) : Prop
Full source
/-- `a ≥ b` is an abbreviation for `b ≤ a`. -/
@[reducible] def GE.ge {α : Type u} [LE α] (a b : α) : Prop := LE.le b a
Greater than or equal to relation
Informal description
For a type $\alpha$ equipped with a "less than or equal to" relation $\leq$, the notation $a \geq b$ is defined as $b \leq a$.
GT.gt definition
{α : Type u} [LT α] (a b : α) : Prop
Full source
/-- `a > b` is an abbreviation for `b < a`. -/
@[reducible] def GT.gt {α : Type u} [LT α] (a b : α) : Prop := LT.lt b a
Greater than relation
Informal description
For a type $\alpha$ equipped with a "less than" relation $<$, the notation $a > b$ is defined as $b < a$.
DecidableLT abbrev
(α : Type u) [LT α]
Full source
/-- Abbreviation for `DecidableRel (· < · : α → α → Prop)`. -/
abbrev DecidableLT (α : Type u) [LT α] := DecidableRel (LT.lt : α → α → Prop)
Decidability of the Less Than Relation on Type $\alpha$
Informal description
For a type $\alpha$ equipped with a "less than" relation $<$, the abbreviation `DecidableLT` denotes the property that this relation is decidable, meaning for any two elements $x, y \in \alpha$, the proposition $x < y$ can be constructively determined to be true or false.
DecidableLE abbrev
(α : Type u) [LE α]
Full source
/-- Abbreviation for `DecidableRel (· ≤ · : α → α → Prop)`. -/
abbrev DecidableLE (α : Type u) [LE α] := DecidableRel (LE.le : α → α → Prop)
Decidability of the Less Than or Equal To Relation on Type $\alpha$
Informal description
For a type $\alpha$ equipped with a "less than or equal to" relation $\leq$, the abbreviation `DecidableLE` denotes the property that this relation is decidable, meaning for any two elements $x, y \in \alpha$, the proposition $x \leq y$ can be constructively determined to be true or false.
Max structure
(α : Type u)
Full source
/--
An overloaded operation to find the greater of two values of type `α`.
-/
class Max (α : Type u) where
  /-- Returns the greater of its two arguments. -/
  max : α → α → α
Maximum operation
Informal description
The structure representing a binary operation that computes the maximum of two elements of type $\alpha$.
maxOfLe definition
[LE α] [DecidableRel (@LE.le α _)] : Max α
Full source
/--
Constructs a `Max` instance from a decidable `≤` operation.
-/
-- Marked inline so that `min x y + max x y` can be optimized to a single branch.
@[inline]
def maxOfLe [LE α] [DecidableRel (@LE.le α _)] : Max α where
  max x y := ite (LE.le x y) y x
Maximum operation from decidable $\leq$ relation
Informal description
Given a type $\alpha$ equipped with a decidable "less than or equal to" relation $\leq$, the function `maxOfLe` constructs a maximum operation on $\alpha$ where for any $x, y \in \alpha$, $\max(x, y)$ returns $y$ if $x \leq y$ and $x$ otherwise.
Min structure
(α : Type u)
Full source
/--
An overloaded operation to find the lesser of two values of type `α`.
-/
class Min (α : Type u) where
  /-- Returns the lesser of its two arguments. -/
  min : α → α → α
Minimum operation
Informal description
The structure `Min` represents an operation to find the minimum of two values of type `α`. It is typically used in types that have a decidable linear order.
minOfLe definition
[LE α] [DecidableRel (@LE.le α _)] : Min α
Full source
/--
Constructs a `Min` instance from a decidable `≤` operation.
-/
-- Marked inline so that `min x y + max x y` can be optimized to a single branch.
@[inline]
def minOfLe [LE α] [DecidableRel (@LE.le α _)] : Min α where
  min x y := ite (LE.le x y) x y
Minimum operation from decidable $\leq$
Informal description
Given a type $\alpha$ with a decidable less-than-or-equal-to relation $\leq$, the function `minOfLe` constructs a minimum operation on $\alpha$ where the minimum of two elements $x$ and $y$ is defined to be $x$ if $x \leq y$ and $y$ otherwise.
Trans structure
(r : α → β → Sort u) (s : β → γ → Sort v) (t : outParam (α → γ → Sort w))
Full source
/--
Transitive chaining of proofs, used e.g. by `calc`.

It takes two relations `r` and `s` as "input", and produces an "output"
relation `t`, with the property that `r a b` and `s b c` implies `t a c`.
The `calc` tactic uses this so that when it sees a chain with `a ≤ b` and `b < c`
it knows that this should be a proof of `a < c` because there is an instance
`Trans (·≤·) (·<·) (·<·)`.
-/
class Trans (r : α → β → Sort u) (s : β → γ → Sort v) (t : outParam (α → γ → Sort w)) where
  /-- Compose two proofs by transitivity, generalized over the relations involved. -/
  trans : r a b → s b c → t a c
Transitive Proof Chaining
Informal description
The structure `Trans` represents a transitive chaining of proofs between relations. Given two relations `r : α → β → Sort u` and `s : β → γ → Sort v`, it produces an output relation `t : α → γ → Sort w` such that if `r a b` and `s b c` hold, then `t a c` can be derived. This is used, for example, by the `calc` tactic to chain proofs involving different relations like `≤` and `<`.
instTransEq instance
(r : α → γ → Sort u) : Trans Eq r r
Full source
instance (r : α → γ → Sort u) : Trans Eq r r where
  trans heq h' := heq ▸ h'
Transitive Chaining with Equality on the Left
Informal description
For any relation $r : \alpha \to \gamma \to \text{Sort} u$, the equality relation $\text{Eq}$ on $\alpha$ can be used to transitively chain proofs with $r$, meaning that if $a = b$ and $r b c$ hold, then $r a c$ can be derived.
instTransEq_1 instance
(r : α → β → Sort u) : Trans r Eq r
Full source
instance (r : α → β → Sort u) : Trans r Eq r where
  trans h' heq := heq ▸ h'
Transitive Chaining with Equality on the Right
Informal description
For any relation $r : \alpha \to \beta \to \text{Sort} u$, the equality relation $\text{Eq}$ on $\beta$ can be used to transitively chain proofs with $r$, meaning that if $r a b$ and $b = c$ hold, then $r a c$ can be derived.
HAdd structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/--
The notation typeclass for heterogeneous addition.
This enables the notation `a + b : γ` where `a : α`, `b : β`.
-/
class HAdd (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a + b` computes the sum of `a` and `b`.
  The meaning of this notation is type-dependent. -/
  hAdd : α → β → γ
Heterogeneous Addition Typeclass
Informal description
The structure `HAdd` represents the typeclass for heterogeneous addition, enabling the notation `a + b : γ` where `a : α` and `b : β`. This allows addition between elements of different types, with the result type `γ` being inferred as an output parameter.
HSub structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/--
The notation typeclass for heterogeneous subtraction.
This enables the notation `a - b : γ` where `a : α`, `b : β`.
-/
class HSub (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a - b` computes the difference of `a` and `b`.
  The meaning of this notation is type-dependent.
  * For natural numbers, this operator saturates at 0: `a - b = 0` when `a ≤ b`. -/
  hSub : α → β → γ
Heterogeneous subtraction typeclass
Informal description
The structure representing the typeclass for heterogeneous subtraction, enabling the notation \( a - b : \gamma \) where \( a : \alpha \) and \( b : \beta \).
HMul structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/--
The notation typeclass for heterogeneous multiplication.
This enables the notation `a * b : γ` where `a : α`, `b : β`.
-/
class HMul (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a * b` computes the product of `a` and `b`.
  The meaning of this notation is type-dependent. -/
  hMul : α → β → γ
Heterogeneous multiplication
Informal description
The structure representing heterogeneous multiplication, enabling the notation `a * b : γ` where `a : α` and `b : β` are elements of possibly different types, and the result is of type `γ`.
HDiv structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/--
The notation typeclass for heterogeneous division.
This enables the notation `a / b : γ` where `a : α`, `b : β`.
-/
class HDiv (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a / b` computes the result of dividing `a` by `b`.
  The meaning of this notation is type-dependent.
  * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`.
  * For `Nat`, `a / b` rounds downwards.
  * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative.
    It is implemented as `Int.ediv`, the unique function satisfying
    `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`.
    Other rounding conventions are available using the functions
    `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding).
  * For `Float`, `a / 0` follows the IEEE 754 semantics for division,
    usually resulting in `inf` or `nan`. -/
  hDiv : α → β → γ
Heterogeneous division typeclass
Informal description
The structure `HDiv` represents the typeclass for heterogeneous division, enabling the notation `a / b : γ` where `a : α` and `b : β`. The output type `γ` is marked as an output parameter that can be inferred during typeclass resolution.
HMod structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/--
The notation typeclass for heterogeneous modulo / remainder.
This enables the notation `a % b : γ` where `a : α`, `b : β`.
-/
class HMod (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a % b` computes the remainder upon dividing `a` by `b`.
  The meaning of this notation is type-dependent.
  * For `Nat` and `Int` it satisfies `a % b + b * (a / b) = a`,
    and `a % 0` is defined to be `a`. -/
  hMod : α → β → γ
Heterogeneous Modulo Operation
Informal description
The typeclass for heterogeneous modulo operation, which enables the notation `a % b : γ` where `a : α` and `b : β`. This allows computing the remainder of elements of different types `α` and `β` to produce a result of type `γ`.
HPow structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/--
The notation typeclass for heterogeneous exponentiation.
This enables the notation `a ^ b : γ` where `a : α`, `b : β`.
-/
class HPow (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a ^ b` computes `a` to the power of `b`.
  The meaning of this notation is type-dependent. -/
  hPow : α → β → γ
Heterogeneous Exponentiation
Informal description
The typeclass for heterogeneous exponentiation, which enables the notation `a ^ b : γ` where `a : α` and `b : β`. This allows exponentiation between elements of different types `α` and `β` to produce a result of type `γ`.
HAppend structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/--
The notation typeclass for heterogeneous append.
This enables the notation `a ++ b : γ` where `a : α`, `b : β`.
-/
class HAppend (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a ++ b` is the result of concatenation of `a` and `b`, usually read "append".
  The meaning of this notation is type-dependent. -/
  hAppend : α → β → γ
Heterogeneous Append
Informal description
The typeclass for heterogeneous append, which enables the notation `a ++ b : γ` where `a : α` and `b : β`. This allows appending elements of different types `α` and `β` to produce a result of type `γ`.
HOrElse structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/--
The typeclass behind the notation `a <|> b : γ` where `a : α`, `b : β`.
Because `b` is "lazy" in this notation, it is passed as `Unit → β` to the
implementation so it can decide when to evaluate it.
-/
class HOrElse (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a <|> b` executes `a` and returns the result, unless it fails in which
  case it executes and returns `b`. Because `b` is not always executed, it
  is passed as a thunk so it can be forced only when needed.
  The meaning of this notation is type-dependent. -/
  hOrElse : α → (Unit → β) → γ
Heterogeneous OrElse Typeclass
Informal description
The typeclass enabling the notation `a <|> b : γ` where `a : α$ and `b : β`. The second argument `b` is passed as a lazy evaluation `Unit → β` to allow the implementation to control when it is evaluated.
HAndThen structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/--
The typeclass behind the notation `a >> b : γ` where `a : α`, `b : β`.
Because `b` is "lazy" in this notation, it is passed as `Unit → β` to the
implementation so it can decide when to evaluate it.
-/
class HAndThen (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a >> b` executes `a`, ignores the result, and then executes `b`.
  If `a` fails then `b` is not executed. Because `b` is not always executed, it
  is passed as a thunk so it can be forced only when needed.
  The meaning of this notation is type-dependent. -/
  hAndThen : α → (Unit → β) → γ
Heterogeneous "and then" operation
Informal description
The typeclass enabling the notation `a >> b : γ` where `a : α` and `b : β`. The second argument `b` is passed as a lazy function `Unit → β` to allow the implementation to control when it is evaluated.
HAnd structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/-- The typeclass behind the notation `a &&& b : γ` where `a : α`, `b : β`. -/
class HAnd (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a &&& b` computes the bitwise AND of `a` and `b`.
  The meaning of this notation is type-dependent. -/
  hAnd : α → β → γ
Heterogeneous conjunction typeclass
Informal description
The typeclass `HAnd` represents the heterogeneous conjunction operation, denoted by `a &&& b : γ` where `a : α` and `b : β`. It provides a way to combine elements of different types `α` and `β` into an element of type `γ` using a conjunction-like operation.
HXor structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/-- The typeclass behind the notation `a ^^^ b : γ` where `a : α`, `b : β`. -/
class HXor (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a ^^^ b` computes the bitwise XOR of `a` and `b`.
  The meaning of this notation is type-dependent. -/
  hXor : α → β → γ
Bitwise XOR typeclass
Informal description
The typeclass representing the operation `a ^^^ b : γ` where `a : α` and `b : β`, with `γ` being an output parameter determined by the types `α` and `β`.
HOr structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/-- The typeclass behind the notation `a ||| b : γ` where `a : α`, `b : β`. -/
class HOr (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a ||| b` computes the bitwise OR of `a` and `b`.
  The meaning of this notation is type-dependent. -/
  hOr : α → β → γ
Heterogeneous disjunction typeclass
Informal description
The typeclass `HOr` represents a heterogeneous disjunction operation between elements of types `α` and `β`, producing an element of type `γ`. It is used to support the notation `a ||| b : γ` where `a : α` and `b : β`.
HShiftLeft structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/-- The typeclass behind the notation `a <<< b : γ` where `a : α`, `b : β`. -/
class HShiftLeft (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a <<< b` computes `a` shifted to the left by `b` places.
  The meaning of this notation is type-dependent.
  * On `Nat`, this is equivalent to `a * 2 ^ b`.
  * On `UInt8` and other fixed width unsigned types, this is the same but
    truncated to the bit width. -/
  hShiftLeft : α → β → γ
Left shift operation typeclass
Informal description
The typeclass supporting the notation `a <<< b : γ` where `a : α` and `b : β`, representing a left shift operation that produces a result in type `γ`.
HShiftRight structure
(α : Type u) (β : Type v) (γ : outParam (Type w))
Full source
/-- The typeclass behind the notation `a >>> b : γ` where `a : α`, `b : β`. -/
class HShiftRight (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  /-- `a >>> b` computes `a` shifted to the right by `b` places.
  The meaning of this notation is type-dependent.
  * On `Nat` and fixed width unsigned types like `UInt8`,
    this is equivalent to `a / 2 ^ b`. -/
  hShiftRight : α → β → γ
Right shift operation typeclass
Informal description
The typeclass supporting the notation `a >>> b : γ` where `a : α` and `b : β`, representing a right shift operation between types `α` and `β` yielding a result in type `γ`.
Zero structure
(α : Type u)
Full source
/-- A type with a zero element. -/
class Zero (α : Type u) where
  /-- The zero element of the type. -/
  zero : α
Type with zero element
Informal description
A structure representing a type `α` equipped with a distinguished zero element `0 : α`.
Add structure
(α : Type u)
Full source
/-- The homogeneous version of `HAdd`: `a + b : α` where `a b : α`. -/
class Add (α : Type u) where
  /-- `a + b` computes the sum of `a` and `b`. See `HAdd`. -/
  add : α → α → α
Homogeneous addition
Informal description
The structure representing a homogeneous addition operation on a type $\alpha$, where for any two elements $a, b \in \alpha$, their sum $a + b$ is also in $\alpha$.
Sub structure
(α : Type u)
Full source
/-- The homogeneous version of `HSub`: `a - b : α` where `a b : α`. -/
class Sub (α : Type u) where
  /-- `a - b` computes the difference of `a` and `b`. See `HSub`. -/
  sub : α → α → α
Homogeneous subtraction
Informal description
The structure representing a homogeneous subtraction operation on a type $\alpha$, where for any elements $a, b \in \alpha$, their difference $a - b$ is also in $\alpha$.
Mul structure
(α : Type u)
Full source
/-- The homogeneous version of `HMul`: `a * b : α` where `a b : α`. -/
class Mul (α : Type u) where
  /-- `a * b` computes the product of `a` and `b`. See `HMul`. -/
  mul : α → α → α
Multiplication operation
Informal description
The structure representing a binary multiplication operation on a type $\alpha$, where for any two elements $a, b \in \alpha$, their product $a * b$ is also an element of $\alpha$.
Neg structure
(α : Type u)
Full source
/--
The notation typeclass for negation.
This enables the notation `-a : α` where `a : α`.
-/
class Neg (α : Type u) where
  /-- `-a` computes the negative or opposite of `a`.
  The meaning of this notation is type-dependent. -/
  neg : α → α
Negation operation
Informal description
The structure representing the negation operation on a type $\alpha$, enabling the notation $-a$ for $a : \alpha$.
Div structure
(α : Type u)
Full source
/-- The homogeneous version of `HDiv`: `a / b : α` where `a b : α`. -/
class Div (α : Type u) where
  /-- `a / b` computes the result of dividing `a` by `b`. See `HDiv`. -/
  div : α → α → α
Homogeneous division operation
Informal description
The structure representing a homogeneous division operation on a type $\alpha$, where for any two elements $a, b \in \alpha$, the division $a / b$ is also an element of $\alpha$.
Mod structure
(α : Type u)
Full source
/-- The homogeneous version of `HMod`: `a % b : α` where `a b : α`. -/
class Mod (α : Type u) where
  /-- `a % b` computes the remainder upon dividing `a` by `b`. See `HMod`. -/
  mod : α → α → α
Homogeneous modulo operation
Informal description
The structure representing the homogeneous modulo operation, where for any type $\alpha$, the operation `%` takes two elements of $\alpha$ and returns another element of $\alpha$.
Dvd structure
(α : Type _)
Full source
/-- Notation typeclass for the `∣` operation (typed as `\|`), which represents divisibility. -/
class Dvd (α : Type _) where
  /-- Divisibility. `a ∣ b` (typed as `\|`) means that there is some `c` such that `b = a * c`. -/
  dvd : α → α → Prop
Divisibility relation
Informal description
The structure representing the divisibility relation `∣` on a type `α`, where `a ∣ b` means that `a` divides `b`.
Pow structure
(α : Type u) (β : Type v)
Full source
/--
The homogeneous version of `HPow`: `a ^ b : α` where `a : α`, `b : β`.
(The right argument is not the same as the left since we often want this even
in the homogeneous case.)

Types can choose to subscribe to particular defaulting behavior by providing
an instance to either `NatPow` or `HomogeneousPow`:
- `NatPow` is for types whose exponents is preferentially a `Nat`.
- `HomogeneousPow` is for types whose base and exponent are preferentially the same.
-/
class Pow (α : Type u) (β : Type v) where
  /-- `a ^ b` computes `a` to the power of `b`. See `HPow`. -/
  pow : α → β → α
Homogeneous Power Operation
Informal description
The structure representing the homogeneous version of the power operation, where for a type $\alpha$ and a type $\beta$, the operation $a^b$ is defined for $a \in \alpha$ and $b \in \beta$. This structure allows types to choose defaulting behavior for exponents by providing instances to either `NatPow` (preferring natural number exponents) or `HomogeneousPow` (preferring exponents from the same type as the base).
NatPow structure
(α : Type u)
Full source
/-- The homogeneous version of `Pow` where the exponent is a `Nat`.
The purpose of this class is that it provides a default `Pow` instance,
which can be used to specialize the exponent to `Nat` during elaboration.

For example, if `x ^ 2` should preferentially elaborate with `2 : Nat` then `x`'s type should
provide an instance for this class. -/
class NatPow (α : Type u) where
  /-- `a ^ n` computes `a` to the power of `n` where `n : Nat`. See `Pow`. -/
  protected pow : α → Nat → α
Natural number power operation
Informal description
The structure `NatPow` represents the homogeneous version of the power operation where the exponent is a natural number. It provides a default instance for the `Pow` typeclass, allowing expressions like `x ^ 2` to preferentially elaborate with `2` as a natural number when the type of `x` provides an instance of this class.
HomogeneousPow structure
(α : Type u)
Full source
/-- The completely homogeneous version of `Pow` where the exponent has the same type as the base.
The purpose of this class is that it provides a default `Pow` instance,
which can be used to specialize the exponent to have the same type as the base's type during elaboration.
This is to say, a type should provide an instance for this class in case `x ^ y` should be elaborated
with both `x` and `y` having the same type.

For example, the `Float` type provides an instance of this class, which causes expressions
such as `(2.2 ^ 2.2 : Float)` to elaborate. -/
class HomogeneousPow (α : Type u) where
  /-- `a ^ b` computes `a` to the power of `b` where `a` and `b` both have the same type. -/
  protected pow : α → α → α
Homogeneous Power Operation
Informal description
The structure `HomogeneousPow` represents a homogeneous version of the power operation where both the base and the exponent have the same type. This class provides a default instance for the power operation `Pow`, allowing expressions like `x ^ y` to be elaborated with `x` and `y` of the same type. For example, the `Float` type uses this to enable expressions such as `(2.2 ^ 2.2 : Float)`.
Append structure
(α : Type u)
Full source
/-- The homogeneous version of `HAppend`: `a ++ b : α` where `a b : α`. -/
class Append (α : Type u) where
  /-- `a ++ b` is the result of concatenation of `a` and `b`. See `HAppend`. -/
  append : α → α → α
Homogeneous Append Operation
Informal description
The structure representing a homogeneous append operation `++` where both operands and the result are of the same type `α`. This is the homogeneous version of the `HAppend` operation.
OrElse structure
(α : Type u)
Full source
/--
The homogeneous version of `HOrElse`: `a <|> b : α` where `a b : α`.
Because `b` is "lazy" in this notation, it is passed as `Unit → α` to the
implementation so it can decide when to evaluate it.
-/
class OrElse (α : Type u) where
  /-- The implementation of `a <|> b : α`. See `HOrElse`. -/
  orElse  : α → (Unit → α) → α
Homogeneous "or else" operation
Informal description
The structure `OrElse` represents a homogeneous version of the "or else" operation (`<|>`), where both operands `a` and `b` are of the same type `α`. The second operand `b` is passed as a lazy computation `Unit → α` to allow the implementation to control when it gets evaluated.
AndThen structure
(α : Type u)
Full source
/--
The homogeneous version of `HAndThen`: `a >> b : α` where `a b : α`.
Because `b` is "lazy" in this notation, it is passed as `Unit → α` to the
implementation so it can decide when to evaluate it.
-/
class AndThen (α : Type u) where
  /-- The implementation of `a >> b : α`. See `HAndThen`. -/
  andThen : α → (Unit → α) → α
Homogeneous AndThen Operation
Informal description
The structure `AndThen` represents the homogeneous version of the `HAndThen` operation, where `a >> b : α` with both `a` and `b` being of type `α`. The second argument `b` is passed lazily as a function `Unit → α` to allow the implementation to control when it is evaluated.
AndOp structure
(α : Type u)
Full source
/--
The homogeneous version of `HAnd`: `a &&& b : α` where `a b : α`.
(It is called `AndOp` because `And` is taken for the propositional connective.)
-/
class AndOp (α : Type u) where
  /-- The implementation of `a &&& b : α`. See `HAnd`. -/
  and : α → α → α
Homogeneous Logical AND Operation
Informal description
The structure `AndOp` represents a homogeneous version of the logical AND operation, where both operands and the result are of the same type $\alpha$. It is used to define the operation `a &&& b : α` for elements `a, b : α`.
Xor structure
(α : Type u)
Full source
/-- The homogeneous version of `HXor`: `a ^^^ b : α` where `a b : α`. -/
class Xor (α : Type u) where
  /-- The implementation of `a ^^^ b : α`. See `HXor`. -/
  xor : α → α → α
Homogeneous XOR operation
Informal description
The structure representing a homogeneous exclusive or (XOR) operation on a type $\alpha$, where both operands and the result are of type $\alpha$. This is the homogeneous version of the `HXor` operation.
OrOp structure
(α : Type u)
Full source
/--
The homogeneous version of `HOr`: `a ||| b : α` where `a b : α`.
(It is called `OrOp` because `Or` is taken for the propositional connective.)
-/
class OrOp (α : Type u) where
  /-- The implementation of `a ||| b : α`. See `HOr`. -/
  or : α → α → α
Homogeneous Or Operation
Informal description
The structure `OrOp α` represents a homogeneous binary operation `|||` on a type `α`, where both operands and the result are of type `α`. This is the homogeneous version of the `HOr` operation.
Complement structure
(α : Type u)
Full source
/-- The typeclass behind the notation `~~~a : α` where `a : α`. -/
class Complement (α : Type u) where
  /-- The implementation of `~~~a : α`. -/
  complement : α → α
Logical complement operation
Informal description
The typeclass `Complement` represents the operation of logical complement (negation) for a type `α`, denoted by the notation `~~~a` where `a : α`.
ShiftLeft structure
(α : Type u)
Full source
/-- The homogeneous version of `HShiftLeft`: `a <<< b : α` where `a b : α`. -/
class ShiftLeft (α : Type u) where
  /-- The implementation of `a <<< b : α`. See `HShiftLeft`. -/
  shiftLeft : α → α → α
Homogeneous left shift operation
Informal description
The structure representing the left shift operation `<<<` on a type `α`, where both operands and the result are of type `α`.
ShiftRight structure
(α : Type u)
Full source
/-- The homogeneous version of `HShiftRight`: `a >>> b : α` where `a b : α`. -/
class ShiftRight (α : Type u) where
  /-- The implementation of `a >>> b : α`. See `HShiftRight`. -/
  shiftRight : α → α → α
Homogeneous right shift operation
Informal description
The structure representing the right shift operation `>>>` on a type `α`, where both operands and the result are of type `α`. This is the homogeneous version of the right shift operation.
instHAdd instance
[Add α] : HAdd α α α
Full source
@[default_instance]
instance instHAdd [Add α] : HAdd α α α where
  hAdd a b := Add.add a b
Homogeneous Addition Induces Heterogeneous Addition
Informal description
For any type $\alpha$ equipped with a homogeneous addition operation, there is a corresponding heterogeneous addition operation where the input types and output type are all $\alpha$.
instHSub instance
[Sub α] : HSub α α α
Full source
@[default_instance]
instance instHSub [Sub α] : HSub α α α where
  hSub a b := Sub.sub a b
Homogeneous Subtraction Induces Heterogeneous Subtraction
Informal description
For any type $\alpha$ equipped with a homogeneous subtraction operation, there is a corresponding heterogeneous subtraction operation where the input types and output type are all $\alpha$.
instHMul instance
[Mul α] : HMul α α α
Full source
@[default_instance]
instance instHMul [Mul α] : HMul α α α where
  hMul a b := Mul.mul a b
Homogeneous Multiplication Induces Heterogeneous Multiplication
Informal description
For any type $\alpha$ equipped with a homogeneous multiplication operation, there is a corresponding heterogeneous multiplication operation where the input types and output type are all $\alpha$.
instHDiv instance
[Div α] : HDiv α α α
Full source
@[default_instance]
instance instHDiv [Div α] : HDiv α α α where
  hDiv a b := Div.div a b
Homogeneous Division Induces Heterogeneous Division
Informal description
For any type $\alpha$ equipped with a homogeneous division operation, there is a corresponding heterogeneous division operation where the input types and output type are all $\alpha$.
instHMod instance
[Mod α] : HMod α α α
Full source
@[default_instance]
instance instHMod [Mod α] : HMod α α α where
  hMod a b := Mod.mod a b
Homogeneous Modulo Induces Heterogeneous Modulo
Informal description
For any type $\alpha$ equipped with a homogeneous modulo operation, there is a corresponding heterogeneous modulo operation where the input types and output type are all $\alpha$.
instHPow instance
[Pow α β] : HPow α β α
Full source
@[default_instance]
instance instHPow [Pow α β] : HPow α β α where
  hPow a b := Pow.pow a b
Homogeneous Power Induces Heterogeneous Power
Informal description
For any type $\alpha$ equipped with a power operation $\mathrm{Pow} \alpha \beta$, there is a corresponding heterogeneous power operation $\mathrm{HPow} \alpha \beta \alpha$ where the output type is $\alpha$.
instPowNat instance
[NatPow α] : Pow α Nat
Full source
@[default_instance]
instance instPowNat [NatPow α] : Pow α Nat where
  pow a n := NatPow.pow a n
Natural Number Power Operation on a Type
Informal description
For any type $\alpha$ equipped with a natural number power operation, there is a canonical power operation $\alpha \times \mathbb{N} \to \alpha$ defined by $x^n$ where $n$ is a natural number.
instPowOfHomogeneousPow instance
[HomogeneousPow α] : Pow α α
Full source
@[default_instance]
instance [HomogeneousPow α] : Pow α α where
  pow a b := HomogeneousPow.pow a b
Homogeneous Power Operation on a Type
Informal description
For any type $\alpha$ equipped with a homogeneous power operation, there is a canonical power operation $\alpha \times \alpha \to \alpha$ defined by $x^y$ where both $x$ and $y$ are elements of $\alpha$.
instHAppendOfAppend instance
[Append α] : HAppend α α α
Full source
@[default_instance]
instance [Append α] : HAppend α α α where
  hAppend a b := Append.append a b
Homogeneous Append as Heterogeneous Append
Informal description
For any type $\alpha$ equipped with a homogeneous append operation `++`, there is a canonical heterogeneous append operation `++` that takes two elements of $\alpha$ and returns an element of $\alpha$.
instHOrElseOfOrElse instance
[OrElse α] : HOrElse α α α
Full source
@[default_instance]
instance [OrElse α] : HOrElse α α α where
  hOrElse a b := OrElse.orElse a b
Homogeneous OrElse Induces Heterogeneous OrElse
Informal description
For any type $\alpha$ equipped with a homogeneous "or else" operation `OrElse α`, there is a corresponding heterogeneous "or else" operation `HOrElse α α α` where both operands and the result are of type $\alpha$.
instHAndThenOfAndThen instance
[AndThen α] : HAndThen α α α
Full source
@[default_instance]
instance [AndThen α] : HAndThen α α α where
  hAndThen a b := AndThen.andThen a b
Homogeneous "and then" as Heterogeneous "and then"
Informal description
For any type $\alpha$ equipped with a homogeneous "and then" operation `>>`, there is a canonical heterogeneous "and then" operation `>>` that takes two elements of $\alpha$ and returns an element of $\alpha$.
instHAndOfAndOp instance
[AndOp α] : HAnd α α α
Full source
@[default_instance]
instance [AndOp α] : HAnd α α α where
  hAnd a b := AndOp.and a b
Homogeneous AND Operation Induces Heterogeneous AND Operation
Informal description
For any type $\alpha$ equipped with a homogeneous logical AND operation `AndOp α`, there is a corresponding heterogeneous AND operation `HAnd α α α` where both operands and the result are of type $\alpha$.
instHXorOfXor instance
[Xor α] : HXor α α α
Full source
@[default_instance]
instance [Xor α] : HXor α α α where
  hXor a b := Xor.xor a b
Homogeneous XOR Induces Heterogeneous XOR
Informal description
For any type $\alpha$ equipped with a homogeneous XOR operation `Xor α`, there is a corresponding heterogeneous XOR operation `HXor α α α` where both operands and the result are of type $\alpha$.
instHOrOfOrOp instance
[OrOp α] : HOr α α α
Full source
@[default_instance]
instance [OrOp α] : HOr α α α where
  hOr a b := OrOp.or a b
Homogeneous Or Operation Induces Heterogeneous Or Operation
Informal description
For any type $\alpha$ with a homogeneous or operation `OrOp α`, there is a corresponding heterogeneous or operation `HOr α α α` where both operands and the result are of type $\alpha$.
instHShiftLeftOfShiftLeft instance
[ShiftLeft α] : HShiftLeft α α α
Full source
@[default_instance]
instance [ShiftLeft α] : HShiftLeft α α α where
  hShiftLeft a b := ShiftLeft.shiftLeft a b
Homogeneous Left Shift Induces Heterogeneous Left Shift
Informal description
For any type $\alpha$ equipped with a homogeneous left shift operation `<<<`, there is a corresponding heterogeneous left shift operation where both operands and the result are of type $\alpha$.
instHShiftRightOfShiftRight instance
[ShiftRight α] : HShiftRight α α α
Full source
@[default_instance]
instance [ShiftRight α] : HShiftRight α α α where
  hShiftRight a b := ShiftRight.shiftRight a b
Homogeneous Right Shift Induces Heterogeneous Right Shift
Informal description
For any type $\alpha$ with a right shift operation `>>>`, there is a corresponding heterogeneous right shift operation where both operands and the result are of type $\alpha$.
Membership structure
(α : outParam (Type u)) (γ : Type v)
Full source
/--
The typeclass behind the notation `a ∈ s : Prop` where `a : α`, `s : γ`.
Because `α` is an `outParam`, the "container type" `γ` determines the type
of the elements of the container.
-/
class Membership (α : outParam (Type u)) (γ : Type v) where
  /-- The membership relation `a ∈ s : Prop` where `a : α`, `s : γ`. -/
  mem : γ → α → Prop
Membership relation typeclass
Informal description
The typeclass `Membership` is used to define the notation `a ∈ s : Prop` where `a : α` is an element and `s : γ` is a container. The type `α` is an output parameter, meaning it can be inferred from the container type `γ` during typeclass resolution. This allows the membership relation to be defined for various container types while keeping the element type flexible.
Nat.add definition
: (@& Nat) → (@& Nat) → Nat
Full source
/--
Addition of natural numbers, typically used via the `+` operator.

This function is overridden in both the kernel and the compiler to efficiently evaluate using the
arbitrary-precision arithmetic library. The definition provided here is the logical model.
-/
@[extern "lean_nat_add"]
protected def Nat.add : (@& Nat) → (@& Nat) → Nat
  | a, Nat.zero   => a
  | a, Nat.succ b => Nat.succ (Nat.add a b)
Addition of natural numbers
Informal description
The addition function for natural numbers, typically denoted by the $+$ operator. It is defined recursively by: - $a + 0 = a$ - $a + \text{succ}(b) = \text{succ}(a + b)$ This function is implemented efficiently using arbitrary-precision arithmetic, with small values unboxed for performance.
instAddNat instance
: Add Nat
Full source
instance instAddNat : Add Nat where
  add := Nat.add
Addition on Natural Numbers
Informal description
The natural numbers $\mathbb{N}$ are equipped with a canonical addition operation $+$ defined recursively by $a + 0 = a$ and $a + \text{succ}(b) = \text{succ}(a + b)$ for all $a, b \in \mathbb{N}$.
Nat.mul definition
: (@& Nat) → (@& Nat) → Nat
Full source
/--
Multiplication of natural numbers, usually accessed via the `*` operator.

This function is overridden in both the kernel and the compiler to efficiently evaluate using the
arbitrary-precision arithmetic library. The definition provided here is the logical model.
-/
@[extern "lean_nat_mul"]
protected def Nat.mul : (@& Nat) → (@& Nat) → Nat
  | _, 0          => 0
  | a, Nat.succ b => Nat.add (Nat.mul a b) a
Multiplication of natural numbers
Informal description
The multiplication function for natural numbers, typically denoted by the $*$ operator. It is defined recursively by: - $a * 0 = 0$ - $a * \text{succ}(b) = a * b + a$ This function is implemented efficiently using arbitrary-precision arithmetic, with small values unboxed for performance.
instMulNat instance
: Mul Nat
Full source
instance instMulNat : Mul Nat where
  mul := Nat.mul
Multiplication on Natural Numbers
Informal description
The natural numbers $\mathbb{N}$ are equipped with a canonical multiplication operation $*$ defined recursively by $a * 0 = 0$ and $a * \text{succ}(b) = a * b + a$ for all $a, b \in \mathbb{N}$.
Nat.pow definition
(m : @& Nat) : (@& Nat) → Nat
Full source
/--
The power operation on natural numbers, usually accessed via the `^` operator.

This function is overridden in both the kernel and the compiler to efficiently evaluate using the
arbitrary-precision arithmetic library. The definition provided here is the logical model.
-/
@[extern "lean_nat_pow"]
protected def Nat.pow (m : @& Nat) : (@& Nat) → Nat
  | 0      => 1
  | succ n => Nat.mul (Nat.pow m n) m
Natural number exponentiation
Informal description
The power function for natural numbers, typically denoted by the $^$ operator. For natural numbers $m$ and $n$, $m^n$ is defined recursively by: - $m^0 = 1$ - $m^{\text{succ}(n)} = m^n * m$ This function is implemented efficiently using arbitrary-precision arithmetic, with small values unboxed for performance.
instNatPowNat instance
: NatPow Nat
Full source
instance instNatPowNat : NatPow Nat := ⟨Nat.pow⟩
Natural Number Exponentiation Structure
Informal description
The natural numbers $\mathbb{N}$ are equipped with a canonical power operation $m^n$ defined recursively by $m^0 = 1$ and $m^{\text{succ}(n)} = m^n \cdot m$ for all $m, n \in \mathbb{N}$.
Nat.beq definition
: (@& Nat) → (@& Nat) → Bool
Full source
/--
Boolean equality of natural numbers, usually accessed via the `==` operator.

This function is overridden in both the kernel and the compiler to efficiently evaluate using the
arbitrary-precision arithmetic library. The definition provided here is the logical model.
-/
@[extern "lean_nat_dec_eq"]
def Nat.beq : (@& Nat) → (@& Nat) → Bool
  | zero,   zero   => true
  | zero,   succ _ => false
  | succ _, zero   => false
  | succ n, succ m => beq n m
Equality test for natural numbers
Informal description
The function `Nat.beq` takes two natural numbers $n$ and $m$ and returns `true` if they are equal and `false` otherwise. This is the logical model for the `==` operator on natural numbers, which is optimized in both the kernel and the compiler for efficient evaluation using arbitrary-precision arithmetic.
Nat.ne_of_beq_eq_false theorem
: {n m : Nat} → Eq (beq n m) false → Not (Eq n m)
Full source
theorem Nat.ne_of_beq_eq_false : {n m : Nat} → Eq (beq n m) falseNot (Eq n m)
  | zero,   zero,   h₁, _  => Bool.noConfusion h₁
  | zero,   succ _, _,  h₂ => Nat.noConfusion h₂
  | succ _, zero,   _,  h₂ => Nat.noConfusion h₂
  | succ n, succ m, h₁, h₂ =>
    have : Eq (beq n m) false := h₁
    Nat.noConfusion h₂ (fun h₂ => absurd h₂ (ne_of_beq_eq_false this))
Natural Number Inequality from Boolean Equality Test Failure
Informal description
For any natural numbers $n$ and $m$, if the equality test `beq n m` evaluates to `false`, then $n$ is not equal to $m$ (i.e., $\neg(n = m)$).
Nat.decEq definition
(n m : @& Nat) : Decidable (Eq n m)
Full source
/--
A decision procedure for equality of natural numbers, usually accessed via the `DecidableEq Nat`
instance.

This function is overridden in both the kernel and the compiler to efficiently evaluate using the
arbitrary-precision arithmetic library. The definition provided here is the logical model.

Examples:
 * `Nat.decEq 5 5 = isTrue rfl`
 * `(if 3 = 4 then "yes" else "no") = "no"`
 * `show 12 = 12 by decide`
-/
@[reducible, extern "lean_nat_dec_eq"]
protected def Nat.decEq (n m : @& Nat) : Decidable (Eq n m) :=
  match h:beq n m with
  | true  => isTrue (eq_of_beq_eq_true h)
  | false => isFalse (ne_of_beq_eq_false h)
Decidable equality for natural numbers
Informal description
The function `Nat.decEq` takes two natural numbers $n$ and $m$ and returns a constructive proof that either $n = m$ (wrapped in `isTrue`) or $n \neq m$ (wrapped in `isFalse`). This serves as a decision procedure for equality of natural numbers, implemented by checking the boolean equality test `beq n m` and converting its result into a proof of equality or disequality.
instDecidableEqNat instance
: DecidableEq Nat
Full source
@[inline] instance : DecidableEq Nat := Nat.decEq
Decidable Equality for Natural Numbers
Informal description
The type of natural numbers $\mathbb{N}$ has decidable equality. That is, for any two natural numbers $n$ and $m$, it is constructively decidable whether $n = m$ holds.
Nat.ble definition
: @& Nat → @& Nat → Bool
Full source
/--
The Boolean less-than-or-equal-to comparison on natural numbers.

This function is overridden in both the kernel and the compiler to efficiently evaluate using the
arbitrary-precision arithmetic library. The definition provided here is the logical model.

Examples:
 * `Nat.ble 2 5 = true`
 * `Nat.ble 5 2 = false`
 * `Nat.ble 5 5 = true`
-/
@[extern "lean_nat_dec_le"]
def Nat.ble : @& Nat → @& NatBool
  | zero,   zero   => true
  | zero,   succ _ => true
  | succ _, zero   => false
  | succ n, succ m => ble n m
Boolean less-than-or-equal-to for natural numbers
Informal description
The function `Nat.ble` takes two natural numbers `n` and `m` and returns `true` if `n` is less than or equal to `m`, and `false` otherwise. This is the Boolean version of the less-than-or-equal-to comparison on natural numbers. Examples: - `Nat.ble 2 5 = true` - `Nat.ble 5 2 = false` - `Nat.ble 5 5 = true`
Nat.le inductive
(n : Nat) : Nat → Prop
Full source
/--
Non-strict, or weak, inequality of natural numbers, usually accessed via the `≤` operator.
-/
protected inductive Nat.le (n : Nat) : Nat → Prop
  /-- Non-strict inequality is reflexive: `n ≤ n` -/
  | refl     : Nat.le n n
  /-- If `n ≤ m`, then `n ≤ m + 1`. -/
  | step {m} : Nat.le n m → Nat.le n (succ m)
Natural number inequality (≤)
Informal description
The relation `Nat.le n m` represents the non-strict (weak) inequality between natural numbers, typically written as $n \leq m$.
instLENat instance
: LE Nat
Full source
instance instLENat : LE Nat where
  le := Nat.le
The Partial Order Structure on Natural Numbers
Informal description
The natural numbers $\mathbb{N}$ are equipped with a canonical partial order structure given by the less-than-or-equal-to relation $\leq$.
Nat.lt definition
(n m : Nat) : Prop
Full source
/--
Strict inequality of natural numbers, usually accessed via the `<` operator.

It is defined as `n < m = n + 1 ≤ m`.
-/
protected def Nat.lt (n m : Nat) : Prop :=
  Nat.le (succ n) m
Strict inequality of natural numbers
Informal description
The strict inequality relation on natural numbers, defined as $n < m$ if and only if $n + 1 \leq m$.
instLTNat instance
: LT Nat
Full source
instance instLTNat : LT Nat where
  lt := Nat.lt
The Strict Order Structure on Natural Numbers
Informal description
The natural numbers $\mathbb{N}$ are equipped with a canonical strict order structure given by the less-than relation $<$.
Nat.not_succ_le_zero theorem
: ∀ (n : Nat), LE.le (succ n) 0 → False
Full source
theorem Nat.not_succ_le_zero : ∀ (n : Nat), LE.le (succ n) 0 → False
  | 0      => nofun
  | succ _ => nofun
Successor of Natural Number Cannot Be Less Than or Equal to Zero
Informal description
For any natural number $n$, the successor of $n$ is not less than or equal to zero. In other words, $\text{succ}(n) \leq 0$ leads to a contradiction.
Nat.not_lt_zero theorem
(n : Nat) : Not (LT.lt n 0)
Full source
theorem Nat.not_lt_zero (n : Nat) : Not (LT.lt n 0) :=
  not_succ_le_zero n
No Natural Number is Less Than Zero
Informal description
For any natural number $n$, it is not true that $n < 0$.
Nat.zero_le theorem
: (n : Nat) → LE.le 0 n
Full source
theorem Nat.zero_le : (n : Nat) → LE.le 0 n
  | zero   => Nat.le.refl
  | succ n => Nat.le.step (zero_le n)
Nonnegativity of Natural Numbers: $0 \leq n$
Informal description
For any natural number $n$, it holds that $0 \leq n$.
Nat.succ_le_succ theorem
: LE.le n m → LE.le (succ n) (succ m)
Full source
theorem Nat.succ_le_succ : LE.le n m → LE.le (succ n) (succ m)
  | Nat.le.refl   => Nat.le.refl
  | Nat.le.step h => Nat.le.step (succ_le_succ h)
Successor Preserves Order on Natural Numbers
Informal description
For any natural numbers $n$ and $m$, if $n \leq m$, then $\text{succ}(n) \leq \text{succ}(m)$.
Nat.zero_lt_succ theorem
(n : Nat) : LT.lt 0 (succ n)
Full source
theorem Nat.zero_lt_succ (n : Nat) : LT.lt 0 (succ n) :=
  succ_le_succ (zero_le n)
Positivity of Successor: $0 < n + 1$
Informal description
For any natural number $n$, it holds that $0 < n + 1$.
Nat.le_step theorem
(h : LE.le n m) : LE.le n (succ m)
Full source
theorem Nat.le_step (h : LE.le n m) : LE.le n (succ m) :=
  Nat.le.step h
Step Property of Natural Number Ordering
Informal description
For any natural numbers $n$ and $m$, if $n \leq m$, then $n \leq m + 1$.
Nat.le_trans theorem
{n m k : Nat} : LE.le n m → LE.le m k → LE.le n k
Full source
protected theorem Nat.le_trans {n m k : Nat} : LE.le n m → LE.le m k → LE.le n k
  | h,  Nat.le.refl    => h
  | h₁, Nat.le.step h₂ => Nat.le.step (Nat.le_trans h₁ h₂)
Transitivity of the Natural Number Order Relation
Informal description
For any natural numbers $n$, $m$, and $k$, if $n \leq m$ and $m \leq k$, then $n \leq k$.
Nat.lt_trans theorem
{n m k : Nat} (h₁ : LT.lt n m) : LT.lt m k → LT.lt n k
Full source
protected theorem Nat.lt_trans {n m k : Nat} (h₁ : LT.lt n m) : LT.lt m k → LT.lt n k :=
  Nat.le_trans (le_step h₁)
Transitivity of the Strict Order on Natural Numbers
Informal description
For any natural numbers $n$, $m$, and $k$, if $n < m$ and $m < k$, then $n < k$.
Nat.le_succ theorem
(n : Nat) : LE.le n (succ n)
Full source
theorem Nat.le_succ (n : Nat) : LE.le n (succ n) :=
  Nat.le.step Nat.le.refl
Successor is Greater Than or Equal in Natural Numbers
Informal description
For any natural number $n$, we have $n \leq n + 1$.
Nat.le_succ_of_le theorem
{n m : Nat} (h : LE.le n m) : LE.le n (succ m)
Full source
theorem Nat.le_succ_of_le {n m : Nat} (h : LE.le n m) : LE.le n (succ m) :=
  Nat.le_trans h (le_succ m)
Successor Preserves Order in Natural Numbers
Informal description
For any natural numbers $n$ and $m$, if $n \leq m$, then $n \leq m + 1$.
Nat.le_refl theorem
(n : Nat) : LE.le n n
Full source
protected theorem Nat.le_refl (n : Nat) : LE.le n n :=
  Nat.le.refl
Reflexivity of the Natural Number Ordering
Informal description
For any natural number $n$, the relation $n \leq n$ holds.
Nat.succ_pos theorem
(n : Nat) : LT.lt 0 (succ n)
Full source
theorem Nat.succ_pos (n : Nat) : LT.lt 0 (succ n) :=
  zero_lt_succ n
Positivity of Successor: $0 < n + 1$
Informal description
For any natural number $n$, the successor of $n$ is strictly greater than zero, i.e., $0 < n + 1$.
Nat.pred definition
: (@& Nat) → Nat
Full source
/--
The predecessor of a natural number is one less than it. The precedessor of `0` is defined to be
`0`.

This definition is overridden in the compiler with an efficient implementation. This definition is
the logical model.
-/
@[extern "lean_nat_pred"]
def Nat.pred : (@& Nat) → Nat
  | 0      => 0
  | succ a => a
Predecessor function on natural numbers
Informal description
The predecessor function on natural numbers, defined by $\mathrm{pred}(n) = n - 1$ for $n > 0$ and $\mathrm{pred}(0) = 0$.
Nat.pred_le_pred theorem
: {n m : Nat} → LE.le n m → LE.le (pred n) (pred m)
Full source
theorem Nat.pred_le_pred : {n m : Nat} → LE.le n m → LE.le (pred n) (pred m)
  | _,           _, Nat.le.refl   => Nat.le.refl
  | 0,      succ _, Nat.le.step h => h
  | succ _, succ _, Nat.le.step h => Nat.le_trans (le_succ _) h
Predecessor Preserves Order in Natural Numbers
Informal description
For any natural numbers $n$ and $m$, if $n \leq m$, then $\mathrm{pred}(n) \leq \mathrm{pred}(m)$, where $\mathrm{pred}(k)$ denotes the predecessor of $k$ (defined as $k - 1$ for $k > 0$ and $0$ for $k = 0$).
Nat.le_of_succ_le_succ theorem
{n m : Nat} : LE.le (succ n) (succ m) → LE.le n m
Full source
theorem Nat.le_of_succ_le_succ {n m : Nat} : LE.le (succ n) (succ m) → LE.le n m :=
  pred_le_pred
Successor Preserves Order in Natural Numbers
Informal description
For any natural numbers $n$ and $m$, if the successor of $n$ is less than or equal to the successor of $m$, then $n \leq m$.
Nat.le_of_lt_succ theorem
{m n : Nat} : LT.lt m (succ n) → LE.le m n
Full source
theorem Nat.le_of_lt_succ {m n : Nat} : LT.lt m (succ n) → LE.le m n :=
  le_of_succ_le_succ
Strict Inequality with Successor Implies Non-Strict Inequality
Informal description
For any natural numbers $m$ and $n$, if $m$ is strictly less than the successor of $n$ (i.e., $m < n + 1$), then $m$ is less than or equal to $n$ (i.e., $m \leq n$).
Nat.lt_or_ge theorem
(n m : Nat) : Or (LT.lt n m) (GE.ge n m)
Full source
protected theorem Nat.lt_or_ge (n m : Nat) : Or (LT.lt n m) (GE.ge n m) :=
  match m with
  | zero   => Or.inr (zero_le n)
  | succ m =>
    match Nat.lt_or_ge n m with
    | Or.inl h => Or.inl (le_succ_of_le h)
    | Or.inr h =>
      match Nat.eq_or_lt_of_le h with
      | Or.inl h1 => Or.inl (h1 ▸ Nat.le_refl _)
      | Or.inr h1 => Or.inr h1
Trichotomy Property for Natural Numbers: $n < m$ or $n \geq m$
Informal description
For any two natural numbers $n$ and $m$, either $n < m$ or $n \geq m$ holds.
Nat.not_succ_le_self theorem
: (n : Nat) → Not (LE.le (succ n) n)
Full source
theorem Nat.not_succ_le_self : (n : Nat) → Not (LE.le (succ n) n)
  | 0      => not_succ_le_zero _
  | succ n => fun h => absurd (le_of_succ_le_succ h) (not_succ_le_self n)
Successor Not Less Than or Equal to Itself in Natural Numbers
Informal description
For any natural number $n$, the successor of $n$ is not less than or equal to $n$ itself, i.e., $\neg(\text{succ}(n) \leq n)$.
Nat.lt_irrefl theorem
(n : Nat) : Not (LT.lt n n)
Full source
protected theorem Nat.lt_irrefl (n : Nat) : Not (LT.lt n n) :=
  Nat.not_succ_le_self n
Irreflexivity of the Strict Order on Natural Numbers
Informal description
For any natural number $n$, it is not the case that $n < n$.
Nat.lt_of_le_of_lt theorem
{n m k : Nat} (h₁ : LE.le n m) (h₂ : LT.lt m k) : LT.lt n k
Full source
protected theorem Nat.lt_of_le_of_lt {n m k : Nat} (h₁ : LE.le n m) (h₂ : LT.lt m k) : LT.lt n k :=
  Nat.le_trans (Nat.succ_le_succ h₁) h₂
Transitivity of $\leq$ and $<$ on Natural Numbers
Informal description
For any natural numbers $n$, $m$, and $k$, if $n \leq m$ and $m < k$, then $n < k$.
Nat.le_antisymm theorem
{n m : Nat} (h₁ : LE.le n m) (h₂ : LE.le m n) : Eq n m
Full source
protected theorem Nat.le_antisymm {n m : Nat} (h₁ : LE.le n m) (h₂ : LE.le m n) : Eq n m :=
  match h₁ with
  | Nat.le.refl   => rfl
  | Nat.le.step h => absurd (Nat.lt_of_le_of_lt h h₂) (Nat.lt_irrefl n)
Antisymmetry of the Natural Order on Natural Numbers: $n \leq m \land m \leq n \to n = m$
Informal description
For any natural numbers $n$ and $m$, if $n \leq m$ and $m \leq n$, then $n = m$.
Nat.lt_of_le_of_ne theorem
{n m : Nat} (h₁ : LE.le n m) (h₂ : Not (Eq n m)) : LT.lt n m
Full source
protected theorem Nat.lt_of_le_of_ne {n m : Nat} (h₁ : LE.le n m) (h₂ : Not (Eq n m)) : LT.lt n m :=
  match Nat.lt_or_ge n m with
  | Or.inl h₃ => h₃
  | Or.inr h₃ => absurd (Nat.le_antisymm h₁ h₃) h₂
Strict Inequality from Non-Equal Ordering in Natural Numbers: $n \leq m \land n \neq m \to n < m$
Informal description
For any natural numbers $n$ and $m$, if $n \leq m$ and $n \neq m$, then $n < m$.
Nat.le_of_ble_eq_true theorem
(h : Eq (Nat.ble n m) true) : LE.le n m
Full source
theorem Nat.le_of_ble_eq_true (h : Eq (Nat.ble n m) true) : LE.le n m :=
  match n, m with
  | 0,      _      => Nat.zero_le _
  | succ _, succ _ => Nat.succ_le_succ (le_of_ble_eq_true h)
Natural Number Order from Boolean Comparison: $\text{Nat.ble}(n, m) = \text{true} \to n \leq m$
Informal description
For any natural numbers $n$ and $m$, if the Boolean comparison `Nat.ble n m` evaluates to `true`, then $n \leq m$.
Nat.ble_self_eq_true theorem
: (n : Nat) → Eq (Nat.ble n n) true
Full source
theorem Nat.ble_self_eq_true : (n : Nat) → Eq (Nat.ble n n) true
  | 0      => rfl
  | succ n => ble_self_eq_true n
Reflexivity of Natural Number Boolean Comparison: $\text{Nat.ble}(n, n) = \text{true}$
Informal description
For any natural number $n$, the Boolean comparison `Nat.ble n n` evaluates to `true`, i.e., $n \leq n$ holds.
Nat.ble_succ_eq_true theorem
: {n m : Nat} → Eq (Nat.ble n m) true → Eq (Nat.ble n (succ m)) true
Full source
theorem Nat.ble_succ_eq_true : {n m : Nat} → Eq (Nat.ble n m) trueEq (Nat.ble n (succ m)) true
  | 0,      _,      _ => rfl
  | succ n, succ _, h => ble_succ_eq_true (n := n) h
Boolean Less-Than-or-Equal-to Preserves Successor
Informal description
For any natural numbers $n$ and $m$, if the Boolean comparison `Nat.ble n m` evaluates to `true` (i.e., $n \leq m$), then `Nat.ble n (m + 1)` also evaluates to `true` (i.e., $n \leq m + 1$).
Nat.ble_eq_true_of_le theorem
(h : LE.le n m) : Eq (Nat.ble n m) true
Full source
theorem Nat.ble_eq_true_of_le (h : LE.le n m) : Eq (Nat.ble n m) true :=
  match h with
  | Nat.le.refl   => Nat.ble_self_eq_true n
  | Nat.le.step h => Nat.ble_succ_eq_true (ble_eq_true_of_le h)
Boolean Comparison Reflects Natural Number Order: $\text{Nat.ble}(n, m) = \text{true}$ when $n \leq m$
Informal description
For any natural numbers $n$ and $m$, if $n \leq m$ holds, then the Boolean comparison `Nat.ble n m` evaluates to `true`.
Nat.not_le_of_not_ble_eq_true theorem
(h : Not (Eq (Nat.ble n m) true)) : Not (LE.le n m)
Full source
theorem Nat.not_le_of_not_ble_eq_true (h : Not (Eq (Nat.ble n m) true)) : Not (LE.le n m) :=
  fun h' => absurd (Nat.ble_eq_true_of_le h') h
Negation of Natural Number Order via Boolean Comparison: $\neg(\text{Nat.ble}(n, m) = \text{true}) \to \neg(n \leq m)$
Informal description
For any natural numbers $n$ and $m$, if the Boolean comparison $\text{Nat.ble}(n, m)$ does not evaluate to $\text{true}$ (i.e., $n \not\leq m$), then $n \leq m$ does not hold.
Nat.decLe instance
(n m : @& Nat) : Decidable (LE.le n m)
Full source
/--
A decision procedure for non-strict inequality of natural numbers, usually accessed via the
`DecidableLE Nat` instance.

Examples:
 * `(if 3 ≤ 4 then "yes" else "no") = "yes"`
 * `(if 6 ≤ 4 then "yes" else "no") = "no"`
 * `show 12 ≤ 12 by decide`
 * `show 5 ≤ 12 by decide`
-/
@[extern "lean_nat_dec_le"]
instance Nat.decLe (n m : @& Nat) : Decidable (LE.le n m) :=
  dite (Eq (Nat.ble n m) true) (fun h => isTrue (Nat.le_of_ble_eq_true h)) (fun h => isFalse (Nat.not_le_of_not_ble_eq_true h))
Decidability of Natural Number Ordering
Informal description
For any two natural numbers $n$ and $m$, the proposition $n \leq m$ is decidable. This means there exists a constructive procedure to determine whether $n$ is less than or equal to $m$.
Nat.decLt instance
(n m : @& Nat) : Decidable (LT.lt n m)
Full source
/--
A decision procedure for strict inequality of natural numbers, usually accessed via the
`DecidableLT Nat` instance.

Examples:
 * `(if 3 < 4 then "yes" else "no") = "yes"`
 * `(if 4 < 4 then "yes" else "no") = "no"`
 * `(if 6 < 4 then "yes" else "no") = "no"`
 * `show 5 < 12 by decide`
-/
@[extern "lean_nat_dec_lt"]
instance Nat.decLt (n m : @& Nat) : Decidable (LT.lt n m) :=
  decLe (succ n) m
Decidability of Strict Order on Natural Numbers
Informal description
For any two natural numbers $n$ and $m$, the proposition $n < m$ is decidable. This means there exists a constructive procedure to determine whether $n$ is strictly less than $m$.
instMinNat instance
: Min Nat
Full source
instance : Min Nat := minOfLe
The Minimum Operation on Natural Numbers
Informal description
The natural numbers $\mathbb{N}$ are equipped with a canonical minimum operation, where for any two natural numbers $n$ and $m$, $\min(n, m)$ is defined to be $n$ if $n \leq m$ and $m$ otherwise.
Nat.sub definition
: (@& Nat) → (@& Nat) → Nat
Full source
/--
Subtraction of natural numbers, truncated at `0`. Usually used via the `-` operator.

If a result would be less than zero, then the result is zero.

This definition is overridden in both the kernel and the compiler to efficiently evaluate using the
arbitrary-precision arithmetic library. The definition provided here is the logical model.

Examples:
* `5 - 3 = 2`
* `8 - 2 = 6`
* `8 - 8 = 0`
* `8 - 20 = 0`
-/
@[extern "lean_nat_sub"]
protected def Nat.sub : (@& Nat) → (@& Nat) → Nat
  | a, 0      => a
  | a, succ b => pred (Nat.sub a b)
Truncated subtraction of natural numbers
Informal description
The truncated subtraction function on natural numbers, defined recursively by: - $a - 0 = a$ for any natural number $a$ - $a - (b + 1) = \mathrm{pred}(a - b)$ for any natural numbers $a$ and $b$ where $\mathrm{pred}(n) = \max(0, n - 1)$. This operation returns zero when the result would otherwise be negative.
instSubNat instance
: Sub Nat
Full source
instance instSubNat : Sub Nat where
  sub := Nat.sub
Truncated Subtraction on Natural Numbers
Informal description
The natural numbers $\mathbb{N}$ are equipped with a canonical subtraction operation, defined as truncated subtraction where $a - b$ returns the difference if $a \geq b$ and zero otherwise.
System.Platform.getNumBits opaque
: Unit → Subtype fun (n : Nat) => Or (Eq n 32) (Eq n 64)
Full source
/--
Gets the word size of the curent platform. The word size may be 64 or 32 bits.

This function is opaque because there is no guarantee at compile time that the target will have the
same word size as the host. It also helps avoid having type checking be architecture-dependent.

Lean only works on 64 and 32 bit systems. This fact is visible in the return type.
-/
@[extern "lean_system_platform_nbits"] opaque System.Platform.getNumBits : UnitSubtype fun (n : Nat) => Or (Eq n 32) (Eq n 64) :=
  fun _ => ⟨64, Or.inr rfl⟩
Platform Word Size Query: 32 or 64 bits
Informal description
The function `getNumBits` takes a unit value `()` and returns a natural number `n` (as a subtype) such that `n` is either 32 or 64, representing the word size of the current platform in bits.
System.Platform.numBits definition
: Nat
Full source
/--
The word size of the current platform, which may be 64 or 32 bits.
-/
def System.Platform.numBits : Nat :=
  (getNumBits ()).val
Platform word size (32 or 64 bits)
Informal description
The word size of the current platform, which is either 32 or 64 bits. This is obtained by extracting the value from the `getNumBits` function applied to the unit value `()`.
System.Platform.numBits_eq theorem
: Or (Eq numBits 32) (Eq numBits 64)
Full source
/--
The word size of the current platform may be 64 or 32 bits.
-/
theorem System.Platform.numBits_eq : Or (Eq numBits 32) (Eq numBits 64) :=
  (getNumBits ()).property
Platform Word Size is 32 or 64 Bits
Informal description
The word size of the current platform is either 32 or 64 bits, i.e., $\text{numBits} = 32 \lor \text{numBits} = 64$.
Fin structure
(n : Nat)
Full source
/--
Natural numbers less than some upper bound.

In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the
canonical type with `n` elements.
-/
@[pp_using_anonymous_constructor]
structure Fin (n : Nat) where
  /-- Creates a `Fin n` from `i : Nat` and a proof that `i < n`. -/
  mk ::
  /--
  The number that is strictly less than `n`.

  `Fin.val` is a coercion, so any `Fin n` can be used in a position where a `Nat` is expected.
  -/
  val  : Nat
  /--
  The number `val` is strictly less than the bound `n`.
  -/
  isLt : LT.lt val n
Finite natural numbers (bounded by n)
Informal description
The type `Fin n` represents natural numbers less than a given upper bound `n`. Specifically, an element of `Fin n` is a natural number `i` satisfying `i < n`. This type is the canonical representation of a finite set with exactly `n` elements.
Fin.val_eq_of_eq theorem
{n} {i j : Fin n} (h : Eq i j) : Eq i.val j.val
Full source
theorem Fin.val_eq_of_eq {n} {i j : Fin n} (h : Eq i j) : Eq i.val j.val :=
  h ▸ rfl
Equality of Fin elements implies equality of their natural number values
Informal description
For any natural number $n$ and any elements $i, j$ of the finite type $\mathrm{Fin}\,n$, if $i = j$ then their underlying natural number values are equal, i.e., $i.\mathrm{val} = j.\mathrm{val}$.
instDecidableEqFin instance
(n : Nat) : DecidableEq (Fin n)
Full source
instance (n : Nat) : DecidableEq (Fin n) :=
  fun i j =>
    match decEq i.val j.val with
    | isTrue h  => isTrue (Fin.eq_of_val_eq h)
    | isFalse h => isFalse (fun h' => absurd (Fin.val_eq_of_eq h') h)
Decidable Equality for Finite Types
Informal description
For any natural number $n$, the finite type $\mathrm{Fin}\,n$ has decidable equality. That is, for any two elements $i, j \in \mathrm{Fin}\,n$, it is constructively decidable whether $i = j$ holds.
instLTFin instance
{n} : LT (Fin n)
Full source
instance {n} : LT (Fin n) where
  lt a b := LT.lt a.val b.val
The Strict Order Structure on Finite Natural Numbers
Informal description
For any natural number $n$, the type $\mathrm{Fin}\,n$ of natural numbers less than $n$ is equipped with a canonical strict order structure given by the less-than relation $<$.
instLEFin instance
{n} : LE (Fin n)
Full source
instance {n} : LE (Fin n) where
  le a b := LE.le a.val b.val
The Partial Order Structure on Finite Natural Numbers
Informal description
For any natural number $n$, the type $\mathrm{Fin}\,n$ of natural numbers less than $n$ is equipped with a canonical partial order structure given by the less-than-or-equal-to relation $\leq$.
Fin.decLt instance
{n} (a b : Fin n) : Decidable (LT.lt a b)
Full source
instance Fin.decLt {n} (a b : Fin n) : Decidable (LT.lt a b) := Nat.decLt ..
Decidability of Strict Order on Finite Natural Numbers
Informal description
For any natural number $n$ and elements $a, b$ in $\mathrm{Fin}\,n$ (the type of natural numbers less than $n$), the proposition $a < b$ is decidable. This means there exists a constructive procedure to determine whether $a$ is strictly less than $b$ in the canonical order on $\mathrm{Fin}\,n$.
Fin.decLe instance
{n} (a b : Fin n) : Decidable (LE.le a b)
Full source
instance Fin.decLe {n} (a b : Fin n) : Decidable (LE.le a b) := Nat.decLe ..
Decidability of Order on Finite Natural Numbers
Informal description
For any natural number $n$ and elements $a, b$ in $\mathrm{Fin}\,n$ (the type of natural numbers less than $n$), the proposition $a \leq b$ is decidable. This means there exists a constructive procedure to determine whether $a$ is less than or equal to $b$ in the canonical order on $\mathrm{Fin}\,n$.
BitVec structure
(w : Nat)
Full source
/--
A bitvector of the specified width.

This is represented as the underlying `Nat` number in both the runtime
and the kernel, inheriting all the special support for `Nat`.
-/
structure BitVec (w : Nat) where
  /-- Construct a `BitVec w` from a number less than `2^w`.
  O(1), because we use `Fin` as the internal representation of a bitvector. -/
  ofFin ::
  /-- Interpret a bitvector as a number less than `2^w`.
  O(1), because we use `Fin` as the internal representation of a bitvector. -/
  toFin : Fin (hPow 2 w)
Bitvector of width \( w \)
Informal description
A bitvector of width \( w \) is represented as a natural number, where the value is treated as a sequence of \( w \) bits. The underlying representation uses the natural number type for efficient arbitrary-precision arithmetic, with optimizations for small values.
BitVec.decEq definition
(x y : BitVec n) : Decidable (Eq x y)
Full source
/--
Bitvectors have decidable equality.

This should be used via the instance `DecidableEq (BitVec n)`.
-/
-- We manually derive the `DecidableEq` instances for `BitVec` because
-- we want to have builtin support for bit-vector literals, and we
-- need a name for this function to implement `canUnfoldAtMatcher` at `WHNF.lean`.
def BitVec.decEq (x y : BitVec n) : Decidable (Eq x y) :=
  match x, y with
  | ⟨n⟩, ⟨m⟩ =>
    dite (Eq n m)
      (fun h => isTrue (h ▸ rfl))
      (fun h => isFalse (fun h' => BitVec.noConfusion h' (fun h' => absurd h' h)))
Decidability of equality for bitvectors
Informal description
For any two bitvectors \( x \) and \( y \) of the same width \( n \), it is decidable whether \( x \) is equal to \( y \). Specifically, the function checks if the underlying natural number representations of \( x \) and \( y \) are equal, and returns a constructive proof of either \( x = y \) or \( x \neq y \).
instDecidableEqBitVec instance
: DecidableEq (BitVec n)
Full source
instance : DecidableEq (BitVec n) := BitVec.decEq
Decidable Equality for Bitvectors
Informal description
For any bitvector width $n$, the equality of two bitvectors of width $n$ is decidable.
BitVec.ofNatLT definition
{n : Nat} (i : Nat) (p : LT.lt i (hPow 2 n)) : BitVec n
Full source
/-- The `BitVec` with value `i`, given a proof that `i < 2^n`. -/
@[match_pattern]
protected def BitVec.ofNatLT {n : Nat} (i : Nat) (p : LT.lt i (hPow 2 n)) : BitVec n where
  toFin := ⟨i, p⟩
Bitvector from natural number with bound check
Informal description
Given a natural number \( i \) and a proof that \( i < 2^n \), the function returns a bitvector of width \( n \) with value \( i \).
BitVec.toNat definition
(x : BitVec n) : Nat
Full source
/--
Return the underlying `Nat` that represents a bitvector.

This is O(1) because `BitVec` is a (zero-cost) wrapper around a `Nat`.
-/
protected def BitVec.toNat (x : BitVec n) : Nat := x.toFin.val
Natural number representation of a bitvector
Informal description
The function extracts the underlying natural number representation of a bitvector \( x \) of width \( n \). This operation is performed in constant time since the bitvector is a zero-cost wrapper around a natural number.
instLTBitVec instance
: LT (BitVec n)
Full source
instance : LT (BitVec n) where lt := (LT.lt ·.toNat ·.toNat)
Strict Order on Bitvectors
Informal description
For any bitvector type `BitVec n` of width `n`, there is a canonical strict order relation `<` defined by comparing the underlying natural number representations of the bitvectors.
instDecidableLtBitVec instance
(x y : BitVec n) : Decidable (LT.lt x y)
Full source
instance (x y : BitVec n) : Decidable (LT.lt x y) :=
  inferInstanceAs (Decidable (LT.lt x.toNat y.toNat))
Decidability of Strict Order on Bitvectors
Informal description
For any two bitvectors $x$ and $y$ of width $n$, the proposition $x < y$ is decidable. This means there exists a constructive procedure to determine whether $x$ is strictly less than $y$ by comparing their underlying natural number representations.
instLEBitVec instance
: LE (BitVec n)
Full source
instance : LE (BitVec n) where le := (LE.le ·.toNat ·.toNat)
The Partial Order Structure on Bitvectors
Informal description
For any bitvector width $n$, the type `BitVec n` is equipped with a canonical partial order structure given by the less-than-or-equal-to relation $\leq$.
instDecidableLeBitVec instance
(x y : BitVec n) : Decidable (LE.le x y)
Full source
instance (x y : BitVec n) : Decidable (LE.le x y) :=
  inferInstanceAs (Decidable (LE.le x.toNat y.toNat))
Decidability of Bitvector Ordering
Informal description
For any two bitvectors $x$ and $y$ of width $n$, the proposition $x \leq y$ is decidable. This means there exists a constructive procedure to determine whether $x$ is less than or equal to $y$ under the canonical partial order on bitvectors.
UInt8.size abbrev
: Nat
Full source
/-- The number of distinct values representable by `UInt8`, that is, `2^8 = 256`. -/
abbrev UInt8.size : Nat := 256
Cardinality of UInt8: $256$ values
Informal description
The number of distinct values representable by an unsigned 8-bit integer is $256$, i.e., $\mathrm{UInt8.size} = 256$.
UInt8 structure
Full source
/--
Unsigned 8-bit integers.

This type has special support in the compiler so it can be represented by an unboxed 8-bit value
rather than wrapping a `BitVec 8`.
-/
structure UInt8 where
  /--
  Creates a `UInt8` from a `BitVec 8`. This function is overridden with a native implementation.
  -/
  ofBitVec ::
  /--
  Unpacks a `UInt8` into a `BitVec 8`. This function is overridden with a native implementation.
  -/
  toBitVec : BitVec 8
Unsigned 8-bit integers
Informal description
The structure representing unsigned 8-bit integers. This type is specially supported by the compiler to be represented as an unboxed 8-bit value rather than wrapping a `BitVec 8`.
UInt8.ofNatLT definition
(n : @& Nat) (h : LT.lt n UInt8.size) : UInt8
Full source
/--
Converts a natural number to an 8-bit unsigned integer. Requires a proof that the number is small
enough to be representable without overflow; it must be smaller than `2^8`.

This function is overridden at runtime with an efficient implementation.
-/
@[extern "lean_uint8_of_nat"]
def UInt8.ofNatLT (n : @& Nat) (h : LT.lt n UInt8.size) : UInt8 where
  toBitVec := BitVec.ofNatLT n h
Unsigned 8-bit integer from natural number with bound check
Informal description
Given a natural number \( n \) and a proof that \( n < 256 \), the function returns the corresponding unsigned 8-bit integer with value \( n \). This function ensures that the input number is within the representable range of an 8-bit unsigned integer.
UInt8.decEq definition
(a b : UInt8) : Decidable (Eq a b)
Full source
/--
Decides whether two 8-bit unsigned integers are equal. Usually accessed via the `DecidableEq UInt8`
instance.

This function is overridden at runtime with an efficient implementation.

Examples:
 * `UInt8.decEq 123 123 = .isTrue rfl`
 * `(if (6 : UInt8) = 7 then "yes" else "no") = "no"`
 * `show (7 : UInt8) = 7 by decide`
-/
@[extern "lean_uint8_dec_eq"]
def UInt8.decEq (a b : UInt8) : Decidable (Eq a b) :=
  match a, b with
  | ⟨n⟩, ⟨m⟩ =>
    dite (Eq n m)
      (fun h => isTrue (h ▸ rfl))
      (fun h => isFalse (fun h' => UInt8.noConfusion h' (fun h' => absurd h' h)))
Decidable equality for unsigned 8-bit integers
Informal description
Given two unsigned 8-bit integers $a$ and $b$, this function constructively decides whether $a = b$ holds, returning either a proof of equality (`isTrue`) or a proof of inequality (`isFalse`). The runtime implementation is optimized for efficiency.
instDecidableEqUInt8 instance
: DecidableEq UInt8
Full source
instance : DecidableEq UInt8 := UInt8.decEq
Decidable Equality for Unsigned 8-bit Integers
Informal description
The type of unsigned 8-bit integers has decidable equality, meaning that for any two elements $a, b \in \mathbb{UInt8}$, the equality $a = b$ can be constructively decided.
instInhabitedUInt8 instance
: Inhabited UInt8
Full source
instance : Inhabited UInt8 where
  default := UInt8.ofNatLT 0 (of_decide_eq_true rfl)
Inhabited Type of Unsigned 8-bit Integers
Informal description
The type of unsigned 8-bit integers is inhabited, with a default value of 0.
UInt16.size abbrev
: Nat
Full source
/-- The number of distinct values representable by `UInt16`, that is, `2^16 = 65536`. -/
abbrev UInt16.size : Nat := 65536
Cardinality of 16-bit Unsigned Integers: $2^{16}$
Informal description
The size of the type `UInt16` is $2^{16} = 65536$, representing the number of distinct values that can be stored in a 16-bit unsigned integer.
UInt16 structure
Full source
/--
Unsigned 16-bit integers.

This type has special support in the compiler so it can be represented by an unboxed 16-bit value
rather than wrapping a `BitVec 16`.
-/
structure UInt16 where
  /--
  Creates a `UInt16` from a `BitVec 16`. This function is overridden with a native implementation.
  -/
  ofBitVec ::
  /--
  Unpacks a `UInt16` into a `BitVec 16`. This function is overridden with a native implementation.
  -/
  toBitVec : BitVec 16
Unsigned 16-bit integer
Informal description
The structure representing unsigned 16-bit integers, which are stored as unboxed 16-bit values for efficiency.
UInt16.ofNatLT definition
(n : @& Nat) (h : LT.lt n UInt16.size) : UInt16
Full source
/--
Converts a natural number to a 16-bit unsigned integer. Requires a proof that the number is small
enough to be representable without overflow; it must be smaller than `2^16`.

This function is overridden at runtime with an efficient implementation.
-/
@[extern "lean_uint16_of_nat"]
def UInt16.ofNatLT (n : @& Nat) (h : LT.lt n UInt16.size) : UInt16 where
  toBitVec := BitVec.ofNatLT n h
Conversion from natural number to 16-bit unsigned integer with bound check
Informal description
Given a natural number \( n \) and a proof that \( n < 2^{16} \), the function returns the corresponding 16-bit unsigned integer representation of \( n \).
UInt16.decEq definition
(a b : UInt16) : Decidable (Eq a b)
Full source
/--
Decides whether two 16-bit unsigned integers are equal. Usually accessed via the
`DecidableEq UInt16` instance.

This function is overridden at runtime with an efficient implementation.

Examples:
 * `UInt16.decEq 123 123 = .isTrue rfl`
 * `(if (6 : UInt16) = 7 then "yes" else "no") = "no"`
 * `show (7 : UInt16) = 7 by decide`
-/
@[extern "lean_uint16_dec_eq"]
def UInt16.decEq (a b : UInt16) : Decidable (Eq a b) :=
  match a, b with
  | ⟨n⟩, ⟨m⟩ =>
    dite (Eq n m)
      (fun h => isTrue (h ▸ rfl))
      (fun h => isFalse (fun h' => UInt16.noConfusion h' (fun h' => absurd h' h)))
Decidable equality for 16-bit unsigned integers
Informal description
Given two 16-bit unsigned integers \( a \) and \( b \), the function `UInt16.decEq` constructs a proof that their equality is decidable. Specifically, it returns either a proof that \( a = b \) (wrapped in `isTrue`) or a proof that \( a \neq b \) (wrapped in `isFalse`).
instDecidableEqUInt16 instance
: DecidableEq UInt16
Full source
instance : DecidableEq UInt16 := UInt16.decEq
Decidable Equality for 16-bit Unsigned Integers
Informal description
The type of unsigned 16-bit integers has decidable equality. That is, for any two 16-bit unsigned integers $a$ and $b$, the equality $a = b$ can be constructively determined.
instInhabitedUInt16 instance
: Inhabited UInt16
Full source
instance : Inhabited UInt16 where
  default := UInt16.ofNatLT 0 (of_decide_eq_true rfl)
Inhabited Type for Unsigned 16-bit Integers
Informal description
The type of unsigned 16-bit integers is inhabited, with a default value of 0.
UInt32.size abbrev
: Nat
Full source
/-- The number of distinct values representable by `UInt32`, that is, `2^32 = 4294967296`. -/
abbrev UInt32.size : Nat := 4294967296
Cardinality of UInt32: $2^{32}$
Informal description
The size of the unsigned 32-bit integer type is $2^{32} = 4294967296$.
UInt32 structure
Full source
/--
Unsigned 32-bit integers.

This type has special support in the compiler so it can be represented by an unboxed 32-bit value
rather than wrapping a `BitVec 32`.
-/
structure UInt32 where
  /--
  Creates a `UInt32` from a `BitVec 32`. This function is overridden with a native implementation.
  -/
  ofBitVec ::
  /--
  Unpacks a `UInt32` into a `BitVec 32`. This function is overridden with a native implementation.
  -/
  toBitVec : BitVec 32
Unsigned 32-bit integers
Informal description
The structure representing unsigned 32-bit integers, which are stored as unboxed 32-bit values for efficiency.
UInt32.ofNatLT definition
(n : @& Nat) (h : LT.lt n UInt32.size) : UInt32
Full source
/--
Converts a natural number to a 32-bit unsigned integer. Requires a proof that the number is small
enough to be representable without overflow; it must be smaller than `2^32`.

This function is overridden at runtime with an efficient implementation.
-/
@[extern "lean_uint32_of_nat"]
def UInt32.ofNatLT (n : @& Nat) (h : LT.lt n UInt32.size) : UInt32 where
  toBitVec := BitVec.ofNatLT n h
Conversion from natural number to unsigned 32-bit integer with bound check
Informal description
Given a natural number \( n \) and a proof that \( n < 2^{32} \), the function returns the corresponding unsigned 32-bit integer representation of \( n \).
UInt32.toNat definition
(n : UInt32) : Nat
Full source
/--
Converts a 32-bit unsigned integer to an arbitrary-precision natural number.

This function is overridden at runtime with an efficient implementation.
-/
@[extern "lean_uint32_to_nat"]
def UInt32.toNat (n : UInt32) : Nat := n.toBitVec.toNat
Natural number representation of a 32-bit unsigned integer
Informal description
The function converts a 32-bit unsigned integer \( n \) to its corresponding natural number representation.
UInt32.decEq definition
(a b : UInt32) : Decidable (Eq a b)
Full source
/--
Decides whether two 32-bit unsigned integers are equal. Usually accessed via the
`DecidableEq UInt32` instance.

This function is overridden at runtime with an efficient implementation.

Examples:
 * `UInt32.decEq 123 123 = .isTrue rfl`
 * `(if (6 : UInt32) = 7 then "yes" else "no") = "no"`
 * `show (7 : UInt32) = 7 by decide`
-/
@[extern "lean_uint32_dec_eq"]
def UInt32.decEq (a b : UInt32) : Decidable (Eq a b) :=
  match a, b with
  | ⟨n⟩, ⟨m⟩ =>
    dite (Eq n m) (fun h => isTrue (h ▸ rfl)) (fun h => isFalse (fun h' => UInt32.noConfusion h' (fun h' => absurd h' h)))
Decidable equality for 32-bit unsigned integers
Informal description
The function takes two 32-bit unsigned integers \( a \) and \( b \) and returns a constructive proof that \( a = b \) is either true or false. Specifically, it returns a `Decidable` instance which is either `isTrue` with a proof of \( a = b \) if they are equal, or `isFalse` with a proof of \( \neg (a = b) \) if they are not equal.
instDecidableEqUInt32 instance
: DecidableEq UInt32
Full source
instance : DecidableEq UInt32 := UInt32.decEq
Decidable Equality for Unsigned 32-bit Integers
Informal description
The type of unsigned 32-bit integers has decidable equality, meaning that for any two elements $a, b \in \text{UInt32}$, the equality $a = b$ can be constructively decided.
instInhabitedUInt32 instance
: Inhabited UInt32
Full source
instance : Inhabited UInt32 where
  default := UInt32.ofNatLT 0 (of_decide_eq_true rfl)
Inhabited Type of Unsigned 32-bit Integers
Informal description
The type of unsigned 32-bit integers is inhabited, with a default value of 0.
instLTUInt32 instance
: LT UInt32
Full source
instance : LT UInt32 where
  lt a b := LT.lt a.toBitVec b.toBitVec
Strict Order on Unsigned 32-bit Integers
Informal description
The type of unsigned 32-bit integers `UInt32` is equipped with a canonical strict order relation `<`.
instLEUInt32 instance
: LE UInt32
Full source
instance : LE UInt32 where
  le a b := LE.le a.toBitVec b.toBitVec
The Partial Order Structure on Unsigned 32-bit Integers
Informal description
The type of unsigned 32-bit integers `UInt32` is equipped with a canonical less-than-or-equal-to relation $\leq$.
UInt32.decLt definition
(a b : UInt32) : Decidable (LT.lt a b)
Full source
/--
Decides whether one 8-bit unsigned integer is strictly less than another. Usually accessed via the
`DecidableLT UInt32` instance.

This function is overridden at runtime with an efficient implementation.

Examples:
 * `(if (6 : UInt32) < 7 then "yes" else "no") = "yes"`
 * `(if (5 : UInt32) < 5 then "yes" else "no") = "no"`
 * `show ¬((7 : UInt32) < 7) by decide`
-/
@[extern "lean_uint32_dec_lt"]
def UInt32.decLt (a b : UInt32) : Decidable (LT.lt a b) :=
  inferInstanceAs (Decidable (LT.lt a.toBitVec b.toBitVec))
Decidability of strict order on unsigned 32-bit integers
Informal description
The function decides whether one unsigned 32-bit integer is strictly less than another, returning a constructive proof of the result. Specifically, for any two unsigned 32-bit integers \( a \) and \( b \), it determines whether \( a < b \) holds, providing either a proof of \( a < b \) or a proof of \( \neg (a < b) \).
UInt32.decLe definition
(a b : UInt32) : Decidable (LE.le a b)
Full source
/--
Decides whether one 32-bit signed integer is less than or equal to another. Usually accessed via the
`DecidableLE UInt32` instance.

This function is overridden at runtime with an efficient implementation.

Examples:
 * `(if (15 : UInt32) ≤ 15 then "yes" else "no") = "yes"`
 * `(if (15 : UInt32) ≤ 5 then "yes" else "no") = "no"`
 * `(if (5 : UInt32) ≤ 15 then "yes" else "no") = "yes"`
 * `show (7 : UInt32) ≤ 7 by decide`
-/
@[extern "lean_uint32_dec_le"]
def UInt32.decLe (a b : UInt32) : Decidable (LE.le a b) :=
  inferInstanceAs (Decidable (LE.le a.toBitVec b.toBitVec))
Decidability of the less-than-or-equal-to relation on unsigned 32-bit integers
Informal description
Given two unsigned 32-bit integers \( a \) and \( b \), the proposition \( a \leq b \) is decidable. This means there exists a constructive procedure to determine whether \( a \) is less than or equal to \( b \) under the canonical partial order on unsigned 32-bit integers.
instDecidableLtUInt32 instance
(a b : UInt32) : Decidable (LT.lt a b)
Full source
instance (a b : UInt32) : Decidable (LT.lt a b) := UInt32.decLt a b
Decidability of Strict Order on Unsigned 32-bit Integers
Informal description
For any two unsigned 32-bit integers \( a \) and \( b \), the proposition \( a < b \) is decidable.
instDecidableLeUInt32 instance
(a b : UInt32) : Decidable (LE.le a b)
Full source
instance (a b : UInt32) : Decidable (LE.le a b) := UInt32.decLe a b
Decidability of the $\leq$ Relation on Unsigned 32-bit Integers
Informal description
For any two unsigned 32-bit integers $a$ and $b$, the proposition $a \leq b$ is decidable. This means there exists a constructive procedure to determine whether $a$ is less than or equal to $b$ under the canonical partial order on unsigned 32-bit integers.
instMaxUInt32 instance
: Max UInt32
Full source
instance : Max UInt32 := maxOfLe
Maximum Operation on Unsigned 32-bit Integers
Informal description
The type of unsigned 32-bit integers `UInt32` is equipped with a canonical maximum operation, where for any two elements `a` and `b`, the maximum is defined as `b` if `a ≤ b` and `a` otherwise.
instMinUInt32 instance
: Min UInt32
Full source
instance : Min UInt32 := minOfLe
Minimum Operation on Unsigned 32-bit Integers
Informal description
The type of unsigned 32-bit integers `UInt32` is equipped with a canonical minimum operation, where for any two elements `a` and `b`, the minimum is defined as `a` if `a ≤ b` and `b` otherwise.
UInt64.size abbrev
: Nat
Full source
/-- The number of distinct values representable by `UInt64`, that is, `2^64 = 18446744073709551616`. -/
abbrev UInt64.size : Nat := 18446744073709551616
Cardinality of UInt64: $2^{64}$
Informal description
The number of distinct values representable by an unsigned 64-bit integer, which is $2^{64} = 18446744073709551616$.
UInt64 structure
Full source
/--
Unsigned 64-bit integers.

This type has special support in the compiler so it can be represented by an unboxed 64-bit value
rather than wrapping a `BitVec 64`.
-/
structure UInt64 where
  /--
  Creates a `UInt64` from a `BitVec 64`. This function is overridden with a native implementation.
  -/
  ofBitVec ::
  /--
  Unpacks a `UInt64` into a `BitVec 64`. This function is overridden with a native implementation.
  -/
  toBitVec : BitVec 64
Unsigned 64-bit integers
Informal description
The structure representing unsigned 64-bit integers, which are stored as unboxed 64-bit values for efficiency. This type is used for computations requiring exact 64-bit unsigned arithmetic.
UInt64.ofNatLT definition
(n : @& Nat) (h : LT.lt n UInt64.size) : UInt64
Full source
/--
Converts a natural number to a 64-bit unsigned integer. Requires a proof that the number is small
enough to be representable without overflow; it must be smaller than `2^64`.

This function is overridden at runtime with an efficient implementation.
-/
@[extern "lean_uint64_of_nat"]
def UInt64.ofNatLT (n : @& Nat) (h : LT.lt n UInt64.size) : UInt64 where
  toBitVec := BitVec.ofNatLT n h
Conversion from natural number to unsigned 64-bit integer with bound check
Informal description
Given a natural number \( n \) and a proof that \( n < 2^{64} \), the function returns the corresponding unsigned 64-bit integer representation of \( n \).
UInt64.decEq definition
(a b : UInt64) : Decidable (Eq a b)
Full source
/--
Decides whether two 64-bit unsigned integers are equal. Usually accessed via the
`DecidableEq UInt64` instance.

This function is overridden at runtime with an efficient implementation.

Examples:
 * `UInt64.decEq 123 123 = .isTrue rfl`
 * `(if (6 : UInt64) = 7 then "yes" else "no") = "no"`
 * `show (7 : UInt64) = 7 by decide`
-/
@[extern "lean_uint64_dec_eq"]
def UInt64.decEq (a b : UInt64) : Decidable (Eq a b) :=
  match a, b with
  | ⟨n⟩, ⟨m⟩ =>
    dite (Eq n m)
      (fun h => isTrue (h ▸ rfl))
      (fun h => isFalse (fun h' => UInt64.noConfusion h' (fun h' => absurd h' h)))
Decidable equality for 64-bit unsigned integers
Informal description
The function `UInt64.decEq` takes two 64-bit unsigned integers `a` and `b` and returns a `Decidable` instance proving whether `a = b`. This is used to constructively decide equality of `UInt64` values, typically accessed via the `DecidableEq UInt64` instance.
instDecidableEqUInt64 instance
: DecidableEq UInt64
Full source
instance : DecidableEq UInt64 := UInt64.decEq
Decidable Equality for Unsigned 64-bit Integers
Informal description
The type of unsigned 64-bit integers has decidable equality, meaning that for any two elements `a` and `b` of type `UInt64`, the equality `a = b` can be constructively decided.
instInhabitedUInt64 instance
: Inhabited UInt64
Full source
instance : Inhabited UInt64 where
  default := UInt64.ofNatLT 0 (of_decide_eq_true rfl)
Inhabited Type of 64-bit Unsigned Integers
Informal description
The type of unsigned 64-bit integers `UInt64` is inhabited, meaning it has a default element.
USize.size abbrev
: Nat
Full source
/-- The number of distinct values representable by `USize`, that is, `2^System.Platform.numBits`. -/
abbrev USize.size : Nat := (hPow 2 System.Platform.numBits)
Definition of USize.size as $2^{\text{numBits}}$ where numBits is platform-dependent (32 or 64)
Informal description
The size of `USize` is defined as $2^n$ where $n$ is the platform word size (either 32 or 64 bits). This means `USize.size` equals either $2^{32} = 4294967296$ or $2^{64} = 18446744073709551616$.
USize.size_eq theorem
: Or (Eq USize.size 4294967296) (Eq USize.size 18446744073709551616)
Full source
theorem USize.size_eq : Or (Eq USize.size 4294967296) (Eq USize.size 18446744073709551616) :=
  show Or (Eq (hPow 2 System.Platform.numBits) 4294967296) (Eq (hPow 2 System.Platform.numBits) 18446744073709551616) from
  match System.Platform.numBits, System.Platform.numBits_eq with
  | _, Or.inl rfl => Or.inl (of_decide_eq_true rfl)
  | _, Or.inr rfl => Or.inr (of_decide_eq_true rfl)
Platform-Dependent Size of Unsigned Word-Size Integers: $|\text{USize}| = 2^{32} \lor 2^{64}$
Informal description
The size of the unsigned word-size integer type `USize` is either $2^{32} = 4294967296$ or $2^{64} = 18446744073709551616$.
USize structure
Full source
/--
Unsigned integers that are the size of a word on the platform's architecture.

On a 32-bit architecture, `USize` is equivalent to `UInt32`. On a 64-bit machine, it is equivalent
to `UInt64`.
-/
structure USize where
  /--
  Creates a `USize` from a `BitVec System.Platform.numBits`. This function is overridden with a
  native implementation.
  -/
  ofBitVec ::
  /--
  Unpacks a `USize` into a `BitVec System.Platform.numBits`. This function is overridden with a native
  implementation.
  -/
  toBitVec : BitVec System.Platform.numBits
Platform-dependent unsigned word-size integer
Informal description
The structure representing unsigned integers whose size matches the word size of the underlying platform architecture. On 32-bit systems, this is equivalent to 32-bit unsigned integers (with maximum value 4294967296), while on 64-bit systems it's equivalent to 64-bit unsigned integers (with maximum value 18446744073709551616).
USize.ofNatLT definition
(n : @& Nat) (h : LT.lt n USize.size) : USize
Full source
/--
Converts a natural number to a `USize`. Requires a proof that the number is small enough to be
representable without overflow.

This function is overridden at runtime with an efficient implementation.
-/
@[extern "lean_usize_of_nat"]
def USize.ofNatLT (n : @& Nat) (h : LT.lt n USize.size) : USize where
  toBitVec := BitVec.ofNatLT n h
Conversion from natural number to `USize` with bound check
Informal description
Given a natural number \( n \) and a proof that \( n \) is less than the maximum value of `USize` (which is platform-dependent, either \(2^{32}\) or \(2^{64}\)), the function returns the corresponding `USize` value representing \( n \).
USize.decEq definition
(a b : USize) : Decidable (Eq a b)
Full source
/--
Decides whether two word-sized unsigned integers are equal. Usually accessed via the
`DecidableEq USize` instance.

This function is overridden at runtime with an efficient implementation.

Examples:
 * `USize.decEq 123 123 = .isTrue rfl`
 * `(if (6 : USize) = 7 then "yes" else "no") = "no"`
 * `show (7 : USize) = 7 by decide`
-/
@[extern "lean_usize_dec_eq"]
def USize.decEq (a b : USize) : Decidable (Eq a b) :=
  match a, b with
  | ⟨n⟩, ⟨m⟩ =>
    dite (Eq n m)
      (fun h => isTrue (h ▸ rfl))
      (fun h => isFalse (fun h' => USize.noConfusion h' (fun h' => absurd h' h)))
Decidable equality for unsigned word-sized integers
Informal description
The function `USize.decEq` takes two unsigned word-sized integers `a` and `b` and returns a `Decidable` instance proving whether `a = b`. This is implemented by comparing the underlying natural number representations of `a` and `b`, returning `isTrue` with a proof of equality if they are equal, or `isFalse` with a proof of inequality otherwise.
instDecidableEqUSize instance
: DecidableEq USize
Full source
instance : DecidableEq USize := USize.decEq
Decidable Equality for Platform-Dependent Unsigned Integers
Informal description
The type `USize` of platform-dependent unsigned word-size integers has decidable equality. That is, for any two elements `a, b : USize`, the equality `a = b` is decidable.
instInhabitedUSize instance
: Inhabited USize
Full source
instance : Inhabited USize where
  default := USize.ofNatLT 0 USize.size_pos
Inhabitedness of Platform-Dependent Unsigned Integers
Informal description
The type `USize` of platform-dependent unsigned word-size integers is inhabited, meaning it has a default element.
Nat.isValidChar abbrev
(n : Nat) : Prop
Full source
/--
A `Nat` denotes a valid Unicode code point if it is less than `0x110000` and it is also not a
surrogate code point (the range `0xd800` to `0xdfff` inclusive).
-/
abbrev Nat.isValidChar (n : Nat) : Prop :=
  Or (LT.lt n 0xd800) (And (LT.lt 0xdfff n) (LT.lt n 0x110000))
Valid Unicode Code Point Condition for Natural Numbers
Informal description
A natural number $n$ represents a valid Unicode code point if it satisfies two conditions: 1. $n < 0x110000$ (i.e., it is within the valid Unicode range) 2. $n$ is not a surrogate code point (i.e., $n \notin [0xd800, 0xdfff]$)
UInt32.isValidChar abbrev
(n : UInt32) : Prop
Full source
/--
A `UInt32` denotes a valid Unicode code point if it is less than `0x110000` and it is also not a
surrogate code point (the range `0xd800` to `0xdfff` inclusive).
-/
abbrev UInt32.isValidChar (n : UInt32) : Prop :=
  n.toNat.isValidChar
Valid Unicode Code Point Condition for 32-bit Unsigned Integers
Informal description
A 32-bit unsigned integer $n$ represents a valid Unicode code point if it satisfies: 1. $n < 0x110000$ (within valid Unicode range) 2. $n$ is not a surrogate code point ($n \notin [0xd800, 0xdfff]$)
Char structure
Full source
/--
Characters are Unicode [scalar values](http://www.unicode.org/glossary/#unicode_scalar_value).
-/
structure Char where
  /-- The underlying Unicode scalar value as a `UInt32`. -/
  val   : UInt32
  /-- The value must be a legal scalar value. -/
  valid : val.isValidChar
Unicode Character
Informal description
The structure representing a Unicode scalar value, which is a character in the Unicode standard. Each character is uniquely identified by its code point, which must be a valid Unicode scalar value (i.e., it must not be a surrogate code point and must be within the valid Unicode range).
Char.ofNatAux definition
(n : @& Nat) (h : n.isValidChar) : Char
Full source
/--
Pack a `Nat` encoding a valid codepoint into a `Char`.
This function is overridden with a native implementation.
-/
@[extern "lean_uint32_of_nat"]
def Char.ofNatAux (n : @& Nat) (h : n.isValidChar) : Char :=
  { val := ⟨BitVec.ofNatLT n (isValidChar_UInt32 h)⟩, valid := h }
Unicode character from natural number with validity proof
Informal description
Given a natural number \( n \) and a proof \( h \) that \( n \) is a valid Unicode code point, the function constructs a Unicode character with code point \( n \). The validity condition ensures that \( n \) is within the valid Unicode range and is not a surrogate code point.
Char.ofNat definition
(n : Nat) : Char
Full source
/--
Converts a `Nat` into a `Char`. If the `Nat` does not encode a valid Unicode scalar value, `'\0'` is
returned instead.
-/
@[noinline, match_pattern]
def Char.ofNat (n : Nat) : Char :=
  dite (n.isValidChar)
    (fun h => Char.ofNatAux n h)
    (fun _ => { val := ⟨BitVec.ofNatLT 0 (of_decide_eq_true rfl)⟩, valid := Or.inl (of_decide_eq_true rfl) })
Unicode character from natural number
Informal description
The function converts a natural number \( n \) into a Unicode character. If \( n \) is a valid Unicode scalar value (i.e., it is within the valid Unicode range and not a surrogate code point), it returns the corresponding character; otherwise, it returns the null character `'\0'`.
Char.val_eq_of_eq theorem
: ∀ {c d : Char}, Eq c d → Eq c.val d.val
Full source
theorem Char.val_eq_of_eq : ∀ {c d : Char}, Eq c d → Eq c.val d.val
  | _, _, rfl => rfl
Equality of Characters Implies Equality of Code Points
Informal description
For any two Unicode characters $c$ and $d$, if $c = d$, then their underlying Unicode code point values are equal, i.e., $c.\text{val} = d.\text{val}$.
Char.ne_of_val_ne theorem
{c d : Char} (h : Not (Eq c.val d.val)) : Not (Eq c d)
Full source
theorem Char.ne_of_val_ne {c d : Char} (h : Not (Eq c.val d.val)) : Not (Eq c d) :=
  fun h' => absurd (val_eq_of_eq h') h
Inequality of Code Points Implies Inequality of Characters
Informal description
For any two Unicode characters $c$ and $d$, if their underlying Unicode code point values are not equal, i.e., $c.\text{val} \neq d.\text{val}$, then the characters themselves are not equal, i.e., $c \neq d$.
Char.val_ne_of_ne theorem
{c d : Char} (h : Not (Eq c d)) : Not (Eq c.val d.val)
Full source
theorem Char.val_ne_of_ne {c d : Char} (h : Not (Eq c d)) : Not (Eq c.val d.val) :=
  fun h' => absurd (eq_of_val_eq h') h
Inequality of Characters Implies Inequality of Code Points
Informal description
For any two Unicode characters $c$ and $d$, if $c \neq d$, then their underlying Unicode code point values are also unequal, i.e., $c.\text{val} \neq d.\text{val}$.
instDecidableEqChar instance
: DecidableEq Char
Full source
instance : DecidableEq Char :=
  fun c d =>
    match decEq c.val d.val with
    | isTrue h  => isTrue (Char.eq_of_val_eq h)
    | isFalse h => isFalse (Char.ne_of_val_ne h)
Decidable Equality for Unicode Characters
Informal description
The type of Unicode characters has decidable equality, meaning that for any two characters $c$ and $d$, the equality $c = d$ can be constructively decided by comparing their underlying Unicode code point values.
Char.utf8Size definition
(c : Char) : Nat
Full source
/-- Returns the number of bytes required to encode this `Char` in UTF-8. -/
def Char.utf8Size (c : Char) : Nat :=
  let v := c.val
  ite (LE.le v (UInt32.ofNatLT 0x7F (of_decide_eq_true rfl))) 1
    (ite (LE.le v (UInt32.ofNatLT 0x7FF (of_decide_eq_true rfl))) 2
      (ite (LE.le v (UInt32.ofNatLT 0xFFFF (of_decide_eq_true rfl))) 3 4))
UTF-8 encoding size of a Unicode character
Informal description
The function `Char.utf8Size` takes a Unicode character `c` and returns the number of bytes (1, 2, 3, or 4) required to encode `c` in UTF-8. The size is determined based on the character's Unicode code point value `v` as follows: - 1 byte if $v \leq 0x7F$ (ASCII range) - 2 bytes if $0x7F < v \leq 0x7FF$ - 3 bytes if $0x7FF < v \leq 0xFFFF$ - 4 bytes otherwise (for code points $> 0xFFFF$)
Option inductive
(α : Type u)
Full source
/--
Optional values, which are either `some` around a value from the underlying type or `none`.

`Option` can represent nullable types or computations that might fail. In the codomain of a function
type, it can also represent partiality.
-/
inductive Option (α : Type u) where
  /-- No value. -/
  | none : Option α
  /-- Some value of type `α`. -/
  | some (val : α) : Option α
Optional Values
Informal description
The type `Option α` represents optional values of type `α`, which can either be `some x` where `x : α` or `none`. This type is used to model nullable types or computations that may fail to produce a value.
instInhabitedOption instance
{α} : Inhabited (Option α)
Full source
instance {α} : Inhabited (Option α) where
  default := none
Optional Types are Inhabited
Informal description
For any type $\alpha$, the type $\text{Option } \alpha$ of optional values is inhabited, with $\text{none}$ as its default element.
Option.getD definition
(opt : Option α) (dflt : α) : α
Full source
/--
Gets an optional value, returning a given default on `none`.

This function is `@[macro_inline]`, so `dflt` will not be evaluated unless `opt` turns out to be
`none`.

Examples:
 * `(some "hello").getD "goodbye" = "hello"`
 * `none.getD "goodbye" = "hello"`
-/
@[macro_inline] def Option.getD (opt : Option α) (dflt : α) : α :=
  match opt with
  | some x => x
  | none => dflt
Default value for optional value
Informal description
Given an optional value `opt` of type `Option α` and a default value `dflt` of type `α`, this function returns the value inside `opt` if it is `some x`, otherwise it returns `dflt`. The evaluation of `dflt` is deferred until needed (when `opt` is `none`).
Option.map definition
(f : α → β) : Option α → Option β
Full source
/--
Apply a function to an optional value, if present.

From the perspective of `Option` as a container with at most one value, this is analogous to
`List.map`. It can also be accessed via the `Functor Option` instance.

Examples:
 * `(none : Option Nat).map (· + 1) = none`
 * `(some 3).map (· + 1) = some 4`
-/
@[inline] protected def Option.map (f : α → β) : Option α → Option β
  | some x => some (f x)
  | none   => none
Mapping over optional values
Informal description
Given a function $f : \alpha \to \beta$ and an optional value $x : \text{Option } \alpha$, the function $\text{Option.map } f$ applies $f$ to the value inside $x$ if it is $\text{some } a$, producing $\text{some } (f a)$, otherwise it returns $\text{none}$.
List inductive
(α : Type u)
Full source
/--
Linked lists: ordered lists, in which each element has a reference to the next element.

Most operations on linked lists take time proportional to the length of the list, because each
element must be traversed to find the next element.

`List α` is isomorphic to `Array α`, but they are useful for different things:
* `List α` is easier for reasoning, and `Array α` is modeled as a wrapper around `List α`.
* `List α` works well as a persistent data structure, when many copies of the tail are shared. When
  the value is not shared, `Array α` will have better performance because it can do destructive
  updates.
-/
inductive List (α : Type u) where
  /-- The empty list, usually written `[]`. -/
  | nil : List α
  /--
  The list whose first element is `head`, where `tail` is the rest of the list.
  Usually written `head :: tail`.
  -/
  | cons (head : α) (tail : List α) : List α
Linked List
Informal description
The type `List α` represents a linked list of elements of type `α`, where each element contains a reference to the next element in the list. Linked lists are ordered collections that are particularly suited for reasoning and persistent data structures, where sharing of tails is common. Operations on linked lists typically have time complexity proportional to the length of the list.
instInhabitedList instance
{α} : Inhabited (List α)
Full source
instance {α} : Inhabited (List α) where
  default := List.nil
Inhabitedness of List Types
Informal description
For any type $\alpha$, the type of lists of $\alpha$ is inhabited, with the empty list as the default element.
List.hasDecEq definition
{α : Type u} [DecidableEq α] : (a b : List α) → Decidable (Eq a b)
Full source
/-- Implements decidable equality for `List α`, assuming `α` has decidable equality. -/
protected def List.hasDecEq {α : Type u} [DecidableEq α] : (a b : List α) → Decidable (Eq a b)
  | nil,       nil       => isTrue rfl
  | cons _ _, nil        => isFalse (fun h => List.noConfusion h)
  | nil,       cons _ _  => isFalse (fun h => List.noConfusion h)
  | cons a as, cons b bs =>
    match decEq a b with
    | isTrue hab  =>
      match List.hasDecEq as bs with
      | isTrue habs  => isTrue (hab ▸ habs ▸ rfl)
      | isFalse nabs => isFalse (fun h => List.noConfusion h (fun _ habs => absurd habs nabs))
    | isFalse nab => isFalse (fun h => List.noConfusion h (fun hab _ => absurd hab nab))
Decidable equality for lists
Informal description
Given a type $\alpha$ with decidable equality, the function `List.hasDecEq` provides a decision procedure for equality of two lists $a$ and $b$ in $\mathrm{List}\,\alpha$. It recursively checks if the corresponding elements of the lists are equal (using the decidable equality of $\alpha$) and returns a constructive proof of $a = b$ if they are equal, or a constructive proof of $\neg (a = b)$ otherwise.
instDecidableEqList instance
{α : Type u} [DecidableEq α] : DecidableEq (List α)
Full source
instance {α : Type u} [DecidableEq α] : DecidableEq (List α) := List.hasDecEq
Decidable Equality for Lists
Informal description
For any type $\alpha$ with decidable equality, the type of lists $\mathrm{List}\,\alpha$ also has decidable equality. That is, given two lists $a$ and $b$ in $\mathrm{List}\,\alpha$, we can algorithmically determine whether $a = b$ holds.
List.length definition
: List α → Nat
Full source
/--
The length of a list.

This function is overridden in the compiler to `lengthTR`, which uses constant stack space.

Examples:
 * `([] : List String).length = 0`
 * `["green", "brown"].length = 2`
-/
def List.length : List α → Nat
  | nil       => 0
  | cons _ as => HAdd.hAdd (length as) 1
Length of a list
Informal description
The function that computes the length of a list, defined recursively by $\text{length}(\text{nil}) = 0$ and $\text{length}(\text{cons}(a, as)) = \text{length}(as) + 1$ for any element $a$ and list $as$.
List.lengthTRAux definition
: List α → Nat → Nat
Full source
/-- Auxiliary function for `List.lengthTR`. -/
def List.lengthTRAux : List α → NatNat
  | nil,       n => n
  | cons _ as, n => lengthTRAux as (Nat.succ n)
Tail-recursive list length auxiliary function
Informal description
The auxiliary function for tail-recursive computation of the length of a list. Given a list `as` and an accumulator `n`, it returns the length of `as` plus `n`. The computation is performed in a tail-recursive manner to optimize stack usage.
List.lengthTR definition
(as : List α) : Nat
Full source
/--
The length of a list.

This is a tail-recursive version of `List.length`, used to implement `List.length` without running
out of stack space.

Examples:
 * `([] : List String).lengthTR = 0`
 * `["green", "brown"].lengthTR = 2`
-/
def List.lengthTR (as : List α) : Nat :=
  lengthTRAux as 0
Tail-recursive list length
Informal description
The tail-recursive function that computes the length of a list $as$ of elements of type $\alpha$. It is implemented using an auxiliary function with an accumulator to ensure stack safety.
List.get definition
{α : Type u} : (as : List α) → Fin as.length → α
Full source
/--
Returns the element at the provided index, counting from `0`.

In other words, for `i : Fin as.length`, `as.get i` returns the `i`'th element of the list `as`.
Because the index is a `Fin` bounded by the list's length, the index will never be out of bounds.

Examples:
 * `["spring", "summer", "fall", "winter"].get (2 : Fin 4) = "fall"`
 * `["spring", "summer", "fall", "winter"].get (0 : Fin 4) = "spring"`
-/
def List.get {α : Type u} : (as : List α) → Fin as.length → α
  | cons a _,  ⟨0, _⟩ => a
  | cons _ as, ⟨Nat.succ i, h⟩ => get as ⟨i, Nat.le_of_succ_le_succ h⟩
List element access by bounded index
Informal description
Given a list `as` of elements of type `α` and an index `i` of type `Fin as.length` (a natural number less than the length of `as`), the function returns the element at position `i` in the list. The index is guaranteed to be within bounds due to the type `Fin as.length`.
List.set definition
: (l : List α) → (n : Nat) → (a : α) → List α
Full source
/--
Replaces the value at (zero-based) index `n` in `l` with `a`. If the index is out of bounds, then
the list is returned unmodified.

Examples:
* `["water", "coffee", "soda", "juice"].set 1 "tea" = ["water", "tea", "soda", "juice"]`
* `["water", "coffee", "soda", "juice"].set 4 "tea" = ["water", "coffee", "soda", "juice"]`
-/
def List.set : (l : List α) → (n : Nat) → (a : α) → List α
  | cons _ as, 0,          b => cons b as
  | cons a as, Nat.succ n, b => cons a (set as n b)
  | nil,       _,          _ => nil
List element replacement at index
Informal description
Given a list $l$ of elements of type $\alpha$, a natural number index $n$, and an element $a$ of type $\alpha$, the function replaces the element at position $n$ in $l$ with $a$. If $n$ is out of bounds (either negative or greater than or equal to the length of $l$), the list remains unchanged. Examples: * `["water", "coffee", "soda", "juice"].set 1 "tea" = ["water", "tea", "soda", "juice"]` * `["water", "coffee", "soda", "juice"].set 4 "tea" = ["water", "coffee", "soda", "juice"]`
List.foldl definition
{α : Type u} {β : Type v} (f : α → β → α) : (init : α) → List β → α
Full source
/--
Folds a function over a list from the left, accumulating a value starting with `init`. The
accumulated value is combined with the each element of the list in order, using `f`.

Examples:
 * `[a, b, c].foldl f z  = f (f (f z a) b) c`
 * `[1, 2, 3].foldl (· ++ toString ·) "" = "123"`
 * `[1, 2, 3].foldl (s!"({·} {·})") "" = "((( 1) 2) 3)"`
-/
@[specialize]
def List.foldl {α : Type u} {β : Type v} (f : α → β → α) : (init : α) → List β → α
  | a, nil      => a
  | a, cons b l => foldl f (f a b) l
Left fold over a list
Informal description
The function `List.foldl` takes a binary operation $f : \alpha \to \beta \to \alpha$, an initial value $a : \alpha$, and a list $l : \text{List } \beta$, and returns the result of iteratively applying $f$ to the accumulated value and each element of the list from left to right. For example: - $\text{foldl } f \ a \ [b_1, b_2, b_3] = f(f(f(a, b_1), b_2), b_3)$ - $\text{foldl } (\lambda s \ x. s + \text{toString } x) \ "" \ [1, 2, 3] = "123"$ - $\text{foldl } (\lambda s \ x. s!"(\{s\} \{x\})") \ "" \ [1, 2, 3] = "((( 1) 2) 3)"$
List.concat definition
{α : Type u} : List α → α → List α
Full source
/--
Adds an element to the *end* of a list.

The added element is the last element of the resulting list.

Examples:
 * `List.concat ["red", "yellow"] "green" = ["red", "yellow", "green"]`
 * `List.concat [1, 2, 3] 4 = [1, 2, 3, 4]`
 * `List.concat [] () = [()]`
-/
def List.concat {α : Type u} : List α → α → List α
  | nil,       b => cons b nil
  | cons a as, b => cons a (concat as b)
Append element to list
Informal description
The function appends an element $b$ of type $\alpha$ to the end of a list $l$ of type $\text{List } \alpha$, resulting in a new list where $b$ is the last element.
String structure
Full source
/--
A string is a sequence of Unicode code points.

At runtime, strings are represented by [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array)
of bytes using the UTF-8 encoding. Both the size in bytes (`String.utf8ByteSize`) and in characters
(`String.length`) are cached and take constant time. Many operations on strings perform in-place
modifications when the reference to the string is unique.
-/
structure String where
  /-- Pack a `List Char` into a `String`. This function is overridden by the
  compiler and is O(n) in the length of the list. -/
  mk ::
  /-- Unpack `String` into a `List Char`. This function is overridden by the
  compiler and is O(n) in the length of the list. -/
  data : List Char
String
Informal description
A string is a sequence of Unicode code points, represented at runtime as dynamically sized arrays of bytes using UTF-8 encoding. The structure caches both the byte size (in UTF-8 encoding) and character length for constant-time access. Many string operations can perform in-place modifications when the string reference is unique.
String.decEq definition
(s₁ s₂ : @& String) : Decidable (Eq s₁ s₂)
Full source
/--
Decides whether two strings are equal. Normally used via the `DecidableEq String` instance and the
`=` operator.

At runtime, this function is overridden with an efficient native implementation.
-/
@[extern "lean_string_dec_eq"]
def String.decEq (s₁ s₂ : @& String) : Decidable (Eq s₁ s₂) :=
  match s₁, s₂ with
  | ⟨s₁⟩, ⟨s₂⟩ =>
    dite (Eq s₁ s₂) (fun h => isTrue (congrArg _ h)) (fun h => isFalse (fun h' => String.noConfusion h' (fun h' => absurd h' h)))
Decidable equality for strings
Informal description
The function `String.decEq` takes two strings `s₁` and `s₂` and returns a `Decidable` instance for the proposition `s₁ = s₂`. It constructs a proof that either `s₁` equals `s₂` (wrapped in `isTrue`) or that `s₁` does not equal `s₂` (wrapped in `isFalse`), allowing the equality of the two strings to be decided algorithmically.
instDecidableEqString instance
: DecidableEq String
Full source
instance : DecidableEq String := String.decEq
Decidable Equality for Strings
Informal description
The type of strings has decidable equality. That is, for any two strings $s_1$ and $s_2$, the equality $s_1 = s_2$ can be algorithmically decided.
String.Pos structure
Full source
/--
A byte position in a `String`, according to its UTF-8 encoding.

Character positions (counting the Unicode code points rather than bytes) are represented by plain
`Nat`s. Indexing a `String` by a `String.Pos` takes constant time, while character positions need to
be translated internally to byte positions, which takes linear time.

A byte position `p` is *valid* for a string `s` if `0 ≤ p ≤ s.endPos` and `p` lies on a UTF-8
character boundary.
-/
structure String.Pos where
  /-- Get the underlying byte index of a `String.Pos` -/
  byteIdx : Nat := 0
Byte position in a UTF-8 string
Informal description
A structure representing a byte position in a UTF-8 encoded string. A byte position `p` is valid for a string `s` if `0 ≤ p ≤ s.endPos` and `p` lies on a UTF-8 character boundary.
instInhabitedPos instance
: Inhabited String.Pos
Full source
instance : Inhabited String.Pos where
  default := {}
Inhabited Type of String Byte Positions
Informal description
The type of byte positions in a UTF-8 string is inhabited, with a default element.
instDecidableEqPos instance
: DecidableEq String.Pos
Full source
instance : DecidableEq String.Pos :=
  fun ⟨a⟩ ⟨b⟩ => match decEq a b with
    | isTrue h => isTrue (h ▸ rfl)
    | isFalse h => isFalse (fun he => String.Pos.noConfusion he fun he => absurd he h)
Decidable Equality for String Byte Positions
Informal description
Equality of byte positions in a UTF-8 string is decidable. That is, for any two byte positions `p` and `q` in a string, it is constructively decidable whether `p = q`.
Substring structure
Full source
/--
A region or slice of some underlying string.

A substring contains an string together with the start and end byte positions of a region of
interest. Actually extracting a substring requires copying and memory allocation, while many
substrings of the same underlying string may exist with very little overhead, and they are more
convenient than tracking the bounds by hand.

Using its constructor explicitly, it is possible to construct a `Substring` in which one or both of
the positions is invalid for the string. Many operations will return unexpected or confusing results
if the start and stop positions are not valid. Instead, it's better to use API functions that ensure
the validity of the positions in a substring to create and manipulate them.
-/
structure Substring where
  /-- The underlying string. -/
  str      : String
  /-- The byte position of the start of the string slice. -/
  startPos : String.Pos
  /-- The byte position of the end of the string slice. -/
  stopPos  : String.Pos
String Segment (Substring)
Informal description
A `Substring` represents a contiguous segment of a string, specified by its start and end byte positions within the underlying string. This structure allows efficient manipulation of string segments without immediate memory allocation for the substring content. While the constructor permits invalid positions, most operations expect valid bounds for correct behavior.
instInhabitedSubstring instance
: Inhabited Substring
Full source
instance : Inhabited Substring where
  default := ⟨"", {}, {}⟩
Inhabited Substring Type
Informal description
The type `Substring` is inhabited, with a default element representing an empty substring.
Substring.bsize definition
: Substring → Nat
Full source
/--
The number of bytes used by the string's UTF-8 encoding.
-/
@[inline] def Substring.bsize : SubstringNat
  | ⟨_, b, e⟩ => e.byteIdx.sub b.byteIdx
Byte size of a substring
Informal description
The function computes the number of bytes in a substring's UTF-8 encoding, calculated as the difference between the end and start byte positions of the substring.
String.utf8ByteSize definition
: (@& String) → Nat
Full source
/--
The number of bytes used by the string's UTF-8 encoding.

At runtime, this function takes constant time because the byte length of strings is cached.
-/
@[extern "lean_string_utf8_byte_size"]
def String.utf8ByteSize : (@& String) → Nat
  | ⟨s⟩ => go s
where
  go : List CharNat
   | .nil       => 0
   | .cons c cs => hAdd (go cs) c.utf8Size
UTF-8 byte size of a string
Informal description
The function computes the number of bytes used by a string's UTF-8 encoding. For a given string $s$, it recursively sums the UTF-8 byte sizes of each character in $s$.
instHAddPos instance
: HAdd String.Pos String.Pos String.Pos
Full source
instance : HAdd String.Pos String.Pos String.Pos where
  hAdd p₁ p₂ := { byteIdx := hAdd p₁.byteIdx p₂.byteIdx }
Addition of UTF-8 String Positions
Informal description
The type `String.Pos` representing byte positions in a UTF-8 string is equipped with a heterogeneous addition operation, where adding two positions yields another position.
instHSubPos instance
: HSub String.Pos String.Pos String.Pos
Full source
instance : HSub String.Pos String.Pos String.Pos where
  hSub p₁ p₂ := { byteIdx := HSub.hSub p₁.byteIdx p₂.byteIdx }
Subtraction of UTF-8 String Positions
Informal description
The type `String.Pos` representing byte positions in a UTF-8 string is equipped with a heterogeneous subtraction operation, where subtracting two positions yields another position.
instHAddPosChar instance
: HAdd String.Pos Char String.Pos
Full source
instance : HAdd String.Pos Char String.Pos where
  hAdd p c := { byteIdx := hAdd p.byteIdx c.utf8Size }
Addition of UTF-8 String Positions with Unicode Characters
Informal description
The type `String.Pos` representing byte positions in a UTF-8 string is equipped with a heterogeneous addition operation, where adding a position and a Unicode character yields another position.
instHAddPosString instance
: HAdd String.Pos String String.Pos
Full source
instance : HAdd String.Pos String String.Pos where
  hAdd p s := { byteIdx := hAdd p.byteIdx s.utf8ByteSize }
Addition of UTF-8 String Positions with Strings
Informal description
The type `String.Pos` representing byte positions in a UTF-8 string is equipped with a heterogeneous addition operation, where adding a position and a string yields another position.
instLEPos instance
: LE String.Pos
Full source
instance : LE String.Pos where
  le p₁ p₂ := LE.le p₁.byteIdx p₂.byteIdx
Partial Order on String Positions
Informal description
The type `String.Pos` representing byte positions in a UTF-8 encoded string is equipped with a canonical partial order structure given by the less-than-or-equal-to relation $\leq$.
instLTPos instance
: LT String.Pos
Full source
instance : LT String.Pos where
  lt p₁ p₂ := LT.lt p₁.byteIdx p₂.byteIdx
The Strict Order Structure on String Positions
Informal description
The type `String.Pos` representing byte positions in a UTF-8 encoded string is equipped with a canonical strict order structure given by the less-than relation $<$.
instDecidableLePos instance
(p₁ p₂ : String.Pos) : Decidable (LE.le p₁ p₂)
Full source
instance (p₁ p₂ : String.Pos) : Decidable (LE.le p₁ p₂) :=
  inferInstanceAs (Decidable (LE.le p₁.byteIdx p₂.byteIdx))
Decidability of Partial Order on String Positions
Informal description
For any two byte positions $p₁$ and $p₂$ in a UTF-8 encoded string, the proposition $p₁ \leq p₂$ is decidable. This means there exists a constructive procedure to determine whether $p₁$ is less than or equal to $p₂$ in the canonical partial order on string positions.
instDecidableLtPos instance
(p₁ p₂ : String.Pos) : Decidable (LT.lt p₁ p₂)
Full source
instance (p₁ p₂ : String.Pos) : Decidable (LT.lt p₁ p₂) :=
  inferInstanceAs (Decidable (LT.lt p₁.byteIdx p₂.byteIdx))
Decidability of Strict Order on String Positions
Informal description
For any two byte positions $p_1$ and $p_2$ in a UTF-8 encoded string, the proposition $p_1 < p_2$ is decidable. This means there exists a constructive procedure to determine whether $p_1$ is strictly less than $p_2$ in the canonical order on string positions.
instMinPos instance
: Min String.Pos
Full source
instance : Min String.Pos := minOfLe
Minimum Operation on String Positions
Informal description
The type `String.Pos` representing byte positions in a UTF-8 encoded string is equipped with a minimum operation, where the minimum of two positions is defined using the canonical partial order on string positions.
instMaxPos instance
: Max String.Pos
Full source
instance : Max String.Pos := maxOfLe
Maximum Operation on String Positions
Informal description
The type `String.Pos` representing byte positions in a UTF-8 encoded string is equipped with a canonical maximum operation, where for any two positions $p₁$ and $p₂$, $\max(p₁, p₂)$ returns the greater of the two positions according to the partial order on string positions.
String.endPos definition
(s : String) : String.Pos
Full source
/--
A UTF-8 byte position that points at the end of a string, just after the last character.

* `"abc".endPos = ⟨3⟩`
* `"L∃∀N".endPos = ⟨8⟩`
-/
@[inline] def String.endPos (s : String) : String.Pos where
  byteIdx := utf8ByteSize s
End position of a UTF-8 string
Informal description
For a given string $s$, the function returns the byte position immediately after the last character of $s$ in its UTF-8 encoding. - For the string `"abc"`, the end position is `3`. - For the string `"L∃∀N"`, the end position is `8`.
String.toSubstring definition
(s : String) : Substring
Full source
/--
Converts a `String` into a `Substring` that denotes the entire string.
-/
@[inline] def String.toSubstring (s : String) : Substring where
  str      := s
  startPos := {}
  stopPos  := s.endPos
String to full substring conversion
Informal description
The function takes a string $s$ and returns a substring that spans the entire string $s$, from the start position (byte 0) to the end position (immediately after the last character of $s$ in its UTF-8 encoding).
String.toSubstring' definition
(s : String) : Substring
Full source
/--
Converts a `String` into a `Substring` that denotes the entire string.

This is a version of `String.toSubstring` that doesn't have an `@[inline]` annotation.
-/
def String.toSubstring' (s : String) : Substring :=
  s.toSubstring
String to full substring conversion (non-inlined)
Informal description
The function takes a string $s$ and returns a substring that spans the entire string $s$, from the start position (byte 0) to the end position (immediately after the last character of $s$ in its UTF-8 encoding). This is a non-inlined version of `String.toSubstring`.
unsafeCast definition
{α : Sort u} {β : Sort v} (a : α) : β
Full source
/--
This function will cast a value of type `α` to type `β`, and is a no-op in the
compiler. This function is **extremely dangerous** because there is no guarantee
that types `α` and `β` have the same data representation, and this can lead to
memory unsafety. It is also logically unsound, since you could just cast
`True` to `False`. For all those reasons this function is marked as `unsafe`.

It is implemented by lifting both `α` and `β` into a common universe, and then
using `cast (lcProof : ULift (PLift α) = ULift (PLift β))` to actually perform
the cast. All these operations are no-ops in the compiler.

Using this function correctly requires some knowledge of the data representation
of the source and target types. Some general classes of casts which are safe in
the current runtime:

* `Array α` to `Array β` where `α` and `β` have compatible representations,
  or more generally for other inductive types.
* `Quot α r` and `α`.
* `@Subtype α p` and `α`, or generally any structure containing only one
  non-`Prop` field of type `α`.
* Casting `α` to/from `NonScalar` when `α` is a boxed generic type
  (i.e. a function that accepts an arbitrary type `α` and is not specialized to
  a scalar type like `UInt8`).
-/
unsafe def unsafeCast {α : Sort u} {β : Sort v} (a : α) : β :=
  PLift.down (ULift.down.{max u v} (cast lcProof (ULift.up.{max u v} (PLift.up a))))
Unsafe type casting
Informal description
The function `unsafeCast` takes a value of type `α` and returns a value of type `β` without any runtime checks. This operation is highly unsafe as it can lead to memory unsafety and logical inconsistencies if the types `α` and `β` have different data representations. The implementation involves lifting both types to a common universe and using a proof of equality to perform the cast, but all these operations are no-ops in the compiler.
panicCore definition
{α : Sort u} [Inhabited α] (msg : String) : α
Full source
/-- Auxiliary definition for `panic`. -/
/-
This is a workaround for `panic` occurring in monadic code. See issue #695.
The `panicCore` definition cannot be specialized since it is an extern.
When `panic` occurs in monadic code, the `Inhabited α` parameter depends on a
`[inst : Monad m]` instance. The `inst` parameter will not be eliminated during
specialization if it occurs inside of a binder (to avoid work duplication), and
will prevent the actual monad from being "copied" to the code being specialized.
When we reimplement the specializer, we may consider copying `inst` if it also
occurs outside binders or if it is an instance.
-/
@[never_extract, extern "lean_panic_fn"]
def panicCore {α : Sort u} [Inhabited α] (msg : String) : α := default
Core panic function returning default value
Informal description
The function `panicCore` takes a type `α` with a default value (via `Inhabited α`) and an error message string, and returns the default value of `α`. This is an auxiliary function used to implement panic behavior when an unrecoverable error occurs.
panic definition
{α : Sort u} [Inhabited α] (msg : String) : α
Full source
/--
`(panic "msg" : α)` has a built-in implementation which prints `msg` to
the error buffer. It *does not* terminate execution, and because it is a safe
function, it still has to return an element of `α`, so it takes `[Inhabited α]`
and returns `default`. It is primarily intended for debugging in pure contexts,
and assertion failures.

Because this is a pure function with side effects, it is marked as
`@[never_extract]` so that the compiler will not perform common sub-expression
elimination and other optimizations that assume that the expression is pure.
-/
@[noinline, never_extract]
def panic {α : Sort u} [Inhabited α] (msg : String) : α :=
  panicCore msg
Panic function returning default value
Informal description
The function `panic` takes a type `α` with a default value (via `Inhabited α`) and an error message string `msg`, prints `msg` to the error buffer, and returns the default value of `α`. It is primarily intended for debugging in pure contexts and assertion failures, and does not terminate execution.
Array structure
(α : Type u)
Full source
/--
`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements
from `α`. This type has special support in the runtime.

Arrays perform best when unshared. As long as there is never more than one reference to an array,
all updates will be performed _destructively_. This results in performance comparable to mutable
arrays in imperative programming languages.

An array has a size and a capacity. The size is the number of elements present in the array, while
the capacity is the amount of memory currently allocated for elements. The size is accessible via
`Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates
an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size
exceeds the capacity, allocation is required to grow the array.

From the point of view of proofs, `Array α` is just a wrapper around `List α`.
-/
structure Array (α : Type u) where
  /--
  Converts a `List α` into an `Array α`.

  The function `List.toArray` is preferred.

  At runtime, this constructor is overridden by `List.toArrayImpl` and is `O(n)` in the length of
  the list.
  -/
  mk ::
  /--
  Converts an `Array α` into a `List α` that contains the same elements in the same order.

  At runtime, this is implemented by `Array.toListImpl` and is `O(n)` in the length of the
  array.
  -/
  toList : List α
Dynamic Array
Informal description
The type `Array α` represents dynamic arrays with elements of type `α`. It is implemented as a wrapper around lists in Lean, but with special runtime support for efficient destructive updates when the array is unshared. The size of an array (number of elements) is observable, while its capacity (allocated memory) is not. Arrays perform best when there is only one reference to them, allowing in-place updates.
List.toArray abbrev
(xs : List α) : Array α
Full source
/--
Converts a `List α` into an `Array α`.

 `O(|xs|)`. At runtime, this operation is implemented by `List.toArrayImpl` and takes time linear in
the length of the list. `List.toArray` should be used instead of `Array.mk`.

Examples:
 * `[1, 2, 3].toArray = #[1, 2, 3]`
 * `["monday", "wednesday", friday"].toArray = #["monday", "wednesday", friday"].`
-/
@[match_pattern]
abbrev List.toArray (xs : List α) : Array α := .mk xs
List to Array Conversion
Informal description
Given a list `xs` of elements of type `α`, the function `List.toArray` constructs an array containing the same elements in the same order. The operation has time complexity $O(n)$ where $n$ is the length of the list.
Array.mkEmpty definition
{α : Type u} (c : @& Nat) : Array α
Full source
/--
Constructs a new empty array with initial capacity `c`.

This will be deprecated in favor of `Array.emptyWithCapacity` in the future.
-/
@[extern "lean_mk_empty_array_with_capacity"]
def Array.mkEmpty {α : Type u} (c : @& Nat) : Array α where
  toList := List.nil
Empty array with initial capacity
Informal description
The function creates a new empty array of type `α` with an initial capacity of `c` natural number elements.
Array.emptyWithCapacity definition
{α : Type u} (c : @& Nat) : Array α
Full source
/--
Constructs a new empty array with initial capacity `c`.
-/
def Array.emptyWithCapacity {α : Type u} (c : @& Nat) : Array α where
  toList := List.nil
Empty array with initial capacity
Informal description
The function creates a new empty array of type $\alpha$ with an initial capacity of $c$ natural number elements.
Array.empty definition
{α : Type u} : Array α
Full source
/--
Constructs a new empty array with initial capacity `0`.

Use `Array.emptyWithCapacity` to create an array with a greater initial capacity.
-/
def Array.empty {α : Type u} : Array α := emptyWithCapacity 0
Empty array
Informal description
The function creates a new empty array of type $\alpha$ with initial capacity $0$.
Array.size definition
{α : Type u} (a : @& Array α) : Nat
Full source
/--
Gets the number of elements stored in an array.

This is a cached value, so it is `O(1)` to access. The space allocated for an array, referred to as
its _capacity_, is at least as large as its size, but may be larger. The capacity of an array is an
internal detail that's not observable by Lean code.
-/
@[reducible, extern "lean_array_get_size"]
def Array.size {α : Type u} (a : @& Array α) : Nat :=
 a.toList.length
Size of an array
Informal description
The function returns the number of elements in an array `a` of type `α`, which is equal to the length of its underlying list representation.
Array.getInternal definition
{α : Type u} (a : @& Array α) (i : @& Nat) (h : LT.lt i a.size) : α
Full source
/--
Use the indexing notation `a[i]` instead.

Access an element from an array without needing a runtime bounds checks,
using a `Nat` index and a proof that it is in bounds.

This function does not use `get_elem_tactic` to automatically find the proof that
the index is in bounds. This is because the tactic itself needs to look up values in
arrays.
-/
@[extern "lean_array_fget"]
def Array.getInternal {α : Type u} (a : @& Array α) (i : @& Nat) (h : LT.lt i a.size) : α :=
  a.toList.get ⟨i, h⟩
Array element access with bounds proof
Informal description
Given an array `a` of type `α`, a natural number index `i`, and a proof that `i` is less than the size of `a`, the function returns the element at position `i` in the array. This is implemented by converting the array to a list and accessing the element at the corresponding position in the list.
Array.getD abbrev
(a : Array α) (i : Nat) (v₀ : α) : α
Full source
/--
Returns the element at the provided index, counting from `0`. Returns the fallback value `v₀` if the
index is out of bounds.

To return an `Option` depending on whether the index is in bounds, use `a[i]?`. To panic if the
index is out of bounds, use `a[i]!`.

Examples:
 * `#["spring", "summer", "fall", "winter"].getD 2 "never" = "fall"`
 * `#["spring", "summer", "fall", "winter"].getD 0 "never" = "spring"`
 * `#["spring", "summer", "fall", "winter"].getD 4 "never" = "never"`
-/
@[inline] abbrev Array.getD (a : Array α) (i : Nat) (v₀ : α) : α :=
  dite (LT.lt i a.size) (fun h => a.getInternal i h) (fun _ => v₀)
Array Element Access with Default Value
Informal description
Given an array $a$ of type $\alpha$, a natural number index $i$, and a default value $v_0$ of type $\alpha$, the function returns the element at position $i$ in $a$ if $i$ is within bounds (i.e., $0 \leq i < \text{size}(a)$), and returns $v_0$ otherwise.
Array.get!Internal definition
{α : Type u} [Inhabited α] (a : @& Array α) (i : @& Nat) : α
Full source
/--
Use the indexing notation `a[i]!` instead.

Access an element from an array, or panic if the index is out of bounds.
-/
@[extern "lean_array_get"]
def Array.get!Internal {α : Type u} [Inhabited α] (a : @& Array α) (i : @& Nat) : α :=
  Array.getD a i default
Safe array access with default fallback
Informal description
Given an array $a$ of type $\alpha$ (where $\alpha$ is an inhabited type with a default value) and a natural number index $i$, the function returns the element at position $i$ in $a$ if $i$ is within bounds (i.e., $0 \leq i < \text{size}(a)$), and returns the default value of $\alpha$ otherwise. This is a panic-free version of array access that uses the type's default value when out of bounds.
Array.push definition
{α : Type u} (a : Array α) (v : α) : Array α
Full source
/--
Adds an element to the end of an array. The resulting array's size is one greater than the input
array. If there are no other references to the array, then it is modified in-place.

This takes amortized `O(1)` time because `Array α` is represented by a dynamic array.

Examples:
* `#[].push "apple" = #["apple"]`
* `#["apple"].push "orange" = #["apple", "orange"]`
-/
@[extern "lean_array_push"]
def Array.push {α : Type u} (a : Array α) (v : α) : Array α where
  toList := List.concat a.toList v
Append element to array
Informal description
The function appends an element $v$ of type $\alpha$ to the end of an array $a$ of type $\text{Array } \alpha$, resulting in a new array where $v$ is the last element. This operation has amortized $O(1)$ time complexity due to the dynamic array implementation.
Array.mkArray0 definition
{α : Type u} : Array α
Full source
/-- Create array `#[]` -/
def Array.mkArray0 {α : Type u} : Array α :=
  emptyWithCapacity 0
Empty array with zero capacity
Informal description
The function creates a new empty array of type $\alpha$ with zero initial capacity.
Array.mkArray1 definition
{α : Type u} (a₁ : α) : Array α
Full source
/-- Create array `#[a₁]` -/
def Array.mkArray1 {α : Type u} (a₁ : α) : Array α :=
  (emptyWithCapacity 1).push a₁
Singleton array constructor
Informal description
The function creates a new array of type $\alpha$ containing exactly one element $a_1$. Internally, it first creates an empty array with capacity for one element and then pushes $a_1$ into it.
Array.mkArray2 definition
{α : Type u} (a₁ a₂ : α) : Array α
Full source
/-- Create array `#[a₁, a₂]` -/
def Array.mkArray2 {α : Type u} (a₁ a₂ : α) : Array α :=
  ((emptyWithCapacity 2).push a₁).push a₂
Two-element array constructor
Informal description
The function creates an array of type $\alpha$ containing exactly two elements $a_1$ and $a_2$ in order. It first creates an empty array with capacity for 2 elements, then pushes $a_1$ and $a_2$ sequentially to construct the final array.
Array.mkArray3 definition
{α : Type u} (a₁ a₂ a₃ : α) : Array α
Full source
/-- Create array `#[a₁, a₂, a₃]` -/
def Array.mkArray3 {α : Type u} (a₁ a₂ a₃ : α) : Array α :=
  (((emptyWithCapacity 3).push a₁).push a₂).push a₃
Three-element array constructor
Informal description
The function creates an array of type $\text{Array } \alpha$ containing exactly three elements $a_1, a_2, a_3$ of type $\alpha$ in that order. The array is constructed by starting with an empty array of capacity 3 and successively pushing each element onto it.
Array.mkArray4 definition
{α : Type u} (a₁ a₂ a₃ a₄ : α) : Array α
Full source
/-- Create array `#[a₁, a₂, a₃, a₄]` -/
def Array.mkArray4 {α : Type u} (a₁ a₂ a₃ a₄ : α) : Array α :=
  ((((emptyWithCapacity 4).push a₁).push a₂).push a₃).push a₄
Array constructor for four elements
Informal description
The function creates an array `#[a₁, a₂, a₃, a₄]` of type `Array α` containing the four elements `a₁`, `a₂`, `a₃`, and `a₄` in order.
Array.mkArray5 definition
{α : Type u} (a₁ a₂ a₃ a₄ a₅ : α) : Array α
Full source
/-- Create array `#[a₁, a₂, a₃, a₄, a₅]` -/
def Array.mkArray5 {α : Type u} (a₁ a₂ a₃ a₄ a₅ : α) : Array α :=
  (((((emptyWithCapacity 5).push a₁).push a₂).push a₃).push a₄).push a₅
Array of five elements
Informal description
The function creates an array of type $\text{Array } \alpha$ containing the five elements $a_1, a_2, a_3, a_4, a_5$ in order.
Array.mkArray6 definition
{α : Type u} (a₁ a₂ a₃ a₄ a₅ a₆ : α) : Array α
Full source
/-- Create array `#[a₁, a₂, a₃, a₄, a₅, a₆]` -/
def Array.mkArray6 {α : Type u} (a₁ a₂ a₃ a₄ a₅ a₆ : α) : Array α :=
  ((((((emptyWithCapacity 6).push a₁).push a₂).push a₃).push a₄).push a₅).push a₆
Array constructor for six elements
Informal description
The function creates an array of type $\text{Array } \alpha$ containing the six elements $a_1, a_2, a_3, a_4, a_5, a_6$ in order.
Array.mkArray7 definition
{α : Type u} (a₁ a₂ a₃ a₄ a₅ a₆ a₇ : α) : Array α
Full source
/-- Create array `#[a₁, a₂, a₃, a₄, a₅, a₆, a₇]` -/
def Array.mkArray7 {α : Type u} (a₁ a₂ a₃ a₄ a₅ a₆ a₇ : α) : Array α :=
  (((((((emptyWithCapacity 7).push a₁).push a₂).push a₃).push a₄).push a₅).push a₆).push a₇
Array of seven elements
Informal description
The function creates an array of type $\alpha$ containing exactly seven elements $a_1, a_2, a_3, a_4, a_5, a_6, a_7$ in that order.
Array.mkArray8 definition
{α : Type u} (a₁ a₂ a₃ a₄ a₅ a₆ a₇ a₈ : α) : Array α
Full source
/-- Create array `#[a₁, a₂, a₃, a₄, a₅, a₆, a₇, a₈]` -/
def Array.mkArray8 {α : Type u} (a₁ a₂ a₃ a₄ a₅ a₆ a₇ a₈ : α) : Array α :=
  ((((((((emptyWithCapacity 8).push a₁).push a₂).push a₃).push a₄).push a₅).push a₆).push a₇).push a₈
Array constructor for eight elements
Informal description
The function creates an array of type $\text{Array } \alpha$ containing exactly eight elements $a_1, a_2, a_3, a_4, a_5, a_6, a_7, a_8$ in that order.
Array.appendCore definition
{α : Type u} (as : Array α) (bs : Array α) : Array α
Full source
/-- Slower `Array.append` used in quotations. -/
protected def Array.appendCore {α : Type u}  (as : Array α) (bs : Array α) : Array α :=
  let rec loop (i : Nat) (j : Nat) (as : Array α) : Array α :=
    dite (LT.lt j bs.size)
      (fun hlt =>
        match i with
        | 0           => as
        | Nat.succ i' => loop i' (hAdd j 1) (as.push (bs.getInternal j hlt)))
      (fun _ => as)
  loop bs.size 0 as
Array concatenation (core implementation)
Informal description
The function concatenates two arrays `as` and `bs` of type `α` by iteratively pushing elements from `bs` onto `as`. The implementation uses a helper loop that processes each element of `bs` in order, stopping when all elements have been appended or when the loop counter reaches zero (though the latter condition should never occur in normal operation since the loop counter is initialized to `bs.size`).
Bind structure
(m : Type u → Type v)
Full source
/--
The `>>=` operator is overloaded via instances of `bind`.

`Bind` is typically used via `Monad`, which extends it.
-/
class Bind (m : Type u → Type v) where
  /--
  Sequences two computations, allowing the second to depend on the value computed by the first.

  If `x : m α` and `f : α → m β`, then `x >>= f : m β` represents the result of executing `x` to get
  a value of type `α` and then passing it to `f`.
  -/
  bind : {α β : Type u} → m α → (α → m β) → m β
Bind operation type class
Informal description
The structure `Bind` represents the type class for the bind operation `>>=` in monadic contexts. It is typically used via the `Monad` type class, which extends it. The bind operation allows chaining of computations in a monadic context by applying a function to the result of a previous computation.
Pure structure
(f : Type u → Type v)
Full source
/--
The `pure` function is overloaded via `Pure` instances.

`Pure` is typically accessed via `Monad` or `Applicative` instances.
-/
class Pure (f : Type u → Type v) where
  /--
  Given `a : α`, then `pure a : f α` represents an action that does nothing and returns `a`.

  Examples:
  * `(pure "hello" : Option String) = some "hello"`
  * `(pure "hello" : Except (Array String) String) = Except.ok "hello"`
  * `(pure "hello" : StateM Nat String).run 105 = ("hello", 105)`
  -/
  pure {α : Type u} : α → f α
Pure type class
Informal description
The structure `Pure` represents the type class for the `pure` function, which lifts a value into a computational context. It is typically used via the `Applicative` or `Monad` type classes, which extend it. The `pure` function is fundamental in applicative and monadic programming, allowing values to be embedded in a context without any side effects.
Functor structure
(f : Type u → Type v)
Full source
/--
A functor in the sense used in functional programming, which means a function `f : Type u → Type v`
has a way of mapping a function over its contents. This `map` operator is written `<$>`, and
overloaded via `Functor` instances.

This `map` function should respect identity and function composition. In other words, for all terms
`v : f α`, it should be the case that:

 * `id <$> v = v`

 * For all functions `h : β → γ` and `g : α → β`, `(h ∘ g) <$> v = h <$> g <$> v`

While all `Functor` instances should live up to these requirements, they are not required to _prove_
that they do. Proofs may be required or provided via the `LawfulFunctor` class.

Assuming that instances are lawful, this definition corresponds to the category-theoretic notion of
[functor](https://en.wikipedia.org/wiki/Functor) in the special case where the category is the
category of types and functions between them.
-/
class Functor (f : Type u → Type v) : Type (max (u+1) v) where
  /--
  Applies a function inside a functor. This is used to overload the `<$>` operator.

  When mapping a constant function, use `Functor.mapConst` instead, because it may be more
  efficient.
  -/
  map : {α β : Type u} → (α → β) → f α → f β
  /--
  Mapping a constant function.

  Given `a : α` and `v : f α`, `mapConst a v` is equivalent to `Function.const _ a <$> v`. For some
  functors, this can be implemented more efficiently; for all other functors, the default
  implementation may be used.
  -/
  mapConst : {α β : Type u} → α → f β → f α := Function.comp map (Function.const _)
Functor in functional programming
Informal description
A functor in functional programming is a type constructor `f : Type → Type` equipped with a mapping operation that applies a function to the contents of the functor. The mapping operation, denoted `<$>`, must satisfy the following properties for all terms `v : f α`: 1. Identity: `id <$> v = v` 2. Composition: For any functions `h : β → γ` and `g : α → β`, `(h ∘ g) <$> v = h <$> (g <$> v)` While these properties are required for all functors, they are not enforced by the type system. Proofs of these properties can be provided separately via the `LawfulFunctor` class. This concept corresponds to the category-theoretic notion of a functor in the category of types and functions between them.
Seq structure
(f : Type u → Type v)
Full source
/--
The `<*>` operator is overloaded using the function `Seq.seq`.

While `<$>` from the class `Functor` allows an ordinary function to be mapped over its contents,
`<*>` allows a function that's “inside” the functor to be applied. When thinking about `f` as
possible side effects, this captures evaluation order: `seq` arranges for the effects that produce
the function to occur prior to those that produce the argument value.

For most applications, `Applicative` or `Monad` should be used rather than `Seq` itself.
-/
class Seq (f : Type u → Type v) : Type (max (u+1) v) where
  /--
  The implementation of the `<*>` operator.

  In a monad, `mf <*> mx` is the same as `do let f ← mf; x ← mx; pure (f x)`: it evaluates the
  function first, then the argument, and applies one to the other.

  To avoid surprising evaluation semantics, `mx` is taken "lazily", using a `Unit → f α` function.
  -/
  seq : {α β : Type u} → f (α → β) → (Unit → f α) → f β
Sequencing operation for functors
Informal description
The structure `Seq` represents the sequencing operation `<*>` for functors. This operation allows applying a function that is "inside" a functor to a value that is also inside the functor, while preserving the evaluation order of effects. It extends the capabilities of `Functor`'s `<$>` operation by handling functions within the functor context.
SeqLeft structure
(f : Type u → Type v)
Full source
/--
The `<*` operator is overloaded using `seqLeft`.

When thinking about `f` as potential side effects, `<*` evaluates first the left and then the right
argument for their side effects, discarding the value of the right argument and returning the value
of the left argument.

For most applications, `Applicative` or `Monad` should be used rather than `SeqLeft` itself.
-/
class SeqLeft (f : Type u → Type v) : Type (max (u+1) v) where
  /--
  Sequences the effects of two terms, discarding the value of the second. This function is usually
  invoked via the `<*` operator.

  Given `x : f α` and `y : f β`, `x <* y` runs `x`, then runs `y`, and finally returns the result of
  `x`.

  The evaluation of the second argument is delayed by wrapping it in a function, enabling
  “short-circuiting” behavior from `f`.
  -/
  seqLeft : {α β : Type u} → f α → (Unit → f β) → f α
Sequencing operator for side effects (left-biased)
Informal description
The structure `SeqLeft` represents a type constructor `f` that supports the `<*` operator, which evaluates both its left and right arguments for their potential side effects but discards the value of the right argument and returns the value of the left argument. This is typically used in contexts where sequencing of side effects is important, such as in applicative or monadic programming.
SeqRight structure
(f : Type u → Type v)
Full source
/--
The `*>` operator is overloaded using `seqRight`.

When thinking about `f` as potential side effects, `*>` evaluates first the left and then the right
argument for their side effects, discarding the value of the left argument and returning the value
of the right argument.

For most applications, `Applicative` or `Monad` should be used rather than `SeqLeft` itself.
-/
class SeqRight (f : Type u → Type v) : Type (max (u+1) v) where
  /--
  Sequences the effects of two terms, discarding the value of the first. This function is usually
  invoked via the `*>` operator.

  Given `x : f α` and `y : f β`, `x *> y` runs `x`, then runs `y`, and finally returns the result of
  `y`.

  The evaluation of the second argument is delayed by wrapping it in a function, enabling
  “short-circuiting” behavior from `f`.
  -/
  seqRight : {α β : Type u} → f α → (Unit → f β) → f β
Sequential evaluation discarding left result
Informal description
The structure `SeqRight` represents the `*>` operator, which evaluates two computations sequentially, discarding the result of the first and returning the result of the second. This is typically used for sequencing side effects in an applicative or monadic context.
Applicative structure
(f : Type u → Type v) extends Functor f, Pure f, Seq f, SeqLeft f, SeqRight f
Full source
/--
An [applicative functor](lean-manual://section/monads-and-do) is more powerful than a `Functor`, but
less powerful than a `Monad`.

Applicative functors capture sequencing of effects with the `<*>` operator, overloaded as `seq`, but
not data-dependent effects. The results of earlier computations cannot be used to control later
effects.

Applicative functors should satisfy four laws. Instances of `Applicative` are not required to prove
that they satisfy these laws, which are part of the `LawfulApplicative` class.
-/
class Applicative (f : Type u → Type v) extends Functor f, Pure f, Seq f, SeqLeft f, SeqRight f where
  map      := fun x y => Seq.seq (pure x) fun _ => y
  seqLeft  := fun a b => Seq.seq (Functor.map (Function.const _) a) b
  seqRight := fun a b => Seq.seq (Functor.map (Function.const _ id) a) b
Applicative Functor
Informal description
An applicative functor is a structure that extends a functor with operations for sequencing computations (`Seq`), injecting pure values (`Pure`), and left/right sequencing (`SeqLeft`, `SeqRight`). It is more powerful than a functor but less powerful than a monad, as it allows sequencing of effects without data-dependent control flow.
Monad structure
(m : Type u → Type v) : Type (max (u+1) v) extends Applicative m, Bind m
Full source
/--
[Monads](https://en.wikipedia.org/wiki/Monad_(functional_programming)) are an abstraction of
sequential control flow and side effects used in functional programming. Monads allow both
sequencing of effects and data-dependent effects: the values that result from an early step may
influence the effects carried out in a later step.

The `Monad` API may be used directly. However, it is most commonly accessed through
[`do`-notation](lean-manual://section/do-notation).

Most `Monad` instances provide implementations of `pure` and `bind`, and use default implementations
for the other methods inherited from `Applicative`. Monads should satisfy certain laws, but
instances are not required to prove this. An instance of `LawfulMonad` expresses that a given
monad's operations are lawful.
-/
class Monad (m : Type u → Type v) : Type (max (u+1) v) extends Applicative m, Bind m where
  map      f x := bind x (Function.comp pure f)
  seq      f x := bind f fun y => Functor.map y (x ())
  seqLeft  x y := bind x fun a => bind (y ()) (fun _ => pure a)
  seqRight x y := bind x fun _ => y ()
Monad
Informal description
A monad is a structure in functional programming that abstracts sequential control flow and side effects. It consists of two main operations: `pure` (or `return`) which lifts a value into the monadic context, and `bind` (or `>>=`) which sequences computations by passing the result of one computation to the next. Monads generalize the concept of function composition to handle side effects and are commonly used with `do`-notation for imperative-style programming. The structure extends `Applicative` and `Bind`, inheriting their operations.
instInhabitedForallOfMonad instance
{α : Type u} {m : Type u → Type v} [Monad m] : Inhabited (α → m α)
Full source
instance {α : Type u} {m : Type u → Type v} [Monad m] : Inhabited (α → m α) where
  default := pure
Inhabitedness of Monadic Functions
Informal description
For any monad $m$ and type $\alpha$, the function type $\alpha \to m \alpha$ is inhabited.
instInhabitedOfMonad instance
{α : Type u} {m : Type u → Type v} [Monad m] [Inhabited α] : Inhabited (m α)
Full source
instance {α : Type u} {m : Type u → Type v} [Monad m] [Inhabited α] : Inhabited (m α) where
  default := pure default
Monadic Preservation of Inhabitedness
Informal description
For any monad $m$ and inhabited type $\alpha$, the type $m \alpha$ is also inhabited.
instNonemptyOfMonad instance
[Monad m] : [Nonempty α] → Nonempty (m α)
Full source
instance [Monad m] : [Nonempty α] → Nonempty (m α)
  | ⟨x⟩ => ⟨pure x⟩
Monadic Preservation of Nonemptiness
Informal description
For any monad $m$ and nonempty type $\alpha$, the type $m \alpha$ is also nonempty.
MonadLift structure
(m : semiOutParam (Type u → Type v)) (n : Type u → Type w)
Full source
/--
Computations in the monad `m` can be run in the monad `n`. These translations are inserted
automatically by the compiler.

Usually, `n` consists of some number of monad transformers applied to `m`, but this is not
mandatory.

New instances should use this class, `MonadLift`. Clients that require one monad to be liftable into
another should instead request `MonadLiftT`, which is the reflexive, transitive closure of
`MonadLift`.
-/
-- Like Haskell's [`MonadTrans`], but `n` does not have to be a monad transformer.
-- Alternatively, an implementation of [`MonadLayer`] without `layerInvmap` (so far).

--   [`MonadTrans`]: https://hackage.haskell.org/package/transformers-0.5.5.0/docs/Control-Monad-Trans-Class.html
--   [`MonadLayer`]: https://hackage.haskell.org/package/layers-0.1/docs/Control-Monad-Layer.html#t:MonadLayer
class MonadLift (m : semiOutParam (Type u → Type v)) (n : Type u → Type w) where
  /-- Translates an action from monad `m` into monad `n`. -/
  monadLift : {α : Type u} → m α → n α
Monad Lifting
Informal description
The structure `MonadLift` represents the ability to lift computations from a monad `m` to another monad `n`. This is typically used when `n` is constructed by applying monad transformers to `m`, though this is not strictly required. Instances of `MonadLift` are automatically inserted by the compiler to enable lifting between monads.
MonadLiftT structure
(m : Type u → Type v) (n : Type u → Type w)
Full source
/--
Computations in the monad `m` can be run in the monad `n`. These translations are inserted
automatically by the compiler.

Usually, `n` consists of some number of monad transformers applied to `m`, but this is not
mandatory.

This is the reflexive, transitive closure of `MonadLift`. Clients that require one monad to be
liftable into another should request an instance of `MonadLiftT`. New instances should instead be
defined for `MonadLift` itself.
-/
-- Corresponds to Haskell's [`MonadLift`].
--
--   [`MonadLift`]: https://hackage.haskell.org/package/layers-0.1/docs/Control-Monad-Layer.html#t:MonadLift
class MonadLiftT (m : Type u → Type v) (n : Type u → Type w) where
  /-- Translates an action from monad `m` into monad `n`. -/
  monadLift : {α : Type u} → m α → n α
Monad Lifting (Transitive Closure)
Informal description
The structure `MonadLiftT` represents the reflexive, transitive closure of monad lifting, where computations in monad `m` can be run in monad `n`. This is typically used when `n` is constructed by applying monad transformers to `m`, though this is not strictly required. Instances of `MonadLiftT` are automatically inserted by the compiler to enable lifting between monads.
liftM abbrev
Full source
@[inherit_doc monadLift]
abbrev liftM := @monadLift
Monadic Lifting Operation
Informal description
The operation `liftM` provides a way to lift a monadic computation from one monad to another, utilizing the `MonadLiftT` structure which represents the reflexive, transitive closure of monad lifting.
instMonadLiftTOfMonadLift instance
(m n o) [MonadLift n o] [MonadLiftT m n] : MonadLiftT m o
Full source
@[always_inline]
instance (m n o) [MonadLift n o] [MonadLiftT m n] : MonadLiftT m o where
  monadLift x := MonadLift.monadLift (m := n) (monadLift x)
Transitivity of Monad Lifting
Informal description
For any monads $m$, $n$, and $o$, if there exists a monad lift from $n$ to $o$ and a transitive monad lift from $m$ to $n$, then there exists a transitive monad lift from $m$ to $o$.
instMonadLiftT instance
(m) : MonadLiftT m m
Full source
instance (m) : MonadLiftT m m where
  monadLift x := x
Reflexive Monad Lifting
Informal description
For any monad $m$, there is a reflexive monad lifting from $m$ to itself.
MonadEval structure
(m : semiOutParam (Type u → Type v)) (n : Type u → Type w)
Full source
/--
Typeclass used for adapting monads. This is similar to `MonadLift`, but instances are allowed to
make use of default state for the purpose of synthesizing such an instance, if necessary.
Every `MonadLift` instance gives a `MonadEval` instance.

The purpose of this class is for the `#eval` command,
which looks for a `MonadEval m CommandElabM` or `MonadEval m IO` instance.
-/
class MonadEval (m : semiOutParam (Type u → Type v)) (n : Type u → Type w) where
  /-- Evaluates a value from monad `m` into monad `n`. -/
  monadEval : {α : Type u} → m α → n α
Monad Evaluation Adapter
Informal description
The typeclass `MonadEval` is used for adapting monads, particularly for the `#eval` command. It allows monads to be evaluated in contexts like `CommandElabM` or `IO`, with instances potentially using default state for synthesis when necessary. Every `MonadLift` instance automatically provides a `MonadEval` instance.
instMonadEvalOfMonadLift instance
[MonadLift m n] : MonadEval m n
Full source
instance [MonadLift m n] : MonadEval m n where
  monadEval := MonadLift.monadLift
Monad Evaluation Adapter from Monad Lifting
Informal description
For any monads `m` and `n`, if there exists a monad lift from `m` to `n`, then there also exists a monad evaluation adapter from `m` to `n`.
MonadEvalT structure
(m : Type u → Type v) (n : Type u → Type w)
Full source
/-- The transitive closure of `MonadEval`. -/
class MonadEvalT (m : Type u → Type v) (n : Type u → Type w) where
  /-- Evaluates a value from monad `m` into monad `n`. -/
  monadEval : {α : Type u} → m α → n α
Transitive Closure of Monad Evaluation Relation
Informal description
The structure `MonadEvalT` represents the transitive closure of the `MonadEval` relation between monads. For monads `m` and `n`, `MonadEvalT m n` holds if there exists a sequence of monads connecting `m` to `n` where each adjacent pair satisfies the `MonadEval` relation.
instMonadEvalTOfMonadEval instance
(m n o) [MonadEval n o] [MonadEvalT m n] : MonadEvalT m o
Full source
instance (m n o) [MonadEval n o] [MonadEvalT m n] : MonadEvalT m o where
  monadEval x := MonadEval.monadEval (m := n) (MonadEvalT.monadEval x)
Transitivity of Monad Evaluation Relation
Informal description
For any monads $m$, $n$, and $o$, if there exists a monad evaluation adapter from $n$ to $o$ and a transitive closure of the monad evaluation relation from $m$ to $n$, then there exists a transitive closure of the monad evaluation relation from $m$ to $o$.
instMonadEvalT instance
(m) : MonadEvalT m m
Full source
instance (m) : MonadEvalT m m where
  monadEval x := x
Reflexivity of Monad Evaluation Relation
Informal description
For any monad $m$, the reflexive closure of the monad evaluation relation holds for $m$ itself.
MonadFunctor structure
(m : semiOutParam (Type u → Type v)) (n : Type u → Type w)
Full source
/--
A way to interpret a fully-polymorphic function in `m` into `n`. Such a function can be thought of
as one that may change the effects in `m`, but can't do so based on specific values that are
provided.

Clients of `MonadFunctor` should typically use `MonadFunctorT`, which is the reflexive, transitive
closure of `MonadFunctor`. New instances should be defined for `MonadFunctor.`
-/
-- Based on [`MFunctor`] from the `pipes` Haskell package, but not restricted to
-- monad transformers. Alternatively, an implementation of [`MonadTransFunctor`].
--   [`MFunctor`]: https://hackage.haskell.org/package/pipes-2.4.0/docs/Control-MFunctor.html
--   [`MonadTransFunctor`]: http://duairc.netsoc.ie/layers-docs/Control-Monad-Layer.html#t:MonadTransFunctor
class MonadFunctor (m : semiOutParam (Type u → Type v)) (n : Type u → Type w) where
  /--
  Lifts a fully-polymorphic transformation of `m` into `n`.
  -/
  monadMap {α : Type u} : ({β : Type u} → m β → m β) → n α → n α
Monad Functor
Informal description
The structure `MonadFunctor` provides a way to interpret a fully-polymorphic function from monad `m` to monad `n`. Such a function can transform the effects in `m` but cannot depend on specific values provided in `m`.
MonadFunctorT structure
(m : Type u → Type v) (n : Type u → Type w)
Full source
/--
A way to interpret a fully-polymorphic function in `m` into `n`. Such a function can be thought of
as one that may change the effects in `m`, but can't do so based on specific values that are
provided.

This is the reflexive, transitive closure of `MonadFunctor`. It automatically chains together
`MonadFunctor` instances as needed. Clients of `MonadFunctor` should typically use `MonadFunctorT`,
but new instances should be defined for `MonadFunctor`.
-/
class MonadFunctorT (m : Type u → Type v) (n : Type u → Type w) where
  /--
  Lifts a fully-polymorphic transformation of `m` into `n`.
  -/
  monadMap {α : Type u} : ({β : Type u} → m β → m β) → n α → n α
Monad Functor Transformer
Informal description
The structure `MonadFunctorT` provides a way to interpret a fully-polymorphic function from monad `m` to monad `n`. Such a function can transform the effects in `m` but cannot depend on specific values provided in `m`. This structure represents the reflexive, transitive closure of `MonadFunctor`, automatically chaining instances of `MonadFunctor` as needed.
instMonadFunctorTOfMonadFunctor instance
(m n o) [MonadFunctor n o] [MonadFunctorT m n] : MonadFunctorT m o
Full source
@[always_inline]
instance (m n o) [MonadFunctor n o] [MonadFunctorT m n] : MonadFunctorT m o where
  monadMap f := MonadFunctor.monadMap (m := n) (monadMap (m := m) f)
Composition of Monad Functor Transformers
Informal description
For any monads $m$, $n$, and $o$, if there exists a monad functor from $n$ to $o$ and a monad functor transformer from $m$ to $n$, then there exists a monad functor transformer from $m$ to $o$.
monadFunctorRefl instance
(m) : MonadFunctorT m m
Full source
instance monadFunctorRefl (m) : MonadFunctorT m m where
  monadMap f := f
Identity Monad Functor
Informal description
For any monad $m$, the identity transformation from $m$ to itself is a monad functor.
Except inductive
(ε : Type u) (α : Type v)
Full source
/--
`Except ε α` is a type which represents either an error of type `ε` or a successful result with a
value of type `α`.

`Except ε : Type u → Type v` is a `Monad` that represents computations that may throw exceptions:
the `pure` operation is `Except.ok` and the `bind` operation returns the first encountered
`Except.error`.
-/
inductive Except (ε : Type u) (α : Type v) where
  /-- A failure value of type `ε` -/
  | error : ε → Except ε α
  /-- A success value of type `α` -/
  | ok    : α → Except ε α
Exceptional Result Type
Informal description
The type `Except ε α` represents a computation that can either result in a value of type `α` or an error of type `ε`. It is used to model computations that may fail or throw exceptions.
instInhabitedExcept instance
{ε : Type u} {α : Type v} [Inhabited ε] : Inhabited (Except ε α)
Full source
instance {ε : Type u} {α : Type v} [Inhabited ε] : Inhabited (Except ε α) where
  default := Except.error default
Inhabitedness of Except Type with Inhabited Error Type
Informal description
For any types $\varepsilon$ and $\alpha$, if $\varepsilon$ is inhabited (i.e., has a default element), then the type `Except ε α` of computations that may result in either an error of type $\varepsilon$ or a value of type $\alpha$ is also inhabited.
MonadExceptOf structure
(ε : semiOutParam (Type u)) (m : Type v → Type w)
Full source
/--
Exception monads provide the ability to throw errors and handle errors.

In this class, `ε` is a `semiOutParam`, which means that it can influence the choice of instance.
`MonadExcept ε` provides the same operations, but requires that `ε` be inferrable from `m`.

`tryCatchThe`, which takes an explicit exception type, is used to desugar `try ... catch ...` steps
inside `do`-blocks when the handlers have type annotations.
-/
class MonadExceptOf (ε : semiOutParam (Type u)) (m : Type v → Type w) where
  /--
  Throws an exception of type `ε` to the nearest enclosing `catch`.
  -/
  throw {α : Type v} : ε → m α
  /--
  Catches errors thrown in `body`, passing them to `handler`. Errors in `handler` are not caught.
  -/
  tryCatch {α : Type v} (body : m α) (handler : ε → m α) : m α
Exception-handling monad structure
Informal description
The structure `MonadExceptOf` represents a monad that can throw and handle exceptions of type `ε`. It provides operations for throwing exceptions (`throwThe`) and catching exceptions (`tryCatchThe`), where `ε` is a semi-output parameter that influences instance resolution but must be concretely provided by instances.
throwThe abbrev
(ε : Type u) {m : Type v → Type w} [MonadExceptOf ε m] {α : Type v} (e : ε) : m α
Full source
/--
Throws an exception, with the exception type specified explicitly. This is useful when a monad
supports throwing more than one type of exception.

Use `throw` for a version that expects the exception type to be inferred from `m`.
-/
abbrev throwThe (ε : Type u) {m : Type v → Type w} [MonadExceptOf ε m] {α : Type v} (e : ε) : m α :=
  MonadExceptOf.throw e
Monadic Exception Throw with Explicit Type
Informal description
Given a monad `m` that supports throwing exceptions of type `ε` (via `MonadExceptOf ε m`), the function `throwThe` takes an exception `e : ε` and produces a monadic computation `m α` that immediately throws the exception `e`.
tryCatchThe abbrev
(ε : Type u) {m : Type v → Type w} [MonadExceptOf ε m] {α : Type v} (x : m α) (handle : ε → m α) : m α
Full source
/--
Catches errors, recovering using `handle`. The exception type is specified explicitly. This is useful when a monad
supports throwing or handling more than one type of exception.

Use `tryCatch`, for a version that expects the exception type to be inferred from `m`.
-/
abbrev tryCatchThe (ε : Type u) {m : Type v → Type w} [MonadExceptOf ε m] {α : Type v} (x : m α) (handle : ε → m α) : m α :=
  MonadExceptOf.tryCatch x handle
Monadic Exception Handling with Explicit Exception Type
Informal description
Given a monad `m` that supports throwing and handling exceptions of type `ε`, a monadic computation `x : m α`, and a handler function `handle : ε → m α`, the function `tryCatchThe` executes `x` and applies `handle` to any exception of type `ε` that is thrown during the execution of `x`. The result is a monadic computation of type `m α`.
MonadExcept structure
(ε : outParam (Type u)) (m : Type v → Type w)
Full source
/--
Exception monads provide the ability to throw errors and handle errors.

In this class, `ε` is an `outParam`, which means that it is inferred from `m`. `MonadExceptOf ε`
provides the same operations, but allows `ε` to influence instance synthesis.

`MonadExcept.tryCatch` is used to desugar `try ... catch ...` steps inside `do`-blocks when the
handlers do not have exception type annotations.
-/
class MonadExcept (ε : outParam (Type u)) (m : Type v → Type w) where
  /--
  Throws an exception of type `ε` to the nearest enclosing handler.
  -/
  throw {α : Type v} : ε → m α
  /--
  Catches errors thrown in `body`, passing them to `handler`. Errors in `handler` are not caught.
  -/
  tryCatch {α : Type v} : (body : m α) → (handler : ε → m α) → m α
Exception Monad
Informal description
The structure `MonadExcept` represents exception monads, which provide the ability to throw and handle errors. Here, `ε` is an output parameter representing the type of exceptions, and `m` is the monad type constructor. The structure allows operations like throwing exceptions and catching them within a monadic context.
MonadExcept.ofExcept definition
[Monad m] [MonadExcept ε m] : Except ε α → m α
Full source
/--
Re-interprets an `Except ε` action in an exception monad `m`, succeeding if it succeeds and throwing
an exception if it throws an exception.
-/
def MonadExcept.ofExcept [Monad m] [MonadExcept ε m] : Except ε α → m α
  | .ok a    => pure a
  | .error e => throw e
Conversion from Except to Monadic Exception Handling
Informal description
Given a monad `m` with exception handling capabilities for exceptions of type `ε`, the function converts an `Except ε α` value into a monadic computation in `m α`. If the input is `Except.ok a`, it returns the pure value `a` in the monad. If the input is `Except.error e`, it throws the exception `e` in the monadic context.
instMonadExceptOfMonadExceptOf instance
(ε : Type u) (m : Type v → Type w) [MonadExceptOf ε m] : MonadExcept ε m
Full source
instance (ε : Type u) (m : Type v → Type w) [MonadExceptOf ε m] : MonadExcept ε m where
  throw    := throwThe ε
  tryCatch := tryCatchThe ε
Monad with Explicit Exception Handling is an Exception Monad
Informal description
For any type `ε` and monad `m` that supports throwing and handling exceptions of type `ε` (via `MonadExceptOf ε m`), `m` is also a `MonadExcept ε m`. This means that any monad with explicit exception handling capabilities inherently satisfies the interface for a general exception monad.
MonadExcept.orElse definition
[MonadExcept ε m] {α : Type v} (t₁ : m α) (t₂ : Unit → m α) : m α
Full source
/--
Unconditional error recovery that ignores which exception was thrown. Usually used via the `<|>`
operator.

If both computations throw exceptions, then the result is the second exception.
-/
@[inline] protected def orElse [MonadExcept ε m] {α : Type v} (t₁ : m α) (t₂ : Unit → m α) : m α :=
  tryCatch t₁ fun _ => t₂ ()
Exception recovery with fallback computation
Informal description
Given a monad `m` with exception handling capabilities for exceptions of type `ε`, and a type `α`, the operation `orElse` takes two computations: the first computation `t₁` of type `m α`, and a second computation `t₂` (which is a function from the unit type to `m α`). If `t₁` throws an exception, `orElse` executes `t₂ ()` (i.e., the second computation applied to the unit value) and returns its result. If both computations throw exceptions, the result is the exception from `t₂ ()`.
MonadExcept.instOrElse instance
[MonadExcept ε m] {α : Type v} : OrElse (m α)
Full source
instance [MonadExcept ε m] {α : Type v} : OrElse (m α) where
  orElse := MonadExcept.orElse
OrElse Operation for Exception Monads
Informal description
For any monad `m` with exception handling capabilities for exceptions of type `ε`, and any type `α`, the type `m α` is equipped with a homogeneous "or else" operation. This operation allows combining two computations in `m α`, where the second computation is evaluated only if the first one throws an exception.
ReaderT definition
(ρ : Type u) (m : Type u → Type v) (α : Type u) : Type (max u v)
Full source
/--
Adds the ability to access a read-only value of type `ρ` to a monad. The value can be locally
overridden by `withReader`, but it cannot be mutated.

Actions in the resulting monad are functions that take the local value as a parameter, returning
ordinary actions in `m`.
-/
def ReaderT (ρ : Type u) (m : Type u → Type v) (α : Type u) : Type (max u v) :=
  ρ → m α
Reader Monad Transformer
Informal description
The `ReaderT` monad transformer adds a read-only environment of type $\rho$ to a base monad $m$. Computations in `ReaderT ρ m α` are functions that take an environment value of type $\rho$ and produce a computation in $m$ returning a value of type $\alpha$. The environment can be locally overridden using `withReader` but cannot be mutated.
instInhabitedReaderT instance
(ρ : Type u) (m : Type u → Type v) (α : Type u) [Inhabited (m α)] : Inhabited (ReaderT ρ m α)
Full source
instance (ρ : Type u) (m : Type u → Type v) (α : Type u) [Inhabited (m α)] : Inhabited (ReaderT ρ m α) where
  default := fun _ => default
Inhabited Reader Monad Transformer
Informal description
For any type $\rho$, monad $m$, and type $\alpha$, if $m \alpha$ is inhabited (i.e., has a default value), then the reader monad transformer $\text{ReaderT} \rho m \alpha$ is also inhabited.
ReaderT.run definition
{ρ : Type u} {m : Type u → Type v} {α : Type u} (x : ReaderT ρ m α) (r : ρ) : m α
Full source
/--
Executes an action from a monad with a read-only value in the underlying monad `m`.
-/
@[always_inline, inline]
def ReaderT.run {ρ : Type u} {m : Type u → Type v} {α : Type u} (x : ReaderT ρ m α) (r : ρ) : m α :=
  x r
Execution of Reader Monad Transformer with Environment
Informal description
The function `ReaderT.run` executes a computation in the `ReaderT` monad transformer by providing it with a read-only environment value $r$ of type $\rho$, resulting in a computation in the base monad $m$ that produces a value of type $\alpha$.
ReaderT.instMonadLift instance
: MonadLift m (ReaderT ρ m)
Full source
instance  : MonadLift m (ReaderT ρ m) where
  monadLift x := fun _ => x
Monad Lifting into Reader Transformer
Informal description
For any monad $m$ and type $\rho$, there is a canonical way to lift computations from $m$ to the reader monad transformer $\text{ReaderT} \rho m$.
ReaderT.instMonadExceptOf instance
(ε) [MonadExceptOf ε m] : MonadExceptOf ε (ReaderT ρ m)
Full source
@[always_inline]
instance (ε) [MonadExceptOf ε m] : MonadExceptOf ε (ReaderT ρ m) where
  throw e  := liftM (m := m) (throw e)
  tryCatch := fun x c r => tryCatchThe ε (x r) (fun e => (c e) r)
Exception Handling in Reader Monad Transformer
Informal description
For any type $\rho$, monad $m$, and exception type $\varepsilon$, if $m$ supports throwing and handling exceptions of type $\varepsilon$ (via `MonadExceptOf ε m`), then the reader monad transformer $\text{ReaderT} \rho m$ also supports throwing and handling exceptions of type $\varepsilon$.
ReaderT.read definition
[Monad m] : ReaderT ρ m ρ
Full source
/--
Retrieves the reader monad's local value. Typically accessed via `read`, or via `readThe` when more
than one local value is available.
-/
@[always_inline, inline]
protected def read [Monad m] : ReaderT ρ m ρ :=
  pure
Reader monad environment accessor
Informal description
The function `ReaderT.read` retrieves the current read-only environment of type $\rho$ in the `ReaderT ρ m` monad transformer, where $m$ is the underlying monad. It effectively lifts the environment into the monadic context without modifying it.
ReaderT.pure definition
[Monad m] {α} (a : α) : ReaderT ρ m α
Full source
/--
Returns the provided value `a`, ignoring the reader monad's local value. Typically used via
`Pure.pure`.
-/
@[always_inline, inline]
protected def pure [Monad m] {α} (a : α) : ReaderT ρ m α :=
  fun _ => pure a
Pure value in Reader monad transformer
Informal description
The function `ReaderT.pure` takes a value `a` of type `α` and returns a computation in the `ReaderT ρ m` monad that ignores the reader's environment and simply returns `a` as a pure value in the base monad `m`.
ReaderT.bind definition
[Monad m] {α β} (x : ReaderT ρ m α) (f : α → ReaderT ρ m β) : ReaderT ρ m β
Full source
/--
Sequences two reader monad computations. Both are provided with the local value, and the second is
passed the value of the first. Typically used via the `>>=` operator.
-/
@[always_inline, inline]
protected def bind [Monad m] {α β} (x : ReaderT ρ m α) (f : α → ReaderT ρ m β) : ReaderT ρ m β :=
  fun r => bind (x r) fun a => f a r
Monadic bind for reader monad transformer
Informal description
Given a monad `m`, a computation `x` in the `ReaderT ρ m α` monad, and a function `f` from `α` to `ReaderT ρ m β`, the function `ReaderT.bind` sequences these computations by first running `x` with the reader environment `r` to obtain a value `a` of type `α`, then applying `f` to `a` and running the resulting computation with the same environment `r`. This operation is the monadic bind for the reader monad transformer.
ReaderT.instFunctorOfMonad instance
[Monad m] : Functor (ReaderT ρ m)
Full source
@[always_inline]
instance [Monad m] : Functor (ReaderT ρ m) where
  map      f x r := Functor.map f (x r)
  mapConst a x r := Functor.mapConst a (x r)
Functor Instance for Reader Monad Transformer
Informal description
For any monad $m$ and type $\rho$, the reader monad transformer $\text{ReaderT} \rho m$ is a functor. This means it provides a mapping operation that applies a function to the result of a computation while preserving the structure of the computation and maintaining the read-only environment $\rho$.
ReaderT.instApplicativeOfMonad instance
[Monad m] : Applicative (ReaderT ρ m)
Full source
@[always_inline]
instance [Monad m] : Applicative (ReaderT ρ m) where
  pure           := ReaderT.pure
  seq      f x r := Seq.seq (f r) fun _ => x () r
  seqLeft  a b r := SeqLeft.seqLeft (a r) fun _ => b () r
  seqRight a b r := SeqRight.seqRight (a r) fun _ => b () r
Applicative Structure of Reader Monad Transformer
Informal description
For any monad $m$ and type $\rho$, the reader monad transformer $\text{ReaderT} \rho m$ is an applicative functor. This means it provides operations for sequencing computations (`Seq`), injecting pure values (`Pure`), and left/right sequencing (`SeqLeft`, `SeqRight`) while maintaining the read-only environment $\rho$.
ReaderT.instMonad instance
[Monad m] : Monad (ReaderT ρ m)
Full source
instance [Monad m] : Monad (ReaderT ρ m) where
  bind := ReaderT.bind
Monad Structure of Reader Monad Transformer
Informal description
For any monad $m$ and type $\rho$, the reader monad transformer $\text{ReaderT} \rho m$ is a monad. This means it provides operations for sequencing computations (`bind`) and injecting pure values (`pure`) while maintaining the read-only environment $\rho$.
ReaderT.instMonadFunctor instance
(ρ m) : MonadFunctor m (ReaderT ρ m)
Full source
instance (ρ m) : MonadFunctor m (ReaderT ρ m) where
  monadMap f x := fun ctx => f (x ctx)
Reader Monad Transformer as Monad Functor
Informal description
For any type $\rho$ and monad $m$, the reader monad transformer $\text{ReaderT} \rho m$ is a monad functor over $m$. This means there exists a natural way to lift monadic computations from $m$ to $\text{ReaderT} \rho m$ while preserving the monadic structure.
ReaderT.adapt definition
{ρ' α : Type u} (f : ρ' → ρ) : ReaderT ρ m α → ReaderT ρ' m α
Full source
/--
Modifies a reader monad's local value with `f`. The resulting computation applies `f` to the
incoming local value and passes the result to the inner computation.
-/
@[always_inline, inline]
protected def adapt {ρ' α : Type u} (f : ρ' → ρ) : ReaderT ρ m α → ReaderT ρ' m α :=
  fun x r => x (f r)
Environment adaptation for reader monad transformer
Informal description
Given a function $f : \rho' \to \rho$, the operation `ReaderT.adapt` transforms a computation in `ReaderT ρ m α` (which depends on an environment of type $\rho$) into a computation in `ReaderT ρ' m α` (which depends on an environment of type $\rho'$). The transformed computation applies $f$ to the new environment before passing it to the original computation.
MonadReaderOf structure
(ρ : semiOutParam (Type u)) (m : Type u → Type v)
Full source
/--
Reader monads provide the ability to implicitly thread a value through a computation. The value can
be read, but not written. A `MonadWithReader ρ` instance additionally allows the value to be locally
overridden for a sub-computation.

In this class, `ρ` is a `semiOutParam`, which means that it can influence the choice of instance.
`MonadReader ρ` provides the same operations, but requires that `ρ` be inferrable from `m`.
-/
-- Note: This class can be seen as a simplification of the more "principled" definition
-- ```
-- class MonadReaderOf (ρ : Type u) (n : Type u → Type u) where
--   lift {α : Type u} : ({m : Type u → Type u} → [Monad m] → ReaderT ρ m α) → n α
-- ```
class MonadReaderOf (ρ : semiOutParam (Type u)) (m : Type u → Type v) where
  /-- Retrieves the local value. -/
  read : m ρ
Monad with implicit reader capability
Informal description
The structure `MonadReaderOf` represents a type class for monads that can implicitly read a value of type `ρ` throughout a computation. The value can be accessed but not modified. The parameter `ρ` is marked as a semi-output parameter, meaning it influences instance resolution while guaranteeing concrete values will be provided during type class synthesis.
MonadReader structure
(ρ : outParam (Type u)) (m : Type u → Type v)
Full source
/--
Reader monads provide the ability to implicitly thread a value through a computation. The value can
be read, but not written. A `MonadWithReader ρ` instance additionally allows the value to be locally
overridden for a sub-computation.

In this class, `ρ` is an `outParam`, which means that it is inferred from `m`. `MonadReaderOf ρ`
provides the same operations, but allows `ρ` to influence instance synthesis.
-/
class MonadReader (ρ : outParam (Type u)) (m : Type u → Type v) where
  /--
  Retrieves the local value.

  Use `readThe` to explicitly specify a type when more than one value is available.
  -/
  read : m ρ
Reader Monad Typeclass
Informal description
The typeclass `MonadReader` represents monads that can implicitly thread a read-only environment of type `ρ` through computations. The environment can be accessed but not modified, and can be locally overridden for sub-computations. The parameter `ρ` is marked as an output parameter, meaning it is inferred from the monad `m` during typeclass resolution.
readThe definition
(ρ : Type u) {m : Type u → Type v} [MonadReaderOf ρ m] : m ρ
Full source
/--
Retrieves the local value whose type is `ρ`.  This is useful when a monad supports reading more that
one type of value.

Use `read` for a version that expects the type `ρ` to be inferred from `m`.
-/
@[always_inline, inline]
def readThe (ρ : Type u) {m : Type u → Type v} [MonadReaderOf ρ m] : m ρ :=
  MonadReaderOf.read
Explicit reader value retrieval
Informal description
The function `readThe` retrieves the current value of type `ρ` from the implicit reader context of the monad `m`. This is used when the monad supports reading multiple types of values, and the specific type `ρ` needs to be explicitly specified.
instMonadReaderOfMonadReaderOf instance
(ρ : Type u) (m : Type u → Type v) [MonadReaderOf ρ m] : MonadReader ρ m
Full source
instance (ρ : Type u) (m : Type u → Type v) [MonadReaderOf ρ m] : MonadReader ρ m where
  read := readThe ρ
Monad with Reader Capability is a Reader Monad
Informal description
For any type $\rho$ and monad $m$ with an implicit reader capability for $\rho$, $m$ is also a reader monad for $\rho$.
instMonadReaderOfOfMonadLift instance
{ρ : Type u} {m : Type u → Type v} {n : Type u → Type w} [MonadLift m n] [MonadReaderOf ρ m] : MonadReaderOf ρ n
Full source
instance {ρ : Type u} {m : Type u → Type v} {n : Type u → Type w} [MonadLift m n] [MonadReaderOf ρ m] : MonadReaderOf ρ n where
  read := liftM (m := m) read
Monad Lifting Preserves Reader Capability
Informal description
For any type $\rho$ and monads $m$ and $n$, if there exists a monad lift from $m$ to $n$ and $m$ has an implicit reader capability for $\rho$, then $n$ also has an implicit reader capability for $\rho$.
instMonadReaderOfReaderTOfMonad instance
{ρ : Type u} {m : Type u → Type v} [Monad m] : MonadReaderOf ρ (ReaderT ρ m)
Full source
instance {ρ : Type u} {m : Type u → Type v} [Monad m] : MonadReaderOf ρ (ReaderT ρ m) where
  read := ReaderT.read
Reader Monad Transformer Implements Reader Capability
Informal description
For any type $\rho$ and monad $m$, the reader monad transformer $\text{ReaderT} \rho m$ has an implicit reader capability for $\rho$.
MonadWithReaderOf structure
(ρ : semiOutParam (Type u)) (m : Type u → Type v)
Full source
/--
A reader monad that additionally allows the value to be locally overridden.

In this class, `ρ` is a `semiOutParam`, which means that it can influence the choice of instance.
`MonadWithReader ρ` provides the same operations, but requires that `ρ` be inferrable from `m`.
-/
class MonadWithReaderOf (ρ : semiOutParam (Type u)) (m : Type u → Type v) where
  /--
  Locally modifies the reader monad's value while running an action.

  During the inner action `x`, reading the value returns `f` applied to the original value. After
  control returns from `x`, the reader monad's value is restored.
  -/
  withReader {α : Type u} (f : ρ → ρ) (x : m α) : m α
Reader monad with local overrides
Informal description
The structure `MonadWithReaderOf` represents a reader monad with a parameter `ρ` that can be locally overridden. Here, `ρ` is a semi-output parameter, meaning it can influence instance resolution while ensuring concrete values are provided during type class synthesis. This monad extends the basic reader monad by allowing temporary modifications to the environment of type `ρ`.
withTheReader definition
(ρ : Type u) {m : Type u → Type v} [MonadWithReaderOf ρ m] {α : Type u} (f : ρ → ρ) (x : m α) : m α
Full source
/--
Locally modifies the reader monad's value while running an action, with the reader monad's local
value type specified explicitly. This is useful when a monad supports reading more than one type of
value.

During the inner action `x`, reading the value returns `f` applied to the original value. After
control returns from `x`, the reader monad's value is restored.

Use `withReader` for a version that expects the local value's type to be inferred from `m`.
-/
@[always_inline, inline]
def withTheReader (ρ : Type u) {m : Type u → Type v} [MonadWithReaderOf ρ m] {α : Type u} (f : ρ → ρ) (x : m α) : m α :=
  MonadWithReaderOf.withReader f x
Temporarily modify reader environment
Informal description
Given a type $\rho$, a monad $m$ with a reader capability for $\rho$, a function $f : \rho \to \rho$, and a computation $x : m \alpha$, the function `withTheReader` temporarily modifies the reader environment by applying $f$ while executing $x$, then restores the original environment afterward.
MonadWithReader structure
(ρ : outParam (Type u)) (m : Type u → Type v)
Full source
/--
A reader monad that additionally allows the value to be locally overridden.

In this class, `ρ` is an `outParam`, which means that it is inferred from `m`. `MonadWithReaderOf ρ`
provides the same operations, but allows `ρ` to influence instance synthesis.
-/
class MonadWithReader (ρ : outParam (Type u)) (m : Type u → Type v) where
  /--
  Locally modifies the reader monad's value while running an action.

  During the inner action `x`, reading the value returns `f` applied to the original value. After
  control returns from `x`, the reader monad's value is restored.
  -/
  withReader {α : Type u} : (ρ → ρ) → m α → m α
Reader monad with local override capability
Informal description
The structure `MonadWithReader` represents a reader monad that allows the value of type `ρ$ to be locally overridden during computation. Here, `ρ` is an output parameter inferred from the monad `m`.
instMonadWithReaderOfMonadWithReaderOf instance
(ρ : Type u) (m : Type u → Type v) [MonadWithReaderOf ρ m] : MonadWithReader ρ m
Full source
instance (ρ : Type u) (m : Type u → Type v) [MonadWithReaderOf ρ m] : MonadWithReader ρ m where
  withReader := withTheReader ρ
Monad with Reader Capability Implies Local Overrides
Informal description
For any type $\rho$ and monad $m$ with a reader capability for $\rho$, $m$ is also a monad with a reader that allows local overrides of $\rho$.
instMonadWithReaderOfOfMonadFunctor instance
{ρ : Type u} {m : Type u → Type v} {n : Type u → Type v} [MonadFunctor m n] [MonadWithReaderOf ρ m] : MonadWithReaderOf ρ n
Full source
instance {ρ : Type u} {m : Type u → Type v} {n : Type u → Type v} [MonadFunctor m n] [MonadWithReaderOf ρ m] : MonadWithReaderOf ρ n where
  withReader f := monadMap (m := m) (withTheReader ρ f)
Monad Functor Preserves Reader Capability
Informal description
For any type $\rho$ and monads $m$ and $n$, if there exists a monad functor from $m$ to $n$ and $m$ has a reader capability for $\rho$, then $n$ also has a reader capability for $\rho$.
instMonadWithReaderOfReaderT instance
{ρ : Type u} {m : Type u → Type v} : MonadWithReaderOf ρ (ReaderT ρ m)
Full source
instance {ρ : Type u} {m : Type u → Type v} : MonadWithReaderOf ρ (ReaderT ρ m) where
  withReader f x := fun ctx => x (f ctx)
Reader Monad Transformer as Monad with Environment
Informal description
For any type $\rho$ and monad $m$, the reader monad transformer $\mathrm{ReaderT}\,\rho\,m$ is a monad with a read-only environment of type $\rho$.
MonadStateOf structure
(σ : semiOutParam (Type u)) (m : Type u → Type v)
Full source
/--
State monads provide a value of a given type (the _state_) that can be retrieved or replaced.
Instances may implement these operations by passing state values around, by using a mutable
reference cell (e.g. `ST.Ref σ`), or in other ways.

In this class, `σ` is a `semiOutParam`, which means that it can influence the choice of instance.
`MonadState σ` provides the same operations, but requires that `σ` be inferrable from `m`.

The mutable state of a state monad is visible between multiple `do`-blocks or functions, unlike
[local mutable state](lean-manual://section/do-notation-let-mut) in `do`-notation.
-/
class MonadStateOf (σ : semiOutParam (Type u)) (m : Type u → Type v) where
  /--
  Retrieves the current value of the monad's mutable state.
  -/
  get : m σ
  /--
  Replaces the current value of the mutable state with a new one.
  -/
  set : σ → m PUnit
  /--
  Applies a function to the current state that both computes a new state and a value. The new state
  replaces the current state, and the value is returned.

  It is equivalent to `do let (a, s) := f (← get); set s; pure a`. However, using `modifyGet` may
  lead to higher performance because it doesn't add a new reference to the state value. Additional
  references can inhibit in-place updates of data.
  -/
  modifyGet {α : Type u} : (σ → Prod α σ) → m α
State monad with type `σ`
Informal description
The type class `MonadStateOf σ m` represents a monad `m` that maintains a mutable state of type `σ`. It provides operations to retrieve the current state (`getThe`) and modify it (`modifyThe`). The state is shared across different computations within the monad, unlike local mutable state in `do`-notation which is confined to a single block.
getThe abbrev
(σ : Type u) {m : Type u → Type v} [MonadStateOf σ m] : m σ
Full source
/--
Gets the current state that has the explicitly-provided type `σ`. When the current monad has
multiple state types available, this function selects one of them.
-/
abbrev getThe (σ : Type u) {m : Type u → Type v} [MonadStateOf σ m] : m σ :=
  MonadStateOf.get
Retrieve State of Type `σ` in Monad `m`
Informal description
Given a monad `m` with state type `σ`, the operation `getThe` retrieves the current state of type `σ` from the monadic context.
modifyThe abbrev
(σ : Type u) {m : Type u → Type v} [MonadStateOf σ m] (f : σ → σ) : m PUnit
Full source
/--
Mutates the current state that has the explicitly-provided type `σ`, replacing its value with the
result of applying `f` to it. When the current monad has multiple state types available, this
function selects one of them.

It is equivalent to `do set (f (← get))`. However, using `modify` may lead to higher performance
because it doesn't add a new reference to the state value. Additional references can inhibit
in-place updates of data.
-/
@[always_inline, inline]
abbrev modifyThe (σ : Type u) {m : Type u → Type v} [MonadStateOf σ m] (f : σ → σ) : m PUnit :=
  MonadStateOf.modifyGet fun s => (PUnit.unit, f s)
State modification operation in monad `m` with state type `σ`
Informal description
Given a monad `m` with state type `σ`, the operation `modifyThe σ f` applies the function `f : σ → σ` to the current state, updating it in place, and returns a trivial result of type `PUnit`.
modifyGetThe abbrev
{α : Type u} (σ : Type u) {m : Type u → Type v} [MonadStateOf σ m] (f : σ → Prod α σ) : m α
Full source
/--
Applies a function to the current state that has the explicitly-provided type `σ`. The function both
computes a new state and a value. The new state replaces the current state, and the value is
returned.

It is equivalent to `do let (a, s) := f (← getThe σ); set s; pure a`. However, using `modifyGetThe`
may lead to higher performance because it doesn't add a new reference to the state value. Additional
references can inhibit in-place updates of data.
-/
@[always_inline, inline]
abbrev modifyGetThe {α : Type u} (σ : Type u) {m : Type u → Type v} [MonadStateOf σ m] (f : σ → Prod α σ) : m α :=
  MonadStateOf.modifyGet f
State monad operation: modify state and get value via `f : σ → α × σ`
Informal description
Given a state monad `m` with state type `σ`, and a function `f : σ → α × σ` that computes both a new state and a value of type `α`, the operation `modifyGetThe` applies `f` to the current state, updates the state to the new value, and returns the computed value of type `α`.
MonadState structure
(σ : outParam (Type u)) (m : Type u → Type v)
Full source
/--
State monads provide a value of a given type (the _state_) that can be retrieved or replaced.
Instances may implement these operations by passing state values around, by using a mutable
reference cell (e.g. `ST.Ref σ`), or in other ways.

In this class, `σ` is an `outParam`, which means that it is inferred from `m`. `MonadStateOf σ`
provides the same operations, but allows `σ` to influence instance synthesis.

The mutable state of a state monad is visible between multiple `do`-blocks or functions, unlike
[local mutable state](lean-manual://section/do-notation-let-mut) in `do`-notation.
-/
class MonadState (σ : outParam (Type u)) (m : Type u → Type v) where
  /--
  Retrieves the current value of the monad's mutable state.
  -/
  get : m σ
  /--
  Replaces the current value of the mutable state with a new one.
  -/
  set : σ → m PUnit
  /--
  Applies a function to the current state that both computes a new state and a value. The new state
  replaces the current state, and the value is returned.

  It is equivalent to `do let (a, s) := f (← get); set s; pure a`. However, using `modifyGet` may
  lead to higher performance because it doesn't add a new reference to the state value. Additional
  references can inhibit in-place updates of data.
  -/
  modifyGet {α : Type u} : (σ → Prod α σ) → m α
State Monad Typeclass
Informal description
The typeclass `MonadState` represents monads that maintain a mutable state of type `σ`. It provides operations to retrieve and modify this state, which is shared across different computations within the monad. The state type `σ` is an output parameter, meaning it is inferred from the monad `m` during typeclass resolution.
instMonadStateOfMonadStateOf instance
(σ : Type u) (m : Type u → Type v) [MonadStateOf σ m] : MonadState σ m
Full source
instance (σ : Type u) (m : Type u → Type v) [MonadStateOf σ m] : MonadState σ m where
  set         := MonadStateOf.set
  get         := getThe σ
  modifyGet f := MonadStateOf.modifyGet f
MonadStateOf implies MonadState
Informal description
For any monad `m` with state type `σ`, if `m` is an instance of `MonadStateOf σ`, then `m` is also an instance of `MonadState σ`.
modify definition
{σ : Type u} {m : Type u → Type v} [MonadState σ m] (f : σ → σ) : m PUnit
Full source
/--
Mutates the current state, replacing its value with the result of applying `f` to it.

Use `modifyThe` to explicitly select a state type to modify.

It is equivalent to `do set (f (← get))`. However, using `modify` may lead to higher performance
because it doesn't add a new reference to the state value. Additional references can inhibit
in-place updates of data.
-/
@[always_inline, inline]
def modify {σ : Type u} {m : Type u → Type v} [MonadState σ m] (f : σ → σ) : m PUnit :=
  modifyGet fun s => (PUnit.unit, f s)
State modification in a monad
Informal description
Given a monad `m` with state type `σ`, the function `modify` applies a transformation `f : σ → σ` to the current state and returns the unit value `PUnit.unit`. This operation is equivalent to first retrieving the state, applying `f` to it, and then setting the new state, but may be more efficient as it avoids creating an additional reference to the state value.
getModify definition
{σ : Type u} {m : Type u → Type v} [MonadState σ m] (f : σ → σ) : m σ
Full source
/--
Replaces the state with the result of applying `f` to it. Returns the old value of the state.

It is equivalent to `get <* modify f` but may be more efficient.
-/
@[always_inline, inline]
def getModify {σ : Type u} {m : Type u → Type v} [MonadState σ m] (f : σ → σ) : m σ :=
  modifyGet fun s => (s, f s)
Get and modify state in a monad
Informal description
Given a monad `m` with state type `σ`, the function `getModify` applies a transformation `f : σ → σ` to the current state and returns the original state value before the modification. This operation is equivalent to first retrieving the state, then applying `f` to it to update the state, while keeping the original value for the result.
instMonadStateOfOfMonadLift instance
{σ : Type u} {m : Type u → Type v} {n : Type u → Type w} [MonadLift m n] [MonadStateOf σ m] : MonadStateOf σ n
Full source
@[always_inline]
instance {σ : Type u} {m : Type u → Type v} {n : Type u → Type w} [MonadLift m n] [MonadStateOf σ m] : MonadStateOf σ n where
  get         := liftM (m := m) MonadStateOf.get
  set       s := liftM (m := m) (MonadStateOf.set s)
  modifyGet f := monadLift (m := m) (MonadState.modifyGet f)
Monad State Preservation under Lifting
Informal description
For any monads $m$ and $n$ with state type $\sigma$, if there exists a monad lift from $m$ to $n$ and $m$ is a state monad with state $\sigma$, then $n$ is also a state monad with state $\sigma$.
EStateM.Result inductive
(ε σ α : Type u)
Full source
/--
The value returned from a combined state and exception monad in which exceptions do not
automatically roll back the state.

`Result ε σ α` is equivalent to `Except ε α × σ`, but using a single combined inductive type yields
a more efficient data representation.
-/
inductive Result (ε σ α : Type u) where
  /-- A success value of type `α` and a new state `σ`. -/
  | ok    : α → σ → Result ε σ α
  /-- An exception of type `ε` and a new state `σ`. -/
  | error : ε → σ → Result ε σ α
Result of stateful computation with exceptions
Informal description
The inductive type `Result ε σ α` represents the possible outcomes of a computation in a combined state and exception monad where exceptions do not automatically roll back the state. It has three constructors: 1. `ok a s` representing a successful computation with result `a` and final state `s`. 2. `error e s` representing a failed computation with exception `e` and final state `s`. This is equivalent to `Except ε α × σ` but uses a more efficient representation.
EStateM.instInhabitedResult instance
[Inhabited ε] [Inhabited σ] : Inhabited (Result ε σ α)
Full source
instance [Inhabited ε] [Inhabited σ] : Inhabited (Result ε σ α) where
  default := Result.error default default
Inhabited Result Type for Stateful Computations with Exceptions
Informal description
For any types $\varepsilon$, $\sigma$, and $\alpha$, if $\varepsilon$ and $\sigma$ are inhabited (have default elements), then the type `Result ε σ α` of stateful computations with exceptions is also inhabited.
EStateM definition
(ε σ α : Type u)
Full source
/--
A combined state and exception monad in which exceptions do not automatically roll back the state.

Instances of `EStateM.Backtrackable` provide a way to roll back some part of the state if needed.

`EStateM ε σ` is equivalent to `ExceptT ε (StateM σ)`, but it is more efficient.
-/
def EStateM (ε σ α : Type u) := σ → Result ε σ α
Stateful computation monad with exceptions
Informal description
The monad `EStateM ε σ α` represents a combined state and exception monad where computations can modify a state of type `σ$ and may fail with an exception of type $\varepsilon$, producing a result of type $\alpha$. Unlike standard exception monads, exceptions in this monad do not automatically roll back the state. A computation in this monad is represented as a function that takes an initial state $\sigma$ and returns either: - A successful result $(a, s')$ where $a$ is the result value and $s'$ is the modified state, or - An error $(e, s')$ where $e$ is the exception and $s'$ is the modified state at the point of failure. This provides an efficient implementation equivalent to `ExceptT ε (StateM σ)` but with better performance characteristics.
EStateM.instInhabited instance
[Inhabited ε] : Inhabited (EStateM ε σ α)
Full source
instance [Inhabited ε] : Inhabited (EStateM ε σ α) where
  default := fun s => Result.error default s
Inhabited Stateful Exception Monad
Informal description
For any types $\varepsilon$, $\sigma$, and $\alpha$, if $\varepsilon$ is inhabited (has a default element), then the monad `EStateM ε σ α` of stateful computations with exceptions is also inhabited.
EStateM.pure definition
(a : α) : EStateM ε σ α
Full source
/--
Returns a value without modifying the state or throwing an exception.
-/
@[always_inline, inline]
protected def pure (a : α) : EStateM ε σ α := fun s =>
  Result.ok a s
Pure value in stateful exception monad
Informal description
The function `EStateM.pure` lifts a value `a` of type `α` into the `EStateM ε σ α` monad, producing a computation that returns `a` without modifying the state or throwing an exception.
EStateM.set definition
(s : σ) : EStateM ε σ PUnit
Full source
@[always_inline, inline, inherit_doc MonadState.set]
protected def set (s : σ) : EStateM ε σ PUnit := fun _ =>
  Result.ok ⟨⟩ s
State update in `EStateM` monad
Informal description
The function `EStateM.set` updates the state of an `EStateM` computation to the given value `s` of type `σ`, producing no meaningful result (represented by `PUnit`).
EStateM.get definition
: EStateM ε σ σ
Full source
@[always_inline, inline, inherit_doc MonadState.get]
protected def get : EStateM ε σ σ := fun s =>
  Result.ok s s
State retrieval in `EStateM` monad
Informal description
The function `EStateM.get` retrieves the current state of type `σ$ from the `EStateM ε σ σ` monad without modifying it, returning the state as the successful result.
EStateM.modifyGet definition
(f : σ → Prod α σ) : EStateM ε σ α
Full source
@[always_inline, inline, inherit_doc MonadState.modifyGet]
protected def modifyGet (f : σ → Prod α σ) : EStateM ε σ α := fun s =>
  match f s with
  | (a, s) => Result.ok a s
State modification and retrieval in `EStateM` monad
Informal description
The function `EStateM.modifyGet` takes a function `f : σ → α × σ` and returns a computation in the `EStateM ε σ α` monad. When executed with an initial state `s`, it applies `f` to `s` to obtain a pair `(a, s')` where `a` is the result value and `s'` is the modified state, and returns `a` as the successful result with the new state `s'`.
EStateM.throw definition
(e : ε) : EStateM ε σ α
Full source
@[always_inline, inline, inherit_doc MonadExcept.throw]
protected def throw (e : ε) : EStateM ε σ α := fun s =>
  Result.error e s
Throw exception in stateful computation monad
Informal description
The function `EStateM.throw` takes an exception `e` of type `ε` and returns a computation in the `EStateM ε σ α` monad that immediately fails with exception `e`, leaving the state unchanged.
EStateM.Backtrackable structure
(δ : outParam (Type u)) (σ : Type u)
Full source
/--
Exception handlers in `EStateM` save some part of the state, determined by `δ`, and restore it if an
exception is caught. By default, `δ` is `Unit`, and no information is saved.
-/
class Backtrackable (δ : outParam (Type u)) (σ : Type u) where
  /--
  Extracts the information in the state that should be rolled back if an exception is handled.
  -/
  save    : σ → δ
  /--
  Updates the current state with the saved information that should be rolled back. This updated
  state becomes the current state when an exception is handled.
  -/
  restore : σ → δ → σ
Backtrackable State in Exception-Handling State Monad
Informal description
The structure `EStateM.Backtrackable` represents a backtrackable state in an exception-handling state monad, where `δ` is an output parameter determining the part of the state to be saved and restored when handling exceptions, and `σ` is the type of the full state.
EStateM.tryCatch definition
{δ} [Backtrackable δ σ] {α} (x : EStateM ε σ α) (handle : ε → EStateM ε σ α) : EStateM ε σ α
Full source
/--
Handles exceptions thrown in the combined error and state monad.

The `Backtrackable δ σ` instance is used to save a snapshot of part of the state prior to running
`x`. If an exception is caught, the state is updated with the saved snapshot, rolling back part of
the state. If no instance of `Backtrackable` is provided, a fallback instance in which `δ` is `Unit`
is used, and no information is rolled back.
-/
@[always_inline, inline]
protected def tryCatch {δ} [Backtrackable δ σ] {α} (x : EStateM ε σ α) (handle : ε → EStateM ε σ α) : EStateM ε σ α := fun s =>
  let d := Backtrackable.save s
  match x s with
  | Result.error e s => handle e (Backtrackable.restore s d)
  | ok               => ok
Exception handling with state backtracking in stateful computations
Informal description
The function `EStateM.tryCatch` executes a stateful computation `x` in the `EStateM` monad and provides exception handling. It first saves a snapshot of the backtrackable part of the state (determined by the `Backtrackable δ σ` instance). If `x` throws an exception `e` with state `s`, it applies the handler function `handle` to `e` and restores the backtrackable part of the state from the saved snapshot. If `x` succeeds, the result is returned unchanged.
EStateM.orElse definition
{δ} [Backtrackable δ σ] (x₁ : EStateM ε σ α) (x₂ : Unit → EStateM ε σ α) : EStateM ε σ α
Full source
/--
Failure handling that does not depend on specific exception values.

The `Backtrackable δ σ` instance is used to save a snapshot of part of the state prior to running
`x₁`. If an exception is caught, the state is updated with the saved snapshot, rolling back part of
the state. If no instance of `Backtrackable` is provided, a fallback instance in which `δ` is `Unit`
is used, and no information is rolled back.
-/
@[always_inline, inline]
protected def orElse {δ} [Backtrackable δ σ] (x₁ : EStateM ε σ α) (x₂ : UnitEStateM ε σ α) : EStateM ε σ α := fun s =>
  let d := Backtrackable.save s;
  match x₁ s with
  | Result.error _ s => x₂ () (Backtrackable.restore s d)
  | ok               => ok
Backtracking fallback for stateful computations with exceptions
Informal description
Given a backtrackable state monad instance `Backtrackable δ σ`, the function `EStateM.orElse` executes a stateful computation `x₁` and, if it fails with an exception, rolls back the backtrackable part of the state and executes the fallback computation `x₂ ()`. If `x₁` succeeds, its result is returned unchanged. More precisely: 1. First, a snapshot `d` of the backtrackable part of the state `s` is saved. 2. Then `x₁` is executed with initial state `s`: - If it results in an error, the backtrackable part of the state is restored from `d` and the fallback computation `x₂ ()` is executed. - If it succeeds, the result is returned directly.
EStateM.adaptExcept definition
{ε' : Type u} (f : ε → ε') (x : EStateM ε σ α) : EStateM ε' σ α
Full source
/--
Transforms exceptions with a function, doing nothing on successful results.
-/
@[always_inline, inline]
def adaptExcept {ε' : Type u} (f : ε → ε') (x : EStateM ε σ α) : EStateM ε' σ α := fun s =>
  match x s with
  | Result.error e s => Result.error (f e) s
  | Result.ok a s    => Result.ok a s
Exception transformation in stateful computations
Informal description
Given a function $f : \varepsilon \to \varepsilon'$ and a stateful computation $x$ in the `EStateM` monad with exception type $\varepsilon$ and state type $\sigma$, the function `EStateM.adaptExcept` transforms any exceptions produced by $x$ using $f$ while preserving successful results. Specifically: - If $x$ produces an error $(e, s')$, then `EStateM.adaptExcept f x` produces $(f(e), s')$. - If $x$ produces a successful result $(a, s')$, then `EStateM.adaptExcept f x$ produces $(a, s')$ unchanged.
EStateM.bind definition
(x : EStateM ε σ α) (f : α → EStateM ε σ β) : EStateM ε σ β
Full source
/--
Sequences two `EStateM ε σ` actions, passing the returned value from the first into the second.
-/
@[always_inline, inline]
protected def bind (x : EStateM ε σ α) (f : α → EStateM ε σ β) : EStateM ε σ β := fun s =>
  match x s with
  | Result.ok a s    => f a s
  | Result.error e s => Result.error e s
Monadic bind for stateful computations with exceptions
Informal description
Given a stateful computation `x` in the `EStateM` monad with exception type `ε` and state type `σ`, and a function `f` that maps results of type `α` to new stateful computations of type `EStateM ε σ β`, the function `EStateM.bind` sequences these computations by: 1. Running `x` with initial state `s`, producing either: - A successful result `(a, s')`, in which case it runs `f a` with state `s'`, or - An error `(e, s')`, in which case it propagates the error with state `s'`.
EStateM.map definition
(f : α → β) (x : EStateM ε σ α) : EStateM ε σ β
Full source
/--
Transforms the value returned from an `EStateM ε σ` action using a function.
-/
@[always_inline, inline]
protected def map (f : α → β) (x : EStateM ε σ α) : EStateM ε σ β := fun s =>
  match x s with
  | Result.ok a s    => Result.ok (f a) s
  | Result.error e s => Result.error e s
Mapping over stateful computations with exceptions
Informal description
Given a function $f : \alpha \to \beta$ and a stateful computation $x$ in the `EStateM` monad with exception type $\varepsilon$ and state type $\sigma$, the function `EStateM.map` applies $f$ to the result of $x$ if it succeeds, preserving the state and any exceptions. Specifically: - If $x$ produces a successful result $(a, s')$, then `EStateM.map f x` produces $(f(a), s')$. - If $x$ produces an error $(e, s')$, then `EStateM.map f x$ produces $(e, s')$ unchanged.
EStateM.seqRight definition
(x : EStateM ε σ α) (y : Unit → EStateM ε σ β) : EStateM ε σ β
Full source
/--
Sequences two `EStateM ε σ` actions, running `x` before `y`. The first action's return value is
ignored.
-/
@[always_inline, inline]
protected def seqRight (x : EStateM ε σ α) (y : UnitEStateM ε σ β) : EStateM ε σ β := fun s =>
  match x s with
  | Result.ok _ s    => y () s
  | Result.error e s => Result.error e s
Sequential composition of stateful computations (right-biased)
Informal description
Given two stateful computations with exceptions `x : EStateM ε σ α` and `y : Unit → EStateM ε σ β`, the function `EStateM.seqRight` first executes `x`, ignoring its result value, and then executes `y ()`. The state is propagated from `x` to `y`, and any exception from `x` will terminate the computation without running `y`. More precisely: - If `x` succeeds with result `(_, s')`, then `y ()` is executed with initial state `s'`. - If `x` fails with error `(e, s')`, the result is `(e, s')` and `y` is not executed.
EStateM.instMonad instance
: Monad (EStateM ε σ)
Full source
@[always_inline]
instance instMonad : Monad (EStateM ε σ) where
  bind     := EStateM.bind
  pure     := EStateM.pure
  map      := EStateM.map
  seqRight := EStateM.seqRight
Monad Instance for Stateful Exception Monad
Informal description
The stateful exception monad `EStateM ε σ` is a monad, meaning it supports the standard monadic operations `pure` and `bind` for sequencing computations with state and exceptions.
EStateM.instOrElseOfBacktrackable instance
{δ} [Backtrackable δ σ] : OrElse (EStateM ε σ α)
Full source
instance {δ} [Backtrackable δ σ] : OrElse (EStateM ε σ α) where
  orElse := EStateM.orElse
Backtrackable State Monad with "Or Else" Operation
Informal description
For any backtrackable state type $\delta$ and full state type $\sigma$ with a `Backtrackable` instance, the monad `EStateM ε σ α` is equipped with a canonical `OrElse` instance. This allows for the composition of stateful computations with exceptions using the "or else" operation, where if the first computation fails, the backtrackable part of the state is restored and the second computation is executed.
EStateM.instMonadStateOf instance
: MonadStateOf σ (EStateM ε σ)
Full source
instance : MonadStateOf σ (EStateM ε σ) where
  set       := EStateM.set
  get       := EStateM.get
  modifyGet := EStateM.modifyGet
State Monad Instance for `EStateM`
Informal description
The monad `EStateM ε σ` is equipped with a canonical `MonadStateOf σ` instance, meaning it maintains and allows modification of a mutable state of type `σ`.
EStateM.instMonadExceptOfOfBacktrackable instance
{δ} [Backtrackable δ σ] : MonadExceptOf ε (EStateM ε σ)
Full source
instance {δ} [Backtrackable δ σ] : MonadExceptOf ε (EStateM ε σ) where
  throw    := EStateM.throw
  tryCatch := EStateM.tryCatch
Exception Handling with State Backtracking in `EStateM`
Informal description
For any backtrackable state type $\delta$ and full state type $\sigma$ with a `Backtrackable` instance, the monad `EStateM ε σ` is equipped with a canonical `MonadExceptOf ε` instance, meaning it can throw and catch exceptions of type $\varepsilon$ while properly handling state backtracking.
EStateM.run definition
(x : EStateM ε σ α) (s : σ) : Result ε σ α
Full source
/--
Executes an `EStateM` action with the initial state `s`. The returned value includes the final state
and indicates whether an exception was thrown or a value was returned.
-/
@[always_inline, inline]
def run (x : EStateM ε σ α) (s : σ) : Result ε σ α := x s
Execution of a stateful computation with exceptions
Informal description
Given a stateful computation `x` in the `EStateM ε σ α` monad and an initial state `s`, the function `EStateM.run` executes the computation and returns a `Result ε σ α` which is either: - `ok a s'` representing a successful computation with result `a` and final state `s'`, or - `error e s'` representing a failed computation with exception `e` and final state `s'`.
EStateM.run' definition
(x : EStateM ε σ α) (s : σ) : Option α
Full source
/--
Executes an `EStateM` with the initial state `s` for the returned value `α`, discarding the final
state. Returns `none` if an unhandled exception was thrown.
-/
@[always_inline, inline]
def run' (x : EStateM ε σ α) (s : σ) : Option α :=
  match run x s with
  | Result.ok v _   => some v
  | Result.error .. => none
Execution of stateful computation with exceptions (discarding state)
Informal description
Given a stateful computation `x` in the `EStateM ε σ α` monad and an initial state `s`, the function `EStateM.run'` executes the computation and returns an optional value of type `α`. If the computation succeeds, it returns `some v` where `v` is the result value; if the computation fails with an exception, it returns `none`. The final state is discarded in both cases.
EStateM.dummySave definition
: σ → PUnit
Full source
/-- The `save` implementation for `Backtrackable PUnit σ`. -/
@[inline] def dummySave : σ → PUnit := fun _ => ⟨⟩
Trivial save operation for backtrackable state monad
Informal description
The function takes a state `s` of type `σ` and returns the unique element of the unit type `PUnit`. This serves as a trivial implementation of a save operation in a backtrackable state monad context.
EStateM.dummyRestore definition
: σ → PUnit → σ
Full source
/-- The `restore` implementation for `Backtrackable PUnit σ`. -/
@[inline] def dummyRestore : σ → PUnit → σ := fun s _ => s
Trivial restore operation for backtrackable state monad
Informal description
The function `EStateM.dummyRestore` takes a state `s` of type `σ` and a value of type `PUnit`, and returns the state `s` unchanged. This serves as a trivial implementation of a restore operation in a backtrackable state monad context.
EStateM.nonBacktrackable instance
: Backtrackable PUnit σ
Full source
/--
A fallback `Backtrackable` instance that saves no information from a state. This allows every type
to be used as a state in `EStateM`, with no rollback.

Because this is the first declared instance of `Backtrackable _ σ`, it will be picked only if there
are no other `Backtrackable _ σ` instances registered.
-/
instance nonBacktrackable : Backtrackable PUnit σ where
  save    := dummySave
  restore := dummyRestore
Trivial Backtrackable State Instance
Informal description
For any state type $\sigma$, there is a trivial backtrackable state instance that saves no information, using the unit type $\mathrm{PUnit}$ as the saved state. This instance allows any type to be used as a state in the exception-handling state monad $\mathrm{EStateM}$ without any rollback capability.
Hashable structure
(α : Sort u)
Full source
/-- Types that can be hashed into a `UInt64`. -/
class Hashable (α : Sort u) where
  /-- Hashes a value into a `UInt64`. -/
  hash : α → UInt64
Hashable type
Informal description
The structure representing types that can be hashed into a 64-bit unsigned integer.
mixHash opaque
(u₁ u₂ : UInt64) : UInt64
Full source
/-- An opaque hash mixing operation, used to implement hashing for products. -/
@[extern "lean_uint64_mix_hash"]
opaque mixHash (u₁ u₂ : UInt64) : UInt64
Hash mixing function for 64-bit unsigned integers
Informal description
Given two unsigned 64-bit integers $u_1$ and $u_2$, the function $\mathrm{mixHash}$ computes a combined hash value of type $\mathrm{UInt64}$.
instHashableSubtype instance
[Hashable α] {p : α → Prop} : Hashable (Subtype p)
Full source
instance [Hashable α] {p : α → Prop} : Hashable (Subtype p) where
  hash a := hash a.val
Hashable Subtype Inheritance
Informal description
For any type $\alpha$ with a hash function and any predicate $p$ on $\alpha$, the subtype $\{x \in \alpha \mid p(x)\}$ inherits a hash function from $\alpha$.
String.hash opaque
(s : @& String) : UInt64
Full source
/--
Computes a hash for strings.
-/
@[extern "lean_string_hash"]
protected opaque String.hash (s : @& String) : UInt64
String Hash Function
Informal description
The function `String.hash` computes a 64-bit unsigned integer hash value for a given string $s$.
instHashableString instance
: Hashable String
Full source
instance : Hashable String where
  hash := String.hash
Hashable Strings
Informal description
The type `String` is equipped with a hash function that maps any string to a 64-bit unsigned integer.
Lean.Name inductive
Full source
/--
Hierarchical names consist of a sequence of components, each of
which is either a string or numeric, that are written separated by dots (`.`).

Hierarchical names are used to name declarations and for creating
unique identifiers for free variables and metavariables.

You can create hierarchical names using a backtick:
```
`Lean.Meta.whnf
```
It is short for `.str (.str (.str .anonymous "Lean") "Meta") "whnf"`.

You can use double backticks to request Lean to statically check whether the name
corresponds to a Lean declaration in scope.
```
``Lean.Meta.whnf
```
If the name is not in scope, Lean will report an error.

There are two ways to convert a `String` to a `Name`:

 1. `Name.mkSimple` creates a name with a single string component.

 2. `String.toName` first splits the string into its dot-separated
    components, and then creates a hierarchical name.
-/
inductive Name where
  /-- The "anonymous" name. -/
  | anonymous : Name
  /--
  A string name. The name `Lean.Meta.run` is represented at
  ```lean
  .str (.str (.str .anonymous "Lean") "Meta") "run"
  ```
  -/
  | str (pre : Name) (str : String)
  /--
  A numerical name. This kind of name is used, for example, to create hierarchical names for
  free variables and metavariables. The identifier `_uniq.231` is represented as
  ```lean
  .num (.str .anonymous "_uniq") 231
  ```
  -/
  | num (pre : Name) (i : Nat)
with
  /-- A hash function for names, which is stored inside the name itself as a
  computed field. -/
  @[computed_field] hash : NameUInt64
    | .anonymous => .ofNatLT 1723 (of_decide_eq_true rfl)
    | .str p s => mixHash p.hash s.hash
    | .num p v => mixHash p.hash (dite (LT.lt v UInt64.size) (fun h => UInt64.ofNatLT v h) (fun _ => UInt64.ofNatLT 17 (of_decide_eq_true rfl)))
Hierarchical Names in Lean
Informal description
The inductive type `Name` represents hierarchical names composed of a sequence of components, where each component is either a string or a numeric value. These components are typically written separated by dots (`.`). Hierarchical names are used for: 1. Naming declarations in Lean 2. Creating unique identifiers for free variables and metavariables A name can be constructed using backtick notation (e.g., `` `Lean.Meta.whnf ``), which is syntactic sugar for building the hierarchical structure. Double backticks (`` ``Lean.Meta.whnf ``) can be used to request static checking that the name corresponds to an existing declaration. There are two main ways to convert strings to names: 1. `Name.mkSimple` creates a single-component name 2. `String.toName` splits the string by dots and creates a hierarchical name
Lean.instInhabitedName instance
: Inhabited Name
Full source
instance : Inhabited Name where
  default := Name.anonymous
Inhabited Type of Lean Names
Informal description
The type of hierarchical names in Lean is inhabited, meaning there exists a default name.
Lean.instHashableName instance
: Hashable Name
Full source
instance : Hashable Name where
  hash := Name.hash
Hashable Hierarchical Names in Lean
Informal description
The type of hierarchical names in Lean can be hashed into a 64-bit unsigned integer.
Lean.Name.mkStr abbrev
(p : Name) (s : String) : Name
Full source
/--
`.str p s` is now the preferred form.
-/
@[export lean_name_mk_string]
abbrev mkStr (p : Name) (s : String) : Name :=
  Name.str p s
String Component Addition to Hierarchical Name
Informal description
Given a hierarchical name `p` and a string `s`, the function constructs a new hierarchical name by appending `s` as a string component to `p`.
Lean.Name.mkNum abbrev
(p : Name) (v : Nat) : Name
Full source
/--
`.num p v` is now the preferred form.
-/
@[export lean_name_mk_numeral]
abbrev mkNum (p : Name) (v : Nat) : Name :=
  Name.num p v
Numeric Component Addition to Hierarchical Name
Informal description
Given a hierarchical name `p` and a natural number `v`, the function constructs a new hierarchical name by appending `v` as a numeric component to `p`.
Lean.Name.mkSimple abbrev
(s : String) : Name
Full source
/--
Converts a `String` to a `Name` without performing any parsing. `mkSimple s` is short for `.str .anonymous s`.

This means that `mkSimple "a.b"` is the name `«a.b»`, not `a.b`.
-/
abbrev mkSimple (s : String) : Name :=
  .str .anonymous s
Single-component name constructor
Informal description
The function `mkSimple` constructs a hierarchical name from a single string component `s`, resulting in the name `«s»` (where `s` is treated as a single unparsed component, even if it contains dots).
Lean.Name.mkStr1 definition
(s₁ : String) : Name
Full source
/-- Make name `s₁` -/
@[reducible] def mkStr1 (s₁ : String) : Name :=
  .str .anonymous s₁
Hierarchical name constructor (single component)
Informal description
The function constructs a hierarchical name from a single string component `s₁`, forming the name `s₁`.
Lean.Name.mkStr2 definition
(s₁ s₂ : String) : Name
Full source
/-- Make name `s₁.s₂` -/
@[reducible] def mkStr2 (s₁ s₂ : String) : Name :=
  .str (.str .anonymous s₁) s₂
Hierarchical name constructor (two components)
Informal description
The function constructs a hierarchical name from two string components `s₁` and `s₂`, forming the name `s₁.s₂`.
Lean.Name.mkStr3 definition
(s₁ s₂ s₃ : String) : Name
Full source
/-- Make name `s₁.s₂.s₃` -/
@[reducible] def mkStr3 (s₁ s₂ s₃ : String) : Name :=
  .str (.str (.str .anonymous s₁) s₂) s₃
Hierarchical name constructor (three components)
Informal description
The function constructs a hierarchical name from three string components `s₁`, `s₂`, and `s₃`, forming the name `s₁.s₂.s₃`.
Lean.Name.mkStr4 definition
(s₁ s₂ s₃ s₄ : String) : Name
Full source
/-- Make name `s₁.s₂.s₃.s₄` -/
@[reducible] def mkStr4 (s₁ s₂ s₃ s₄ : String) : Name :=
  .str (.str (.str (.str .anonymous s₁) s₂) s₃) s₄
Hierarchical name constructor (four components)
Informal description
The function constructs a hierarchical name from four string components `s₁`, `s₂`, `s₃`, and `s₄`, forming the name `s₁.s₂.s₃.s₄`.
Lean.Name.mkStr5 definition
(s₁ s₂ s₃ s₄ s₅ : String) : Name
Full source
/-- Make name `s₁.s₂.s₃.s₄.s₅` -/
@[reducible] def mkStr5 (s₁ s₂ s₃ s₄ s₅ : String) : Name :=
  .str (.str (.str (.str (.str .anonymous s₁) s₂) s₃) s₄) s₅
Hierarchical name constructor (five components)
Informal description
The function constructs a hierarchical name from five string components `s₁`, `s₂`, `s₃`, `s₄`, and `s₅`, forming the name `s₁.s₂.s₃.s₄.s₅`.
Lean.Name.mkStr6 definition
(s₁ s₂ s₃ s₄ s₅ s₆ : String) : Name
Full source
/-- Make name `s₁.s₂.s₃.s₄.s₅.s₆` -/
@[reducible] def mkStr6 (s₁ s₂ s₃ s₄ s₅ s₆ : String) : Name :=
  .str (.str (.str (.str (.str (.str .anonymous s₁) s₂) s₃) s₄) s₅) s₆
Hierarchical name constructor (six components)
Informal description
The function constructs a hierarchical name from six string components $s_1, s_2, s_3, s_4, s_5, s_6$, forming the name $s_1.s_2.s_3.s_4.s_5.s_6$.
Lean.Name.mkStr7 definition
(s₁ s₂ s₃ s₄ s₅ s₆ s₇ : String) : Name
Full source
/-- Make name `s₁.s₂.s₃.s₄.s₅.s₆.s₇` -/
@[reducible] def mkStr7 (s₁ s₂ s₃ s₄ s₅ s₆ s₇ : String) : Name :=
  .str (.str (.str (.str (.str (.str (.str .anonymous s₁) s₂) s₃) s₄) s₅) s₆) s₇
Hierarchical name constructor (seven components)
Informal description
The function constructs a hierarchical name from seven string components $s_1, s_2, \dots, s_7$, forming the name $s_1.s_2.s_3.s_4.s_5.s_6.s_7$.
Lean.Name.mkStr8 definition
(s₁ s₂ s₃ s₄ s₅ s₆ s₇ s₈ : String) : Name
Full source
/-- Make name `s₁.s₂.s₃.s₄.s₅.s₆.s₇.s₈` -/
@[reducible] def mkStr8 (s₁ s₂ s₃ s₄ s₅ s₆ s₇ s₈ : String) : Name :=
  .str (.str (.str (.str (.str (.str (.str (.str .anonymous s₁) s₂) s₃) s₄) s₅) s₆) s₇) s₈
Hierarchical name constructor for eight components
Informal description
The function constructs a hierarchical name from eight string components $s_1, s_2, \dots, s_8$, forming the name $s_1.s_2.s_3.s_4.s_5.s_6.s_7.s_8$.
Lean.Name.beq definition
: (@& Name) → (@& Name) → Bool
Full source
/-- (Boolean) equality comparator for names. -/
@[extern "lean_name_eq"]
protected def beq : (@& Name) → (@& Name) → Bool
  | anonymous, anonymous => true
  | str p₁ s₁, str p₂ s₂ => and (BEq.beq s₁ s₂) (Name.beq p₁ p₂)
  | num p₁ n₁, num p₂ n₂ => and (BEq.beq n₁ n₂) (Name.beq p₁ p₂)
  | _,         _         => false
Boolean equality for hierarchical names
Informal description
The boolean equality function for hierarchical names in Lean. Given two names, it returns `true` if they are structurally equal, and `false` otherwise. Specifically: - Two anonymous names are equal. - Two string-named components are equal if both their string parts and parent names are equal. - Two numeric-named components are equal if both their numeric parts and parent names are equal. - All other cases are not equal.
Lean.Name.instBEq instance
: BEq Name
Full source
instance : BEq Name where
  beq := Name.beq
Boolean Equality for Hierarchical Names in Lean
Informal description
The type `Name` of hierarchical names in Lean is equipped with a boolean equality relation `==` that checks for structural equality between two names. Specifically: - Two anonymous names are considered equal. - Two string-named components are equal if both their string parts and parent names are equal. - Two numeric-named components are equal if both their numeric parts and parent names are equal. - All other cases are considered not equal.
Lean.Name.appendCore definition
: Name → Name → Name
Full source
/--
This function does not have special support for macro scopes.
See `Name.append`.
-/
def appendCore : NameNameName
  | n, .anonymous => n
  | n, .str p s => .str (appendCore n p) s
  | n, .num p d => .num (appendCore n p) d
Hierarchical name concatenation
Informal description
The function appends two hierarchical names in Lean, where a hierarchical name is a sequence of components (either strings or numbers) separated by dots. Given two names `n` and `m`, it recursively constructs a new name by appending the components of `m` to `n`. If `m` is anonymous (empty), it returns `n` unchanged. Otherwise, it processes each component of `m` (string or numeric) and builds the resulting name by adding these components to the result of appending `n` with the parent structure of `m`.
Lean.defaultMaxRecDepth definition
Full source
/-- The default maximum recursion depth. This is adjustable using the `maxRecDepth` option. -/
def defaultMaxRecDepth := 512
Default maximum recursion depth
Informal description
The default maximum recursion depth is set to 512. This value can be adjusted using the `maxRecDepth` option.
Lean.maxRecDepthErrorMessage definition
: String
Full source
/-- The message to display on stack overflow. -/
def maxRecDepthErrorMessage : String :=
  "maximum recursion depth has been reached\nuse `set_option maxRecDepth <num>` to increase limit\nuse `set_option diagnostics true` to get diagnostic information"
Maximum recursion depth error message
Informal description
The error message displayed when the maximum recursion depth is exceeded during execution. The message suggests increasing the recursion limit via `set_option maxRecDepth ` or enabling diagnostics with `set_option diagnostics true` for more information.
Lean.instInhabitedSourceInfo instance
: Inhabited SourceInfo
Full source
instance : Inhabited SourceInfo := ⟨SourceInfo.none⟩
Inhabited Type Instance for SourceInfo
Informal description
The type `SourceInfo` is inhabited, meaning it has a designated default element.
Lean.SourceInfo.getTrailing? definition
(info : SourceInfo) : Option Substring
Full source
/--
Gets the substring representing the trailing whitespace of a `SourceInfo`, if available.
-/
def getTrailing? (info : SourceInfo) : Option Substring :=
  match info with
  | original (trailing := trailing) .. => some trailing
  | _                                  => none
Trailing whitespace substring from SourceInfo
Informal description
Given a `SourceInfo` object, this function retrieves the substring representing the trailing whitespace if it is available, otherwise returns `none`. The trailing whitespace is only present when the `SourceInfo` is constructed with the `original` variant.
Lean.SyntaxNodeKind abbrev
Full source
/--
Specifies the interpretation of a `Syntax.node` value. An abbreviation for `Name`.

Node kinds may be any name, and do not need to refer to declarations in the environment.
Conventionally, however, a node's kind corresponds to the `Parser` or `ParserDesc` declaration that
produces it. There are also a number of built-in node kinds that are used by the parsing
infrastructure, such as `nullKind` and `choiceKind`; these do not correspond to parser declarations.
-/
abbrev SyntaxNodeKind := Name
Syntax Node Kind in Lean Parsing Infrastructure
Informal description
The type `Lean.SyntaxNodeKind` represents the interpretation of a syntax node value in Lean's parsing infrastructure. It is an abbreviation for `Name` and specifies the kind of a syntax node, which may correspond to a parser declaration or be one of the built-in node kinds used by the parsing system.
Lean.Syntax.Preresolved inductive
Full source
/--
A possible binding of an identifier in the context in which it was quoted.

Identifiers in quotations may refer to either global declarations or to namespaces that are in scope
at the site of the quotation. These are saved in the `Syntax.ident` constructor and are part of the
implementation of hygienic macros.
-/
inductive Syntax.Preresolved where
  /-- A potential namespace reference -/
  | namespace (ns : Name)
  /-- A potential global constant or section variable reference, with additional field accesses -/
  | decl (n : Name) (fields : List String)
Pre-resolved syntax bindings
Informal description
An inductive type representing possible bindings of an identifier in the context where it was quoted. Identifiers in quotations may refer to either global declarations or namespaces that are in scope at the quotation site. These bindings are saved in the `Syntax.ident` constructor and are part of the implementation of hygienic macros.
Lean.Syntax inductive
Full source
/--
Lean syntax trees.

Syntax trees are used pervasively throughout Lean: they are produced by the parser, transformed by
the macro expander, and elaborated. They are also produced by the delaborator and presented to
users.
-/
inductive Syntax where
  /--
  A portion of the syntax tree that is missing because of a parse error.

  The indexing operator on `Syntax` also returns `Syntax.missing` when the index is out of bounds.
  -/
  | missing : Syntax
  /--
  A node in the syntax tree that may have further syntax as child nodes. The node's `kind`
  determines its interpretation.

  For nodes produced by the parser, the `info` field is typically `Lean.SourceInfo.none`, and source
  information is stored in the corresponding fields of identifiers and atoms. This field is used in
  two ways:
   1. The delaborator uses it to associate nodes with metadata that are used to implement
      interactive features.
   2. Nodes created by quotations use the field to mark the syntax as synthetic (storing the result
      of `Lean.SourceInfo.fromRef`) even when its leading or trailing tokens are not.
  -/
  -- Remark: the `node` constructor did not have an `info` field in previous versions. This caused a
  -- bug in the interactive widgets, where the popup for `a + b` was the same as for `a`. The
  -- delaborator used to associate subexpressions with pretty-printed syntax by setting the (string)
  -- position of the first atom/identifier to the (expression) position of the subexpression. For
  -- example, both `a` and `a + b` have the same first identifier, and so their infos got mixed up.
  | node   (info : SourceInfo) (kind : SyntaxNodeKind) (args : Array Syntax) : Syntax
  /--
  A non-identifier atomic component of syntax.

  All of the following are atoms:
   * keywords, such as `def`, `fun`, and `inductive`
   * literals, such as numeric or string literals
   * punctuation and delimiters, such as `(`, `)`, and `=>`.

  Identifiers are represented by the `Lean.Syntax.ident` constructor. Atoms also correspond to
  quoted strings inside `syntax` declarations.
  -/
  | atom   (info : SourceInfo) (val : String) : Syntax
  /--
  An identifier.

  In addition to source information, identifiers have the following fields:
  * `rawVal` is the literal substring from the input file
  * `val` is the parsed Lean name, potentially including macro scopes.
  * `preresolved` is the list of possible declarations this could refer to, populated by
    [quotations](lean-manual://section/quasiquotation).
  -/
  | ident  (info : SourceInfo) (rawVal : Substring) (val : Name) (preresolved : List Syntax.Preresolved) : Syntax
Lean Syntax Trees
Informal description
The inductive type representing syntax trees in Lean, which are used throughout the system for parsing, macro expansion, elaboration, and presentation to users. These trees are produced by the parser, transformed by macros, and ultimately elaborated into Lean terms.
Lean.Syntax.node1 definition
(info : SourceInfo) (kind : SyntaxNodeKind) (a₁ : Syntax) : Syntax
Full source
/-- Create syntax node with 1 child -/
def Syntax.node1 (info : SourceInfo) (kind : SyntaxNodeKind) (a₁ : Syntax) : Syntax :=
  Syntax.node info kind (Array.mkArray1 a₁)
Syntax node with one child
Informal description
The function constructs a syntax tree node with a single child node, given source information, a node kind, and the child syntax node. The child is stored in an array of size one.
Lean.Syntax.node2 definition
(info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ : Syntax) : Syntax
Full source
/-- Create syntax node with 2 children -/
def Syntax.node2 (info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ : Syntax) : Syntax :=
  Syntax.node info kind (Array.mkArray2 a₁ a₂)
Syntax node with two children
Informal description
The function constructs a syntax tree node with two children `a₁` and `a₂`, given source information `info` and a node kind `kind`. It internally creates an array containing the two children and combines them into a syntax node.
Lean.Syntax.node3 definition
(info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ : Syntax) : Syntax
Full source
/-- Create syntax node with 3 children -/
def Syntax.node3 (info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ : Syntax) : Syntax :=
  Syntax.node info kind (Array.mkArray3 a₁ a₂ a₃)
Syntax node with three children
Informal description
The function constructs a syntax tree node with three children, given source information, a node kind, and three syntax elements. The resulting node combines these elements into a single syntax structure using an array of exactly three elements.
Lean.Syntax.node4 definition
(info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ a₄ : Syntax) : Syntax
Full source
/-- Create syntax node with 4 children -/
def Syntax.node4 (info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ a₄ : Syntax) : Syntax :=
  Syntax.node info kind (Array.mkArray4 a₁ a₂ a₃ a₄)
Syntax node with four children
Informal description
The function constructs a syntax tree node with four children, given source information, a node kind, and four syntax elements. The resulting node combines these elements into an array structure.
Lean.Syntax.node5 definition
(info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ a₄ a₅ : Syntax) : Syntax
Full source
/-- Create syntax node with 5 children -/
def Syntax.node5 (info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ a₄ a₅ : Syntax) : Syntax :=
  Syntax.node info kind (Array.mkArray5 a₁ a₂ a₃ a₄ a₅)
Syntax node with five children
Informal description
The function creates a syntax tree node with source information `info`, node kind `kind`, and five child syntax nodes $a_1, a_2, a_3, a_4, a_5$.
Lean.Syntax.node6 definition
(info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ a₄ a₅ a₆ : Syntax) : Syntax
Full source
/-- Create syntax node with 6 children -/
def Syntax.node6 (info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ a₄ a₅ a₆ : Syntax) : Syntax :=
  Syntax.node info kind (Array.mkArray6 a₁ a₂ a₃ a₄ a₅ a₆)
Syntax node with six children
Informal description
The function constructs a syntax tree node with six children, given source information, a node kind, and six syntax elements. The resulting node combines these elements into a single syntax structure.
Lean.Syntax.node7 definition
(info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ a₄ a₅ a₆ a₇ : Syntax) : Syntax
Full source
/-- Create syntax node with 7 children -/
def Syntax.node7 (info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ a₄ a₅ a₆ a₇ : Syntax) : Syntax :=
  Syntax.node info kind (Array.mkArray7 a₁ a₂ a₃ a₄ a₅ a₆ a₇)
Syntax node with seven children
Informal description
The function constructs a syntax tree node with seven children, given source information, a node kind, and seven syntax elements $a_1$ through $a_7$.
Lean.Syntax.node8 definition
(info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ a₄ a₅ a₆ a₇ a₈ : Syntax) : Syntax
Full source
/-- Create syntax node with 8 children -/
def Syntax.node8 (info : SourceInfo) (kind : SyntaxNodeKind) (a₁ a₂ a₃ a₄ a₅ a₆ a₇ a₈ : Syntax) : Syntax :=
  Syntax.node info kind (Array.mkArray8 a₁ a₂ a₃ a₄ a₅ a₆ a₇ a₈)
Syntax node with eight children
Informal description
The function constructs a syntax node with source information `info`, node kind `kind`, and exactly eight child syntax nodes $a_1, a_2, a_3, a_4, a_5, a_6, a_7, a_8$.
Lean.SyntaxNodeKinds definition
Full source
/--
`SyntaxNodeKinds` is a set of `SyntaxNodeKind`, implemented as a list.

Singleton `SyntaxNodeKinds` are extremely common. They are written as name literals, rather than as
lists; list syntax is required only for empty or non-singleton sets of kinds.
-/
def SyntaxNodeKinds := List SyntaxNodeKind
Syntax Node Kinds
Informal description
The type `SyntaxNodeKinds` represents a set of syntax node kinds in Lean's parsing infrastructure, implemented as a list of `SyntaxNodeKind` values. Singleton sets are common and can be written directly as name literals, while list syntax is used for empty or non-singleton sets.
Lean.TSyntax structure
(ks : SyntaxNodeKinds)
Full source
/--
Typed syntax, which tracks the potential kinds of the `Syntax` it contains.

While syntax quotations produce or expect `TSyntax` values of the correct kinds, this is not
otherwise enforced; it can easily be circumvented by direct use of the constructor.
-/
structure TSyntax (ks : SyntaxNodeKinds) where
  /-- The underlying `Syntax` value. -/
  raw : Syntax
Typed Syntax
Informal description
The structure `TSyntax` represents typed syntax in Lean, which tracks the potential kinds of the syntax nodes it contains. It is parameterized by a set of syntax node kinds `ks`. While syntax quotations typically produce or expect `TSyntax` values of the correct kinds, this typing is not strictly enforced and can be circumvented by direct use of the constructor.
Lean.instInhabitedSyntax instance
: Inhabited Syntax
Full source
instance : Inhabited Syntax where
  default := Syntax.missing
Inhabited Syntax Trees
Informal description
The type `Syntax` representing Lean syntax trees is inhabited, with a designated default value.
Lean.instInhabitedTSyntax instance
: Inhabited (TSyntax ks)
Full source
instance : Inhabited (TSyntax ks) where
  default := ⟨default⟩
Inhabited Typed Syntax Trees
Informal description
For any set of syntax node kinds `ks`, the type `TSyntax ks` of typed Lean syntax trees is inhabited, meaning it has a designated default value.
Lean.choiceKind abbrev
: SyntaxNodeKind
Full source
/--
The `` `choice `` kind is used to represent ambiguous parse results.

The parser prioritizes longer matches over shorter ones, but there is not always a unique longest
match. All the parse results are saved, and the determination of which to use is deferred
until typing information is available.
-/
abbrev choiceKind : SyntaxNodeKind := `choice
Ambiguous Parse Result Syntax Node Kind
Informal description
The syntax node kind `choice` is used to represent ambiguous parse results in Lean's parsing infrastructure. When multiple valid parse results exist with the same length, the parser defers the selection of the correct one until typing information becomes available.
Lean.nullKind abbrev
: SyntaxNodeKind
Full source
/--
`` `null `` is the “fallback” kind, used when no other kind applies. Null nodes result from
repetition operators, and empty null nodes represent the failure of an optional parse.

The null kind is used for raw list parsers like `many`.
-/
abbrev nullKind : SyntaxNodeKind := `null
Null Syntax Node Kind in Lean Parsing
Informal description
The syntax node kind `null` is used as a fallback when no other kind applies, particularly for nodes resulting from repetition operators or representing the failure of an optional parse in Lean's parsing infrastructure.
Lean.groupKind abbrev
: SyntaxNodeKind
Full source
/--
The `` `group `` kind is used for nodes that result from `Lean.Parser.group`. This avoids confusion
with the null kind when used inside `optional`.
-/
abbrev groupKind : SyntaxNodeKind := `group
Syntax Node Kind for Group Parsing
Informal description
The syntax node kind `group` is used for nodes resulting from `Lean.Parser.group`, distinguishing them from nodes with the null kind when used inside an `optional` parser.
Lean.identKind abbrev
: SyntaxNodeKind
Full source
/--
The pseudo-kind assigned to identifiers: `` `ident ``.

The name `` `ident `` is not actually used as a kind for `Syntax.node` values. It is used by
convention as the kind of `Syntax.ident` values.
-/
abbrev identKind : SyntaxNodeKind := `ident
Syntax Node Kind for Identifiers
Informal description
The syntax node kind `ident` is used to represent identifiers in Lean's parsing infrastructure. It is the pseudo-kind assigned to identifier nodes (`` `ident ``) in the abstract syntax tree, though it is not actually used as a kind for `Syntax.node` values. Instead, it conventionally denotes the kind of `Syntax.ident` values.
Lean.strLitKind abbrev
: SyntaxNodeKind
Full source
/-- `` `str `` is the node kind of string literals like `"foo"`. -/
abbrev strLitKind : SyntaxNodeKind := `str
Syntax Node Kind for String Literals
Informal description
The syntax node kind `strLitKind` represents string literals in Lean's parsing infrastructure, such as `"foo"`.
Lean.charLitKind abbrev
: SyntaxNodeKind
Full source
/-- `` `char `` is the node kind of character literals like `'A'`. -/
abbrev charLitKind : SyntaxNodeKind := `char
Syntax Node Kind for Character Literals
Informal description
The syntax node kind `charLitKind` represents character literals in Lean's parsing infrastructure, such as `'A'`.
Lean.numLitKind abbrev
: SyntaxNodeKind
Full source
/-- `` `num `` is the node kind of number literals like `42`. -/
abbrev numLitKind : SyntaxNodeKind := `num
Syntax Node Kind for Numeric Literals
Informal description
The syntax node kind `numLitKind` represents numeric literals in Lean's parsing infrastructure, such as `42`.
Lean.scientificLitKind abbrev
: SyntaxNodeKind
Full source
/-- `` `scientific `` is the node kind of floating point literals like `1.23e-3`. -/
abbrev scientificLitKind : SyntaxNodeKind := `scientific
Syntax Node Kind for Scientific Notation Literals
Informal description
The syntax node kind `scientificLitKind` represents floating-point literals in Lean's parsing infrastructure, such as `1.23e-3`.
Lean.nameLitKind abbrev
: SyntaxNodeKind
Full source
/-- `` `name `` is the node kind of name literals like `` `foo ``. -/
abbrev nameLitKind : SyntaxNodeKind := `name
Syntax Node Kind for Name Literals
Informal description
The syntax node kind `nameLitKind` represents name literals in Lean's parsing infrastructure, such as `` `foo ``.
Lean.fieldIdxKind abbrev
: SyntaxNodeKind
Full source
/-- `` `fieldIdx ` is the node kind of projection indices like the `2` in `x.2`. -/
abbrev fieldIdxKind : SyntaxNodeKind := `fieldIdx
Syntax Node Kind for Projection Indices
Informal description
The syntax node kind `fieldIdxKind` represents projection indices in Lean's parsing infrastructure, such as the `2` in `x.2`.
Lean.hygieneInfoKind abbrev
: SyntaxNodeKind
Full source
/--
`` `hygieneInfo `` is the node kind of the `Lean.Parser.hygieneInfo` parser, which produces an
“invisible token” that captures the hygiene information at the current point without parsing
anything.

They can be used to generate identifiers (with `Lean.HygieneInfo.mkIdent`) as if they were
introduced in a macro's input, rather than by its implementation.
-/
abbrev hygieneInfoKind : SyntaxNodeKind := `hygieneInfo
Syntax Node Kind for Hygiene Information
Informal description
The syntax node kind `hygieneInfoKind` represents hygiene information in Lean's parsing infrastructure, which is used to track identifier scoping and prevent naming conflicts during macro expansion.
Lean.interpolatedStrLitKind abbrev
: SyntaxNodeKind
Full source
/--
`` `interpolatedStrLitKind `` is the node kind of interpolated string literal
fragments like `"value = {` and `}"` in `s!"value = {x}"`.
-/
abbrev interpolatedStrLitKind : SyntaxNodeKind := `interpolatedStrLitKind
Syntax Node Kind for Interpolated String Literal Fragments
Informal description
The syntax node kind `interpolatedStrLitKind` represents fragments of interpolated string literals, such as `"value = {` and `}"` in expressions like `s!"value = {x}"`.
Lean.interpolatedStrKind abbrev
: SyntaxNodeKind
Full source
/--
`` `interpolatedStrKind `` is the node kind of an interpolated string literal like `"value = {x}"`
in `s!"value = {x}"`.
-/
abbrev interpolatedStrKind : SyntaxNodeKind := `interpolatedStrKind
Syntax Node Kind for Interpolated String Literals
Informal description
The syntax node kind `interpolatedStrKind` represents interpolated string literals in Lean, such as `s!"value = {x}"`.
Lean.mkNode definition
(k : SyntaxNodeKind) (args : Array Syntax) : TSyntax (.cons k .nil)
Full source
/-- Creates an info-less node of the given kind and children. -/
@[inline] def mkNode (k : SyntaxNodeKind) (args : Array Syntax) : TSyntax (.cons k .nil) :=
  ⟨Syntax.node SourceInfo.none k args⟩
Syntax node constructor
Informal description
The function `mkNode` constructs a syntax tree node of kind `k` with the given array of child nodes `args`. The resulting node has no source information attached and is wrapped in a `TSyntax` type that statically tracks its kind.
Lean.Syntax.getKind definition
(stx : Syntax) : SyntaxNodeKind
Full source
/--
Gets the kind of a `Syntax.node` value, or the pseudo-kind of any other `Syntax` value.

“Pseudo-kinds” are kinds that are assigned by convention to non-`Syntax.node` values:
`identKind` for `Syntax.ident`, `` `missing `` for `Syntax.missing`, and the atom's string literal
for atoms.
-/
def getKind (stx : Syntax) : SyntaxNodeKind :=
  match stx with
  | Syntax.node _ k _    => k
  -- We use these "pseudo kinds" for antiquotation kinds.
  -- For example, an antiquotation `$id:ident` (using Lean.Parser.Term.ident)
  -- is compiled to ``if stx.isOfKind `ident ...``
  | Syntax.missing     => `missing
  | Syntax.atom _ v    => Name.mkSimple v
  | Syntax.ident ..    => identKind
Syntax node kind retrieval
Informal description
The function `getKind` retrieves the kind of a syntax tree node `stx`. For a `Syntax.node`, it returns the node's kind. For `Syntax.missing`, it returns the pseudo-kind `` `missing ``. For `Syntax.atom`, it returns the atom's string value as a simple name. For `Syntax.ident`, it returns the pseudo-kind `identKind`.
Lean.Syntax.setKind definition
(stx : Syntax) (k : SyntaxNodeKind) : Syntax
Full source
/--
Changes the kind at the root of a `Syntax.node` to `k`.

Returns all other `Syntax` values unchanged.
-/
def setKind (stx : Syntax) (k : SyntaxNodeKind) : Syntax :=
  match stx with
  | Syntax.node info _ args => Syntax.node info k args
  | _                       => stx
Syntax tree node kind modification
Informal description
The function takes a syntax tree `stx` and a node kind `k`, and returns a new syntax tree where the root node kind of `stx` is replaced with `k`. If `stx` is not a node (e.g., it's an identifier or token), the function returns `stx` unchanged.
Lean.Syntax.isOfKind definition
(stx : Syntax) (k : SyntaxNodeKind) : Bool
Full source
/--
Checks whether syntax has the given kind or pseudo-kind.

“Pseudo-kinds” are kinds that are assigned by convention to non-`Syntax.node` values:
`identKind` for `Syntax.ident`, `` `missing `` for `Syntax.missing`, and the atom's string literal
for atoms.
-/
def isOfKind (stx : Syntax) (k : SyntaxNodeKind) : Bool :=
  beq stx.getKind k
Syntax node kind check
Informal description
The function checks whether a syntax tree node `stx` has the specified kind `k`. Here, "kind" refers to either the actual node kind (for `Syntax.node` values) or one of the pseudo-kinds assigned by convention to other syntax tree variants: `identKind` for identifiers, `` `missing `` for missing nodes, or the atom's string literal for atomic values.
Lean.Syntax.getArg definition
(stx : Syntax) (i : Nat) : Syntax
Full source
/--
Gets the `i`'th argument of the syntax node. This can also be written `stx[i]`.
Returns `missing` if `i` is out of range.
-/
def getArg (stx : Syntax) (i : Nat) : Syntax :=
  match stx with
  | Syntax.node _ _ args => args.getD i Syntax.missing
  | _                    => Syntax.missing
Syntax tree node argument accessor
Informal description
Given a syntax tree node `stx` and a natural number index `i`, the function returns the `i`-th child node of `stx`. If `stx` is not a node or if `i` is out of bounds, the function returns a missing syntax node.
Lean.Syntax.getArgs definition
(stx : Syntax) : Array Syntax
Full source
/-- Gets the list of arguments of the syntax node, or `#[]` if it's not a `node`. -/
def getArgs (stx : Syntax) : Array Syntax :=
  match stx with
  | Syntax.node _ _ args => args
  | _                    => Array.empty
Syntax node arguments accessor
Informal description
The function takes a syntax tree node `stx` and returns its array of child nodes. If `stx` is not a node (i.e., it's an atom or missing), returns an empty array.
Lean.Syntax.getNumArgs definition
(stx : Syntax) : Nat
Full source
/-- Gets the number of arguments of the syntax node, or `0` if it's not a `node`. -/
def getNumArgs (stx : Syntax) : Nat :=
  match stx with
  | Syntax.node _ _ args => args.size
  | _                    => 0
Number of syntax node arguments
Informal description
The function takes a syntax tree node `stx` and returns the number of its child nodes. If `stx` is not a node (i.e., it's an atom or missing), returns 0.
Lean.Syntax.getOptional? definition
(stx : Syntax) : Option Syntax
Full source
/--
Assuming `stx` was parsed by `optional`, returns the enclosed syntax
if it parsed something and `none` otherwise.
-/
def getOptional? (stx : Syntax) : Option Syntax :=
  match stx with
  | Syntax.node _ k args => match and (beq k nullKind) (beq args.size 1) with
    | true  => some (args.get!Internal 0)
    | false => none
  | _                    => none
Extraction of optional parsed syntax
Informal description
Given a syntax tree node `stx` that was parsed by an `optional` parser, this function returns the enclosed syntax if the parser successfully parsed something (wrapped in `some`), and returns `none` otherwise. Specifically, it checks if the node is a null-kind node with exactly one argument (the pattern used by `optional` parsers), returning that argument if so.
Lean.Syntax.isMissing definition
: Syntax → Bool
Full source
/-- Is this syntax `.missing`? -/
def isMissing : SyntaxBool
  | Syntax.missing => true
  | _ => false
Missing syntax node check
Informal description
The function checks whether a given syntax tree node is the special `.missing` node, returning `true` if it is and `false` otherwise.
Lean.Syntax.isNodeOf definition
(stx : Syntax) (k : SyntaxNodeKind) (n : Nat) : Bool
Full source
/-- Is this syntax a `node` with kind `k`? -/
def isNodeOf (stx : Syntax) (k : SyntaxNodeKind) (n : Nat) : Bool :=
  and (stx.isOfKind k) (beq stx.getNumArgs n)
Syntax node kind and arity check
Informal description
The function checks whether a syntax tree node `stx` is of kind `k` and has exactly `n` child nodes. It returns `true` if both conditions are satisfied, and `false` otherwise.
Lean.Syntax.isIdent definition
: Syntax → Bool
Full source
/-- `stx.isIdent` is `true` iff `stx` is an identifier. -/
def isIdent : SyntaxBool
  | ident .. => true
  | _        => false
Identifier syntax node check
Informal description
The function `isIdent` checks whether a given syntax tree node is an identifier, returning `true` if it is and `false` otherwise.
Lean.Syntax.getId definition
: Syntax → Name
Full source
/-- If this is an `ident`, return the parsed value, else `.anonymous`. -/
def getId : SyntaxName
  | ident _ _ val _ => val
  | _               => Name.anonymous
Syntax identifier extraction
Informal description
The function extracts the name from a syntax tree node if it represents an identifier, returning the parsed name value. For all other syntax tree nodes, it returns the anonymous name (`.anonymous`).
Lean.Syntax.getInfo? definition
: Syntax → Option SourceInfo
Full source
/-- Retrieve the immediate info from the Syntax node. -/
def getInfo? : SyntaxOption SourceInfo
  | atom info ..  => some info
  | ident info .. => some info
  | node info ..  => some info
  | missing       => none
Source information of a syntax node
Informal description
The function retrieves the source information associated with a Lean syntax tree node, returning it as an optional value. For atomic nodes, identifiers, and regular nodes, it returns their respective source information if present. For missing nodes, it returns `none`.
Lean.Syntax.getHeadInfo? definition
: Syntax → Option SourceInfo
Full source
/-- Retrieve the left-most node or leaf's info in the Syntax tree. -/
partial def getHeadInfo? : SyntaxOption SourceInfo
  | atom info _   => some info
  | ident info .. => some info
  | node SourceInfo.none _ args   =>
    let rec loop (i : Nat) : Option SourceInfo :=
      match decide (LT.lt i args.size) with
      | true => match getHeadInfo? (args.get!Internal i) with
         | some info => some info
         | none      => loop (hAdd i 1)
      | false => none
    loop 0
  | node info _ _ => some info
  | _             => none
Source information of left-most syntax node
Informal description
The function retrieves the left-most node or leaf's source information in a Lean syntax tree, returning it as an optional value. If the syntax tree is an atom or identifier, it returns the associated source info. For nodes with no source info, it recursively searches through the arguments until it finds the first one with source info. If no source info is found, it returns `none`.
Lean.Syntax.getHeadInfo definition
(stx : Syntax) : SourceInfo
Full source
/-- Retrieve the left-most leaf's info in the Syntax tree, or `none` if there is no token. -/
partial def getHeadInfo (stx : Syntax) : SourceInfo :=
  match stx.getHeadInfo? with
  | somesome info => info
  | none      => SourceInfo.none
Source information of left-most syntax node (with default)
Informal description
The function retrieves the source information of the left-most leaf in a Lean syntax tree. If no source information is found, it returns `SourceInfo.none`.
Lean.Syntax.SepArray structure
(sep : String)
Full source
/--
An array of syntax elements interspersed with the given separators.

Separator arrays result from repetition operators such as `,*`.
[Coercions](lean-manual://section/coercions) to and from `Array Syntax` insert or remove separators
as required.

The typed equivalent is `Lean.Syntax.TSepArray`.
-/
structure SepArray (sep : String) where
  /-- The array of elements and separators, ordered like
  `#[el1, sep1, el2, sep2, el3]`. -/
  elemsAndSeps : Array Syntax
Separated Syntax Array
Informal description
A structure representing an array of syntax elements interspersed with given separators. This is typically used to handle repetition operators in syntax parsing, where elements are separated by specific tokens (e.g., commas in a list). The structure allows coercions to and from `Array Syntax`, automatically inserting or removing separators as needed.
Lean.Syntax.TSepArray structure
(ks : SyntaxNodeKinds) (sep : String)
Full source
/--
An array of syntax elements that alternate with the given separator. Each syntax element has a kind
drawn from `ks`.

Separator arrays result from repetition operators such as `,*`.
[Coercions](lean-manual://section/coercions) to and from `Array (TSyntax ks)` insert or remove
separators as required. The untyped equivalent is `Lean.Syntax.SepArray`.
-/
structure TSepArray (ks : SyntaxNodeKinds) (sep : String) where
  /-- The array of elements and separators, ordered like
  `#[el1, sep1, el2, sep2, el3]`. -/
  elemsAndSeps : Array Syntax
Typed Separated Syntax Array
Informal description
The structure `TSepArray ks sep` represents an array of typed syntax elements (with kinds drawn from `ks`) that alternate with the given separator string `sep`. This is used to handle repetition patterns in syntax parsing where elements are separated by a specific token (e.g., comma-separated lists). The structure supports coercions to and from `Array (TSyntax ks)`, automatically inserting or removing separators as needed.
Lean.TSyntaxArray abbrev
(ks : SyntaxNodeKinds)
Full source
/--
An array of syntaxes of kind `ks`.
-/
abbrev TSyntaxArray (ks : SyntaxNodeKinds) := Array (TSyntax ks)
Typed Syntax Array for Node Kinds `ks`
Informal description
The type `TSyntaxArray ks` represents an array of typed syntax elements where each element belongs to one of the syntax node kinds specified by `ks`. This structure is used to handle collections of syntax nodes while maintaining type information about their possible kinds.
Lean.TSyntaxArray.rawImpl definition
: TSyntaxArray ks → Array Syntax
Full source
/-- Implementation of `TSyntaxArray.raw`. -/
unsafe def TSyntaxArray.rawImpl : TSyntaxArray ks → Array Syntax := unsafeCast
Untyped conversion of typed syntax array
Informal description
The function `Lean.TSyntaxArray.rawImpl` converts a typed syntax array (where each element belongs to one of the specified syntax node kinds `ks`) into an untyped array of raw syntax trees. This is implemented using an unsafe type cast operation.
Lean.TSyntaxArray.raw opaque
(as : TSyntaxArray ks) : Array Syntax
Full source
/-- Converts a `TSyntaxArray` to an `Array Syntax`, without reallocation. -/
@[implemented_by TSyntaxArray.rawImpl]
opaque TSyntaxArray.raw (as : TSyntaxArray ks) : Array Syntax := Array.empty
Conversion from Typed to Untyped Syntax Array
Informal description
Given a typed syntax array `as` with node kinds `ks`, the function returns the underlying untyped syntax array without reallocation.
Lean.TSyntaxArray.mkImpl definition
: Array Syntax → TSyntaxArray ks
Full source
/-- Implementation of `TSyntaxArray.mk`. -/
unsafe def TSyntaxArray.mkImpl : Array SyntaxTSyntaxArray ks := unsafeCast
Typed syntax array constructor implementation
Informal description
The function takes an array of syntax trees and returns a typed syntax array where each element belongs to one of the specified node kinds `ks`. This is implemented using an unsafe type cast operation.
Lean.TSyntaxArray.mk opaque
(as : Array Syntax) : TSyntaxArray ks
Full source
/-- Converts an `Array Syntax` to a `TSyntaxArray`, without reallocation. -/
@[implemented_by TSyntaxArray.mkImpl]
opaque TSyntaxArray.mk (as : Array Syntax) : TSyntaxArray ks := Array.empty
Construction of Typed Syntax Array from Array of Syntax Trees
Informal description
Given an array `as` of syntax trees, the function constructs a typed syntax array where each element belongs to one of the syntax node kinds specified by `ks`.
Lean.mkAtom definition
(val : String) : Syntax
Full source
/-- Constructs a synthetic `atom` with no source info. -/
def mkAtom (val : String) : Syntax :=
  Syntax.atom SourceInfo.none val
Syntax atom constructor
Informal description
The function constructs a syntax atom (a leaf node in the syntax tree) with the given string value and no source information.
Lean.instInhabitedParserDescr instance
: Inhabited ParserDescr
Full source
instance : Inhabited ParserDescr where
  default := ParserDescr.symbol ""
Inhabited Parser Description Type
Informal description
The type `ParserDescr` is inhabited, meaning it has a designated default element.
Lean.TrailingParserDescr abbrev
Full source
/--
Although `TrailingParserDescr` is an abbreviation for `ParserDescr`, Lean will
look at the declared type in order to determine whether to add the parser to
the leading or trailing parser table. The determination is done automatically
by the `syntax` command.
-/
abbrev TrailingParserDescr := ParserDescr
Trailing Parser Description Type
Informal description
The abbreviation `TrailingParserDescr` is equivalent to `ParserDescr`, but is used by Lean's syntax system to automatically determine whether to register a parser in the leading or trailing parser table during syntax declaration.
Lean.MacroScope abbrev
Full source
/--
A macro scope identifier is just a `Nat` that gets bumped every time we
enter a new macro scope. Within a macro scope, all occurrences of identifier `x`
parse to the same thing, but `x` parsed from different macro scopes will
produce different identifiers.
-/
abbrev MacroScope := Nat
Macro Scope Identifier
Informal description
A macro scope identifier is a natural number that increments each time a new macro scope is entered. Identifiers parsed within the same macro scope refer to the same entity, while the same identifier parsed in different macro scopes will refer to distinct entities.
Lean.reservedMacroScope definition
Full source
/-- Macro scope used internally. It is not available for our frontend. -/
def reservedMacroScope := 0
Reserved macro scope identifier
Informal description
The reserved macro scope identifier, which is set to 0 and used internally by Lean's macro system. This scope is not available for use in frontend code.
Lean.firstFrontendMacroScope definition
Full source
/-- First macro scope available for our frontend -/
def firstFrontendMacroScope := hAdd reservedMacroScope 1
First frontend macro scope identifier
Informal description
The first macro scope identifier available for use in frontend code, defined as the successor of the reserved macro scope identifier (which is 0).
Lean.MonadRef structure
(m : Type → Type)
Full source
/--
A `MonadRef` is a monad that has a `ref : Syntax` in the read-only state.
This is used to keep track of the location where we are working; if an exception
is thrown, the `ref` gives the location where the error will be reported,
assuming no more specific location is provided.
-/
class MonadRef (m : Type → Type) where
  /-- Get the current value of the `ref` -/
  getRef      : m Syntax
  /-- Run `x : m α` with a modified value for the `ref` -/
  withRef {α} : Syntax → m α → m α
Monad with Syntax Reference
Informal description
A `MonadRef` is a monad that maintains a reference to a syntax tree node `ref : Syntax` in its read-only state. This reference is used to track the current location being processed, which helps in error reporting by providing the location where an error occurred if no more specific location is given.
Lean.instMonadRefOfMonadLiftOfMonadFunctor instance
(m n : Type → Type) [MonadLift m n] [MonadFunctor m n] [MonadRef m] : MonadRef n
Full source
instance (m n : Type → Type) [MonadLift m n] [MonadFunctor m n] [MonadRef m] : MonadRef n where
  getRef        := liftM (getRef : m _)
  withRef ref x := monadMap (m := m) (MonadRef.withRef ref) x
Monad Reference Preservation under Monad Lifting and Functor Transformation
Informal description
For any monads $m$ and $n$, if there exists a monad lift from $m$ to $n$ and a monad functor from $m$ to $n$, and $m$ is a monad with syntax reference, then $n$ is also a monad with syntax reference.
Lean.replaceRef definition
(ref : Syntax) (oldRef : Syntax) : Syntax
Full source
/--
Replaces `oldRef` with `ref`, unless `ref` has no position info.
This biases us to having a valid span to report an error on.
-/
def replaceRef (ref : Syntax) (oldRef : Syntax) : Syntax :=
  match ref.getPos? with
  | somesome _ => ref
  | _      => oldRef
Syntax reference replacement
Informal description
The function replaces the syntax reference `oldRef` with `ref`, unless `ref` has no position information. This ensures we maintain valid position information for error reporting.
Lean.withRef definition
[Monad m] [MonadRef m] {α} (ref : Syntax) (x : m α) : m α
Full source
/--
Run `x : m α` with a modified value for the `ref`. This is not exactly
the same as `MonadRef.withRef`, because it uses `replaceRef` to avoid putting
syntax with bad spans in the state.
-/
@[always_inline, inline]
def withRef [Monad m] [MonadRef m] {α} (ref : Syntax) (x : m α) : m α :=
  bind getRef fun oldRef =>
  let ref := replaceRef ref oldRef
  MonadRef.withRef ref x
Monadic computation with modified syntax reference
Informal description
The function `Lean.withRef` executes a monadic computation `x : m α` with a modified syntax reference `ref`. It first retrieves the current reference `oldRef`, then replaces it with `ref` (unless `ref` lacks position information), and finally runs the computation with this updated reference. This ensures proper error reporting by maintaining accurate source locations.
Lean.withRef? definition
[Monad m] [MonadRef m] {α} (ref? : Option Syntax) (x : m α) : m α
Full source
/--
If `ref? = some ref`, run `x : m α` with a modified value for the `ref` by calling `withRef`.
Otherwise, run `x` directly.
-/
@[always_inline, inline]
def withRef? [Monad m] [MonadRef m] {α} (ref? : Option Syntax) (x : m α) : m α :=
  match ref? with
  | somesome ref => withRef ref x
  | _        => x
Conditional syntax reference modification for monadic computation
Informal description
Given a monad `m` that supports syntax references, the function `Lean.withRef?` executes the monadic computation `x : m α` with a modified syntax reference if `ref?` is `some ref`. Otherwise, it runs `x` directly without modifying the reference.
Lean.MonadQuotation structure
(m : Type → Type) extends MonadRef m
Full source
/-- A monad that supports syntax quotations. Syntax quotations (in term
    position) are monadic values that when executed retrieve the current "macro
    scope" from the monad and apply it to every identifier they introduce
    (independent of whether this identifier turns out to be a reference to an
    existing declaration, or an actually fresh binding during further
    elaboration). We also apply the position of the result of `getRef` to each
    introduced symbol, which results in better error positions than not applying
    any position. -/
class MonadQuotation (m : Type → Type) extends MonadRef m where
  /-- Get the fresh scope of the current macro invocation -/
  getCurrMacroScope : m MacroScope
  /-- Get the module name of the current file. This is used to ensure that
  hygienic names don't clash across multiple files. -/
  getMainModule     : m Name
  /--
  Execute action in a new macro invocation context. This transformer should be
  used at all places that morally qualify as the beginning of a "macro call",
  e.g. `elabCommand` and `elabTerm` in the case of the elaborator. However, it
  can also be used internally inside a "macro" if identifiers introduced by
  e.g. different recursive calls should be independent and not collide. While
  returning an intermediate syntax tree that will recursively be expanded by
  the elaborator can be used for the same effect, doing direct recursion inside
  the macro guarded by this transformer is often easier because one is not
  restricted to passing a single syntax tree. Modelling this helper as a
  transformer and not just a monadic action ensures that the current macro
  scope before the recursive call is restored after it, as expected.
  -/
  withFreshMacroScope {α : Type} : m α → m α
Monad with Syntax Quotation Support
Informal description
The structure `MonadQuotation` represents a monad that supports syntax quotations. It extends `MonadRef` and provides the capability to handle syntax quotations in term position. These monadic values, when executed, retrieve the current "macro scope" from the monad and apply it to every identifier they introduce, regardless of whether the identifier refers to an existing declaration or a fresh binding during further elaboration. Additionally, the position of the result of `getRef` is applied to each introduced symbol, improving error positions.
Lean.MonadRef.mkInfoFromRefPos definition
[Monad m] [MonadRef m] : m SourceInfo
Full source
/-- Construct a synthetic `SourceInfo` from the `ref` in the monad state. -/
@[inline]
def MonadRef.mkInfoFromRefPos [Monad m] [MonadRef m] : m SourceInfo :=
  return SourceInfo.fromRef (← getRef)
Construct SourceInfo from current syntax reference
Informal description
Given a monad `m` that supports syntax references, this function constructs a `SourceInfo` object by retrieving the current syntax reference from the monad state. The `SourceInfo` object is used to track source code locations for error reporting and other purposes.
Lean.instMonadQuotationOfMonadFunctorOfMonadLift instance
[MonadFunctor m n] [MonadLift m n] [MonadQuotation m] : MonadQuotation n
Full source
instance [MonadFunctor m n] [MonadLift m n] [MonadQuotation m] : MonadQuotation n where
  getCurrMacroScope   := liftM (m := m) getCurrMacroScope
  getMainModule       := liftM (m := m) getMainModule
  withFreshMacroScope := monadMap (m := m) withFreshMacroScope
Preservation of Syntax Quotation Support under Monad Functor and Lift
Informal description
For any monads $m$ and $n$, if there exists a monad functor from $m$ to $n$ and a monad lift from $m$ to $n$, and $m$ supports syntax quotations, then $n$ also supports syntax quotations.
Lean.Name.hasMacroScopes definition
: Name → Bool
Full source
/-- Does this name have hygienic macro scopes? -/
def Name.hasMacroScopes : NameBool
  | str _ s => beq s "_hyg"
  | num p _ => hasMacroScopes p
  | _       => false
Check for hygienic macro scopes in a name
Informal description
The function checks whether a given hierarchical name contains hygienic macro scopes. A name has hygienic macro scopes if it contains the substring `_hyg` or if any of its parent components (in the case of hierarchical names) contain hygienic macro scopes.
Lean.Name.eraseMacroScopes definition
(n : Name) : Name
Full source
/-- Remove the macro scopes from the name. -/
@[export lean_erase_macro_scopes]
def Name.eraseMacroScopes (n : Name) : Name :=
  match n.hasMacroScopes with
  | true  => eraseMacroScopesAux n
  | false => n
Removal of hygienic macro scopes from a name
Informal description
The function removes all hygienic macro scopes from a given hierarchical name. If the name does not contain any macro scopes, it returns the name unchanged.
Lean.Name.simpMacroScopes definition
(n : Name) : Name
Full source
/-- Helper function we use to create binder names that do not need to be unique. -/
@[export lean_simp_macro_scopes]
def Name.simpMacroScopes (n : Name) : Name :=
  match n.hasMacroScopes with
  | true  => simpMacroScopesAux n
  | false => n
Simplification of hygienic macro scopes in names
Informal description
The function simplifies the hygienic macro scopes in a hierarchical name. If the name contains macro scopes (checked via `hasMacroScopes`), it applies the auxiliary simplification function `simpMacroScopesAux`; otherwise, it returns the name unchanged.
Lean.MacroScopesView structure
Full source
/--
A `MacroScopesView` represents a parsed hygienic name. `extractMacroScopes`
will decode it from a `Name`, and `.review` will re-encode it. The grammar of a
hygienic name is:
```
<name>._@.(<module_name>.<scopes>)*.<mainModule>._hyg.<scopes>
```
-/
structure MacroScopesView where
  /-- The original (unhygienic) name. -/
  name       : Name
  /-- All the name components `(<module_name>.<scopes>)*` from the imports
  concatenated together. -/
  imported   : Name
  /-- The main module in which this identifier was parsed. -/
  mainModule : Name
  /-- The list of macro scopes. -/
  scopes     : List MacroScope
Hygienic Name View in Lean's Macro System
Informal description
The structure `MacroScopesView` represents a parsed hygienic name in Lean's macro system. It captures the decomposition of a name with macro scopes, which follows the grammar: ``` ._@.(.)*.._hyg. ``` where: - `` is the original name - `_@` is a delimiter - `.` pairs represent scopes from imported modules - `` is the current module name - `_hyg` is a special delimiter - `` are the current macro scopes This structure can be decoded from a `Name` using `extractMacroScopes` and re-encoded using the `.review` method.
Lean.instInhabitedMacroScopesView instance
: Inhabited MacroScopesView
Full source
instance : Inhabited MacroScopesView where
  default := ⟨default, default, default, default⟩
Inhabited Type of Hygienic Name Views
Informal description
The type `MacroScopesView` representing hygienic name views in Lean's macro system is inhabited, meaning it has a default value.
Lean.MacroScopesView.review definition
(view : MacroScopesView) : Name
Full source
/-- Encode a hygienic name from the parsed pieces. -/
def MacroScopesView.review (view : MacroScopesView) : Name :=
  match view.scopes with
  | List.nil      => view.name
  | List.consList.cons _ _ =>
    let base := (Name.mkStr (Name.appendCore (Name.appendCore (Name.mkStr view.name "_@") view.imported) view.mainModule) "_hyg")
    view.scopes.foldl Name.mkNum base
Reconstruction of hygienic name from macro scope view
Informal description
The function reconstructs a hygienic name from its parsed components stored in a `MacroScopesView` structure. Given a view containing: - The original name (`view.name`) - A list of imported module names and their scopes (`view.imported`) - The main module name (`view.mainModule`) - A list of current macro scopes (`view.scopes`) It constructs the name by: 1. If there are no scopes, returning just the original name 2. Otherwise, building a name with the format: ``` ._@..._hyg. ``` where scopes are appended as numeric components.
Lean.extractMacroScopes definition
(n : Name) : MacroScopesView
Full source
/--
  Revert all `addMacroScope` calls. `v = extractMacroScopes n → n = v.review`.
  This operation is useful for analyzing/transforming the original identifiers, then adding back
  the scopes (via `MacroScopesView.review`). -/
def extractMacroScopes (n : Name) : MacroScopesView :=
  match n.hasMacroScopes with
  | true  => extractMacroScopesAux n List.nil
  | false => { name := n, scopes := List.nil, imported := Name.anonymous, mainModule := Name.anonymous }
Decomposition of hygienic macro scopes in names
Informal description
The function decomposes a hierarchical name with hygienic macro scopes into its constituent parts: the original name, the list of macro scopes, the imported module names, and the main module name. For names without macro scopes, it returns the original name with empty scope and module information.
Lean.addMacroScope definition
(mainModule : Name) (n : Name) (scp : MacroScope) : Name
Full source
/-- Add a new macro scope onto the name `n`, in the given `mainModule`. -/
def addMacroScope (mainModule : Name) (n : Name) (scp : MacroScope) : Name :=
  match n.hasMacroScopes with
  | true =>
    let view := extractMacroScopes n
    match beq view.mainModule mainModule with
    | true  => Name.mkNum n scp
    | false =>
      { view with
        imported   := view.scopes.foldl Name.mkNum (Name.appendCore view.imported view.mainModule)
        mainModule := mainModule
        scopes     := List.cons scp List.nil
      }.review
  | false =>
    Name.mkNum (Name.mkStr (Name.appendCore (Name.mkStr n "_@") mainModule) "_hyg") scp
Adding a macro scope to a hierarchical name
Informal description
The function `Lean.addMacroScope` takes a main module name `mainModule`, a hierarchical name `n`, and a macro scope identifier `scp`, and returns a new name with the macro scope added. If the input name already has macro scopes, it checks if the main module matches. If they match, it simply appends the new scope; otherwise, it reconstructs the name with the new scope in the current module context. If the input name has no macro scopes, it creates a new hygienic name by adding the module and scope information in the format `._@.._hyg.`.
Lean.Name.append definition
(a b : Name) : Name
Full source
/--
Appends two names `a` and `b`, propagating macro scopes from `a` or `b`, if any, to the result.
Panics if both `a` and `b` have macro scopes.

This function is used for the `Append Name` instance.

See also `Lean.Name.appendCore`, which appends names without any consideration for macro scopes.
Also consider `Lean.Name.eraseMacroScopes` to erase macro scopes before appending, if appropriate.
-/
def Name.append (a b : Name) : Name :=
  match a.hasMacroScopes, b.hasMacroScopes with
  | true, true  =>
    panic "Error: invalid `Name.append`, both arguments have macro scopes, consider using `eraseMacroScopes`"
  | true, false =>
    let view := extractMacroScopes a
    { view with name := appendCore view.name b }.review
  | false, true =>
    let view := extractMacroScopes b
    { view with name := appendCore a view.name }.review
  | false, false => appendCore a b
Hierarchical name append with macro scope preservation
Informal description
The function appends two hierarchical names `a` and `b` while preserving macro scopes from either `a` or `b` (but not both). If both names contain macro scopes, the function raises an error. Given names without macro scopes, it performs simple hierarchical concatenation. For names with scopes, it preserves the scopes of the input that has them while appending the base names.
Lean.instAppendName instance
: Append Name
Full source
instance : Append Name where
  append := Name.append
Append Operation for Hierarchical Names
Informal description
The type `Name` of hierarchical names in Lean is equipped with an append operation `++` that concatenates two names while preserving macro scopes when present.
Lean.MonadQuotation.addMacroScope definition
{m : Type → Type} [MonadQuotation m] [Monad m] (n : Name) : m Name
Full source
/--
Add a new macro scope onto the name `n`, using the monad state to supply the
main module and current macro scope.
-/
@[inline] def MonadQuotation.addMacroScope {m : Type → Type} [MonadQuotation m] [Monad m] (n : Name) : m Name :=
  bind getMainModule     fun mainModule =>
  bind getCurrMacroScope fun scp =>
  pure (Lean.addMacroScope mainModule n scp)
Adding a macro scope to a name in a quotation monad
Informal description
Given a hierarchical name `n`, this function adds a new macro scope to `n` using the current main module and macro scope from the monadic context. The resulting name incorporates hygienic information to ensure unique identification across different macro expansions.
Lean.Syntax.matchesNull definition
(stx : Syntax) (n : Nat) : Bool
Full source
/-- Is this syntax a null `node`? -/
def matchesNull (stx : Syntax) (n : Nat) : Bool :=
  stx.isNodeOf nullKind n
Null syntax node matcher
Informal description
The function checks whether a syntax tree node `stx` is a null node with exactly `n` child nodes. It returns `true` if both conditions are satisfied, and `false` otherwise.
Lean.Syntax.matchesIdent definition
(stx : Syntax) (id : Name) : Bool
Full source
/--
  Function used for determining whether a syntax pattern `` `(id) `` is matched.
  There are various conceivable notions of when two syntactic identifiers should be regarded as identical,
  but semantic definitions like whether they refer to the same global name cannot be implemented without
  context information (i.e. `MonadResolveName`). Thus in patterns we default to the structural solution
  of comparing the identifiers' `Name` values, though we at least do so modulo macro scopes so that
  identifiers that "look" the same match. This is particularly useful when dealing with identifiers that
  do not actually refer to Lean bindings, e.g. in the `stx` pattern `` `(many($p)) ``. -/
def matchesIdent (stx : Syntax) (id : Name) : Bool :=
  and stx.isIdent (beq stx.getId.eraseMacroScopes id.eraseMacroScopes)
Identifier syntax matching (modulo macro scopes)
Informal description
The function checks whether a given syntax tree node `stx` is an identifier and whether its name (after removing any hygienic macro scopes) matches the given name `id` (also with macro scopes removed). It returns `true` if both conditions are satisfied, and `false` otherwise.
Lean.Syntax.matchesLit definition
(stx : Syntax) (k : SyntaxNodeKind) (val : String) : Bool
Full source
/-- Is this syntax a node kind `k` wrapping an `atom _ val`? -/
def matchesLit (stx : Syntax) (k : SyntaxNodeKind) (val : String) : Bool :=
  match stx with
  | Syntax.node _ k' args => and (beq k k') (match args.getD 0 Syntax.missing with
    | Syntax.atom _ val' => beq val val'
    | _                  => false)
  | _                     => false
Syntax node kind and atom value matcher
Informal description
Given a syntax tree node `stx`, a node kind `k`, and a string value `val`, this function checks whether `stx` is a node of kind `k` wrapping an atom with value `val`. Specifically, it returns `true` if: 1. `stx` is a syntax node with kind `k'` equal to `k`, and 2. The first argument of `stx` (if it exists) is an atom with value equal to `val`. Otherwise, it returns `false`.
Lean.Macro.instNonemptyMethodsRef instance
: Nonempty MethodsRef
Full source
instance : Nonempty MethodsRef := MethodsRefPointed.property
Nonempty MethodsRef
Informal description
The type `MethodsRef` is nonempty, meaning there exists at least one element of this type.
Lean.Macro.Context structure
Full source
/-- The read-only context for the `MacroM` monad. -/
structure Context where
  /-- An opaque reference to the `Methods` object. This is done to break a
  dependency cycle: the `Methods` involve `MacroM` which has not been defined yet. -/
  methods        : MethodsRef
  /-- The currently parsing module. -/
  mainModule     : Name
  /-- The current macro scope. -/
  currMacroScope : MacroScope
  /-- The current recursion depth. -/
  currRecDepth   : Nat := 0
  /-- The maximum recursion depth. -/
  maxRecDepth    : Nat := defaultMaxRecDepth
  /-- The syntax which supplies the position of error messages. -/
  ref            : Syntax
Macro Context
Informal description
The structure representing the read-only context for the macro monad in Lean, which contains information needed during macro expansion. This context includes details about macro scopes and other metadata required for hygienic macro processing.
Lean.Macro.Exception inductive
Full source
/-- An exception in the `MacroM` monad. -/
inductive Exception where
  /-- A general error, given a message and a span (expressed as a `Syntax`). -/
  | error             : SyntaxString → Exception
  /-- An unsupported syntax exception. We keep this separate because it is
  used for control flow: if one macro does not support a syntax then we try
  the next one. -/
  | unsupportedSyntax : Exception
Macro Exception
Informal description
The inductive type `Lean.Macro.Exception` represents exceptions that can occur during macro execution in the `MacroM` monad. This type is used to handle and propagate errors that arise during macro expansion and processing.
Lean.Macro.State structure
Full source
/-- The mutable state for the `MacroM` monad. -/
structure State where
  /-- The global macro scope counter, used for producing fresh scope names. -/
  macroScope : MacroScope
  /-- The list of trace messages that have been produced, each with a trace
  class and a message. -/
  traceMsgs  : List (Prod Name String) := List.nil
  deriving Inhabited
Macro Processing State
Informal description
The structure `Lean.Macro.State` represents the mutable state used in the `MacroM` monad for handling macro processing in Lean. This state maintains information needed during macro expansion and hygienic name resolution.
Lean.Macro.instInhabitedState instance
: Inhabited✝ (@Lean.Macro.State)
Full source
Inhabited
Inhabited Macro Processing State
Informal description
The macro processing state in Lean is inhabited, meaning there exists a default value for this state.
Lean.MacroM abbrev
Full source
/--
The `MacroM` monad is the main monad for macro expansion. It has the
information needed to handle hygienic name generation, and is the monad that
`macro` definitions live in.

Notably, this is a (relatively) pure monad: there is no `IO` and no access to
the `Environment`. That means that things like declaration lookup are
impossible here, as well as `IO.Ref` or other side-effecting operations.
For more capabilities, macros can instead be written as `elab` using `adaptExpander`.
-/
abbrev MacroM := ReaderT Macro.Context (EStateM Macro.Exception Macro.State)
Macro Expansion Monad with Hygiene Support
Informal description
The `MacroM` monad is a pure monad used for macro expansion in Lean, providing hygienic name generation capabilities. It combines a reader monad for accessing a read-only macro context and a state monad for tracking mutable macro processing state, while also supporting exceptions for error handling during macro execution.
Lean.Macro abbrev
Full source
/--
A `macro` has type `Macro`, which is a `Syntax → MacroM Syntax`: it
receives an input syntax and is supposed to "expand" it into another piece of
syntax.
-/
abbrev Macro := SyntaxMacroM Syntax
Macro Transformation Function
Informal description
A macro in Lean is a function of type `Macro`, which maps an input syntax tree to another syntax tree in the `MacroM` monad, effectively performing syntactic transformations during macro expansion.
Lean.Macro.instMonadRefMacroM instance
: MonadRef MacroM
Full source
instance : MonadRef MacroM where
  getRef     := bind read fun ctx => pure ctx.ref
  withRef    := fun ref x => withReader (fun ctx => { ctx with ref := ref }) x
Syntax Reference in Macro Expansion Monad
Informal description
The macro expansion monad `MacroM` in Lean maintains a reference to a syntax tree node, which is used to track the current location being processed for error reporting.
Lean.Macro.addMacroScope definition
(n : Name) : MacroM Name
Full source
/-- Add a new macro scope to the name `n`. -/
def addMacroScope (n : Name) : MacroM Name :=
  bind read fun ctx =>
  pure (Lean.addMacroScope ctx.mainModule n ctx.currMacroScope)
Adding macro scope to a name
Informal description
The function `Lean.Macro.addMacroScope` takes a name `n` and returns a new name in the `MacroM` monad by adding the current macro scope from the context to `n`. The resulting name follows Lean's hygienic naming convention, which ensures unique identifiers during macro expansion by incorporating the main module name and current scope information.
Lean.Macro.throwUnsupported definition
{α} : MacroM α
Full source
/-- Throw an `unsupportedSyntax` exception. -/
def throwUnsupported {α} : MacroM α :=
  throw Exception.unsupportedSyntax
Unsupported syntax exception
Informal description
The function throws an `unsupportedSyntax` exception in the `MacroM` monad, indicating that the current syntax is not supported during macro expansion.
Lean.Macro.throwError definition
{α} (msg : String) : MacroM α
Full source
/--
Throw an error with the given message,
using the `ref` for the location information.
-/
def throwError {α} (msg : String) : MacroM α :=
  bind getRef fun ref =>
  throw (Exception.error ref msg)
Error throwing in macro expansion
Informal description
The function throws an error in the macro expansion monad with the given message, using the current syntax reference for location information.
Lean.Macro.throwErrorAt definition
{α} (ref : Syntax) (msg : String) : MacroM α
Full source
/-- Throw an error with the given message and location information. -/
def throwErrorAt {α} (ref : Syntax) (msg : String) : MacroM α :=
  withRef ref (throwError msg)
Error throwing with syntax reference in macro expansion
Informal description
The function throws an error in the macro expansion monad with the given message `msg`, using the provided syntax reference `ref` for location information.
Lean.Macro.withFreshMacroScope definition
{α} (x : MacroM α) : MacroM α
Full source
/--
Increments the macro scope counter so that inside the body of `x` the macro
scope is fresh.
-/
@[inline] protected def withFreshMacroScope {α} (x : MacroM α) : MacroM α :=
  bind (modifyGet (fun s => (s.macroScope, { s with macroScope := hAdd s.macroScope 1 }))) fun fresh =>
  withReader (fun ctx => { ctx with currMacroScope := fresh }) x
Execute computation in fresh macro scope
Informal description
The function `withFreshMacroScope` takes a computation `x` in the macro expansion monad `MacroM` and executes it in a fresh macro scope. Internally, it increments the macro scope counter and updates the current macro scope context before running `x`. This ensures hygienic name resolution during macro expansion by preventing accidental name collisions.
Lean.Macro.withIncRecDepth definition
{α} (ref : Syntax) (x : MacroM α) : MacroM α
Full source
/-- Run `x` with an incremented recursion depth counter. -/
@[inline] def withIncRecDepth {α} (ref : Syntax) (x : MacroM α) : MacroM α :=
  bind read fun ctx =>
  match beq ctx.currRecDepth ctx.maxRecDepth with
  | true  => throw (Exception.error ref maxRecDepthErrorMessage)
  | false => withReader (fun ctx => { ctx with currRecDepth := hAdd ctx.currRecDepth 1 }) x
Macro computation with incremented recursion depth
Informal description
The function executes the macro computation `x` with an incremented recursion depth counter. If the current recursion depth equals the maximum allowed depth, it throws an error with the given syntax reference `ref` and a message indicating the recursion limit was exceeded. Otherwise, it proceeds with the computation in a context where the recursion depth is increased by 1.
Lean.Macro.instMonadQuotationMacroM instance
: MonadQuotation MacroM
Full source
instance : MonadQuotation MacroM where
  getCurrMacroScope ctx := pure ctx.currMacroScope
  getMainModule     ctx := pure ctx.mainModule
  withFreshMacroScope   := Macro.withFreshMacroScope
Syntax Quotation Support in Macro Expansion Monad
Informal description
The macro expansion monad `MacroM` supports syntax quotations, providing hygienic name resolution during macro processing. This means that identifiers introduced within quotations are automatically scoped to prevent naming conflicts, while maintaining proper reference to existing declarations.
Lean.Macro.Methods structure
Full source
/-- The opaque methods that are available to `MacroM`. -/
structure Methods where
  /-- Expands macros in the given syntax. A return value of `none` means there
  was nothing to expand. -/
  expandMacro?      : SyntaxMacroM (Option Syntax)
  /-- Get the current namespace in the file. -/
  getCurrNamespace  : MacroM Name
  /-- Check if a given name refers to a declaration. -/
  hasDecl           : NameMacroM Bool
  /-- Resolves the given name to an overload list of namespaces. -/
  resolveNamespace  : NameMacroM (List Name)
  /-- Resolves the given name to an overload list of global definitions.
  The `List String` in each alternative is the deduced list of projections
  (which are ambiguous with name components). -/
  resolveGlobalName : NameMacroM (List (Prod Name (List String)))
  deriving Inhabited
Macro Methods Structure
Informal description
The structure `Lean.Macro.Methods` represents the collection of opaque methods available in the `MacroM` monad for manipulating macro scopes and hygienic name generation in Lean's metaprogramming framework.
Lean.Macro.instInhabitedMethods instance
: Inhabited✝ (@Lean.Macro.Methods)
Full source
Inhabited
Inhabitedness of Lean Macro Methods
Informal description
The type of macro methods in Lean is inhabited, meaning there exists a default collection of methods for manipulating macro scopes and hygienic name generation.
Lean.Macro.mkMethodsImp definition
(methods : Methods) : MethodsRef
Full source
/-- Implementation of `mkMethods`. -/
unsafe def mkMethodsImp (methods : Methods) : MethodsRef :=
  unsafeCast methods
Opaque macro methods reference constructor (implementation)
Informal description
The function `Lean.Macro.mkMethodsImp` takes a collection of macro methods and returns an opaque reference to these methods, represented as a `MethodsRef`. This is implemented using an unsafe type cast operation.
Lean.Macro.mkMethods opaque
(methods : Methods) : MethodsRef
Full source
/-- Make an opaque reference to a `Methods`. -/
@[implemented_by mkMethodsImp]
opaque mkMethods (methods : Methods) : MethodsRef
Construction of Opaque Macro Methods Reference
Informal description
Given a collection of macro methods `methods`, the function `mkMethods` constructs an opaque reference to these methods, represented as a `MethodsRef`.
Lean.Macro.instInhabitedMethodsRef instance
: Inhabited MethodsRef
Full source
instance : Inhabited MethodsRef where
  default := mkMethods default
Inhabitedness of Macro Methods References
Informal description
The type of opaque references to macro methods in Lean's metaprogramming framework is inhabited, meaning there exists a default reference to macro methods.
Lean.Macro.getMethodsImp definition
: MacroM Methods
Full source
/-- Implementation of `getMethods`. -/
unsafe def getMethodsImp : MacroM Methods :=
  bind read fun ctx => pure (unsafeCast (ctx.methods))
Implementation of macro methods retrieval
Informal description
The function `getMethodsImp` retrieves the current macro methods from the read-only context in the `MacroM` monad. These methods are used for macro expansion with hygiene support in Lean's metaprogramming framework. The implementation performs an unsafe cast of the methods field from the context to maintain opacity of the methods structure.
Lean.Macro.getMethods opaque
: MacroM Methods
Full source
/-- Extract the methods list from the `MacroM` state. -/
@[implemented_by getMethodsImp] opaque getMethods : MacroM Methods
Retrieval of Macro Methods List
Informal description
The function `getMethods` retrieves the current methods list from the `MacroM` monad state, which contains the macro expansion methods with hygiene support.
Lean.Macro.expandMacro? definition
(stx : Syntax) : MacroM (Option Syntax)
Full source
/--
`expandMacro? stx` returns `some stxNew` if `stx` is a macro,
and `stxNew` is its expansion.
-/
def expandMacro? (stx : Syntax) : MacroM (Option Syntax) := do
  (← getMethods).expandMacro? stx
Macro expansion function
Informal description
The function `expandMacro?` takes a syntax tree `stx` and returns an optional syntax tree `some stxNew` if `stx` is a macro and `stxNew` is its expansion, or `none` otherwise. This operation is performed within the `MacroM` monad, which handles macro expansion with hygiene support.
Lean.Macro.hasDecl definition
(declName : Name) : MacroM Bool
Full source
/-- Returns `true` if the environment contains a declaration with name `declName` -/
def hasDecl (declName : Name) : MacroM Bool := do
  (← getMethods).hasDecl declName
Declaration existence check
Informal description
The function `hasDecl` checks whether a declaration with the given name `declName` exists in the current environment, returning a Boolean value indicating its presence.
Lean.Macro.getCurrNamespace definition
: MacroM Name
Full source
/-- Gets the current namespace given the position in the file. -/
def getCurrNamespace : MacroM Name := do
  (← getMethods).getCurrNamespace
Current namespace retrieval in macro context
Informal description
The function retrieves the current namespace from the macro context in the `MacroM` monad, returning a hierarchical name representing the namespace where the current macro expansion is taking place.
Lean.Macro.resolveNamespace definition
(n : Name) : MacroM (List Name)
Full source
/-- Resolves the given name to an overload list of namespaces. -/
def resolveNamespace (n : Name) : MacroM (List Name) := do
  (← getMethods).resolveNamespace n
Namespace resolution in macro context
Informal description
The function `resolveNamespace` takes a hierarchical name `n` and returns a list of possible namespace resolutions in the current macro context. This operation is performed within the `MacroM` monad, which handles macro expansion with hygiene support.
Lean.Macro.resolveGlobalName definition
(n : Name) : MacroM (List (Prod Name (List String)))
Full source
/--
Resolves the given name to an overload list of global definitions.
The `List String` in each alternative is the deduced list of projections
(which are ambiguous with name components).

Remark: it will not trigger actions associated with reserved names. Recall that Lean
has reserved names. For example, a definition `foo` has a reserved name `foo.def` for theorem
containing stating that `foo` is equal to its definition. The action associated with `foo.def`
automatically proves the theorem. At the macro level, the name is resolved, but the action is not
executed. The actions are executed by the elaborator when converting `Syntax` into `Expr`.
-/
def resolveGlobalName (n : Name) : MacroM (List (Prod Name (List String))) := do
  (← getMethods).resolveGlobalName n
Global name resolution with projections
Informal description
The function `resolveGlobalName` takes a hierarchical name `n` and returns a list of possible global definitions that match the name, along with their deduced projection lists. Each alternative in the result is a pair consisting of the resolved name and a list of string projections. This operation is performed within the `MacroM` monad, which handles macro expansion with hygiene support.
Lean.Macro.trace definition
(clsName : Name) (msg : String) : MacroM Unit
Full source
/-- Add a new trace message, with the given trace class and message. -/
def trace (clsName : Name) (msg : String) : MacroM Unit := do
  modify fun s => { s with traceMsgs := List.cons (Prod.mk clsName msg) s.traceMsgs }
Trace message in macro context
Informal description
The function `Lean.Macro.trace` adds a new trace message with the given trace class `clsName` and message `msg` to the macro processing state. This operation is performed within the `MacroM` monad, which handles macro expansion with hygiene support.
Lean.PrettyPrinter.UnexpandM abbrev
Full source
/--
The unexpander monad, essentially `Syntax → Option α`. The `Syntax` is the `ref`,
and it has the possibility of failure without an error message.
-/
abbrev UnexpandM := ReaderT Syntax (EStateM Unit Unit)
Syntax Unexpansion Monad
Informal description
The `UnexpandM` monad is a specialized monad for syntax unexpansion operations, which is essentially a function from `Syntax` to an optional result type `α`. It carries a reference to the syntax being processed (`ref`) and may fail without producing an error message.
Lean.PrettyPrinter.Unexpander abbrev
Full source
/--
Function that tries to reverse macro expansions as a post-processing step of delaboration.
While less general than an arbitrary delaborator, it can be declared without importing `Lean`.
Used by the `[app_unexpander]` attribute.
-/
-- a `kindUnexpander` could reasonably be added later
abbrev Unexpander := SyntaxUnexpandM Syntax
Syntax Unexpander Function for Delaboration
Informal description
The `Unexpander` type represents a function that attempts to reverse macro expansions during delaboration (pretty-printing). It operates within the `UnexpandM` monad, taking a syntax tree as input and potentially returning a modified syntax tree that more closely resembles the original user input before macro expansion. This mechanism is used by the `[app_unexpander]` attribute to provide custom pretty-printing behavior without requiring full delaborator implementations.
Lean.PrettyPrinter.instMonadQuotationUnexpandM instance
: MonadQuotation UnexpandM
Full source
instance : MonadQuotation UnexpandM where
  getRef              := read
  withRef ref x       := withReader (fun _ => ref) x
  -- unexpanders should not need to introduce new names
  getCurrMacroScope   := pure 0
  getMainModule       := pure `_fakeMod
  withFreshMacroScope := id
Syntax Quotation Support in Unexpansion Monad
Informal description
The syntax unexpansion monad `UnexpandM` supports syntax quotations, meaning it can handle quoted syntax terms while maintaining proper macro hygiene and source position information.