tp_lean/quantifiers_and_equality.lean

147 lines
3.7 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--
-- 4. Quantifiers and Equality
--
-- The Universal Quantifier
example (α : Type) (p q : α → Prop) : (∀ x : α, p x ∧ q x) → ∀ y : α, p y :=
fun h : ∀ x : α, p x ∧ q x =>
fun y : α =>
show p y from (h y).left
variable (α : Type) (r : αα → Prop)
variable (trans_r : ∀ {x y z}, r x y → r y z → r x z)
variable (a b c : α)
variable (hab : r a b) (hbc : r b c)
#check trans_r
#check @trans_r
#check trans_r hab
#check trans_r hab hbc
-- Equality
#check Eq.refl
#check Eq.symm
#check Eq.trans
universe u
#check @Eq.refl.{u}
#check @Eq.symm.{u}
#check @Eq.trans.{u}
variable (a b c d : α)
variable (hab : a = b) (hcb : c = b) (hcd : c = d)
example : a = d :=
Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd
example : a = d := (hab.trans hcb.symm).trans hcd
variable (α β : Type)
example (f : α → β) (a : α) : (fun x => f x) a = f a := Eq.refl _
example (f : α → β) (a : α) : (fun x => f x) a = f a := rfl
example (α : Type) (a b : α) (p : α → Prop)
(h1 : a = b) (h2 : p a) : p b :=
Eq.subst h1 h2
example (α : Type) (a b : α) (p : α → Prop)
(h1 : a = b) (h2 : p a) : p b :=
h1 ▸ h2
variable (α : Type)
variable (a b : α)
variable (f g : α → Nat)
variable (h₁ : a = b)
variable (h₂ : f = g)
example : f a = f b := congrArg f h₁
example : f a = g a := congrFun h₂ a
variable (a : Nat) in
example : a + 0 = a := Nat.add_zero a
-- Calculational Proofs
variable (a b c d : Nat) in
variable (h1 : a = b) in
variable (h2 : b = c + 1) in
variable (h3 : c = d) in
variable (h4 : e = 1 + d) in
theorem T : a = e :=
calc
a = b := h1
_ = c + 1 := h2
_ = d + 1 := congrArg Nat.succ h3
_ = 1 + d := Nat.add_comm d 1
_ = e := h4.symm
-- The Existential Quantifier
example : ∃ x : Nat, x > 0 :=
have h : 1 > 0 := Nat.zero_lt_succ 0
Exists.intro 1 h
variable (α : Type) (p q : α → Prop) in
example (h : ∃ x, p x ∧ q x) : ∃ x, q x ∧ p x :=
Exists.elim h
fun w =>
fun hw : p w ∧ q w =>
Exists.intro w ⟨hw.right, hw.left⟩
#check @Exists.elim.{u}
#check Sigma
variable (α : Type) (p q : α → Prop) in
example (h : ∃ x, p x ∧ q x) : ∃ x, q x ∧ p x :=
match h with
| ⟨w, hw⟩ => ⟨w, hw.right, hw.left⟩
-- More on the Proof Language
variable (f : Nat → Nat)
variable (h : ∀ x : Nat, f x ≤ f (x + 1))
example : f 0 ≤ f 3 :=
have : f 0 ≤ f 1 := h 0
have : f 0 ≤ f 2 := Nat.le_trans (by assumption) (h 1)
show f 0 ≤ f 3 from Nat.le_trans (by assumption) (h 2)
example : f 0 ≥ f 1 → f 1 ≥ f 2 → f 0 = f 2 :=
fun _ : f 0 ≥ f 1 =>
fun _ : f 1 ≥ f 2 =>
have : f 0 ≥ f 2 := Nat.le_trans f 1 ≥ f 2 f 0 ≥ f 1
have : f 0 ≤ f 2 := Nat.le_trans (h 0) (h 1)
show f 0 = f 2 from Nat.le_antisymm this f 0 ≥ f 2
-- Exercises
variable (α : Type) (p q : α → Prop)
example : (∀ x, p x ∧ q x) ↔ (∀ x, p x) ∧ (∀ x, q x) :=
have h1 : (∀ (x : α), p x ∧ q x) → (∀ (x : α), p x) ∧ ∀ (x : α), q x :=
fun h =>
have h11 : ∀ (x : α), p x :=
fun x : α => (h x).left
have h12 : ∀ (x : α), q x :=
fun x : α => (h x).right
And.intro h11 h12
have h2 : ((∀ (x : α), p x) ∧ ∀ (x : α), q x) → ∀ (x : α), p x ∧ q x :=
fun h =>
fun x : α =>
⟨h.left x, h.right x⟩
Iff.intro h1 h2
example : (∀ x, p x → q x) → (∀ x, p x) → (∀ x, q x) :=
fun h1 =>
fun h2 =>
fun x : α =>
show q x from (h1 x) (h2 x)
example : (∀ x, p x) (∀ x, q x) → ∀ x, p x q x :=
fun h =>
h.elim
(fun hp =>
fun x => Or.inl (hp x))
(fun hq =>
fun x => Or.inr (hq x))