Decidable equality for Empty
Equations
PEmpty.elim : Empty → C
says that a value of any type can be constructed from
PEmpty
. This can be thought of as a compiler-checked assertion that a code path is unreachable.
Equations
Instances For
Decidable equality for PEmpty
Equations
Delays evaluation. The delayed code is evaluated at most once.
A thunk is code that constructs a value when it is requested via Thunk.get
, Thunk.map
, or
Thunk.bind
. The resulting value is cached, so the code is executed at most once. This is also
known as lazy or call-by-need evaluation.
The Lean runtime has special support for the Thunk
type in order to implement the caching
behavior.
Instances For
Stores an already-computed value in a thunk.
Because the value has already been computed, there is no laziness.
Equations
- Thunk.pure a = { fn := fun (x : Unit) => a }
Instances For
Constructs a new thunk that forces x
and then applies x
to the result. Upon forcing, the result
of f
is cached and the reference to the thunk x
is dropped.
Instances For
definitions #
If and only if, or logical bi-implication. a ↔ b
means that a
implies b
and vice versa.
By propext
, this implies that a
and b
are equal and hence any expression involving a
is equivalent to the corresponding expression with b
instead.
Conventions for notations in identifiers:
The recommended spelling of
↔
in identifiers isiff
.The recommended spelling of
<->
in identifiers isiff
(prefer↔
over<->
).
- intro :: (
- mp : a → b
Modus ponens for if and only if. If
a ↔ b
anda
, thenb
. - mpr : b → a
Modus ponens for if and only if, reversed. If
a ↔ b
andb
, thena
. - )
Instances For
If and only if, or logical bi-implication. a ↔ b
means that a
implies b
and vice versa.
By propext
, this implies that a
and b
are equal and hence any expression involving a
is equivalent to the corresponding expression with b
instead.
Conventions for notations in identifiers:
- The recommended spelling of
<->
in identifiers isiff
(prefer↔
over<->
).
Equations
- «term_<->_» = Lean.ParserDescr.trailingNode `«term_<->_» 20 21 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " <-> ") (Lean.ParserDescr.cat `term 21))
Instances For
If and only if, or logical bi-implication. a ↔ b
means that a
implies b
and vice versa.
By propext
, this implies that a
and b
are equal and hence any expression involving a
is equivalent to the corresponding expression with b
instead.
Conventions for notations in identifiers:
- The recommended spelling of
↔
in identifiers isiff
.
Equations
- «term_↔_» = Lean.ParserDescr.trailingNode `«term_↔_» 20 21 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ↔ ") (Lean.ParserDescr.cat `term 21))
Instances For
The disjoint union of types α
and β
, ordinarily written α ⊕ β
.
An element of α ⊕ β
is either an a : α
wrapped in Sum.inl
or a b : β
wrapped in Sum.inr
.
α ⊕ β
is not equivalent to the set-theoretic union of α
and β
because its values include an
indication of which of the two types was chosen. The union of a singleton set with itself contains
one element, while Unit ⊕ Unit
contains distinct values inl ()
and inr ()
.
- inl
{α : Type u}
{β : Type v}
(val : α)
: α ⊕ β
Left injection into the sum type
α ⊕ β
. - inr
{α : Type u}
{β : Type v}
(val : β)
: α ⊕ β
Right injection into the sum type
α ⊕ β
.
Instances For
The disjoint union of types α
and β
, ordinarily written α ⊕ β
.
An element of α ⊕ β
is either an a : α
wrapped in Sum.inl
or a b : β
wrapped in Sum.inr
.
α ⊕ β
is not equivalent to the set-theoretic union of α
and β
because its values include an
indication of which of the two types was chosen. The union of a singleton set with itself contains
one element, while Unit ⊕ Unit
contains distinct values inl ()
and inr ()
.
Equations
- «term_⊕_» = Lean.ParserDescr.trailingNode `«term_⊕_» 30 31 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ⊕ ") (Lean.ParserDescr.cat `term 30))
Instances For
The disjoint union of arbitrary sorts α
β
, or α ⊕' β
.
It differs from α ⊕ β
in that it allows α
and β
to have arbitrary sorts Sort u
and Sort v
,
instead of restricting them to Type u
and Type v
. This means that it can be used in situations
where one side is a proposition, like True ⊕' Nat
. However, the resulting universe level
constraints are often more difficult to solve than those that result from Sum
.
- inl
{α : Sort u}
{β : Sort v}
(val : α)
: α ⊕' β
Left injection into the sum type
α ⊕' β
. - inr
{α : Sort u}
{β : Sort v}
(val : β)
: α ⊕' β
Right injection into the sum type
α ⊕' β
.
Instances For
The disjoint union of arbitrary sorts α
β
, or α ⊕' β
.
It differs from α ⊕ β
in that it allows α
and β
to have arbitrary sorts Sort u
and Sort v
,
instead of restricting them to Type u
and Type v
. This means that it can be used in situations
where one side is a proposition, like True ⊕' Nat
. However, the resulting universe level
constraints are often more difficult to solve than those that result from Sum
.
Equations
- «term_⊕'_» = Lean.ParserDescr.trailingNode `«term_⊕'_» 30 31 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ⊕' ") (Lean.ParserDescr.cat `term 30))
Instances For
If the left type in a sum is inhabited then the sum is inhabited.
This is not an instance to avoid non-canonical instances when both the left and right types are inhabited.
Equations
- PSum.inhabitedLeft = { default := PSum.inl default }
Instances For
If the right type in a sum is inhabited then the sum is inhabited.
This is not an instance to avoid non-canonical instances when both the left and right types are inhabited.
Equations
- PSum.inhabitedRight = { default := PSum.inr default }
Instances For
Dependent pairs, in which the second element's type depends on the value of the first element. The
type Sigma β
is typically written Σ a : α, β a
or (a : α) × β a
.
Although its values are pairs, Sigma
is sometimes known as the dependent sum type, since it is
the type level version of an indexed summation.
- fst : α
The first component of a dependent pair.
- snd : β self.fst
The second component of a dependent pair. Its type depends on the first component.
Instances For
Fully universe-polymorphic dependent pairs, in which the second element's type depends on the value
of the first element and both types are allowed to be propositions. The type PSigma β
is typically
written Σ' a : α, β a
or (a : α) ×' β a
.
In practice, this generality leads to universe level constraints that are difficult to solve, so
PSigma
is rarely used in manually-written code. It is usually only used in automation that
constructs pairs of arbitrary types.
To pair a value with a proof that a predicate holds for it, use Subtype
. To demonstrate that a
value exists that satisfies a predicate, use Exists
. A dependent pair with a proposition as its
first component is not typically useful due to proof irrelevance: there's no point in depending on a
specific proof because all proofs are equal anyway.
- fst : α
The first component of a dependent pair.
- snd : β self.fst
The second component of a dependent pair. Its type depends on the first component.
Instances For
Existential quantification. If p : α → Prop
is a predicate, then ∃ x : α, p x
asserts that there is some x
of type α
such that p x
holds.
To create an existential proof, use the exists
tactic,
or the anonymous constructor notation ⟨x, h⟩
.
To unpack an existential, use cases h
where h
is a proof of ∃ x : α, p x
,
or let ⟨x, hx⟩ := h
where `.
Because Lean has proof irrelevance, any two proofs of an existential are definitionally equal. One consequence of this is that it is impossible to recover the witness of an existential from the mere fact of its existence. For example, the following does not compile:
example (h : ∃ x : Nat, x = x) : Nat :=
let ⟨x, _⟩ := h -- fail, because the goal is `Nat : Type`
x
The error message recursor 'Exists.casesOn' can only eliminate into Prop
means
that this only works when the current goal is another proposition:
example (h : ∃ x : Nat, x = x) : True :=
let ⟨x, _⟩ := h -- ok, because the goal is `True : Prop`
trivial
- intro
{α : Sort u}
{p : α → Prop}
(w : α)
(h : p w)
: Exists p
Existential introduction. If
a : α
andh : p a
, then⟨a, h⟩
is a proof that∃ x : α, p x
.
Instances For
An indication of whether a loop's body terminated early that's used to compile the for x in xs
notation.
A collection's ForIn
or ForIn'
instance describe's how to iterate over its elements. The monadic
action that represents the body of the loop returns a ForInStep α
, where α
is the local state
used to implement features such as let mut
.
- done
{α : Type u}
: α → ForInStep α
The loop should terminate early.
ForInStep.done
is produced by uses ofbreak
orreturn
in the loop body. - yield
{α : Type u}
: α → ForInStep α
The loop should continue with the next iteration, using the returned state.
ForInStep.yield
is produced bycontinue
and by reaching the bottom of the loop body.
Instances For
Equations
- instInhabitedForInStep = { default := ForInStep.done default }
Monadic iteration in do
-blocks, using the for x in xs
notation.
The parameter m
is the monad of the do
-block in which iteration is performed, ρ
is the type of
the collection being iterated over, and α
is the type of elements.
Monadically iterates over the contents of a collection
xs
, with a local stateb
and the possibility of early termination.Because a
do
block supports local mutable bindings along withreturn
, andbreak
, the monadic action passed toForIn.forIn
takes a starting state in addition to the current element of the collection and returns an updated state together with an indication of whether iteration should continue or terminate. If the action returnsForInStep.done
, thenForIn.forIn
should stop iteration and return the updated state. If the action returnsForInStep.yield
, thenForIn.forIn
should continue iterating if there are further elements, passing the updated state to the action.More information about the translation of
for
loops intoForIn.forIn
is available in the Lean reference manual.
Instances
Monadic iteration in do
-blocks with a membership proof, using the for h : x in xs
notation.
The parameter m
is the monad of the do
-block in which iteration is performed, ρ
is the type of
the collection being iterated over, α
is the type of elements, and d
is the specific membership
predicate to provide.
Monadically iterates over the contents of a collection
xs
, with a local stateb
and the possibility of early termination. At each iteration, the body of the loop is provided with a proof that the current element is in the collection.Because a
do
block supports local mutable bindings along withreturn
, andbreak
, the monadic action passed toForIn'.forIn'
takes a starting state in addition to the current element of the collection with its membership proof. The action returns an updated state together with an indication of whether iteration should continue or terminate. If the action returnsForInStep.done
, thenForIn'.forIn'
should stop iteration and return the updated state. If the action returnsForInStep.yield
, thenForIn'.forIn'
should continue iterating if there are further elements, passing the updated state to the action.More information about the translation of
for
loops intoForIn'.forIn'
is available in the Lean reference manual.
Instances
Auxiliary type used to compile do
notation. It is used when compiling a do block
nested inside a combinator like tryCatch
. It encodes the possible ways the
block can exit:
pure (a : α) s
means that the block exited normally with return valuea
.return (b : β) s
means that the block exited via areturn b
early-exit command.break s
means thatbreak
was called, meaning that we should exit from the containing loop.continue s
means thatcontinue
was called, meaning that we should continue to the next iteration of the containing loop.
All cases return a value s : σ
which bundles all the mutable variables of the do-block.
- pure
{α β σ : Type u}
: α → σ → DoResultPRBC α β σ
pure (a : α) s
means that the block exited normally with return valuea
- return {α β σ : Type u} : β → σ → DoResultPRBC α β σ
- break {α β σ : Type u} : σ → DoResultPRBC α β σ
- continue {α β σ : Type u} : σ → DoResultPRBC α β σ
Instances For
Auxiliary type used to compile do
notation. It is the same as
DoResultPRBC α β σ
except that break
and continue
are not available
because we are not in a loop context.
- pure
{α β σ : Type u}
: α → σ → DoResultPR α β σ
pure (a : α) s
means that the block exited normally with return valuea
- return {α β σ : Type u} : β → σ → DoResultPR α β σ
Instances For
Auxiliary type used to compile do
notation. It is an optimization of
DoResultPRBC PEmpty PEmpty σ
to remove the impossible cases,
used when neither pure
nor return
are possible exit paths.
- break {σ : Type u} : σ → DoResultBC σ
- continue {σ : Type u} : σ → DoResultBC σ
Instances For
Auxiliary type used to compile do
notation. It is an optimization of
either DoResultPRBC α PEmpty σ
or DoResultPRBC PEmpty α σ
to remove the
impossible case, used when either pure
or return
is never used.
- pureReturn {α σ : Type u} : α → σ → DoResultSBC α σ
- break {α σ : Type u} : σ → DoResultSBC α σ
- continue {α σ : Type u} : σ → DoResultSBC α σ
Instances For
HasEquiv α
is the typeclass which supports the notation x ≈ y
where x y : α
.
- Equiv : α → α → Sort v
x ≈ y
says thatx
andy
are equivalent. Because this is a typeclass, the notion of equivalence is type-dependent.Conventions for notations in identifiers:
- The recommended spelling of
≈
in identifiers isequiv
.
- The recommended spelling of
Instances
x ≈ y
says that x
and y
are equivalent. Because this is a typeclass,
the notion of equivalence is type-dependent.
Conventions for notations in identifiers:
- The recommended spelling of
≈
in identifiers isequiv
.
Equations
- «term_≈_» = Lean.ParserDescr.trailingNode `«term_≈_» 50 51 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ≈ ") (Lean.ParserDescr.cat `term 51))
Instances For
set notation #
Notation type class for the strict subset relation ⊂
.
- SSubset : α → α → Prop
Strict subset relation:
a ⊂ b
Conventions for notations in identifiers:
- The recommended spelling of
⊂
in identifiers isssubset
.
- The recommended spelling of
Instances
Subset relation: a ⊆ b
Conventions for notations in identifiers:
- The recommended spelling of
⊆
in identifiers issubset
.
Equations
- «term_⊆_» = Lean.ParserDescr.trailingNode `«term_⊆_» 50 51 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ⊆ ") (Lean.ParserDescr.cat `term 51))
Instances For
Strict subset relation: a ⊂ b
Conventions for notations in identifiers:
- The recommended spelling of
⊂
in identifiers isssubset
.
Equations
- «term_⊂_» = Lean.ParserDescr.trailingNode `«term_⊂_» 50 51 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ⊂ ") (Lean.ParserDescr.cat `term 51))
Instances For
Superset relation: a ⊇ b
Conventions for notations in identifiers:
- The recommended spelling of
⊇
in identifiers issuperset
(prefer⊆
over⊇
).
Equations
- «term_⊇_» = Lean.ParserDescr.trailingNode `«term_⊇_» 50 51 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ⊇ ") (Lean.ParserDescr.cat `term 51))
Instances For
Strict superset relation: a ⊃ b
Conventions for notations in identifiers:
- The recommended spelling of
⊃
in identifiers isssuperset
(prefer⊂
over⊃
).
Equations
- «term_⊃_» = Lean.ParserDescr.trailingNode `«term_⊃_» 50 51 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ⊃ ") (Lean.ParserDescr.cat `term 51))
Instances For
a ∪ b
is the union ofa
and b
.
Conventions for notations in identifiers:
- The recommended spelling of
∪
in identifiers isunion
.
Equations
- «term_∪_» = Lean.ParserDescr.trailingNode `«term_∪_» 65 65 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ∪ ") (Lean.ParserDescr.cat `term 66))
Instances For
a ∩ b
is the intersection ofa
and b
.
Conventions for notations in identifiers:
- The recommended spelling of
∩
in identifiers isinter
.
Equations
- «term_∩_» = Lean.ParserDescr.trailingNode `«term_∩_» 70 70 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ∩ ") (Lean.ParserDescr.cat `term 71))
Instances For
a \ b
is the set difference of a
and b
,
consisting of all elements in a
that are not in b
.
Conventions for notations in identifiers:
- The recommended spelling of
\
in identifiers issdiff
.
Equations
- «term_\_» = Lean.ParserDescr.trailingNode `«term_\_» 70 71 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " \\ ") (Lean.ParserDescr.cat `term 71))
Instances For
collections #
EmptyCollection α
is the typeclass which supports the notation ∅
, also written as {}
.
- emptyCollection : α
∅
or{}
is the empty set or empty collection. It is supported by theEmptyCollection
typeclass.Conventions for notations in identifiers:
The recommended spelling of
{}
in identifiers isempty
.The recommended spelling of
∅
in identifiers isempty
.
Instances
∅
or {}
is the empty set or empty collection.
It is supported by the EmptyCollection
typeclass.
Conventions for notations in identifiers:
- The recommended spelling of
{}
in identifiers isempty
.
Equations
- «term{}» = Lean.ParserDescr.node `«term{}» 1024 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol "{") (Lean.ParserDescr.symbol "}"))
Instances For
∅
or {}
is the empty set or empty collection.
It is supported by the EmptyCollection
typeclass.
Conventions for notations in identifiers:
- The recommended spelling of
∅
in identifiers isempty
.
Equations
- «term∅» = Lean.ParserDescr.node `«term∅» 1024 (Lean.ParserDescr.symbol "∅")
Instances For
Type class for the singleton
operation.
Used to implement the { a, b, c }
syntax.
- singleton : α → β
Instances
Task α
is a primitive for asynchronous computation.
It represents a computation that will resolve to a value of type α
,
possibly being computed on another thread. This is similar to Future
in Scala,
Promise
in Javascript, and JoinHandle
in Rust.
The tasks have an overridden representation in the runtime.
- pure :: (
- get : α
Blocks the current thread until the given task has finished execution, and then returns the result of the task. If the current thread is itself executing a (non-dedicated) task, the maximum threadpool size is temporarily increased by one while waiting so as to ensure the process cannot be deadlocked by threadpool starvation. Note that when the current thread is unblocked, more tasks than the configured threadpool size may temporarily be running at the same time until sufficiently many tasks have finished.
Task.map
andTask.bind
should be preferred overTask.get
for setting up task dependencies where possible as they do not require temporarily growing the threadpool in this way. - )
Instances For
Equations
- instInhabitedTask = { default := { get := default } }
Task priority.
Tasks with higher priority will always be scheduled before tasks with lower priority. Tasks with a
priority greater than Task.Priority.max
are scheduled on dedicated threads.
Equations
Instances For
The default priority for spawned tasks, also the lowest priority: 0
.
Equations
Instances For
The highest regular priority for spawned tasks: 8
.
Spawning a task with a priority higher than Task.Priority.max
is not an error but will spawn a
dedicated worker for the task. This is indicated using Task.Priority.dedicated
. Regular priority
tasks are placed in a thread pool and worked on according to their priority order.
Equations
Instances For
Indicates that a task should be scheduled on a dedicated thread.
Any priority higher than Task.Priority.max
will result in the task being scheduled
immediately on a dedicated thread. This is particularly useful for long-running and/or
I/O-bound tasks since Lean will, by default, allocate no more non-dedicated workers
than the number of cores to reduce context switches.
Equations
Instances For
map f x
maps function f
over the task x
: that is, it constructs
(and immediately launches) a new task which will wait for the value of x
to
be available and then calls f
on the result.
prio
, if provided, is the priority of the task.
If sync
is set to true, f
is executed on the current thread if x
has already finished and
otherwise on the thread that x
finished on. prio
is ignored in this case. This should only be
done when executing f
is cheap and non-blocking.
Instances For
bind x f
does a monad "bind" operation on the task x
with function f
:
that is, it constructs (and immediately launches) a new task which will wait
for the value of x
to be available and then calls f
on the result,
resulting in a new task which is then run for a result.
prio
, if provided, is the priority of the task.
If sync
is set to true, f
is executed on the current thread if x
has already finished and
otherwise on the thread that x
finished on. prio
is ignored in this case. This should only be
done when executing f
is cheap and non-blocking.
Instances For
NonScalar
is a type that is not a scalar value in our runtime.
It is used as a stand-in for an arbitrary boxed value to avoid excessive
monomorphization, and it is only created using unsafeCast
. It is somewhat
analogous to C void*
in usage, but the type itself is not special.
- val : Nat
You should not use this function
Instances For
PNonScalar
is a type that is not a scalar value in our runtime.
It is used as a stand-in for an arbitrary boxed value to avoid excessive
monomorphization, and it is only created using unsafeCast
. It is somewhat
analogous to C void*
in usage, but the type itself is not special.
This is the universe-polymorphic version of PNonScalar
; it is preferred to use
NonScalar
instead where applicable.
- mk
(v : Nat)
: PNonScalar
You should not use this function
Instances For
Boolean operators #
x != y
is boolean not-equal. It is the negation of x == y
which is supplied by
the BEq
typeclass.
Unlike x ≠ y
(which is notation for Ne x y
), this is Bool
valued instead of
Prop
valued. It is mainly intended for programming applications.
Conventions for notations in identifiers:
- The recommended spelling of
!=
in identifiers isbne
.
Instances For
x != y
is boolean not-equal. It is the negation of x == y
which is supplied by
the BEq
typeclass.
Unlike x ≠ y
(which is notation for Ne x y
), this is Bool
valued instead of
Prop
valued. It is mainly intended for programming applications.
Conventions for notations in identifiers:
- The recommended spelling of
!=
in identifiers isbne
.
Equations
- «term_!=_» = Lean.ParserDescr.trailingNode `«term_!=_» 50 51 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " != ") (Lean.ParserDescr.cat `term 51))
Instances For
A Boolean equality test coincides with propositional equality.
In other words:
a == b
impliesa = b
.a == a
is true.
If
a == b
evaluates totrue
, thena
andb
are equal in the logic.==
is reflexive, that is,(a == a) = true
.
Instances
Logical connectives and equality #
If h : α = β
is a proof of type equality, then h.mpr : β → α
is the induced
"cast" operation in the reverse direction, mapping elements of β
to elements of α
.
You can prove theorems about the resulting element by induction on h
, since
rfl.mpr
is definitionally the identity function.
Instances For
a ≠ b
, or Ne a b
is defined as ¬ (a = b)
or a = b → False
,
and asserts that a
and b
are not equal.
Conventions for notations in identifiers:
- The recommended spelling of
≠
in identifiers isne
.
Equations
- «term_≠_» = Lean.ParserDescr.trailingNode `«term_≠_» 50 51 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ≠ ") (Lean.ParserDescr.cat `term 51))
Instances For
If two terms are heterogeneously equal then their types are propositionally equal.
Exists #
Decidable #
Equations
Instances For
Equations
Instances For
Similar to decide
, but uses an explicit instance
Equations
- toBoolUsing d = decide p
Instances For
Construct a q
if some proposition p
is decidable, and both the truth and falsity of p
are
sufficient to construct a q
.
This is a synonym for dite
, the dependent if-then-else operator.
Equations
- Decidable.byCases h1 h2 = h1 h
- Decidable.byCases h1 h2 = h2 h
Instances For
Transfer a decidability proof across an equivalence of propositions.
Equations
- decidable_of_decidable_of_iff h = if hp : p then isTrue ⋯ else isFalse ⋯
Instances For
Transfer a decidability proof across an equality of propositions.
Equations
Instances For
if-then-else expression theorems #
Split an if-then-else into cases. The split
tactic is generally easier to use than this theorem.
Equations
- iteInduction hpos hneg = hpos h
- iteInduction hpos hneg = hneg h
Instances For
Equations
Equations
- instDecidableDite = dT h
- instDecidableDite = dE h
Auxiliary definition for generating compact noConfusion
for enumeration types
Equations
- noConfusionTypeEnum f P x y = Decidable.casesOn (inst (f x) (f y)) (fun (x : ¬f x = f y) => P) fun (x : f x = f y) => P → P
Instances For
Auxiliary definition for generating compact noConfusion
for enumeration types
Equations
- noConfusionEnum f h = Decidable.casesOn (inst (f x) (f y)) (fun (h' : ¬f x = f y) => ⋯.elim) fun (x : f x = f y) (x : P) => x
Instances For
Inhabited #
Equations
- instInhabitedTrue = { default := True.intro }
Equations
- instInhabitedPNonScalar = { default := PNonScalar.mk default }
Equations
- instInhabitedNonScalar = { default := { val := default } }
Equations
- instInhabitedForInStep_1 = { default := ForInStep.done default }
Subsingleton #
A subsingleton is a type with at most one element. It is either empty or has a unique element.
All propositions are subsingletons because of proof irrelevance: false propositions are empty, and all proofs of a true proposition are equal to one another. Some non-propositional types are also subsingletons.
- intro :: (
Any two elements of a subsingleton are equal.
- )
Instances
If a type is a subsingleton, then all of its elements are equal.
If two types are equal and one of them is a subsingleton, then all of their elements are heterogeneously equal.
An equivalence relation r : α → α → Prop
is a relation that is
Equality is an equivalence relation, and equivalence relations share many of the properties of equality.
- refl (x : α) : r x x
An equivalence relation is reflexive:
r x x
- symm {x y : α} : r x y → r y x
- trans {x y z : α} : r x y → r y z → r x z
Instances For
The empty relation is the relation on α
which is always False
.
Equations
- emptyRelation x✝¹ x✝ = False
Instances For
Subrelation q r
means that q ⊆ r
or ∀ x y, q x y → r x y
.
It is the analogue of the subset relation on relations.
Equations
- Subrelation q r = ∀ {x y : α}, q x y → r x y
Instances For
The transitive closure TransGen r
of a relation r
is the smallest relation which is
transitive and contains r
. TransGen r a z
if and only if there exists a sequence
a r b r ... r z
of length at least 1 connecting a
to z
.
- single {α : Sort u} {r : α → α → Prop} {a b : α} : r a b → TransGen r a b
- tail {α : Sort u} {r : α → α → Prop} {a b c : α} : TransGen r a b → r b c → TransGen r a c
Instances For
Subtype #
Equations
- ⟨b, h₂⟩.instDecidableEq ⟨b_1, h₂_1⟩ = if h : b = b_1 then isTrue ⋯ else isFalse ⋯
Sum #
If the left type in a sum is inhabited then the sum is inhabited.
This is not an instance to avoid non-canonical instances when both the left and right types are inhabited.
Equations
- Sum.inhabitedLeft = { default := Sum.inl default }
Instances For
If the right type in a sum is inhabited then the sum is inhabited.
This is not an instance to avoid non-canonical instances when both the left and right types are inhabited.
Equations
- Sum.inhabitedRight = { default := Sum.inr default }
Instances For
Equations
- instDecidableEqSum (Sum.inl a_2) (Sum.inl b_2) = if h : a_2 = b_2 then isTrue ⋯ else isFalse ⋯
- instDecidableEqSum (Sum.inr a_2) (Sum.inr b_2) = if h : a_2 = b_2 then isTrue ⋯ else isFalse ⋯
- instDecidableEqSum (Sum.inr val) (Sum.inl val_1) = isFalse ⋯
- instDecidableEqSum (Sum.inl val) (Sum.inr val_1) = isFalse ⋯
Product #
Equations
- One or more equations did not get rendered due to their size.
Lexicographical order for products.
Two pairs are lexicographically ordered if their first elements are ordered or if their first elements are equal and their second elements are ordered.
Instances For
Dependent products #
Universe polymorphic unit #
Equations
- instInhabitedPUnit = { default := PUnit.unit }
Setoid #
A setoid is a type with a distinguished equivalence relation, denoted ≈
.
The Quotient
type constructor requires a Setoid
instance.
- r : α → α → Prop
x ≈ y
is the distinguished equivalence relation of a setoid. - iseqv : Equivalence r
The relation
x ≈ y
is an equivalence relation.
Instances
Equations
- instHasEquivOfSetoid = { Equiv := Setoid.r }
A setoid's equivalence relation is reflexive.
Propositional extensionality #
The axiom of propositional extensionality. It asserts that if propositions
a
and b
are logically equivalent (i.e. we can prove a
from b
and vice versa),
then a
and b
are equal, meaning that we can replace a
with b
in all
contexts.
For simple expressions like a ∧ c ∨ d → e
we can prove that because all the logical
connectives respect logical equivalence, we can replace a
with b
in this expression
without using propext
. However, for higher order expressions like P a
where
P : Prop → Prop
is unknown, or indeed for a = b
itself, we cannot replace a
with b
without an axiom which says exactly this.
This is a relatively uncontroversial axiom, which is intuitionistically valid.
It does however block computation when using #reduce
to reduce proofs directly
(which is not recommended), meaning that canonicity,
the property that all closed terms of type Nat
normalize to numerals,
fails to hold when this (or any) axiom is used:
set_option pp.proofs true
def foo : Nat := by
have : (True → True) ↔ True := ⟨λ _ => trivial, λ _ _ => trivial⟩
have := propext this ▸ (2 : Nat)
exact this
#reduce foo
-- propext { mp := fun x x => True.intro, mpr := fun x => True.intro } ▸ 2
#eval foo -- 2
#eval
can evaluate it to a numeral because the compiler erases casts and
does not evaluate proofs, so propext
, whose return type is a proposition,
can never block it.
Equations
Prop lemmas #
implies #
Quotients #
The quotient axiom, which asserts the equality of elements related by the quotient's relation.
The relation r
does not need to be an equivalence relation to use this axiom. When r
is not an
equivalence relation, the quotient is with respect to the equivalence relation generated by r
.
Quot.sound
is part of the built-in primitive quotient type:
Quot
is the built-in quotient type.Quot.mk
places elements of the underlying typeα
into the quotient.Quot.lift
allows the definition of functions from the quotient to some other type.Quot.ind
is used to write proofs about quotients by assuming that all elements are constructed withQuot.mk
; it is analogous to the recursor for a structure.
Quotient types are described in more detail in the Lean Language Reference.
Lifts a function from an underlying type to a function on a quotient, requiring that it respects the quotient's relation.
Given a relation r : α → α → Prop
and a quotient's value q : Quot r
, applying a f : α → β
requires a proof c
that f
respects r
. In this case, Quot.liftOn q f h : β
evaluates
to the result of applying f
to the underlying value in α
from q
.
Quot.liftOn
is a version of the built-in primitive Quot.lift
with its parameters re-ordered.
Quotient types are described in more detail in the Lean Language Reference.
Instances For
A dependent recursion principle for Quot
. It is analogous to the
recursor for a structure, and can be used when the resulting type
is not necessarily a proposition.
While it is very general, this recursor can be tricky to use. The following simpler alternatives may be easier to use:
Quot.lift
is useful for defining non-dependent functions.Quot.ind
is useful for proving theorems about quotients.Quot.recOnSubsingleton
can be used whenever the target type is aSubsingleton
.Quot.hrecOn
uses heterogeneous equality instead of rewriting withQuot.sound
.
Quot.recOn
is a version of this recursor that takes the quotient parameter first.
Equations
- Quot.rec f h q = Eq.ndrecOn ⋯ (Quot.lift (Quot.indep f) ⋯ q).snd
Instances For
A dependent recursion principle for Quot
that takes the quotient first. It is analogous to the
recursor for a structure, and can be used when the resulting type
is not necessarily a proposition.
While it is very general, this recursor can be tricky to use. The following simpler alternatives may be easier to use:
Quot.lift
is useful for defining non-dependent functions.Quot.ind
is useful for proving theorems about quotients.Quot.recOnSubsingleton
can be used whenever the target type is aSubsingleton
.Quot.hrecOn
uses heterogeneous equality instead of rewriting withQuot.sound
.
Quot.rec
is a version of this recursor that takes the quotient parameter last.
Equations
- Quot.recOn q f h = Quot.rec f h q
Instances For
An alternative induction principle for quotients that can be used when the target type is a subsingleton, in which all elements are equal.
In these cases, the proof that the function respects the quotient's relation is trivial, so any function can be lifted.
Quot.rec
does not assume that the type is a subsingleton.
Equations
- Quot.recOnSubsingleton q f = Quot.rec (fun (a : α) => f a) ⋯ q
Instances For
A dependent recursion principle for Quot
that uses heterogeneous
equality, analogous to a recursor for
a structure.
Quot.recOn
is a version of this recursor that uses Eq
instead of HEq
.
Equations
- Quot.hrecOn q f c = Quot.recOn q f ⋯
Instances For
Quotient types coarsen the propositional equality for a type so that terms related by some
equivalence relation are considered equal. The equivalence relation is given by an instance of
Setoid
.
Set-theoretically, Quotient s
can seen as the set of equivalence classes of α
modulo the
Setoid
instance's relation s.r
. Functions from Quotient s
must prove that they respect s.r
:
to define a function f : Quotient s → β
, it is necessary to provide f' : α → β
and prove that
for all x : α
and y : α
, s.r x y → f' x = f' y
. Quotient.lift
implements this operation.
The key quotient operators are:
Quotient.mk
places elements of the underlying typeα
into the quotient.Quotient.lift
allows the definition of functions from the quotient to some other type.Quotient.sound
asserts the equality of elements related byr
Quotient.ind
is used to write proofs about quotients by assuming that all elements are constructed withQuotient.mk
.
Quotient
is built on top of the primitive quotient type Quot
, which does not require a proof
that the relation is an equivalence relation. Quotient
should be used instead of Quot
for
relations that actually are equivalence relations.
Instances For
Places an element of a type into the quotient that equates terms according to an equivalence relation.
The setoid instance is provided explicitly. Quotient.mk'
uses instance synthesis instead.
Given v : α
, Quotient.mk s v : Quotient s
is like v
, except all observations of v
's value
must respect s.r
. Quotient.lift
allows values in a quotient to be mapped to other types, so long
as the mapping respects s.r
.
Equations
- Quotient.mk s a = Quot.mk Setoid.r a
Instances For
Places an element of a type into the quotient that equates terms according to an equivalence relation.
The equivalence relation is found by synthesizing a Setoid
instance. Quotient.mk
instead expects
the instance to be provided explicitly.
Given v : α
, Quotient.mk' v : Quotient s
is like v
, except all observations of v
's value
must respect s.r
. Quotient.lift
allows values in a quotient to be mapped to other types, so long
as the mapping respects s.r
.
Equations
- Quotient.mk' a = Quotient.mk s a
Instances For
The quotient axiom, which asserts the equality of elements related in the setoid.
Because Quotient
is built on a lower-level type Quot
, Quotient.sound
is implemented as a
theorem. It is derived from Quot.sound
, the soundness axiom for the lower-level quotient type
Quot
.
Lifts a function from an underlying type to a function on a quotient, requiring that it respects the quotient's equivalence relation.
Given s : Setoid α
and a quotient Quotient s
, applying a function f : α → β
requires a proof
h
that f
respects the equivalence relation s.r
. In this case, the function
Quotient.lift f h : Quotient s → β
computes the same values as f
.
Quotient.liftOn
is a version of this operation that takes the quotient value as its first explicit
parameter.
Equations
- Quotient.lift f = Quot.lift f
Instances For
A reasoning principle for quotients that allows proofs about quotients to assume that all values are
constructed with Quotient.mk
.
Lifts a function from an underlying type to a function on a quotient, requiring that it respects the quotient's equivalence relation.
Given s : Setoid α
and a quotient value q : Quotient s
, applying a function f : α → β
requires
a proof c
that f
respects the equivalence relation s.r
. In this case, the term
Quotient.liftOn q f h : β
reduces to the result of applying f
to the underlying α
value.
Quotient.lift
is a version of this operation that takes the quotient value last, rather than
first.
Equations
- q.liftOn f c = Quot.liftOn q f c
Instances For
The analogue of Quot.inductionOn
: every element of Quotient s
is of the form Quotient.mk s a
.
A dependent recursion principle for Quotient
. It is analogous to the
recursor for a structure, and can be used when the resulting type
is not necessarily a proposition.
While it is very general, this recursor can be tricky to use. The following simpler alternatives may be easier to use:
Quotient.lift
is useful for defining non-dependent functions.Quotient.ind
is useful for proving theorems about quotients.Quotient.recOnSubsingleton
can be used whenever the target type is aSubsingleton
.Quotient.hrecOn
uses heterogeneous equality instead of rewriting withQuotient.sound
.
Quotient.recOn
is a version of this recursor that takes the quotient parameter first.
Equations
- Quotient.rec f h q = Quot.rec f h q
Instances For
A dependent recursion principle for Quotient
. It is analogous to the
recursor for a structure, and can be used when the resulting type
is not necessarily a proposition.
While it is very general, this recursor can be tricky to use. The following simpler alternatives may be easier to use:
Quotient.lift
is useful for defining non-dependent functions.Quotient.ind
is useful for proving theorems about quotients.Quotient.recOnSubsingleton
can be used whenever the target type is aSubsingleton
.Quotient.hrecOn
uses heterogeneous equality instead of rewriting withQuotient.sound
.
Quotient.rec
is a version of this recursor that takes the quotient parameter last.
Equations
- Quotient.recOn q f h = Quot.recOn q f h
Instances For
An alternative recursion or induction principle for quotients that can be used when the target type is a subsingleton, in which all elements are equal.
In these cases, the proof that the function respects the quotient's equivalence relation is trivial, so any function can be lifted.
Quotient.rec
does not assume that the target type is a subsingleton.
Equations
Instances For
A dependent recursion principle for Quotient
that uses heterogeneous
equality, analogous to a recursor for
a structure.
Quotient.recOn
is a version of this recursor that uses Eq
instead of HEq
.
Equations
- Quotient.hrecOn q f c = Quot.hrecOn q f c
Instances For
Lifts a binary function from the underlying types to a binary function on quotients. The function must respect both quotients' equivalence relations.
Quotient.lift
is a version of this operation for unary functions. Quotient.liftOn₂
is a version
that take the quotient parameters first.
Equations
- Quotient.lift₂ f c q₁ q₂ = Quotient.lift (fun (a₁ : α) => Quotient.lift (f a₁) ⋯ q₂) ⋯ q₁
Instances For
Lifts a binary function from the underlying types to a binary function on quotients. The function must respect both quotients' equivalence relations.
Quotient.liftOn
is a version of this operation for unary functions. Quotient.lift₂
is a version
that take the quotient parameters last.
Equations
- q₁.liftOn₂ q₂ f c = Quotient.lift₂ f c q₁ q₂
Instances For
If two values are equal in a quotient, then they are related by its equivalence relation.
An alternative induction or recursion operator for defining binary operations on quotients that can be used when the target type is a subsingleton.
In these cases, the proof that the function respects the quotient's equivalence relation is trivial, so any function can be lifted.
Equations
- Quotient.recOnSubsingleton₂ q₁ q₂ g = Quot.recOnSubsingleton q₁ fun (a : α) => Quot.recOnSubsingleton q₂ fun (a_1 : β) => g a a_1
Instances For
Equations
- q₁.decidableEq q₂ = Quotient.recOnSubsingleton₂ q₁ q₂ fun (a₁ a₂ : α) => match d a₁ a₂ with | isTrue h₁ => isTrue ⋯ | isFalse h₂ => isFalse ⋯
Function extensionality #
Function extensionality. If two functions return equal results for all possible arguments, then they are equal.
It is called “extensionality” because it provides a way to prove two objects equal based on the properties of the underlying mathematical functions, rather than based on the syntax used to denote them. Function extensionality is a theorem that can be proved using quotient types.
Squash #
The quotient of α
by the universal relation. The elements of Squash α
are those of α
, but all
of them are equal and cannot be distinguished.
Squash α
is a Subsingleton
: it is empty if α
is empty, otherwise it has just one element. It
is the “universal Subsingleton
” mapped from α
.
Nonempty α
also has these properties. It is a proposition, which means that its elements (i.e.
proofs) are erased from compiled code and represented by a dummy value. Squash α
is a Type u
,
and its representation in compiled code is identical to that of α
.
Consequently, Squash.lift
may extract an α
value into any subsingleton type β
, while
Nonempty.rec
can only do the same when β
is a proposition.
Instances For
Extracts a squashed value into any subsingleton type.
If β
is a subsingleton, a function α → β
cannot distinguish between elements of α
and thus
automatically respects the universal relation that Squash
quotients with.
Instances For
Kernel reduction hints #
Depends on the correctness of the Lean compiler, interpreter, and all [implemented_by ...]
and [extern ...]
annotations.
When the kernel tries to reduce a term Lean.reduceBool c
, it will invoke the Lean interpreter to evaluate c
.
The kernel will not use the interpreter if c
is not a constant.
This feature is useful for performing proofs by reflection.
Remark: the Lean frontend allows terms of the from Lean.reduceBool t
where t
is a term not containing
free variables. The frontend automatically declares a fresh auxiliary constant c
and replaces the term with
Lean.reduceBool c
. The main motivation is that the code for t
will be pre-compiled.
Warning: by using this feature, the Lean compiler and interpreter become part of your trusted code base. This is extra 30k lines of code. More importantly, you will probably not be able to check your development using external type checkers that do not implement this feature. Keep in mind that if you are using Lean as programming language, you are already trusting the Lean compiler and interpreter. So, you are mainly losing the capability of type checking your development using external checkers.
Recall that the compiler trusts the correctness of all [implemented_by ...]
and [extern ...]
annotations.
If an extern function is executed, then the trusted code base will also include the implementation of the associated
foreign function.
Similar to Lean.reduceBool
for closed Nat
terms.
Remark: we do not have plans for supporting a generic reduceValue {α} (a : α) : α := a
.
The main issue is that it is non-trivial to convert an arbitrary runtime object back into a Lean expression.
We believe Lean.reduceBool
enables most interesting applications (e.g., proof by reflection).
The axiom ofReduceBool
is used to perform proofs by reflection. See reduceBool
.
This axiom is usually not used directly, because it has some syntactic restrictions.
Instead, the native_decide
tactic can be used to prove any proposition whose
decidability instance can be evaluated to true
using the lean compiler / interpreter.
Warning: by using this feature, the Lean compiler and interpreter become part of your trusted code base. This is extra 30k lines of code. More importantly, you will probably not be able to check your development using external type checkers that do not implement this feature. Keep in mind that if you are using Lean as programming language, you are already trusting the Lean compiler and interpreter. So, you are mainly losing the capability of type checking your development using external checkers.
The axiom ofReduceNat
is used to perform proofs by reflection. See reduceBool
.
Warning: by using this feature, the Lean compiler and interpreter become part of your trusted code base. This is extra 30k lines of code. More importantly, you will probably not be able to check your development using external type checkers that do not implement this feature. Keep in mind that if you are using Lean as programming language, you are already trusting the Lean compiler and interpreter. So, you are mainly losing the capability of type checking your development using external checkers.
The term opaqueId x
will not be reduced by the kernel.
Associative op
indicates op
is an associative operation,
i.e. (a ∘ b) ∘ c = a ∘ (b ∘ c)
.
An associative operation satisfies
(a ∘ b) ∘ c = a ∘ (b ∘ c)
.
Instances
Commutative op
says that op
is a commutative operation,
i.e. a ∘ b = b ∘ a
.
A commutative operation satisfies
a ∘ b = b ∘ a
.
Instances
IdempotentOp op
indicates op
is an idempotent binary operation.
i.e. a ∘ a = a
.
An idempotent operation satisfies
a ∘ a = a
.
Instances
LawfulLeftIdentify op o
indicates o
is a verified left identity of
op
.
Left identity
o
is an identity.
Instances
LawfulRightIdentify op o
indicates o
is a verified right identity of
op
.
Right identity
o
is an identity.
Instances
Identity op o
indicates o
is a left and right identity of op
.
This class does not require a proof that o
is an identity, and is used
primarily for inferring the identity using class resolution.
Instances
LawfulIdentity op o
indicates o
is a verified left and right
identity of op
.
Instances
LawfulCommIdentity
can simplify defining instances of LawfulIdentity
on commutative functions by requiring only a left or right identity
proof.
This class is intended for simplifying defining instances of
LawfulIdentity
and functions needed commutative operations with
identity should just add a LawfulIdentity
constraint.