tp_lean/quantifiers_and_equality.lean

148 lines
3.7 KiB
Text
Raw Normal View History

--
-- 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))