2.7. Worked Examples
Each example below appears two ways, as a proof term and as a tactic proof. The two present the same proof, and Lean checks both scripts when the notes are built. The quantifier rules follow the same introduction and elimination discipline as the connectives of Lecture 1, so we omit the derivation trees and let the terms mirror them. These propositions are disjoint from the examples of the earlier sections and from the exercises.
2.7.1. Contraposition under quantifiers
The witness of the failure of Q also witnesses the failure of P, since the implication at that element sends a proof of P a to a proof of Q a. The pattern in intro destructs the existential.
example (α : Type) (P Q : α → Prop)
(h : ∀ x, P x → Q x) : (∃ x, ¬Q x) → ∃ x, ¬P x :=
fun ⟨a, hnQa⟩ => ⟨a, fun hPa => hnQa (h a hPa)⟩
example (α : Type) (P Q : α → Prop)
(h : ∀ x, P x → Q x) : (∃ x, ¬Q x) → ∃ x, ¬P x := α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x → Q x⊢ (∃ x, ¬Q x) → ∃ x, ¬P x
α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x → Q xa:αhnQa:¬Q a⊢ ∃ x, ¬P x
α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x → Q xa:αhnQa:¬Q a⊢ ¬P a
α:TypeP:α → PropQ:α → Proph:∀ (x : α), P x → Q xa:αhnQa:¬Q ahPa:P a⊢ False
All goals completed! 🐙
2.7.2. A disjunction of universals
Whichever side holds, its instance at each element proves the pointwise disjunction. The term eliminates the disjunction with .elim, and the tactic proof with cases.
example (α : Type) (P Q : α → Prop) :
(∀ x, P x) ∨ (∀ x, Q x) → ∀ x, P x ∨ Q x :=
fun h a =>
h.elim (fun hp => Or.inl (hp a))
(fun hq => Or.inr (hq a))
example (α : Type) (P Q : α → Prop) :
(∀ x, P x) ∨ (∀ x, Q x) → ∀ x, P x ∨ Q x := α: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
cases h with
α:TypeP:α → PropQ:α → Propa:αhp:∀ (x : α), P x⊢ P a ∨ Q a All goals completed! 🐙
α:TypeP:α → PropQ:α → Propa:αhq:∀ (x : α), Q x⊢ P a ∨ Q a All goals completed! 🐙
2.7.3. Intersection preserves inclusion
The inclusion applies to the left part of the membership, and the right part passes through unchanged.
example (α : Type) (s t u : Set α)
(h : s ⊆ t) : s ∩ u ⊆ t ∩ u :=
fun x hx => ⟨h x hx.left, hx.right⟩
example (α : Type) (s t u : Set α)
(h : s ⊆ t) : s ∩ u ⊆ t ∩ u := α:Types:Set αt:Set αu:Set αh:s ⊆ t⊢ s ∩ u ⊆ t ∩ u
α:Types:Set αt:Set αu:Set αh:s ⊆ tx:αhx:x ∈ s ∩ u⊢ x ∈ t ∩ u
α:Types:Set αt:Set αu:Set αh:s ⊆ tx:αhx:x ∈ s ∩ u⊢ x ∈ tα:Types:Set αt:Set αu:Set αh:s ⊆ tx:αhx:x ∈ s ∩ u⊢ x ∈ u
α:Types:Set αt:Set αu:Set αh:s ⊆ tx:αhx:x ∈ s ∩ u⊢ x ∈ t All goals completed! 🐙
α:Types:Set αt:Set αu:Set αh:s ⊆ tx:αhx:x ∈ s ∩ u⊢ x ∈ u All goals completed! 🐙
2.7.4. Classical existence
The theorem not_forall_exists of the negation laws section produces a witness where ¬P fails, and Classical.byContradiction removes the double negation, as in Lecture 1.
example (α : Type) (P : α → Prop)
(h : ¬∀ x, ¬P x) : ∃ x, P x :=
(not_forall_exists α (fun x => ¬P x) h).elim
fun a hnnPa => ⟨a, Classical.byContradiction hnnPa⟩
example (α : Type) (P : α → Prop)
(h : ¬∀ x, ¬P x) : ∃ x, P x := α:TypeP:α → Proph:¬∀ (x : α), ¬P x⊢ ∃ x, P x
α:TypeP:α → Proph:¬∀ (x : α), ¬P xa:αhnnPa:¬¬P a⊢ ∃ x, P x
All goals completed! 🐙