プログラムを作成していく中で、論理式を避けて通ることはできません。
また複数ある条件をそのまま記述していくことで、複雑に入り組んだように見えてしまうこともあります。
このような時にカルノー図を用いることによって、論理式をシンプルに記述することができます。
今回はカルノー図の考え方の基本について学び、Pythonで実際に確認をしていきたいと思います。
カルノー図とは
カルノー図(Karnaugh Map)とは、1950年代にベル研究所のモーリス・カルノー(Maurice Karnaugh)によって発明され、論理回路の設計などでの論理式の単純化に用いられる図のことを言います。
まずは、以下の簡単な例を見ていきます。
2つのオブジェクトの状態をチェックする
以下の2つのオブジェクト、fooとbarがあるとして、
それぞれの状態(true、もしくはfalse)を判定して、結果を出力する装置を考えます。

以下の3つの条件がみたされた場合、判定結果はtrueとなります。
- foo=false, bar=true
- foo=false, bar=false
- foo=true, bar=true
命題を定義する
まず以下に命題A、Bを定義します。
- foo=true
- bar=true
この命題を上記の条件に当てはめると、
- not A AND B
- not A AND not B
- A AND B
となり、1 OR 2 OR 3という論理式で表すことができます。
条件をそのままプログラミングする
まずは、与えられた条件をそのまま論理式でコーディングしてみます。
def check(a, b):
if (not a and b) or (not a and not b) or (a and b):
return True
else:
return False
if __name__ == '__main__':
status = [
(True, True),
(True, False),
(False, True),
(False, False),
]
for a, b in status:
result = check(a, b)
print(result)
実行すると、以下の結果が得られます。
True False True True
カルノー図を作成する
今回は入力するパラメータが2つなので、2^2 = 4マスの対応表となり、上記の条件に合致するマスにチェック(番号)を入れます。

上記で得られた対応表から隣接するチェックをグループとして囲みます。

すると、横長と縦長の2つのグループに分けることができ、
- 横長は、fooがfalse
- 縦長は、barがtrue
という領域になるので、not A OR Bと表すことができます。
上記でコーディングした判定する関数内の論理式を上記に修正してみます。
def check(a, b):
if not a or b:
return True
else:
return False
if __name__ == '__main__':
status = [
(True, True),
(True, False),
(False, True),
(False, False),
]
for a, b in status:
result = check(a, b)
print(result)
実行すると同じ結果が得られることが確認できます。
True False True True
最後に
今回は入力するパラメータは2つと、シンプルな条件での確認となりましたが、それでも最初に記述した論理式よりずっとシンプルに表現することができました。
さらに複数のパラメータで複雑な条件の下だともっとそのパワーを発揮しますが、入力するパラメータの数が多すぎすると、対応表が煩雑になり、基本的に5、6個以上のパラメータがある場合は向かないようです。