第3章 証明技法

章間ナビゲーション

この章で使う記号

記号 意味
P ⇒ Q P から Q が従う
¬Q ⇒ ¬P 対偶
∀n ∈ N 自然数全体に対する主張
Base 帰納法の基底部
Step 帰納法の帰納ステップ
I(k) ループ不変条件や帰納法の仮定を表す記号
矛盾を表すことがある記号

この章で解消する詰まりどころ

理論計算機科学の本文では、定義・補題・定理・証明が連続します。証明を読めない原因は、難しい式変形ではなく、証明の型を知らないことが多いです。

この章の目的は、次の状態を作ることです。

  • 定義を展開して証明を開始できる。
  • 直接証明、対偶証明、背理法を選べる。
  • 反例で普遍命題を否定できる。
  • 数学的帰納法と構造帰納法を使える。
  • アルゴリズムの正しさをループ不変条件や帰納法で説明できる。

本体教科書のどこで使うか

  • 第1章 数学的基礎
  • 第3章 形式言語とオートマトン理論
  • 第4章 計算可能性理論
  • 第5章 計算複雑性理論
  • 第6章 アルゴリズムの数学的解析
  • 第7章 データ構造の理論
  • 第12章 並行計算の理論

証明は全章で使います。特に、形式言語、計算可能性、複雑性、アルゴリズム解析では、証明の型を知らないと本文を追えません。


1. 証明とは何か

証明とは、仮定と定義から出発し、許された推論だけで結論に到達する説明です。

証明で重要なのは、次の3点です。

  1. 何を示すかを明確にする。
  2. どの定義を使うかを明確にする。
  3. どの証明の型を使うかを選ぶ。

例として、次の命題を考えます。

任意の整数 n について、n が偶数ならば n^2 は偶数である。

この命題は、論理式としては次です。

∀n∈Z, even(n) -> even(n^2)

証明では、まず n を任意に取ります。次に n が偶数であると仮定します。偶数の定義より、ある整数 k が存在して n = 2k と書けます。すると、

n^2 = (2k)^2 = 4k^2 = 2(2k^2)

です。2k^2 は整数なので、n^2 は偶数です。

ここで使ったのは次です。

  • 偶数の定義
  • 任意の整数に対する証明の始め方
  • 含意 P -> Q の証明方法

2. 定義展開

理論計算機科学の証明は、多くの場合、定義を展開すれば進みます。

例:

A ⊆ B かつ B ⊆ C ならば A ⊆ C を証明せよ。

使う定義:

A ⊆ B とは、任意の x について x∈A ならば x∈B であること。

証明:

A ⊆ B かつ B ⊆ C と仮定する。
A ⊆ C を示すには、任意の x について x∈A ならば x∈C を示せばよい。
任意の x を取り、x∈A と仮定する。
A ⊆ B より x∈B である。
B ⊆ C より x∈C である。
したがって x∈A ならば x∈C である。
よって A ⊆ C である。

この証明には高度な発想はありません。定義を展開して、順番につなげています。

定義展開の手順

1. 示すべき結論の定義を展開する。
2. 仮定の定義を展開する。
3. 任意の要素、任意の入力、任意の状態を1つ取る。
4. 仮定から結論へ進む。

3. 直接証明

直接証明は、仮定から結論へまっすぐ進む証明です。

対象は主に次の形です。

P -> Q

証明テンプレート:

P を仮定する。
[定義を展開する]
[必要な計算または推論を行う]
したがって Q が成り立つ。

例:偶数同士の和

命題:

a と b が偶数ならば、a+b も偶数である。

証明:

a と b が偶数であると仮定する。
偶数の定義より、ある整数 m,n が存在して a=2m, b=2n と書ける。
このとき a+b = 2m+2n = 2(m+n) である。
m+n は整数なので、a+b は偶数である。

直接証明が向いている場合

  • 結論が定義展開で自然に出る。
  • 仮定から式変形できる。
  • 「存在する」を示すために具体的な対象を構成できる。

4. 対偶証明

含意 P -> Q は、その対偶 ¬Q -> ¬P と同値です。

対偶証明のテンプレート:

対偶 ¬Q -> ¬P を示す。
¬Q を仮定する。
[定義を展開する]
[必要な推論を行う]
したがって ¬P が成り立つ。
よって元の命題 P -> Q も成り立つ。

例:平方が偶数なら元も偶数

命題:

n^2 が偶数ならば n は偶数である。

直接証明より対偶の方が簡単です。

対偶:

n が偶数でないならば、n^2 は偶数でない。

整数では「偶数でない」は「奇数」です。したがって、

n が奇数ならば n^2 は奇数である。

を示せばよいです。

証明:

n が奇数であると仮定する。
奇数の定義より、ある整数 k が存在して n=2k+1 と書ける。
このとき
n^2 = (2k+1)^2 = 4k^2+4k+1 = 2(2k^2+2k)+1
である。
2k^2+2k は整数なので、n^2 は奇数である。
よって対偶が成り立つため、元の命題も成り立つ。

対偶証明が向いている場合

  • 結論の否定から仮定の否定へ進みやすい。
  • 「〜ならば〜でない」という主張が自然に出る。
  • 偶奇、整除、包含関係などで有効。

5. 背理法

背理法は、示したい命題の否定を仮定し、矛盾を導く方法です。

テンプレート:

示したい命題が成り立たないと仮定する。
[推論する]
矛盾が生じる。
したがって、仮定が誤りであり、元の命題が成り立つ。

例:√2 は無理数

命題:

√2 は無理数である。

証明:

√2 が有理数であると仮定する。
すると、互いに素な整数 p,q が存在して √2 = p/q と書ける。ただし q≠0。
両辺を2乗すると 2 = p^2/q^2 なので、p^2 = 2q^2 である。
したがって p^2 は偶数であり、前節の結果より p は偶数である。
p=2r と書ける。
すると 4r^2 = 2q^2 なので、q^2 = 2r^2 であり、q^2 は偶数である。
同様に q も偶数である。
これは p と q が互いに素であることに矛盾する。
したがって √2 は無理数である。

背理法が向いている場合

  • 「存在しない」を示したい。
  • 否定を仮定すると条件が強くなり、扱いやすくなる。
  • 不可能性証明、下界証明、計算不能性の直観に使う。

6. 場合分け

対象を有限個のケースに分け、それぞれで結論を示します。

テンプレート:

場合1: ...
  [証明]
場合2: ...
  [証明]
...
すべての場合で結論が成り立つので、命題は成り立つ。

例:整数 n について n(n+1) は偶数

任意の整数 n について、n は偶数か奇数です。

  • n が偶数なら、n(n+1) は偶数を因子に持つので偶数。
  • n が奇数なら、n+1 は偶数なので、n(n+1) は偶数。

したがって常に偶数です。

注意

場合分けでは、ケースが漏れていないことと、ケースが対象全体を覆っていることを明示します。


7. 反例

普遍命題 ∀x, P(x) を否定するには、P(x) が成り立たない具体例を1つ示せば十分です。

例:

すべての素数は奇数である。

これは偽です。反例は 2 です。2 は素数ですが、奇数ではありません。

反例で否定できる命題

  • すべての x について P(x)
  • 任意の入力でアルゴリズム A は正しい
  • 任意のグラフで性質 P が成り立つ

1つでも失敗例があれば、普遍命題は偽です。

反例で否定できないもの

存在命題 ∃x, P(x) を反例1つで否定することはできません。存在命題を否定するには、すべての候補で P(x) が成り立たないことを示す必要があります。


8. 数学的帰納法

数学的帰納法は、自然数 n に関する命題 P(n) を示す方法です。

テンプレート:

基底部: P(0) または P(1) を示す。
帰納ステップ: 任意の k について P(k) を仮定し、P(k+1) を示す。
したがって、すべての n について P(n) が成り立つ。

例:1+2+…+n

命題:

n ≥ 1 について、1+2+...+n = n(n+1)/2

基底部:

n=1 のとき、左辺は 1、右辺は 1(1+1)/2 = 1。
よって成り立つ。

帰納ステップ:

k ≥ 1 について 1+2+...+k = k(k+1)/2 が成り立つと仮定する。
このとき、
1+2+...+k+(k+1)
= k(k+1)/2 + (k+1)
= (k+1)(k/2 + 1)
= (k+1)(k+2)/2
である。
これは n=k+1 の場合の式である。
したがって P(k) -> P(k+1) が成り立つ。

結論:

数学的帰納法により、すべての n≥1 について成り立つ。

帰納法でよくある誤り

誤り1: 基底部を示さない。

誤り2: P(k) を仮定せずに P(k+1) を示そうとする。

誤り3: P(k) を示しただけで、P(k+1) を示していない。

誤り4: P(k) を使う場所がない。これは帰納法が不要か、証明が欠けている可能性があります。


9. 強い帰納法

強い帰納法では、P(k+1) を示すために P(0), P(1), ..., P(k) をすべて仮定できます。

テンプレート:

基底部を示す。
帰納ステップ:
  P(0), P(1), ..., P(k) がすべて成り立つと仮定する。
  その仮定から P(k+1) を示す。

例:2以上の整数は素数の積に分解できる

命題:

すべての整数 n≥2 は素数の積として表せる。

証明スケッチ:

n が素数なら、それ自身が素数の積である。
n が合成数なら、n=ab かつ 2≤a<n, 2≤b<n と書ける。
強い帰納法の仮定により、a と b は素数の積に分解できる。
したがって n=ab も素数の積に分解できる。

強い帰納法は、再帰的アルゴリズムや分割統治法の正しさでよく使います。


10. 構造帰納法

構造帰納法は、自然数ではなく、再帰的に定義された対象に対する帰納法です。

対象例:

  • 文字列
  • 数式
  • 論理式
  • プログラムの構文

文字列の例

アルファベット Σ 上の文字列を次のように定義します。

1. ε は文字列である。
2. w が文字列で a∈Σ ならば wa は文字列である。
3. 以上で作られるものだけが文字列である。

文字列の長さ |w| を次のように定義します。

|ε| = 0
|wa| = |w| + 1

示したい命題:

任意の文字列 u,v について |uv| = |u| + |v|

証明は v の構造に関する帰納法で行えます。

基底部:

v=ε のとき、uε = u なので |uε| = |u|。
また |u| + |ε| = |u| + 0 = |u|。
よって成り立つ。

帰納ステップ:

v=w a とする。ただし w は文字列、a∈Σ。
帰納法の仮定として |uw| = |u| + |w| を仮定する。
このとき、
|u(wa)| = |(uw)a| = |uw| + 1 = |u| + |w| + 1 = |u| + |wa|
である。

したがって、任意の v について命題が成り立ちます。

構造帰納法が本体で効く箇所

  • 正規表現で定義される言語の性質
  • 文法による導出
  • 構文木
  • 論理式の意味論
  • 再帰的定義された計算過程

11. アルゴリズムの正しさとループ不変条件

アルゴリズムの正しさを示すときは、通常、次の2つを分けます。

  1. 停止すること。
  2. 停止したとき、正しい答えを返すこと。

ループを含むアルゴリズムでは、ループ不変条件を使います。

ループ不変条件とは、ループの各反復の開始時点で常に成り立つ性質です。

示すこと:

初期化: ループ開始前に不変条件が成り立つ。
保存: ある反復の開始時に不変条件が成り立つなら、次の反復の開始時にも成り立つ。
終了: ループ終了条件と不変条件から、求める正しさが従う。

例:線形探索

LinearSearch(A, x):
    for i = 0 to len(A)-1:
        if A[i] == x:
            return i
    return NOT_FOUND

不変条件:

各反復の開始時点で、A[0], ..., A[i-1] には x が存在しない。

初期化:

i=0 のとき、A[0], ..., A[-1] は空範囲なので、x が存在しないという主張は真である。

保存:

反復開始時に A[0], ..., A[i-1] に x が存在しないとする。
もし A[i] == x なら i を返して終了する。
そうでなければ A[i] != x なので、次の反復開始時には A[0], ..., A[i] に x が存在しない。

終了:

ループが最後まで終わった場合、不変条件より A 全体に x は存在しない。
したがって NOT_FOUND は正しい。

12. 証明を書くときのチェックリスト

証明を書いたら、次を確認します。

[ ] 示すべき命題を明記した。
[ ] 任意の対象を1つ取る箇所を書いた。
[ ] 仮定を書いた。
[ ] 使う定義を展開した。
[ ] 結論が何かを途中で見失っていない。
[ ] 存在命題では、具体的な対象または構成方法を示した。
[ ] 普遍命題では、任意性を確保した。
[ ] 帰納法では、基底部と帰納ステップがある。
[ ] アルゴリズムでは、正しさと停止性を分けた。

13. 練習問題

  1. A⊆B かつ C⊆D ならば A∪C ⊆ B∪D を証明せよ。
  2. a が奇数ならば a^2 は奇数であることを証明せよ。
  3. ab が奇数ならば ab は奇数であることを対偶で証明せよ。
  4. 任意の整数 n について n^3-n は3で割り切れることを証明せよ。
  5. 2^n ≥ n+1 を帰納法で証明せよ。
  6. 文字列 w について |w|=0 ならば w=ε を、文字列の定義に基づいて説明せよ。
  7. 線形探索のループ不変条件を書き、正しさを説明せよ。

次に読む章