含意 (→) を AND/OR/NOT で表現

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

含意 (→) を AND/OR/NOT で表現

このレッスンで分かること

  • 論理学には「ならば」を表す という記号があります
  • 含意の重要な性質は、aFalse のときは b の値に関わらず a → bTrue になるという点です
  • 2 入力なので 4 通り

含意 (→) を AND/OR/NOT で表現 とは

論理学の含意 a → b を AND/OR/NOT の組み合わせで実装し、0/1 で返す関数を作ります。「a ならば b」の真偽の不思議さも体感します。

論理学には「ならば」を表す という記号があります。a → b は日本語で「a ならば b」と読み、命題論理の基本演算の 1 つです。前提 aTrue のときに帰結 bTrue なら全体は TrueaTrue なのに bFalse なら全体は False というルールです。AND OR NOT の組み合わせで作れるので、新しい記号というよりは「合成ゲート」だと考えるとスッキリ理解できます。

含意の重要な性質は、aFalse のときは b の値に関わらず a → bTrue になるという点です。これは「前提が成り立たない場合、結論については何も主張していない」と解釈できます。日常感覚では「雨が降った傘を持つ」が偽になるのは、雨が降ったのに傘を持たないときだけ、という感じです。雨が降らない日はそもそもこの命題が問題にならないので、便宜上 True 扱いになるのです。

含意の難所は「前提が False のときは全部 True」。この 空虚な真 (vacuous truth) がプログラマーの第一関門。

真理値表

2 入力なので 4 通り。表を覚えると速いです。

aba → b
FFT
FTT
TFF
TTT

表を眺めると、a → bNOT a OR b と同じ結果になっていることが分かります。これが含意を AND/OR/NOT で表現する公式です。

プレーンテキスト

a → b = (NOT a) OR b

この等価式は、論理学の証明や SAT ソルバー、Prolog などで頻繁に登場します。たとえば「在庫がない → 注文不可」は、NOT 在庫がない OR 注文不可 と書き換えられ、これは「在庫がある OR 注文不可」と同じ意味になります。

Python

def impl(a, b): return (not a) or b print(impl(False, False)) # True print(impl(True, False)) # False print(impl(True, True)) # True

等価変形を可視化

diagram (will load when visible)

図のポイント (テキスト併記)

  • NOT a OR b を回路で書くと、上のようなフローになります

NOT a OR b を回路で書くと、上のようなフローになります。論理回路の世界では OR ゲートの 1 つの入力に NOT ゲートを通すだけで含意が作れる、というシンプルな構造です。これは半導体設計から SQLCHECK 制約まで応用範囲がとても広い等価式です。

NOT a OR b」というたった 1 行の式が、論理学の「ならば」のすべてを表現します。

含意の言い換え

含意にはいくつかの言い換えがあります。

  • 対偶 (contraposition)a → b(NOT b) → (NOT a) が等価なこと。証明テクニックとして有名です。
  • 逆 (converse)b → a で、これは元と同値ではないので注意。
  • 裏 (inverse)(NOT a) → (NOT b) で、これも元と同値ではありません。

Python

# 対偶も同じ結果になる def contra(a, b): return impl(not b, not a) print(impl(True, False)) # False print(contra(True, False)) # False (同じ)

つまり「雨が降った → 傘を持つ」の対偶は「傘を持たない → 雨が降らなかった」で、論理的には等価です。証明問題で「対偶を使う」と楽になるケースの裏側には、この等価変形があります。

対偶は元と等価。逆と裏は等価ではない。混同しないように注意。

よくある間違い

1 つめは、a → bb → a だと思ってしまうケースです。これは「逆」であり、元と同値ではありません。2 つめは、前提が False のときに直感に反して結果が True になることに戸惑うケース。「空虚な真」と呼ばれる現象で、論理学の入り口でつまずきやすい部分です。3 つめは、Pythona >>= b を含意演算子だと勘違いするケース。Python には含意専用の記号がなく、not a or b と書くのが定石です。

Python

# 前提が False のとき、何を b に渡しても True print(impl(False, True)) # True print(impl(False, False)) # True (空虚な真)

やってみよう

2 つの真偽値を 0/1 で表した a b を受け取り、a → b の結果を 01 で返す関数 implication(a, b) を実装します。実装は (NOT a) OR b を素直に書くだけで OK です。a = 1, b = 0 のときだけ 0 (False)、それ以外の 3 通りは 1 (True) を返せば正解です。比較演算で書くなら (a != 1) or (b == 1) と書いて int に変換するアプローチもありです。

よくある質問

Q. a → b と b → a の違いは何ですか?

A. a → b(含意)と b → a(逆)は論理的に等価ではありません。「雨が降る → 地面が濡れる」が真でも、「地面が濡れる → 雨が降った」は必ずしも真ではありません。本文の真理値表を使って 4 通りを比較すると、a=True, b=False のとき a → bFalse ですが、b → aTrue になり、結果が異なることが確認できます。

Q. 空虚な真はなぜ「真」扱いになるのですか?

A. 含意 a → b は「a が成立したとき、必ず b も成立する」という約束です。a が最初から False ならその約束が破られる機会がないため、約束は守られたと見なす、というのが論理学の取り決めです。これを空虚な真(vacuous truth)と呼びます。日常言語では違和感を感じますが、数学の証明や仕様記述では非常に便利な性質です。

Q. Python に含意専用の演算子がないのはなぜですか?

A. not a or b という一般演算子の組み合わせで完全に表現できるため、専用記号を追加するメリットが薄いからです。>> は右シフト演算子として既に使われており、含意への転用は混乱を招きます。実務でも含意が単独で頻出するケースは少なく、not a or b をそのまま書くのが Python の慣習です。

次のレッスン

次は ド・モルガンの法則 に進みましょう。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. 含意 (→) の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. 含意 (→) とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. (NOT a) OR b と等価な処理を実装する
  2. a が 0 のときは b に関わらず 1 を返す
  3. a が 1 かつ b が 0 のときだけ 0 を返す

入出力例

test-cases.txt

implication(0, 0)1 implication(0, 1)1 implication(1, 0)0 implication(1, 1)1

ヒント

main.py
main.py
学習モード

メモ

含意 (→) を AND/OR/NOT で表現

⌘S で保存