Edited at

論理演算子を論理学的に理解する

More than 1 year has passed since last update.

複雑な論理演算をするときには、いくつか注意することがある。

一つ目は、「演算子の優先順位」で、二つ目は「演算子の入れ替え」。

一つ目は簡単だが、演算子には優先順位がある。詳しくは以下URL。

https://docs.ruby-lang.org/ja/latest/doc/spec=2foperator.html

a && b || c

は、「aかつbが真、またはcが真のとき、真」を意味する。

「aが真かつ、bまたはcが真のとき、真」としたければ、

a && ( b || c )

とする。

二つ目は、上の式を否定したい時などに注意しなければならないことで、

「aかつbが真、またはcが真のとき、偽」としたければ、

! (a && b || c)

でもよいが、これは、

(!a || !b ) && !c

「aまたはbが偽かつ、cが偽のとき、真」と同値である。

具体例を考えれば、この同値関係は納得できるだろうが、プログラムを書いてる間にいちいち考えるのは面倒だ。そこで、論理学の公式を覚えておくと、具体的に考えずに、簡単に書き換えができる。

覚えておくとよい論理学の公式は以下の通りだ。

not not A = A

A and A = A (and の同一律)

A or A = A (orの同一律)

A and B = B and A (and の交換則)

A or B = B or A (or の交換則)

A and B and C = A and (B and C) (and の結合則)

A or B or C = A or (B or C) (or の結合則)

A and True = True and A = A

A and False = False and A = False

A or False = False or A = A

A or True = True or A = True

A or A and B = A and B or A = A

A and (A or B) = A and (B or A) = (A or B) and A = (B or A) and A = A

A and not A = not A and A = False (排中律)

A or not A = not A or A = True (排中律)

A and (B or C) = (B or C) and A = A and B or A and C (分配律)

A or B and C = B and C or A = (A or B) and (A or C) (分配律)

not(A and B) = not A or not B (ド・モルガン則)

not(A or B) = not A and not B (ド・モルガン則)

大体の公式は「当たり前」だ。覚えておくのは、最後の4つくらいだろう。これらを使って先ほどの例を考える。

! ( A && B || C)

= !( A && B ) && !C

= ( !A || !B ) && !C

となる。もっとややこしい状態を考える。

「A=Bが真であり、かつC=DまたはC=Eでないとき、ある処理を実行する」を作りたい場合、順番に、


sample.rb

if A == B 

unless C == D || C == E
  #処理
end
end

と書いてもいいが、あまり階層を作りたくないので、一つの式で済ませたい。

論理学の公式を使うと、

A=B && !(C=D || C=E)

は、

A=B && (C!=D && C!=E)

とできるので、


sample.rb

if A == B && (C != D && C != E)

 #処理
end

みたいにする。プログラムのif文は、「もし〜なら」で理解しておくより、「〜が真ならば」で理解しておいた方が、論理演算子の処理が楽になる。