mathlib documentation

logic.basic

Basic logic properties

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.

def hidden {α : Sort u_1} :
Π {a : α}, α

An identity function with its main argument implicit. This will be printed as hidden even if it is applied to a large term, so it can be used for elision, as done in the elide and unelide tactics.

Equations
def empty.elim {C : Sort u_1} :
empty → C

Ex falso, the nondependent eliminator for the empty type.

@[instance]
def subsingleton.prod {α : Type u_1} {β : Type u_2} [subsingleton α] [subsingleton β] :

@[instance]

Equations
@[instance]
def sort.inhabited  :
inhabited (Sort u_1)

Equations
@[instance]
def sort.inhabited'  :
inhabited (default (Sort u_1))

Equations
@[instance]
def psum.inhabited_left {α : Sort u_1} {β : Sort u_2} [inhabited α] :
inhabited (psum α β)

Equations
@[instance]
def psum.inhabited_right {α : Sort u_1} {β : Sort u_2} [inhabited β] :
inhabited (psum α β)

Equations
@[instance]
def decidable_eq_of_subsingleton {α : Sort u_1} [subsingleton α] :

Equations
@[simp]
theorem eq_iff_true_of_subsingleton {α : Type u_1} [subsingleton α] (x y : α) :
x = y true

@[simp]
theorem coe_coe {α : Sort u_1} {β : Sort u_2} {γ : Sort u_3} [has_coe α β] [has_coe_t β γ] (a : α) :

Add an instance to "undo" coercion transitivity into a chain of coercions, because most simp lemmas are stated with respect to simple coercions and will not match when part of a chain.

theorem coe_fn_coe_trans {α : Sort u_1} {β : Sort u_2} {γ : Sort u_3} [has_coe α β] [has_coe_t_aux β γ] [has_coe_to_fun γ] (x : α) :

@[simp]
theorem coe_fn_coe_base {α : Sort u_1} {β : Sort u_2} [has_coe α β] [has_coe_to_fun β] (x : α) :

theorem coe_sort_coe_trans {α : Sort u_1} {β : Sort u_2} {γ : Sort u_3} [has_coe α β] [has_coe_t_aux β γ] [has_coe_to_sort γ] (x : α) :

@[simp]
theorem coe_sort_coe_base {α : Sort u_1} {β : Sort u_2} [has_coe α β] [has_coe_to_sort β] (x : α) :

@[nolint]
constant pempty  :
Sort u

pempty is the universe-polymorphic analogue of empty.

def pempty.elim {C : Sort u_1} :
pempty → C

Ex falso, the nondependent eliminator for the pempty type.

@[simp]
theorem forall_pempty {P : pempty → Prop} :
(∀ (x : pempty), P x) true

@[simp]
theorem exists_pempty {P : pempty → Prop} :
(∃ (x : pempty), P x) false

theorem congr_arg_heq {α : Sort u_1} {β : α → Sort u_2} (f : Π (a : α), β a) {a₁ a₂ : α} :
a₁ = a₂f a₁ == f a₂

theorem plift.down_inj {α : Sort u_1} (a b : plift α) :
a.down = b.downa = b

theorem ne_comm {α : Sort u_1} {a b : α} :
a b b a

@[simp]
theorem eq_iff_eq_cancel_left {α : Type u_1} {b c : α} :
(∀ {a : α}, a = b a = c) b = c

@[simp]
theorem eq_iff_eq_cancel_right {α : Type u_1} {a b : α} :
(∀ {c : α}, a = c b = c) a = b

@[class]
def fact  :
Prop → Prop

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.

Equations
Instances
theorem fact.elim {p : Prop} :
fact p → p

Declarations about propositional connectives

Declarations about implies

theorem iff_of_eq {a b : Prop} :
a = b(a b)

theorem iff_iff_eq {a b : Prop} :
a b a = b

@[simp]
theorem eq_iff_iff {p q : Prop} :
p = q (p q)

@[simp]
theorem imp_self {a : Prop} :
a → a true

@[nolint]
theorem imp_intro {α β : Prop} :
α → β → α

theorem imp_false {a : Prop} :
a → false ¬a

theorem imp_and_distrib {b c : Prop} {α : Sort u_1} :
α → b c (α → b) (α → c)

@[simp]
theorem and_imp {a b c : Prop} :
a b → c a → b → c

theorem iff_def {a b : Prop} :
a b (a → b) (b → a)

theorem iff_def' {a b : Prop} :
a b (b → a) (a → b)

theorem imp_true_iff {α : Sort u_1} :
α → true true

@[simp]
theorem imp_iff_right {a b : Prop} :
a → (a → b b)

Declarations about not

def not.elim {a : Prop} {α : Sort u_1} :
¬a → a → α

Ex falso for negation. From ¬ a and a anything follows. This is the same as absurd with the arguments flipped, but it is in the not namespace so that projection notation can be used.

Equations
theorem not.imp {a b : Prop} :
¬b → (a → b)¬a

theorem not_not_of_not_imp {a b : Prop} :
¬(a → b)¬¬a

theorem not_of_not_imp {b a : Prop} :
¬(a → b)¬b

@[nolint]
theorem dec_em (p : Prop) [decidable p] :
p ¬p

theorem em (p : Prop) :
p ¬p

theorem or_not {p : Prop} :
p ¬p

theorem by_contradiction {p : Prop} :
(¬p → false) → p

theorem by_contra {p : Prop} :
(¬p → false) → p

theorem decidable.not_not {a : Prop} [decidable a] :

@[simp]
theorem not_not {a : Prop} :

The Double Negation Theorem: ¬ ¬ P is equivalent to P. The left-to-right direction, double negation elimination (DNE), is classically true but not constructively.

theorem of_not_not {a : Prop} :
¬¬a → a

theorem decidable.of_not_imp {a b : Prop} [decidable a] :
¬(a → b) → a

theorem of_not_imp {a b : Prop} :
¬(a → b) → a

theorem decidable.not_imp_symm {a b : Prop} [decidable a] :
(¬a → b)¬b → a

@[nolint]
theorem not.decidable_imp_symm {a b : Prop} [decidable a] :
(¬a → b)¬b → a

theorem not.imp_symm {a b : Prop} :
(¬a → b)¬b → a

theorem decidable.not_imp_comm {a b : Prop} [decidable a] [decidable b] :
¬a → b ¬b → a

theorem not_imp_comm {a b : Prop} :
¬a → b ¬b → a

theorem imp.swap {a b c : Prop} :
a → b → c b → a → c

theorem imp_not_comm {a b : Prop} :
a → ¬b b → ¬a

Declarations about and

theorem not_and_of_not_left {a : Prop} (b : Prop) :
¬a → ¬(a b)

theorem not_and_of_not_right (a : Prop) {b : Prop} :
¬b → ¬(a b)

theorem and.imp_left {a b c : Prop} :
(a → b)a cb c

theorem and.imp_right {a b c : Prop} :
(a → b)c ac b

theorem and.right_comm {a b c : Prop} :
(a b) c (a c) b

theorem and.rotate {a b c : Prop} :
a b c b c a

theorem and_not_self_iff (a : Prop) :

theorem not_and_self_iff (a : Prop) :

theorem and_iff_left_of_imp {a b : Prop} :
(a → b)(a b a)

theorem and_iff_right_of_imp {a b : Prop} :
(b → a)(a b b)

@[simp]
theorem and_iff_left_iff_imp {a b : Prop} :
a b a a → b

@[simp]
theorem and_iff_right_iff_imp {a b : Prop} :
a b b b → a

theorem and.congr_right_iff {a b c : Prop} :
a b a c a → (b c)

@[simp]
theorem and_self_left {a b : Prop} :
a a b a b

@[simp]
theorem and_self_right {a b : Prop} :
(a b) b a b

Declarations about or

theorem or.right_comm {a b c : Prop} :
(a b) c (a c) b

theorem or_of_or_of_imp_of_imp {a b c d : Prop} :
a b(a → c)(b → d)c d

theorem or_of_or_of_imp_left {a b c : Prop} :
a c(a → b)b c

theorem or_of_or_of_imp_right {a b c : Prop} :
c a(a → b)c b

theorem or.elim3 {a b c d : Prop} :
a b c(a → d)(b → d)(c → d) → d

theorem or_imp_distrib {a b c : Prop} :
a b → c (a → c) (b → c)

theorem decidable.or_iff_not_imp_left {a b : Prop} [decidable a] :
a b ¬a → b

theorem or_iff_not_imp_left {a b : Prop} :
a b ¬a → b

theorem decidable.or_iff_not_imp_right {a b : Prop} [decidable b] :
a b ¬b → a

theorem or_iff_not_imp_right {a b : Prop} :
a b ¬b → a

theorem decidable.not_imp_not {a b : Prop} [decidable a] :
¬a → ¬b b → a

theorem not_imp_not {a b : Prop} :
¬a → ¬b b → a

Declarations about distributivity

theorem and_or_distrib_left {a b c : Prop} :
a (b c) a b a c

distributes over (on the left).

theorem or_and_distrib_right {a b c : Prop} :
(a b) c a c b c

distributes over (on the right).

theorem or_and_distrib_left {a b c : Prop} :
a b c (a b) (a c)

distributes over (on the left).

theorem and_or_distrib_right {a b c : Prop} :
a b c (a c) (b c)

distributes over (on the right).

@[simp]
theorem or_self_left {a b : Prop} :
a a b a b

@[simp]
theorem or_self_right {a b : Prop} :
(a b) b a b

Declarations about iff

theorem iff_of_true {a b : Prop} :
a → b → (a b)

theorem iff_of_false {a b : Prop} :
¬a → ¬b → (a b)

theorem iff_true_left {a b : Prop} :
a → (a b b)

theorem iff_true_right {a b : Prop} :
a → (b a b)

theorem iff_false_left {a b : Prop} :
¬a → (a b ¬b)

theorem iff_false_right {a b : Prop} :
¬a → (b a ¬b)

theorem decidable.not_or_of_imp {a b : Prop} [decidable a] :
(a → b)¬a b

theorem not_or_of_imp {a b : Prop} :
(a → b)¬a b

theorem decidable.imp_iff_not_or {a b : Prop} [decidable a] :
a → b ¬a b

theorem imp_iff_not_or {a b : Prop} :
a → b ¬a b

theorem decidable.imp_or_distrib {a b c : Prop} [decidable a] :
a → b c (a → b) (a → c)

theorem imp_or_distrib {a b c : Prop} :
a → b c (a → b) (a → c)

theorem decidable.imp_or_distrib' {a b c : Prop} [decidable b] :
a → b c (a → b) (a → c)

theorem imp_or_distrib' {a b c : Prop} :
a → b c (a → b) (a → c)

theorem not_imp_of_and_not {a b : Prop} :
a ¬b¬(a → b)

theorem decidable.not_imp {a b : Prop} [decidable a] :
¬(a → b) a ¬b

theorem not_imp {a b : Prop} :
¬(a → b) a ¬b

theorem imp_imp_imp {a b c d : Prop} :
(c → a)(b → d)(a → b)c → d

theorem decidable.peirce (a b : Prop) [decidable a] :
((a → b) → a) → a

theorem peirce (a b : Prop) :
((a → b) → a) → a

theorem peirce' {a : Prop} :
(∀ (b : Prop), (a → b) → a) → a

theorem decidable.not_iff_not {a b : Prop} [decidable a] [decidable b] :
¬a ¬b (a b)

theorem not_iff_not {a b : Prop} :
¬a ¬b (a b)

theorem decidable.not_iff_comm {a b : Prop} [decidable a] [decidable b] :
¬a b (¬b a)

theorem not_iff_comm {a b : Prop} :
¬a b (¬b a)

theorem decidable.not_iff {a b : Prop} [decidable b] :
¬(a b) (¬a b)

theorem not_iff {a b : Prop} :
¬(a b) (¬a b)

theorem decidable.iff_not_comm {a b : Prop} [decidable a] [decidable b] :
a ¬b (b ¬a)

theorem iff_not_comm {a b : Prop} :
a ¬b (b ¬a)

theorem decidable.iff_iff_and_or_not_and_not {a b : Prop} [decidable b] :
a b a b ¬a ¬b

theorem iff_iff_and_or_not_and_not {a b : Prop} :
a b a b ¬a ¬b

theorem decidable.iff_iff_not_or_and_or_not {a b : Prop} [decidable a] [decidable b] :
a b (¬a b) (a ¬b)

theorem iff_iff_not_or_and_or_not {a b : Prop} :
a b (¬a b) (a ¬b)

theorem decidable.not_and_not_right {a b : Prop} [decidable b] :
¬(a ¬b) a → b

theorem not_and_not_right {a b : Prop} :
¬(a ¬b) a → b

def decidable_of_iff {b : Prop} (a : Prop) (h : a b) [D : decidable a] :

Transfer decidability of a to decidability of b, if the propositions are equivalent. Important: this function should be used instead of rw on decidable b, because the kernel will get stuck reducing the usage of propext otherwise, and dec_trivial will not work.

Equations
def decidable_of_iff' {a : Prop} (b : Prop) (h : a b) [D : decidable b] :

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
def decidable_of_bool {a : Prop} (b : bool) :
(b a)decidable a

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

theorem not_and_of_not_or_not {a b : Prop} :
¬a ¬b¬(a b)

theorem decidable.not_and_distrib {a b : Prop} [decidable a] :
¬(a b) ¬a ¬b

theorem decidable.not_and_distrib' {a b : Prop} [decidable b] :
¬(a b) ¬a ¬b

theorem not_and_distrib {a b : Prop} :
¬(a b) ¬a ¬b

One of de Morgan's laws: the negation of a conjunction is logically equivalent to the disjunction of the negations.

@[simp]
theorem not_and {a b : Prop} :
¬(a b) a → ¬b

theorem not_and' {a b : Prop} :
¬(a b) b → ¬a

theorem not_or_distrib {a b : Prop} :
¬(a b) ¬a ¬b

One of de Morgan's laws: the negation of a disjunction is logically equivalent to the conjunction of the negations.

theorem decidable.or_iff_not_and_not {a b : Prop} [decidable a] [decidable b] :
a b ¬(¬a ¬b)

theorem or_iff_not_and_not {a b : Prop} :
a b ¬(¬a ¬b)

theorem decidable.and_iff_not_or_not {a b : Prop} [decidable a] [decidable b] :
a b ¬(¬a ¬b)

theorem and_iff_not_or_not {a b : Prop} :
a b ¬(¬a ¬b)

Declarations about equality

@[simp]
theorem heq_iff_eq {α : Sort u_1} {a b : α} :
a == b a = b

theorem proof_irrel_heq {p q : Prop} (hp : p) (hq : q) :
hp == hq

theorem ne_of_mem_of_not_mem {α : out_param (Type u_1)} {β : Type u_2} [has_mem α β] {s : β} {a b : α} :
a sb sa b

theorem eq_equivalence {α : Sort u_1} :

@[simp]
theorem eq_rec_constant {α : Sort u_1} {a a' : α} {β : Sort u_2} (y : β) (h : a = a') :
eq.rec y h = y

Transport through trivial families is the identity.

@[simp]
theorem eq_mp_rfl {α : Sort u_1} {a : α} :
_.mp a = a

@[simp]
theorem eq_mpr_rfl {α : Sort u_1} {a : α} :
_.mpr a = a

theorem heq_of_eq_mp {α β : Sort u_1} {a : α} {a' : β} (e : α = β) :
e.mp a = a'a == a'

theorem rec_heq_of_heq {α : Sort u_1} {a b : α} {β : Sort u_2} {C : α → Sort u_2} {x : C a} {y : β} (eq : a = b) :
x == y_root_.eq.rec x eq == y

@[simp]
theorem eq_mpr_heq {α β : Sort u} (h : β = α) (x : α) :
h.mpr x == x

theorem eq.congr {α : Sort u_1} {x₁ x₂ y₁ y₂ : α} :
x₁ = y₁x₂ = y₂(x₁ = x₂ y₁ = y₂)

theorem eq.congr_left {α : Sort u_1} {x y z : α} :
x = y(x = z y = z)

theorem eq.congr_right {α : Sort u_1} {x y z : α} :
x = y(z = x z = y)

theorem congr_arg2 {α : Type u_1} {β : Type u_2} {γ : Type u_3} (f : α → β → γ) {x x' : α} {y y' : β} :
x = x'y = y'f x y = f x' y'

Declarations about quantifiers

theorem forall_imp {α : Sort u_1} {p q : α → Prop} (h : ∀ (a : α), p aq a) (a : ∀ (a : α), p a) (a_1 : α) :
q a_1

theorem Exists.imp {α : Sort u_1} {q p : α → Prop} :
(∀ (a : α), p aq a)(∃ (a : α), p a)(∃ (a : α), q a)

theorem exists_imp_exists' {α : Sort u_1} {β : Sort u_2} {p : α → Prop} {q : β → Prop} (f : α → β) :
(∀ (a : α), p aq (f a))(∃ (a : α), p a)(∃ (b : β), q b)

theorem forall_swap {α : Sort u_1} {β : Sort u_2} {p : α → β → Prop} :
(∀ (x : α) (y : β), p x y) ∀ (y : β) (x : α), p x y

theorem exists_swap {α : Sort u_1} {β : Sort u_2} {p : α → β → Prop} :
(∃ (x : α) (y : β), p x y) ∃ (y : β) (x : α), p x y

@[simp]
theorem exists_imp_distrib {α : Sort u_1} {p : α → Prop} {b : Prop} :
(∃ (x : α), p x) → b ∀ (x : α), p x → b

def Exists.some {α : Sort u_1} {p : α → Prop} :
(∃ (a : α), p a) → α

Extract an element from a existential statement, using classical.some.

Equations
theorem Exists.some_spec {α : Sort u_1} {p : α → Prop} (P : ∃ (a : α), p a) :
p P.some

Show that an element extracted from P : ∃ a, p a using P.some satisfies p.

theorem not_exists_of_forall_not {α : Sort u_1} {p : α → Prop} :
(∀ (x : α), ¬p x)(¬∃ (x : α), p x)

@[simp]
theorem not_exists {α : Sort u_1} {p : α → Prop} :
(¬∃ (x : α), p x) ∀ (x : α), ¬p x

theorem not_forall_of_exists_not {α : Sort u_1} {p : α → Prop} :
(∃ (x : α), ¬p x)(¬∀ (x : α), p x)

theorem decidable.not_forall {α : Sort u_1} {p : α → Prop} [decidable (∃ (x : α), ¬p x)] [Π (x : α), decidable (p x)] :
(¬∀ (x : α), p x) ∃ (x : α), ¬p x

@[simp]
theorem not_forall {α : Sort u_1} {p : α → Prop} :
(¬∀ (x : α), p x) ∃ (x : α), ¬p x

theorem decidable.not_forall_not {α : Sort u_1} {p : α → Prop} [decidable (∃ (x : α), p x)] :
(¬∀ (x : α), ¬p x) ∃ (x : α), p x

theorem not_forall_not {α : Sort u_1} {p : α → Prop} :
(¬∀ (x : α), ¬p x) ∃ (x : α), p x

theorem decidable.not_exists_not {α : Sort u_1} {p : α → Prop} [Π (x : α), decidable (p x)] :
(¬∃ (x : α), ¬p x) ∀ (x : α), p x

@[simp]
theorem not_exists_not {α : Sort u_1} {p : α → Prop} :
(¬∃ (x : α), ¬p x) ∀ (x : α), p x

@[simp]
theorem forall_true_iff {α : Sort u_1} :
α → true true

theorem forall_true_iff' {α : Sort u_1} {p : α → Prop} :
(∀ (a : α), p a true)((∀ (a : α), p a) true)

@[simp]
theorem forall_2_true_iff {α : Sort u_1} {β : α → Sort u_2} :
(∀ (a : α), β atrue) true

@[simp]
theorem forall_3_true_iff {α : Sort u_1} {β : α → Sort u_2} {γ : Π (a : α), β aSort u_3} :
(∀ (a : α) (b : β a), γ a btrue) true

@[simp]
theorem forall_const {b : Prop} (α : Sort u_1) [i : nonempty α] :
α → b b

@[simp]
theorem exists_const {b : Prop} (α : Sort u_1) [i : nonempty α] :
(∃ (x : α), b) b

theorem forall_and_distrib {α : Sort u_1} {p q : α → Prop} :
(∀ (x : α), p x q x) (∀ (x : α), p x) ∀ (x : α), q x

theorem exists_or_distrib {α : Sort u_1} {p q : α → Prop} :
(∃ (x : α), p x q x) (∃ (x : α), p x) ∃ (x : α), q x

@[simp]
theorem exists_and_distrib_left {α : Sort u_1} {q : Prop} {p : α → Prop} :
(∃ (x : α), q p x) q ∃ (x : α), p x

@[simp]
theorem exists_and_distrib_right {α : Sort u_1} {q : Prop} {p : α → Prop} :
(∃ (x : α), p x q) (∃ (x : α), p x) q

@[simp]
theorem forall_eq {α : Sort u_1} {p : α → Prop} {a' : α} :
(∀ (a : α), a = a'p a) p a'

@[simp]
theorem forall_eq' {α : Sort u_1} {p : α → Prop} {a' : α} :
(∀ (a : α), a' = ap a) p a'

@[simp]
theorem forall_eq_or_imp {α : Sort u_1} {p q : α → Prop} {a' : α} :
(∀ (a : α), a = a' q ap a) p a' ∀ (a : α), q ap a

@[simp]
theorem exists_eq {α : Sort u_1} {a' : α} :
∃ (a : α), a = a'

@[simp]
theorem exists_eq' {α : Sort u_1} {a' : α} :
∃ (a : α), a' = a

@[simp]
theorem exists_eq_left {α : Sort u_1} {p : α → Prop} {a' : α} :
(∃ (a : α), a = a' p a) p a'

@[simp]
theorem exists_eq_right {α : Sort u_1} {p : α → Prop} {a' : α} :
(∃ (a : α), p a a = a') p a'

@[simp]
theorem exists_apply_eq_apply {α : Type u_1} {β : Type u_2} (f : α → β) (a' : α) :
∃ (a : α), f a = f a'

@[simp]
theorem exists_apply_eq_apply' {α : Type u_1} {β : Type u_2} (f : α → β) (a' : α) :
∃ (a : α), f a' = f a

@[simp]
theorem exists_exists_and_eq_and {α : Sort u_1} {β : Sort u_2} {f : α → β} {p : α → Prop} {q : β → Prop} :
(∃ (b : β), (∃ (a : α), p a f a = b) q b) ∃ (a : α), p a q (f a)

@[simp]
theorem exists_exists_eq_and {α : Sort u_1} {β : Sort u_2} {f : α → β} {p : β → Prop} :
(∃ (b : β), (∃ (a : α), f a = b) p b) ∃ (a : α), p (f a)

@[simp]
theorem forall_apply_eq_imp_iff {α : Sort u_1} {β : Sort u_2} {f : α → β} {p : β → Prop} :
(∀ (a : α) (b : β), f a = bp b) ∀ (a : α), p (f a)

@[simp]
theorem forall_apply_eq_imp_iff' {α : Sort u_1} {β : Sort u_2} {f : α → β} {p : β → Prop} :
(∀ (b : β) (a : α), f a = bp b) ∀ (a : α), p (f a)

@[simp]
theorem forall_eq_apply_imp_iff {α : Sort u_1} {β : Sort u_2} {f : α → β} {p : β → Prop} :
(∀ (a : α) (b : β), b = f ap b) ∀ (a : α), p (f a)

@[simp]
theorem forall_eq_apply_imp_iff' {α : Sort u_1} {β : Sort u_2} {f : α → β} {p : β → Prop} :
(∀ (b : β) (a : α), b = f ap b) ∀ (a : α), p (f a)

@[simp]
theorem exists_eq_left' {α : Sort u_1} {p : α → Prop} {a' : α} :
(∃ (a : α), a' = a p a) p a'

@[simp]
theorem exists_eq_right' {α : Sort u_1} {p : α → Prop} {a' : α} :
(∃ (a : α), p a a' = a) p a'

theorem exists_comm {α : Sort u_1} {β : Sort u_2} {p : α → β → Prop} :
(∃ (a : α) (b : β), p a b) ∃ (b : β) (a : α), p a b

theorem forall_or_of_or_forall {α : Sort u_1} {p : α → Prop} {b : Prop} (h : b ∀ (x : α), p x) (x : α) :
b p x

theorem decidable.forall_or_distrib_left {α : Sort u_1} {q : Prop} {p : α → Prop} [decidable q] :
(∀ (x : α), q p x) q ∀ (x : α), p x

theorem forall_or_distrib_left {α : Sort u_1} {q : Prop} {p : α → Prop} :
(∀ (x : α), q p x) q ∀ (x : α), p x

theorem decidable.forall_or_distrib_right {α : Sort u_1} {q : Prop} {p : α → Prop} [decidable q] :
(∀ (x : α), p x q) (∀ (x : α), p x) q

theorem forall_or_distrib_right {α : Sort u_1} {q : Prop} {p : α → Prop} :
(∀ (x : α), p x q) (∀ (x : α), p x) q

theorem forall_iff_forall_surj {α : Type u_1} {β : Type u_2} {f : α → β} (h : function.surjective f) {P : β → Prop} :
(∀ (a : α), P (f a)) ∀ (b : β), P b

A predicate holds everywhere on the image of a surjective functions iff it holds everywhere.

@[simp]
theorem exists_prop {p q : Prop} :
(∃ (h : p), q) p q

@[simp]
theorem exists_false {α : Sort u_1} :
¬∃ (a : α), false

theorem Exists.fst {b : Prop} {p : b → Prop} :
Exists p → b

theorem Exists.snd {b : Prop} {p : b → Prop} (h : Exists p) :
p _

@[simp]
theorem forall_prop_of_true {p : Prop} {q : p → Prop} (h : p) :
(∀ (h' : p), q h') q h

@[simp]
theorem exists_prop_of_true {p : Prop} {q : p → Prop} (h : p) :
(∃ (h' : p), q h') q h

@[simp]
theorem forall_prop_of_false {p : Prop} {q : p → Prop} :
¬p → ((∀ (h' : p), q h') true)

@[simp]
theorem exists_prop_of_false {p : Prop} {q : p → Prop} :
¬p → (¬∃ (h' : p), q h')

theorem exists_unique.exists {α : Sort u_1} {p : α → Prop} :
(∃! (x : α), p x)(∃ (x : α), p x)

theorem exists_unique.unique {α : Sort u_1} {p : α → Prop} (h : ∃! (x : α), p x) {y₁ y₂ : α} :
p y₁p y₂y₁ = y₂

@[simp]
theorem exists_unique_iff_exists {α : Sort u_1} [subsingleton α] {p : α → Prop} :
(∃! (x : α), p x) ∃ (x : α), p x

theorem exists_unique.elim2 {α : Sort u_1} {p : α → Sort u_2} [∀ (x : α), subsingleton (p x)] {q : Π (x : α), p x → Prop} {b : Prop} :
(∃! (x : α) (h : p x), q x h)(∀ (x : α) (h : p x), q x h(∀ (y : α) (hy : p y), q y hyy = x) → b) → b

theorem exists_unique.intro2 {α : Sort u_1} {p : α → Sort u_2} [∀ (x : α), subsingleton (p x)] {q : Π (x : α), p x → Prop} (w : α) (hp : p w) :
q w hp(∀ (y : α) (hy : p y), q y hyy = w)(∃! (x : α) (hx : p x), q x hx)

theorem exists_unique.exists2 {α : Sort u_1} {p : α → Sort u_2} {q : Π (x : α), p x → Prop} :
(∃! (x : α) (hx : p x), q x hx)(∃ (x : α) (hx : p x), q x hx)

theorem exists_unique.unique2 {α : Sort u_1} {p : α → Sort u_2} [∀ (x : α), subsingleton (p x)] {q : Π (x : α), p x → Prop} (h : ∃! (x : α) (hx : p x), q x hx) {y₁ y₂ : α} (hpy₁ : p y₁) (hqy₁ : q y₁ hpy₁) (hpy₂ : p y₂) :
q y₂ hpy₂y₁ = y₂

Classical lemmas

theorem classical.cases {p : Prop → Prop} (h1 : p true) (h2 : p false) (a : Prop) :
p a

@[nolint]
theorem classical.dec (p : Prop) :

@[nolint]
theorem classical.dec_pred {α : Sort u_1} (p : α → Prop) :

@[nolint]
theorem classical.dec_rel {α : Sort u_1} (p : α → α → Prop) :

@[nolint]
theorem classical.dec_eq (α : Sort u_1) :

def classical.exists_cases {α : Sort u_1} {p : α → Prop} {C : Sort u} :
C → (Π (a : α), p a → C) → C

Construct a function from a default value H0, and a function to use if there exists a value satisfying the predicate.

Equations
theorem classical.some_spec2 {α : Sort u_1} {p : α → Prop} {h : ∃ (a : α), p a} (q : α → Prop) :
(∀ (a : α), p aq a)q (classical.some h)

def classical.subtype_of_exists {α : Type u_1} {P : α → Prop} :
(∃ (x : α), P x){x // P x}

A version of classical.indefinite_description which is definitionally equal to a pair

Equations
def exists.classical_rec_on {α : Sort u_1} {p : α → Prop} (h : ∃ (a : α), p a) {C : Sort u} :
(Π (a : α), p a → C) → C

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

Declarations about bounded quantifiers

theorem bex_def {α : Sort u_1} {p q : α → Prop} :
(∃ (x : α) (h : p x), q x) ∃ (x : α), p x q x

theorem bex.elim {α : Sort u_1} {p : α → Prop} {P : Π (x : α), p x → Prop} {b : Prop} :
(∃ (x : α) (h : p x), P x h)(∀ (a : α) (h : p a), P a h → b) → b

theorem bex.intro {α : Sort u_1} {p : α → Prop} {P : Π (x : α), p x → Prop} (a : α) (h₁ : p a) :
P a h₁(∃ (x : α) (h : p x), P x h)

theorem ball_congr {α : Sort u_1} {p : α → Prop} {P Q : Π (x : α), p x → Prop} :
(∀ (x : α) (h : p x), P x h Q x h)((∀ (x : α) (h : p x), P x h) ∀ (x : α) (h : p x), Q x h)

theorem bex_congr {α : Sort u_1} {p : α → Prop} {P Q : Π (x : α), p x → Prop} :
(∀ (x : α) (h : p x), P x h Q x h)((∃ (x : α) (h : p x), P x h) ∃ (x : α) (h : p x), Q x h)

theorem ball.imp_right {α : Sort u_1} {p : α → Prop} {P Q : Π (x : α), p x → Prop} (H : ∀ (x : α) (h : p x), P x hQ x h) (h₁ : ∀ (x : α) (h : p x), P x h) (x : α) (h : p x) :
Q x h

theorem bex.imp_right {α : Sort u_1} {p : α → Prop} {P Q : Π (x : α), p x → Prop} :
(∀ (x : α) (h : p x), P x hQ x h)(∃ (x : α) (h : p x), P x h)(∃ (x : α) (h : p x), Q x h)

theorem ball.imp_left {α : Sort u_1} {r p q : α → Prop} (H : ∀ (x : α), p xq x) (h₁ : ∀ (x : α), q xr x) (x : α) :
p xr x

theorem bex.imp_left {α : Sort u_1} {r p q : α → Prop} :
(∀ (x : α), p xq x)(∃ (x : α) (_x : p x), r x)(∃ (x : α) (_x : q x), r x)

theorem ball_of_forall {α : Sort u_1} {p : α → Prop} (h : ∀ (x : α), p x) (x : α) :
p x

theorem forall_of_ball {α : Sort u_1} {p q : α → Prop} (H : ∀ (x : α), p x) (h : ∀ (x : α), p xq x) (x : α) :
q x

theorem bex_of_exists {α : Sort u_1} {p q : α → Prop} :
(∀ (x : α), p x)(∃ (x : α), q x)(∃ (x : α) (_x : p x), q x)

theorem exists_of_bex {α : Sort u_1} {p q : α → Prop} :
(∃ (x : α) (_x : p x), q x)(∃ (x : α), q x)

@[simp]
theorem bex_imp_distrib {α : Sort u_1} {p : α → Prop} {P : Π (x : α), p x → Prop} {b : Prop} :
(∃ (x : α) (h : p x), P x h) → b ∀ (x : α) (h : p x), P x h → b

theorem not_bex {α : Sort u_1} {p : α → Prop} {P : Π (x : α), p x → Prop} :
(¬∃ (x : α) (h : p x), P x h) ∀ (x : α) (h : p x), ¬P x h

theorem not_ball_of_bex_not {α : Sort u_1} {p : α → Prop} {P : Π (x : α), p x → Prop} :
(∃ (x : α) (h : p x), ¬P x h)(¬∀ (x : α) (h : p x), P x h)

theorem decidable.not_ball {α : Sort u_1} {p : α → Prop} {P : Π (x : α), p x → Prop} [decidable (∃ (x : α) (h : p x), ¬P x h)] [Π (x : α) (h : p x), decidable (P x h)] :
(¬∀ (x : α) (h : p x), P x h) ∃ (x : α) (h : p x), ¬P x h

theorem not_ball {α : Sort u_1} {p : α → Prop} {P : Π (x : α), p x → Prop} :
(¬∀ (x : α) (h : p x), P x h) ∃ (x : α) (h : p x), ¬P x h

theorem ball_true_iff {α : Sort u_1} (p : α → Prop) :
(∀ (x : α), p xtrue) true

theorem ball_and_distrib {α : Sort u_1} {p : α → Prop} {P Q : Π (x : α), p x → Prop} :
(∀ (x : α) (h : p x), P x h Q x h) (∀ (x : α) (h : p x), P x h) ∀ (x : α) (h : p x), Q x h

theorem bex_or_distrib {α : Sort u_1} {p : α → Prop} {P Q : Π (x : α), p x → Prop} :
(∃ (x : α) (h : p x), P x h Q x h) (∃ (x : α) (h : p x), P x h) ∃ (x : α) (h : p x), Q x h

theorem classical.not_ball {α : Sort u_1} {p : α → Prop} {P : Π (x : α), p x → Prop} :
(¬∀ (x : α) (h : p x), P x h) ∃ (x : α) (h : p x), ¬P x h

theorem ite_eq_iff {α : Sort u_1} {p : Prop} [decidable p] {a b c : α} :
ite p a b = c p a = c ¬p b = c

Declarations about nonempty

@[instance]
def has_zero.nonempty {α : Type u} [has_zero α] :

@[instance]
def has_one.nonempty {α : Type u} [has_one α] :

theorem exists_true_iff_nonempty {α : Sort u_1} :
(∃ (a : α), true) nonempty α

@[simp]
theorem nonempty_Prop {p : Prop} :

theorem not_nonempty_iff_imp_false {α : Type u} :
¬nonempty α α → false

@[simp]
theorem nonempty_sigma {α : Type u} {γ : α → Type w} :
nonempty (Σ (a : α), γ a) ∃ (a : α), nonempty (γ a)

@[simp]
theorem nonempty_subtype {α : Sort u} {p : α → Prop} :
nonempty (subtype p) ∃ (a : α), p a

@[simp]
theorem nonempty_prod {α : Type u} {β : Type v} :

@[simp]
theorem nonempty_pprod {α : Sort u} {β : Sort v} :

@[simp]
theorem nonempty_sum {α : Type u} {β : Type v} :

@[simp]
theorem nonempty_psum {α : Sort u} {β : Sort v} :

@[simp]
theorem nonempty_psigma {α : Sort u} {β : α → Sort v} :
nonempty (psigma β) ∃ (a : α), nonempty (β a)

@[simp]

@[simp]
theorem nonempty_ulift {α : Type u} :

@[simp]
theorem nonempty_plift {α : Sort u} :

@[simp]
theorem nonempty.forall {α : Sort u} {p : nonempty α → Prop} :
(∀ (h : nonempty α), p h) ∀ (a : α), p _

@[simp]
theorem nonempty.exists {α : Sort u} {p : nonempty α → Prop} :
(∃ (h : nonempty α), p h) ∃ (a : α), p _

theorem classical.nonempty_pi {α : Sort u} {β : α → Sort v} :
nonempty (Π (a : α), β a) ∀ (a : α), nonempty (β a)

def classical.inhabited_of_nonempty' {α : Sort u} [h : nonempty α] :

Using classical.choice, lifts a (Prop-valued) nonempty instance to a (Type-valued) inhabited instance. classical.inhabited_of_nonempty already exists, in core/init/classical.lean, but the assumption is not a type class argument, which makes it unsuitable for some applications.

Equations
def nonempty.some {α : Sort u} :
nonempty α → α

Using classical.choice, extracts a term from a nonempty type.

Equations
def classical.arbitrary (α : Sort u) [h : nonempty α] :
α

Using classical.choice, extracts a term from a nonempty type.

Equations
theorem nonempty.map {α : Sort u} {β : Sort v} :
(α → β)nonempty αnonempty β

Given f : α → β, if α is nonempty then β is also nonempty. nonempty cannot be a functor, because functor is restricted to Type.

theorem nonempty.map2 {α : Sort u_1} {β : Sort u_2} {γ : Sort u_3} :
(α → β → γ)nonempty αnonempty βnonempty γ

theorem nonempty.congr {α : Sort u} {β : Sort v} :
(α → β)(β → α)(nonempty α nonempty β)

theorem nonempty.elim_to_inhabited {α : Sort u_1} [h : nonempty α] {p : Prop} :
(inhabited α → p) → p

@[instance]
def prod.nonempty {α : Type u_1} {β : Type u_2} [h : nonempty α] [h2 : nonempty β] :
nonempty × β)

theorem apply_dite {α : Sort u_1} {β : Sort u_2} (f : α → β) (P : Prop) [decidable P] (x : P → α) (y : ¬P → α) :
f (dite P x y) = dite P (λ (h : P), f (x h)) (λ (h : ¬P), f (y h))

A function applied to a dite is a dite of that function applied to each of the branches.

theorem apply_ite {α : Sort u_1} {β : Sort u_2} (f : α → β) (P : Prop) [decidable P] (x y : α) :
f (ite P x y) = ite P (f x) (f y)

A function applied to a ite is a ite of that function applied to each of the branches.

theorem apply_dite2 {α : Sort u_1} {β : Sort u_2} {γ : Sort u_3} (f : α → β → γ) (P : Prop) [decidable P] (a : P → α) (b : ¬P → α) (c : P → β) (d : ¬P → β) :
f (dite P a b) (dite P c d) = dite P (λ (h : P), f (a h) (c h)) (λ (h : ¬P), f (b h) (d h))

A two-argument function applied to two dites is a dite of that two-argument function applied to each of the branches.

theorem apply_ite2 {α : Sort u_1} {β : Sort u_2} {γ : Sort u_3} (f : α → β → γ) (P : Prop) [decidable P] (a b : α) (c d : β) :
f (ite P a b) (ite P c d) = ite P (f a c) (f b d)

A two-argument function applied to two ites is a ite of that two-argument function applied to each of the branches.

theorem dite_apply {α : Sort u_1} {β : α → Sort u_2} (P : Prop) [decidable P] (f : P → Π (a : α), β a) (g : ¬P → Π (a : α), β a) (x : α) :
dite P f g x = dite P (λ (h : P), f h x) (λ (h : ¬P), g h x)

A 'dite' producing a Pi type Π a, β a, applied to a value x : α is a dite that applies either branch to x.

theorem ite_apply {α : Sort u_1} {β : α → Sort u_2} (P : Prop) [decidable P] (f g : Π (a : α), β a) (x : α) :
ite P f g x = ite P (f x) (g x)

A 'ite' producing a Pi type Π a, β a, applied to a value x : α is a ite that applies either branch to x

@[simp]
theorem dite_not {α : Sort u_1} (P : Prop) [decidable P] (x : ¬P → α) (y : ¬¬P → α) :
dite (¬P) x y = dite P (λ (h : P), y _) x

Negation of the condition P : Prop in a dite is the same as swapping the branches.

@[simp]
theorem ite_not {α : Sort u_1} (P : Prop) [decidable P] (x y : α) :
ite (¬P) x y = ite P y x

Negation of the condition P : Prop in a ite is the same as swapping the branches.

theorem ite_and {α : Sort u_1} {p q : Prop} [decidable p] [decidable q] {x y : α} :
ite (p q) x y = ite p (ite q x y) y