2.4 反證法與逆否命題#
本節目標#
- 理解反證法(proof by contradiction)與逆否命題(contrapositive)的數學意義。
- 學會 Lean tactic:
by_contra、push_neg、by_cases。 - 認識經典邏輯(Classical)與直覺主義邏輯的差異:排中律的角色。
- 熟悉
not_not、absurd、Classical.byContradiction等常用引理。
數學意義#
反證法:想證 \(P\) ,就先假設 \(\lnot P\) ,推出矛盾(False), 於是 \(\lnot P\) 不可能成立,故 \(P\) 成立。
這條規則叫做雙重否定消去。它看起來無害,卻是「經典邏輯」的標誌—— 直覺主義邏輯不接受它(見後文淺談)。
逆否命題: \(P \to Q\) 與 \(\lnot Q \to \lnot P\) 等價。 證明 \(\lnot Q \to \lnot P\) 有時比直接證 \(P \to Q\) 容易, 因為「 \(\lnot Q\) 成立」是額外的資訊,可以用來推導。
經典例子: \(\sqrt{2}\) 是無理數(預告)#
標準證明是反證法:假設 \(\sqrt{2} = a/b\) (最簡分數),推導出 \(a, b\) 同為偶數, 矛盾。Mathlib 中已有此定理,摘錄其敘述:
-- Mathlib 已證明:√2 是無理數
-- #check @irrational_sqrt_two
-- irrational_sqrt_two : Irrational √2
完整形式化頗長(需要良序原理、無窮遞降等工具),本節先練習它的「骨架」: 如何假設矛盾、如何使用 ¬ 型的假設。
by_contra:反證法入門#
by_contra h 把目標 \(P\) 變成假設 h : ¬P,然後目標變成 False:
example (p : Prop) (h : ¬¬p) : p := by
by_contra hp
exact h hp
-- 一行的 term mode:Classical.byContradiction
example (p : Prop) (h : ¬¬p) : p := Classical.byContradiction h
注意:這個 by_contra 能證的,直覺主義也承認一半—— by_contra 本質上呼叫 Classical.byContradiction,所以用了它就進入經典邏輯。 Lean 的建構主義核心不內建雙重否定消去,必須明確引入 Classical 命名空間的工具。
push_neg:把否定推過量詞與連接詞#
push_neg 把「否定」往裡推,換成等價的規範形式:
| 原式 | push_neg 後 |
|---|---|
| \(\lnot(P \land Q)\) | \(\lnot P \lor \lnot Q\) |
| \(\lnot(P \lor Q)\) | \(\lnot P \land \lnot Q\) |
| \(\lnot\forall x, P(x)\) | \(\exists x, \lnot P(x)\) |
| \(\lnot\exists x, P(x)\) | \(\forall x, \lnot P(x)\) |
| \(\lnot (a < b)\) | \(a \geq b\) |
| \(\lnot (a \leq b)\) | \(a > b\) |
example (p q : Prop) (h : ¬(p ∧ q)) : ¬p ∨ ¬q := by
push_neg at h -- h 變成 ¬p ∨ ¬q
exact h
-- 否定全稱量詞:¬∀ 變 ∃¬
example (P : Nat → Prop) (h : ¬∀ n, P n) : ∃ n, ¬P n := by
push_neg at h
exact h
更嚴謹的示範:
example (P : Nat → Prop) (h : ∃ n, ¬P n) : ¬∀ n, P n := by
intro hall -- 目標 False;hall : ∀ n, P n
obtain ⟨n, hn⟩ := h
exact hn (hall n)
example (P : Nat → Prop) (h : ¬∃ n, P n) : ∀ n, ¬P n := by
intro n hn
exact h ⟨n, hn⟩
-- push_neg 的正向用途:證明不等式時把 ¬a ≤ b 化為 a > b
example (a b : ℝ) (h : ¬(a ≤ b)) : b < a := by
push_neg at h
exact h
by_cases:排中律的二分法#
\(P \lor \lnot P\) 是排中律(law of excluded middle)。在經典邏輯中永遠可用, by_cases hp : p 會產生兩個分支:hp : p 與 hp : ¬p:
example (p q : Prop) (h : (p → q) → p) : p := by
by_cases hp : p
· exact hp
· -- 假設 ¬p:則 p → q 對任何 q 成立(爆炸原理),套 h 得 p,矛盾
exact absurd (h (fun hp' => absurd hp' hp)) hp
-- 排中律本身在 Lean 中必須來自 Classical:
#check @Classical.em
-- Classical.em : ∀ (p : Prop), p ∨ ¬p
by_cases 與 Classical.em 是同一件事的 tactic 化。 直覺主義者會說:知道 \(\lnot\lnot P\) 並不真的「建構出」 \(P\) 的證據; 但排中律讓我們可以「先假定不在,看會發生什麼」——這是反證法與二分討論的共同基礎。
直覺主義 vs 經典邏輯(淺談)#
| 議題 | 經典邏輯 | 直覺主義邏輯 |
|---|---|---|
| 排中律 \(P \lor \lnot P\) | 恆真 | 一般不可證 |
| 雙重否定消去 \(\lnot\lnot P \to P\) | 成立 | 不成立 |
| \(\exists\) 的證明 | 可用反證法 | 必須給出具體 witness |
| Curry–Howard | 不完全成立 | 證明即程式,完全成立 |
直覺主義拒絕排中律的理由:若 \(P\) 是「存在一個反例」,用排中律「證」 \(P\) 等於沒有真的找出那個例子。在 Curry–Howard 下,直覺主義的證明就是可執行程式, 所以每個 \(\exists\) 證明都附帶一個可以計算的 witness。 Lean 選了務實路線:核心是直覺主義的,但透過 Classical 公理層提供完整經典邏輯。 所以你可以自由使用 by_contra、by_cases,只是要記得它們是「加料」的工具。
常用引理一覽(都在 Classical 或 Not 附近):
#check @Classical.em -- p ∨ ¬p
#check @Classical.byContradiction -- ¬¬p → p
#check @not_not -- ¬¬p ↔ p
#check @absurd -- a → ¬a → b
#check @not_forall -- ¬∀ x, p x ↔ ∃ x, ¬p x(需 Classical)
綜合範例:逆否命題證法#
定理:若 \(x^2 = 0\) 則 \(x = 0\) 的逆否版本——若 \(x \neq 0\) 則 \(x^2 \neq 0\) :
example (x : ℝ) (hx : x ≠ 0) : x ^ 2 ≠ 0 := by
intro h -- 假設 x^2 = 0
exact hx (pow_eq_zero_iff (by norm_num) |>.mp h)
-- 反證法版本
example (x : ℝ) : x ^ 2 = 0 → x = 0 := by
intro h
by_contra hx
have hx' : x ≠ 0 := hx
exact hx' (pow_eq_zero_iff (by norm_num) |>.mp h)
第一個證明是直接的逆否推理(其實就是普通蘊含); 第二個是反證法。觀察:反證法版本繞了一圈卻也完成了任務—— 很多時候,反證法能讓「否定條件」變成可用的正面資訊(例如 \(x \neq 0\) 拿來當除法分母非零的依據),這正是它的價值。
小結與練習#
重點回顧:
- 反證法:
by_contra h假設 \(\lnot P\) 推矛盾;背後是Classical.byContradiction。 push_neg把否定規範化: \(\lnot\forall \to \exists\lnot\) 、 \(\lnot(a \leq b) \to a > b\) 。by_cases= 排中律二分法 =Classical.em。- 直覺主義核心不收雙重否定消去;
Classical公理層補上經典邏輯。 - 逆否命題 \(\lnot Q \to \lnot P\) 與 \(P \to Q\) 等價(此等價本身在直覺主義下單向成立)。
練習(依難度分級):
基礎
- 用
by_contra證明:¬¬True → True。 - 證明:
(x : ℕ) → x ≠ 0 → x + 1 ≠ 0(用intro與Nat.succ_ne_zero,不需反證法)。 - 用
push_neg證明:(a b : ℝ) → ¬(a < b) → b ≤ a。
進階
- 證明:
¬∃ n : ℕ, n + 1 = 0(提示:intro ⟨n, hn⟩後omega或exact Nat.succ_ne_zero n hn.symm)。 - 用
by_cases證明:(p : Prop) → (p ∨ ¬p) → (¬¬p → p)。 - 證明:
(P Q : Prop) → (¬Q → ¬P) → (P → Q)(逆否命題;需要by_cases分討論)。
挑戰
- 挑戰平方根骨架:在 Lean 中證明「不存在有理數 \(r\) 使 \(r^2 = 2\) 」的關鍵引理: 若 \(a^2 = 2b^2\) ( \(a, b : ℕ\) ),則 \(a\) 是偶數(提示:
Nat.abs不需要, 用Nat的奇偶性引理Nat.even_or_odd與平方的奇偶性)。 - 證明:
(∀ P : Prop, P ∨ ¬P) → (¬¬p → p)——從排中律推導雙重否定消去, 並說明為什麼反向(從雙否消去推排中律)在直覺主義下也需要額外步驟 (提示:對 \(p \lor \lnot p\) 取雙重否定後用 De Morgan)。