Basic logic properties #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
This file is one of the earliest imports in mathlib.
Implementation notes #
Theorems that require decidability hypotheses are in the namespace "decidable". Classical versions are in the namespace "classical".
In the presence of automation, this whole file may be unnecessary. On the other hand, maybe it is useful for writing automation.
Equations
- empty.decidable_eq = λ (a : empty), a.elim
Equations
- sort.inhabited = {default := punit}
Equations
- sort.inhabited' = {default := punit.star}
Equations
Equations
Equations
If all points are equal to a given point x
, then α
is a subsingleton.
Non-dependent version of coe_fn_coe_trans
, helps rw
figure out the argument.
Non-dependent version of coe_fn_coe_base
, helps rw
figure out the argument.
Many structures such as bundled morphisms coerce to functions so that you can
transparently apply them to arguments. For example, if e : α ≃ β
and a : α
then you can write e a
and this is elaborated as ⇑e a
. This type of
coercion is implemented using the has_coe_to_fun
type class. There is one
important consideration:
If a type coerces to another type which in turn coerces to a function,
then it must implement has_coe_to_fun
directly:
structure sparkling_equiv (α β) extends α ≃ β
-- if we add a `has_coe` instance,
instance {α β} : has_coe (sparkling_equiv α β) (α ≃ β) :=
⟨sparkling_equiv.to_equiv⟩
-- then a `has_coe_to_fun` instance **must** be added as well:
instance {α β} : has_coe_to_fun (sparkling_equiv α β) :=
⟨λ _, α → β, λ f, f.to_equiv.to_fun⟩
(Rationale: if we do not declare the direct coercion, then ⇑e a
is not in
simp-normal form. The lemma coe_fn_coe_base
will unfold it to ⇑↑e a
. This
often causes loops in the simplifier.)
- out : p
Wrapper for adding elementary propositions to the type class systems. Warning: this can easily be abused. See the rest of this docstring for details.
Certain propositions should not be treated as a class globally, but sometimes it is very convenient to be able to use the type class system in specific circumstances.
For example, zmod p
is a field if and only if p
is a prime number.
In order to be able to find this field instance automatically by type class search,
we have to turn p.prime
into an instance implicit assumption.
On the other hand, making nat.prime
a class would require a major refactoring of the library,
and it is questionable whether making nat.prime
a class is desirable at all.
The compromise is to add the assumption [fact p.prime]
to zmod.field
.
In particular, this class is not intended for turning the type class system into an automated theorem prover for first order logic.
In most cases, we should not have global instances of fact
; typeclass search only reads the head
symbol and then tries any instances, which means that adding any such instance will cause slowdowns
everywhere. We instead make them as lemmata and make them local instances as required.
Swaps two pairs of arguments to a function.
Equations
- function.swap₂ f = λ (i₂ : ι₂) (j₂ : κ₂ i₂) (i₁ : ι₁) (j₁ : κ₁ i₁), f i₁ j₁ i₂ j₂
If x : α . tac_name
then x.out : α
. These are definitionally equal, but this can
nevertheless be useful for various reasons, e.g. to apply further projection notation or in an
argument to simp
.
Declarations about propositional connectives #
In most of mathlib, we use the law of excluded middle (LEM) and the axiom of choice (AC) freely.
The decidable
namespace contains versions of lemmas from the root namespace that explicitly
attempt to avoid the axiom of choice, usually by adding decidability assumptions on the inputs.
You can check if a lemma uses the axiom of choice by using #print axioms foo
and seeing if
classical.choice
appears in the list.
As mathlib is primarily classical,
if the type signature of a def
or lemma
does not require any decidable
instances to state,
it is preferable not to introduce any decidable
instances that are needed in the proof
as arguments, but rather to use the classical
tactic as needed.
In the other direction, when decidable
instances do appear in the type signature,
it is better to use explicitly introduced ones rather than allowing Lean to automatically infer
classical ones, as these may cause instance mismatch errors later.
Declarations about distributivity #
Declarations about iff
Transfer decidability of b
to decidability of a
, if the propositions are equivalent.
This is the same as decidable_of_iff
but the iff is flipped.
Equations
Prove that a
is decidable by constructing a boolean b
and a proof that b ↔ a
.
(This is sometimes taken as an alternate definition of decidability.)
Equations
De Morgan's laws #
Declarations about equality #
Declarations about quantifiers #
We intentionally restrict the type of α
in this lemma so that this is a safer to use in simp
than forall_swap
.
Extract an element from a existential statement, using classical.some
.
Equations
- P.some = classical.some P
See is_empty.exists_iff
for the false
version.
See is_empty.forall_iff
for the false
version.
Classical lemmas #
Any prop p
is decidable classically. A shorthand for classical.prop_decidable
.
Equations
Any predicate p
is decidable classically.
Equations
- classical.dec_pred p = λ (a : α), classical.prop_decidable (p a)
Any relation p
is decidable classically.
Equations
- classical.dec_rel p = λ (a b : α), classical.prop_decidable (p a b)
Any type α
has decidable equality classically.
Equations
- classical.dec_eq α = λ (a b : α), classical.prop_decidable (a = b)
A version of classical.indefinite_description which is definitionally equal to a pair
Equations
classical.by_contradiction'
is equivalent to lean's axiom classical.choice
.
Equations
- classical.choice_of_by_contradiction' contra = λ (H : nonempty α), contra _
This function has the same type as exists.rec_on
, and can be used to case on an equality,
but exists.rec_on
can only eliminate into Prop, while this version eliminates into any universe
using the axiom of choice.
Equations
- exists.classical_rec_on h H = H (classical.some h) _