含意 (→) を AND/OR/NOT で表現
「雨なら傘を持つ」と言った人は、いつ嘘つきになるのか
朝に「雨なら傘を持っていく」と約束したとします。夜になって、この人は約束を守ったのか、破ったのか。判定してみてください。
雨が降って傘を持っていた日は、守っています。雨が降ったのに傘を持たなかった日は、破っています。では、晴れた日はどうでしょうか。傘を持っていても、持っていなくても、この約束について責める理由はありません。もともと雨の日の話しかしていないからです。
これが論理学の含意で、a ならば b、記号では a → b と書きます。
偽になるのは、1 通りだけ
起こりうる 4 通りを並べます。
- 晴れ・傘なし ... 約束の対象外なので、破っていない
- 晴れ・傘あり ... 約束の対象外なので、破っていない
- 雨・傘なし ... 約束を破った
- 雨・傘あり ... 約束を守った
偽になるのは 3 番目だけで、残りの 3 通りはすべて真です。含意は「破られたときだけ偽」と決められていて、それ以外はまとめて真にする、という取り決めになっています。
Python
days = [
(False, False), # 晴れ・傘なし
(False, True), # 晴れ・傘あり
(True, False), # 雨・傘なし
(True, True), # 雨・傘あり
]前提が成り立たない日は、破りようがない
引っかかるのは、上の 1 番目と 2 番目です。晴れているのに真、しかも傘のあるなしに関係なく真。直感には反しますが、約束が破られていないのは確かです。破る機会が来なかったのだから、嘘つきにはできません。
この「前提が偽なら全部真」を空虚な真と呼びます。「1 件も該当が無いリストは、条件を全部満たしている」と言われて納得しにくいのと、同じ形です。仕様を書くときには便利な性質で、例外を並べずに済みます。
含意は、入力チェックの形でよく出てきます。「メール通知を選んだなら、アドレスの入力が要る」がそれです。メール通知を選んでいない人にアドレスを求めてはいけないので、前提が偽の行は通さなければなりません。空虚な真を「よく分からない決まり」ではなく「前提が外れた人は素通しする」と読めるようになると、この手の条件を素直に書けるようになります。
ひっくり返すと、別の約束になる
b ならば a、つまり「傘を持っていたなら雨だった」は、元の約束とは別物です。雨でなくても傘を持つ日はあるので、元が真でもこちらは偽になりえます。これを逆と呼びます。
一方で「傘を持たなかったなら雨ではなかった」は、元と必ず同じ結果になります。こちらは対偶です。証明で対偶に置き換えると楽になることがあるのは、入れ替えても意味が変わらないからです。逆と対偶は名前も形も似ているので、混ぜないでください。
要件
- (NOT a) OR b と等価な処理を実装する
- a が 0 のときは b に関わらず 1 を返す
- a が 1 かつ b が 0 のときだけ 0 を返す
入出力例
implication(0, 0) → 1
implication(0, 1) → 1
implication(1, 0) → 0
implication(1, 1) → 1