Quantifiers, negation laws, quantifier order, and sets as predicates in Lean
Christiano Braga · Mestrado em Sistemas e Computação · IME
Based on How To Prove It with Lean (HTPIwL), chapters 2 and 3.
A predicate on a type α assigns a proposition to each element, so in Lean it is a function α → Prop.
fun n => n > 3 : Nat → Prop#check fun n : Nat => n > 3
fun n => n > 3 : Nat → PropQuantifiers bind the variable of a predicate and produce a proposition (Frege, 1879). The variable ranges over a type, inferred when the context determines it.
Symbol | Name | Reading |
|---|---|---|
∀ x, P x | universal quantifier | P x holds for every x |
∃ x, P x | existential quantifier | P x holds for some x |
∃ n, n > 3 : Prop#check ∃ n : Nat, n > 3
∀ (n : Nat), n > 3 : Prop#check ∀ n : Nat, n > 3
∃ n, n > 3 : Prop∀ (n : Nat), n > 3 : Prop
A quantifier takes the predicate, of type Nat → Prop, to a proposition, of type Prop.
Introduce ∀ x, P x by considering an arbitrary element: intro, the same tactic that introduces implications.
Eliminate it by instantiation. A universal hypothesis is a function, so h a instantiates it at a; specialize does it in place.
example (α : Type) (P Q : α → Prop)
(h : ∀ x, P x ∧ Q x) : ∀ x, P x := α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x ∧ Q x⊢ ∀ (x : α), P x
α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x ∧ Q xa:α⊢ P a
All goals completed! 🐙
example (α : Type) (P Q : α → Prop) (h : ∀ x, P x → Q x)
(a : α) (hPa : P a) : Q a := α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x → Q xa:αhPa:P a⊢ Q a
α:TypeP:α → PropQ:α → Propa:αh:P a → Q ahPa:P a⊢ Q a
All goals completed! 🐙
The universal quantifier distributes over conjunction. The proof combines the quantifier rules with the Lecture 1 rules for conjunction and the biconditional.
theorem forall_and_distrib (α : Type) (P Q : α → Prop) :
(∀ x, P x ∧ Q x) ↔ (∀ x, P x) ∧ (∀ x, Q x) := α:TypeP:α → PropQ:α → Prop⊢ (∀ (x : α), P x ∧ Q x) ↔ (∀ (x : α), P x) ∧ ∀ (x : α), Q x
α:TypeP:α → PropQ:α → Prop⊢ (∀ (x : α), P x ∧ Q x) → (∀ (x : α), P x) ∧ ∀ (x : α), Q xα:TypeP:α → PropQ:α → Prop⊢ ((∀ (x : α), P x) ∧ ∀ (x : α), Q x) → ∀ (x : α), P x ∧ Q x
α:TypeP:α → PropQ:α → Prop⊢ (∀ (x : α), P x ∧ Q x) → (∀ (x : α), P x) ∧ ∀ (x : α), Q x α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x ∧ Q x⊢ (∀ (x : α), P x) ∧ ∀ (x : α), Q x
α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x ∧ Q x⊢ ∀ (x : α), P xα:TypeP:α → PropQ:α → Proph:∀ (x : α), P x ∧ Q x⊢ ∀ (x : α), Q x
α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x ∧ Q x⊢ ∀ (x : α), P x α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x ∧ Q xa:α⊢ P a
All goals completed! 🐙
α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x ∧ Q x⊢ ∀ (x : α), Q x α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x ∧ Q xa:α⊢ Q a
All goals completed! 🐙
α:TypeP:α → PropQ:α → Prop⊢ ((∀ (x : α), P x) ∧ ∀ (x : α), Q x) → ∀ (x : α), P x ∧ Q x α:TypeP:α → PropQ:α → Proph:(∀ (x : α), P x) ∧ ∀ (x : α), Q xa:α⊢ P a ∧ Q a
All goals completed! 🐙
Introduce ∃ x, P x by exhibiting a witness with its proof: the anonymous constructor ⟨3, rfl⟩, or the exists tactic.
Eliminate it by naming a witness and its proof: cases (one case, constructor intro) or obtain ⟨a, ha⟩ := h in one step.
example : ∃ n : Nat, n * n = 9 := ⟨3, rfl⟩
example (α : Type) (P Q : α → Prop)
(h : ∃ x, P x ∧ Q x) : ∃ x, P x := α:TypeP:α → PropQ:α → Proph:∃ x, P x ∧ Q x⊢ ∃ x, P x
cases h with
α:TypeP:α → PropQ:α → Propa:αha:P a ∧ Q a⊢ ∃ x, P x All goals completed! 🐙
example (α : Type) (P Q : α → Prop)
(h : ∃ x, P x ∧ Q x) : ∃ x, Q x := α:TypeP:α → PropQ:α → Proph:∃ x, P x ∧ Q x⊢ ∃ x, Q x
α:TypeP:α → PropQ:α → Propa:αha:P a ∧ Q a⊢ ∃ x, Q x
All goals completed! 🐙
The theorem below combines the two quantifiers. A pointwise implication carries existence from P to Q, and the witness does not change.
theorem exists_imp_exists (α : Type) (P Q : α → Prop)
(h : ∀ x, P x → Q x) : (∃ x, P x) → ∃ x, Q x := α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x → Q x⊢ (∃ x, P x) → ∃ x, Q x
α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x → Q xhex:∃ x, P x⊢ ∃ x, Q x
α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x → Q xa:αhPa:P a⊢ ∃ x, Q x
All goals completed! 🐙
Name | Equivalence |
|---|---|
Negation of ∃ | ¬(∃ x, P x) ≡ ∀ x, ¬P x |
Negation of ∀ | ¬(∀ x, P x) ≡ ∃ x, ¬P x |
They exchange negation with the quantifiers, extending the De Morgan laws of Lecture 1.
The first law is constructive in both directions.
In the second, producing the witness needs classical reasoning, as the first De Morgan law did: two applications of Classical.byContradiction.
theorem not_exists_iff (α : Type) (P : α → Prop) :
¬(∃ x, P x) ↔ ∀ x, ¬P x := α:TypeP:α → Prop⊢ (¬∃ x, P x) ↔ ∀ (x : α), ¬P x
α:TypeP:α → Prop⊢ (¬∃ x, P x) → ∀ (x : α), ¬P xα:TypeP:α → Prop⊢ (∀ (x : α), ¬P x) → ¬∃ x, P x
α:TypeP:α → Prop⊢ (¬∃ x, P x) → ∀ (x : α), ¬P x α:TypeP:α → Proph:¬∃ x, P xa:αhPa:P a⊢ False
All goals completed! 🐙
α:TypeP:α → Prop⊢ (∀ (x : α), ¬P x) → ¬∃ x, P x α:TypeP:α → Proph:∀ (x : α), ¬P xhex:∃ x, P x⊢ False
α:TypeP:α → Proph:∀ (x : α), ¬P xa:αhPa:P a⊢ False
All goals completed! 🐙
theorem not_forall_exists (α : Type) (P : α → Prop)
(h : ¬∀ x, P x) : ∃ x, ¬P x := α:TypeP:α → Proph:¬∀ (x : α), P x⊢ ∃ x, ¬P x
α:TypeP:α → Proph:¬∀ (x : α), P x⊢ (¬∃ x, ¬P x) → False
α:TypeP:α → Proph:¬∀ (x : α), P xhne:¬∃ x, ¬P x⊢ False
α:TypeP:α → Proph:¬∀ (x : α), P xhne:¬∃ x, ¬P x⊢ ∀ (x : α), P x
α:TypeP:α → Proph:¬∀ (x : α), P xhne:¬∃ x, ¬P xa:α⊢ P a
α:TypeP:α → Proph:¬∀ (x : α), P xhne:¬∃ x, ¬P xa:α⊢ ¬P a → False
α:TypeP:α → Proph:¬∀ (x : α), P xhne:¬∃ x, ¬P xa:αhnPa:¬P a⊢ False
All goals completed! 🐙
intro accepts the anonymous constructor pattern, introducing the existential and destructing it in one step.
A negated goal is a function into False, so a proof term with a pattern-matching fun proves it, with no tactics.
Pattern intro
example (α : Type) (P : α → Prop)
(h : ∀ x, ¬P x) : ¬∃ x, P x := α:TypeP:α → Proph:∀ (x : α), ¬P x⊢ ¬∃ x, P x
α:TypeP:α → Proph:∀ (x : α), ¬P xa:αhPa:P a⊢ False
All goals completed! 🐙
Proof term
example (α : Type) (P : α → Prop)
(h : ∀ x, P x) : ¬∃ x, ¬P x :=
fun ⟨a, hnPa⟩ => hnPa (h a)
The order determines what a statement asserts.
In ∀ y, ∃ x, R x y, the witness x may depend on y; in ∃ x, ∀ y, R x y, a single witness serves every y. The uniform witness is the stronger statement.
Quantifiers of the same kind commute; the exchanges for ∀ and ∃ appeared as examples in §2.2 and §2.3.
Quantifiers of different kinds do not commute. Only one direction holds: the stronger order implies the weaker one.
theorem exists_forall_swap (α β : Type) (R : α → β → Prop)
(h : ∃ x, ∀ y, R x y) : ∀ y, ∃ x, R x y := α:Typeβ:TypeR:α → β → Proph:∃ x, ∀ (y : β), R x y⊢ ∀ (y : β), ∃ x, R x y
α:Typeβ:TypeR:α → β → Proph:∃ x, ∀ (y : β), R x yb:β⊢ ∃ x, R x b
α:Typeβ:TypeR:α → β → Propb:βa:αha:∀ (y : β), R a y⊢ ∃ x, R x b
All goals completed! 🐙
The converse fails. Over ℕ take R x y as x ≥ y. Both claims of the counterexample hold in Lean.
example : ∀ y : Nat, ∃ x : Nat, x ≥ y := ⊢ ∀ (y : Nat), ∃ x, x ≥ y
b:Nat⊢ ∃ x, x ≥ b
All goals completed! 🐙
example : ¬∃ x : Nat, ∀ y : Nat, x ≥ y := ⊢ ¬∃ x, ∀ (y : Nat), x ≥ y
a:Natha:∀ (y : Nat), a ≥ y⊢ False
All goals completed! 🐙
A set of elements of α is determined by which elements belong to it, so the membership predicate determines the set. We take this as the definition.
A set given by a property is the predicate, and a membership proof is a proof of the property.
def Set (α : Type) : Type := α → Prop
def Evens : Set Nat := fun n => ∃ k, n = 2 * k
example : (6 : Nat) ∈ Evens := ⟨3, rfl⟩
A type class declares an operation and leaves it without meaning; an instance supplies the meaning at one type. The symbol reaches our sets in three steps.
The symbol is notation from the core module Init.Notation, and it abbreviates an application. The name on its right is the one field of a class from Init.Prelude.
notation:50 a:50 " ∈ " b:50 => Membership.mem b a class Membership (α : outParam (Type u)) (γ : Type v) where mem : γ → α → Prop
The container comes first in mem and second in the notation, so x ∈ s abbreviates Membership.mem s x.
The third step is ours. The elaborator searches the registered instances for the type of s, and Set α is a definition of this lecture, so without an instance of our own the search fails.
The instances below end that search: x ∈ s is s x by definition, and ⊆, ∪ and ∩ are defined from it.
instance : Membership α (Set α) :=
⟨fun s a => s a⟩
instance : HasSubset (Set α) :=
⟨fun s t => ∀ x, x ∈ s → x ∈ t⟩
instance : Union (Set α) :=
⟨fun s t => fun x => x ∈ s ∨ x ∈ t⟩
instance : Inter (Set α) :=
⟨fun s t => fun x => x ∈ s ∧ x ∈ t⟩
Each notation unfolds to its definition
example (α : Type) (s t : Set α) (h : s ⊆ t)
(x : α) (hx : x ∈ s) : x ∈ t := h x hx
example (α : Type) (s t : Set α) (x : α)
(hx : x ∈ s) : x ∈ s ∪ t := Or.inl hx
example (α : Type) (s t : Set α) (x : α)
(hx : x ∈ s ∩ t) : x ∈ t := hx.right
Naive set theory admits a set for every property. Take R to be the set of all sets that are not elements of themselves.
Then R ∈ R holds exactly when R ∉ R, a contradiction, and the theory collapses.
In Lean, s : Set α contains only elements of α, and s itself has type Set α, not α, so s ∈ s is not well typed. There is no way to state the property that defines R, and the paradox does not arise.
B. Russell, letter to Frege, 16 June 1902.
The inclusion s ⊆ t is a universally quantified implication, so its proofs begin with intro x hx.
Membership in ∩ is a conjunction and in ∪ a disjunction; the connective rules of Lecture 1 apply. Set identities are stated as inclusions, since equality needs extensionality.
theorem inter_subset_left (α : Type) (s t : Set α) :
s ∩ t ⊆ s := α:Types:Set αt:Set α⊢ s ∩ t ⊆ s
α:Types:Set αt:Set αx:αhx:x ∈ s ∩ t⊢ x ∈ s
All goals completed! 🐙
theorem union_subset_swap (α : Type) (s t : Set α) :
s ∪ t ⊆ t ∪ s := α:Types:Set αt:Set α⊢ s ∪ t ⊆ t ∪ s
α:Types:Set αt:Set αx:αhx:x ∈ s ∪ t⊢ x ∈ t ∪ s
cases hx with
α:Types:Set αt:Set αx:αh:x ∈ s⊢ x ∈ t ∪ s All goals completed! 🐙
α:Types:Set αt:Set αx:αh:x ∈ t⊢ x ∈ t ∪ s All goals completed! 🐙
A predicate is a function α → Prop; quantifiers bind its variable and yield a proposition.
∀: introduce with intro; eliminate by instantiation, h a or specialize.
∃: introduce with a witness, ⟨3, rfl⟩ or exists; eliminate with obtain ⟨a, ha⟩ := h.
The negation laws exchange ¬ with the quantifiers; ¬∃ is constructive in both directions, ¬∀ needs Classical.byContradiction.
Quantifier order matters: the uniform witness ∃ x, ∀ y is stronger, and only (∃ x, ∀ y) → (∀ y, ∃ x) holds.
A set is its membership predicate, Set α := α → Prop, with Membership, HasSubset, Union, Inter instances giving the notation.
Inclusion proofs start with intro x hx; membership in ∩ is a conjunction and in ∪ a disjunction, pointwise.
Exercises: see the lecture notes.