このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

正確な記述と演繹のための非日本語記法

少し前に「TypeScriptで(無理して)論理式: 言霊排除」という記事を書きました。タイトル内の「言霊排除」の意味は、次のようなことです。

自然言語(日本語)には言霊〈ことだま〉が宿るとかいいますが、強烈なイメージ喚起力は言霊のパワーなのかも知れません。...[snip]... 数学的・論理的な命題の記述と解釈においては、言霊の影響 -- 現実世界や感情の世界への連想・参照 -- をできるだけ排除したい。...[snip]... ともかく、命題を扱う際は真偽判定に集中してください。言霊の影響を断ち切ってください。

命題自体を日本語(自然言語)で書くのをやめても、その周辺で使っている日本語により、またしても日常的な不正確さ/曖昧さ/根拠薄弱な推論の悪習へと引きずり込まれてしまうことがあるようです。なんとかせねば。

この記事の内容は「証明の“お膳立て”のやり方」シリーズと類似してますが、より入門的な構成・語り口にしています。モノをチャンと考えるときの枠組みのお話です。

内容:

日本語と日常と非論理

我々はほとんど常に日本語を使い/日本語で考えています。日本語による表現には不正確さや曖昧さがあります*1。その日本語表現をベースに、根拠がハッキリしない雰囲気的な推論を日常的に行っています。そして、それでもたいして不都合はないのです。日常生活において、正確な表現や確実な推論が必要な場面は意外に少ないからです。

日本語の語彙と文法のなかで、正確な表現/確実な推論をこなす人も確かにいます。しかし、日本語を使用することにより、考え方までグダグダになってしまう人もいます。悪しき言霊の影響を受けやすい人は、論理的思考において日本語を使うのをやめるほうがいいと思います。

そうなると、日本語ではない人工言語を習得することになり、習得の負担が増えます。でも、それは仕方ない。日本語のなかで論理的思考をチャンとしている人は、語彙と文法が日本語と共通している別な言語を使っているのです。もうひとつの言語の習得はいずれにしても必要なのです。新言語が、なまじ日本語と同じ語彙・文法だとかえって混乱する人のほうが多いので、語彙・文法は日本語と違っていたほうがむしろ望ましいと言えます。新言語により、曖昧さと雰囲気の世界から脱出しましょう。

命題の例

等式や不等式は典型的な命題です。次の等式・不等式を例に使います。

  1. (a + b)2 = a2 + 2ab + b2
  2. (a + b)2 = a2 + b2
  3. x + y ≧ 0

これらは記号的な表現だけで構成されていますが、次の命題には日本語が含まれます。

  • n, mが3の倍数ならば、 n + m は3の倍数である

「3の倍数である」を表す記号的な表現を「M3」としましょう。「6は3の倍数である」は「M3(6)」です。「nは3の倍数である」は「M3(n)」と書きます。この記法を使えば:

  • M3(n) かつ M3(m) ならば M3(n + m)

さらに、「かつ」と「ならば」も記号的表現にして:

  • (M3(n) ∧ M3(m)) ⇒ M3(n + m)

この命題を含めて4つの命題が今後使う例です。

  1. (a + b)2 = a2 + 2ab + b2
  2. (a + b)2 = a2 + b2
  3. x + y ≧ 0
  4. (M3(n) ∧ M3(m)) ⇒ M3(n + m)

命題の正しさ

命題が提示されたことと、その命題が正しいことは別なことです。なにかが正しい根拠として、「テレビで誰々が言っていた」「インターネットのなんとかページに書いてあった」とかを引き合いに出す人がいますが、これは、命題が提示されていたことを即座にその命題の正しさに結びつけています。

もちろん、「十分に信頼できる人が言った/十分に信頼できるメディアに書いてあった」は正しさの根拠として使ってもよいのですが、単に「提示されていた」から即座に「正しい」という判断を下すのは危険です。とある命題が正しいことを英語で言えば The proposition is correct. となるでしょう。語順を変えて「IsCorrect 命題」という形を、命題の正しさの主張(メタ命題と呼ぶことがある)に使います。逆に、とある命題が正しくないという主張は「IsWrong 命題」とします。

前節で挙げた4つの命題は単に提示されただけと考えると、それらを真偽判定した結果(の可能性)は次の8つになります。

  1. IsCorrect (a + b)2 = a2 + 2ab + b2
  2. IsCorrect (a + b)2 = a2 + b2
  3. IsCorrect x + y ≧ 0
  4. IsCorrect (M3(n) ∧ M3(m)) ⇒ M3(n + m)
  5. IsWrong (a + b)2 = a2 + 2ab + b2
  6. IsWrong (a + b)2 = a2 + b2
  7. IsWrong x + y ≧ 0
  8. IsWrong (M3(n) ∧ M3(m)) ⇒ M3(n + m)

命題が真か偽か分からないときは、IsUncertain を使うことにします。これも入れると、真偽判定の結果は12個になります。

  1. IsCorrect (a + b)2 = a2 + 2ab + b2
  2. IsCorrect (a + b)2 = a2 + b2
  3. IsCorrect x + y ≧ 0
  4. IsCorrect (M3(n) ∧ M3(m)) ⇒ M3(n + m)
  5. IsWrong (a + b)2 = a2 + 2ab + b2
  6. IsWrong (a + b)2 = a2 + b2
  7. IsWrong x + y ≧ 0
  8. IsWrong (M3(n) ∧ M3(m)) ⇒ M3(n + m)
  9. IsUncertain (a + b)2 = a2 + 2ab + b2
  10. IsUncertain (a + b)2 = a2 + b2
  11. IsUncertain x + y ≧ 0
  12. IsUncertain (M3(n) ∧ M3(m)) ⇒ M3(n + m)

文脈

例にしている4つの命題について、真偽判定を実際にしようとすると、情報が不足していることに気付きます。

例えば、x + y ≧ 0 で、文字x, yが何を表すかわかりません。x, yに関して、何かの条件が事前に課されていたかもしれません。このような、当該の命題以外の情報を文脈〈context〉と呼びます。通常、命題は文脈のなかに置かれます。文脈から切り離すと真偽不明どころか意味不明になるかも知れません。

文脈を明示的に書くために、Forというキーワードを使うことにします。例えば:

For x∈N, y∈N.
  x + y ≧ 0

文脈を複数のForで書いてもいいとします。

For x∈N.
For y∈N.
  x + y ≧ 0

同じ命題を別な文脈のなかに置いてみましょう。

For x∈R, y∈R.
  x + y ≧ 0

さらに別な文脈に置いてみます*2

For x∈R, y∈R.
For x ≧0, y ≧0.
  x + y ≧ 0

文脈付きの(文脈のなかに置かれた)命題に真偽判定の結果を追加すると、次のようになります*3

For x∈N, y∈N.
  IsCorrect x + y ≧ 0
For x∈N.
For y∈N.
  IsCorrect x + y ≧ 0
For x∈R, y∈R.
  IsWrong x + y ≧ 0
For x∈R, y∈R.
For x ≧0, y ≧0.
  IsCorrect x + y ≧ 0

文脈を命題のなかに押し込む

「命題は文脈のなかに置かれる」と言いました。となると、文脈なしでは真偽判定ができないことになります。これでは困ることがあります。そこで、文脈を命題側に押し込む操作をします。

例えば、

For x∈R, y∈R.
For x ≧0, y ≧0.
  x + y ≧ 0

これの二番目のForで書かれた文脈を、命題に入れてしまうと:

For x∈R, y∈R.
  (x ≧0 ∧ y ≧0) ⇒ x + y ≧ 0

文脈としてはカンマで区切ってあった命題を、記号「∧」(かつ)でつないで、「⇒」(ならば)の前に入れればいいのです。

文脈を複数のForに分割するやり方は一通りではありません。それによって、文脈を押し込んだ命題の形は変わります。例えば、

For x∈R, y∈R.
For x ≧0.
For y ≧0.
  x + y ≧ 0

から、下2つのForを順次命題側に押し込むと:

For x∈R, y∈R.
  x ≧0 ⇒ (y ≧0 ⇒ x + y ≧ 0)

これで何の問題もありません。次の2つの命題は表現が違うだけで内容的に同じなのです。

  1. (x ≧0 ∧ y ≧0) ⇒ x + y ≧ 0
  2. x ≧0 ⇒ (y ≧0 ⇒ x + y ≧ 0)

さて、For x∈R, y∈R. という文脈も命題に押し込みましょう。変数がどの集合に所属しているかを示す命題は、プログラミングでいうと変数の型宣言みたいなものです。このタイプの命題は特別扱いをします。x∈R ならば、∀x∈R. という形に直して、命題の先頭に付けます。例えば、

For x∈R, y∈R.
  (x ≧0 ∧ y ≧0) ⇒ x + y ≧ 0

から、次の形に変形されます。

∀x∈R.∀y∈R.( (x ≧0 ∧ y ≧0) ⇒ x + y ≧ 0 )

得られた命題を、強いて日本語に翻訳するなら:

  • 任意の実数x、任意の実数yに対して、x ≧0 かつ y ≧0 ならば x + y ≧ 0

この命題なら、文脈なしでも不明な点や誤解される所はないでしょう。

文脈付きの命題でも、文脈をどんどん命題のなかに詰め込んでしまえば、文脈なしで通用する単独の命題にパッケージ化できます。

文脈付き命題の操作

命題を論理的に操作することはもちろん重要です。例えば、二重否定の法則とかド・モルガンの法則を使って命題を変形するとかですね。しかしそれだけではなくて、文脈の操作もとても重要です。命題をうまく扱えない原因が、実は文脈をうまく扱えないことであることは多いです。

4つの例に、文脈を付けてみます。

For a∈R.
For b∈R.
  (a + b)2 = a2 + 2ab + b2
For a, b∈R.
  (a + b)2 = a2 + b2
For x∈Z, y∈Z.
  x + y ≧ 0
For n, m∈Z.
  (M3(n) ∧ M3(m)) ⇒ M3(n + m)

これらは文脈の一例で、他の文脈を付けることもできます。当然に、文脈により真偽も変わります。例えば、(a + b)2 = a2 + b2 も、文脈によっては真になります。

For a = 0.
For b = 1.
  (a + b)2 = a2 + b2

練習のために、前節で述べた「文脈を命題のなかに押し込む」ことをやってみます。そのとき、変形前の文脈付き命題を横線('-'の並び)の上に、変形後の文脈付き命題を横線の下に書く書き方を使います。次のようになりますね、変形を追いかけてみてください。

 For a∈R.
 For b∈R.
   (a + b)2 = a2 + 2ab + b2
 --------------------------------------------------
 For a∈R.
   ∀b∈R.( (a + b)2 = a2 + 2ab + b2 )
 --------------------------------------------------
   ∀a∈R.( ∀b∈R.( (a + b)2 = a2 + 2ab + b2 ) )
 For a, b∈R.
   (a + b)2 = a2 + b2
 ------------------------------------
   ∀a, b∈R.( (a + b)2 = a2 + b2 )
 For x∈Z, y∈Z.
   x + y ≧ 0
 --------------------------------
   ∀x∈Z.∀y∈Z.( x + y ≧ 0 )
 For n, m∈Z.
   (M3(n) ∧ M3(m)) ⇒ M3(n + m)
 ----------------------------------------------
   ∀n, m∈Z.( (M3(n) ∧ M3(m)) ⇒ M3(n + m) )
 For a = 0.
 For b = 1.
   (a + b)2 = a2 + b2
 ----------------------------------------------
 For a = 0.
   b = 1 ⇒ (a + b)2 = a2 + b2
 ----------------------------------------------
   a = 0 ⇒ ( b = 1 ⇒ (a + b)2 = a2 + b2 )

文脈を押し込んだ単一の命題に対して、真偽判定の結果を添えてみましょう。

  1. IsCorrect ∀a∈R.( ∀b∈R.( (a + b)2 = a2 + 2ab + b2 ) )
  2. IsWrong ∀a, b∈R.( (a + b)2 = a2 + b2 )
  3. IsWrong ∀x∈Z.∀y∈Z.( x + y ≧ 0 )
  4. IsCorrect ∀n, m∈Z.( (M3(n) ∧ M3(m)) ⇒ M3(n + m) )
  5. IsCorrect a = 0 ⇒ ( b = 1 ⇒ (a + b)2 = a2 + b2 )

正しさの根拠

前節の最後で、命題の先頭にIsCorrectまたはIsWrongを付けた形を並べました。命題に真偽判定の結果を添えたわけです。このとき、真偽はどうやって判定したのでしょう?つまり、「真偽判定の正しさ」が問題になります。

  • 命題が提示されただけでは、その命題が正しいかどうか分からない。
  • 真偽判定の結果が提示されただけでは、その判定が正しいかどうか分からない。

真偽判定に対して、そう判定した根拠を書かなくてはなりません。それが証明〈proof〉です。IsCorrectと判定したなら正しい根拠、IsWrongと判定したなら間違いである根拠を示す必要があります。IsWrongの根拠のほうは反証〈disproof | 反駁〉と呼びますが、広い意味の証明は反証も含みます。

ここでは、判定の根拠(証明または反証)を書くためににBecauseというキーワードを使うことにします。次のような形式になります。

For a∈R.
For b∈R.
  IsCorrect (a + b)2 = a2 + 2ab + b2
Because
  ここに
  証明を書く
End

証明の書き方は今回の話題ではないので述べません。肯定的な証明(IsCorrectの根拠)だけではなくて反証(否定の証明)を書く場合もあります。

For a, b∈R.
  IsWrong (a + b)2 = a2 + b2
Because
  ここに
  反証を書く
End

曖昧で雰囲気的な議論を避ける、つまり論理的な議論をするには、次の構成要素をセットとして考えます。

  1. 命題に対する文脈
  2. 命題
  3. 命題の真偽判定(ここでは IsCorrect, IsWrong で示した)
  4. 真と判定したなら肯定的な証明、偽と判定したなら否定的な証明(反証)

これらのうち一部が省略されることはしばしばあります。何が省略されているのかを強く意識しましょう。必要があれば確認しましょう。そうでないと、曖昧で雰囲気的な議論へと堕ちていきます。曖昧さと雰囲気を許してしまう態度、マーマーなーなーな精神こそ、論理的議論遂行の最大の障害です。

共有されている予備知識

次の文脈付きの命題を考えます。

For n, m∈Z.
  (M3(n) ∧ M3(m)) ⇒ M3(n + m)

これは文脈が付いているので、真偽判定が可能なはずです。実際、IsCorrectと判定しています。しかし、真偽判定の際に、M3が「3の倍数」という意味であることを考慮しています。いきなり、何の説明もなく上の文脈付き命題を出されたら、M3が不明なので真偽判定は不可能です。

「M3とは何であるか」の情報も文脈に必要なのです。ただ、文脈に書くと煩雑になるので、独立した別な記述にしましょう。

For n∈N.
  M3(n) := (n%3 = 0)

これは、M3の定義です。':='は定義のための等号です。定義の書き方は色々あります。いくつか書き方の例を挙げますが、「色々あるよ」ってだけで、どれかひとつ理解できれば書き方のバラエティを気にする必要はありません*4

M3(n∈N) := (n%3 = 0)
M3(n∈N) :⇔ (n%3 = 0)
M3 := λn∈N.( (n%3 = 0) ∈Bool)
∀n∈N.( M3(n) :⇔ n%3 = 0 )

(M3(n) ∧ M3(m)) ⇒ M3(n + m) という命題では、記号「M3」を既に知っている前提があるわけです。つまり、命題を解釈する際の予備知識があったわけです。予備知識がM3だけだったのか? というと、そうではありません。

(a + b)2 = a2 + 2ab + b2 に出てくる指数表記に関しても、それが掛け算を表すことは予備知識のひとつです。次のような定義を事前に知っている必要があります。

For a∈R.
  a2 := aa

さらに、単にaを並べることが、実は掛け算であることも予備知識です。

For a∈R.
  aa := a×a

(a + b)2 = a2 + 2ab + b2 の証明のなかで、実数の掛け算の交換法則が使われますが、それも予備知識ですね。

For a, b∈R.
  a×b = b×a

他にもたくさんの予備知識が必要ですが、それらをイチイチ書き出すことは通常はしません。それは、対話の当事者のあいだで共有されている予備知識だよね、ということで暗黙に前提されるのです。

ただし、暗黙の前提は危険でもあります。共有されていると思っていた予備知識が、実は共有されていない、ズレていたってことはありますよね。共有されているかどうか不安なときは、確認作業をしましょう。

おわりに

ねんがらねんぢゅう論理的な議論をする必要はありません。そんなことしていると嫌われますからね(苦笑)。ですが、論理的に考えて、論理的に表現して、論理的に説得する必要があるときは、それが出来るほうが望ましいでしょう。

命題について云々するときは、その命題そのものだけでなく、次のフォーマットで必要事項を書き出すといいでしょう。

その命題の文脈

  真偽判定
  命題

真偽判定の根拠

具体例を出せば:

その命題の文脈: a, b∈R

  真偽判定: IsWrong(偽である)
  命題: (a + b)2 = a2 + b2

真偽判定の根拠:
  a = 1, b = 1 としたとき、
  左辺 = (1 + 1)2 = 22 = 4
  右辺 = 12 + 12 = 1 + 1 = 2
  これは命題の反例となっているので、
  この命題は偽である。

文脈では書き切れない予備知識が背後にありますが、その予備知識が、対話の当事者間でチャンと共有されているかどうかの確認も重要です。

*1:日本語固有の問題ということではありません。自然言語は総じて不正確さ/曖昧さを避けられません。

*2:僕がローカルに使っていた(いる)記法では、変数が所属する集合(型)の指定にはFor、事前に想定する命題はGivenかWhenで書き分けますが、ここでは全部Forにしました。

*3:僕がローカルに使っていた(いる)記法では、IsCorrectの代わりにHoldsです。IsWrong相当は、Holdsの後の命題を否定にします。Holdsに相当する論理における標準的記法は、|- です。

*4:書き方のバラエティはとんでもない量であるので、そんなことをイチイチ気にしていたら消耗してしまいます。単に「いっぱいあるなー」と心得ておけばいいのです。