(この記事は 地平線に行く とのマルチポストです)
「ド・モルガンの法則」ってなにそれ?おいしいの?って聞かれたことがあります。
おいしくはないのですが、プログラムを書く上では超大事!です。
ここでは、プログラムを読み書きするうえでド・モルガンの法則をどのように使えばいいかを紹介します。
ド・モルガンの法則とは?
(知っている人は、次の章まで読み飛ばして構いません)
ド・モルガンの法則とは、以下の規則性のことです。
!(A || B) は (!A && !B) に等しい
!(A && B) は (!A || !B) に等しい
(ここで、|| は OR, && は AND, ! は NOT )
確認してみましょう。
!(A || B) は (!A && !B) に等しい
+-------+-------+-------+
| | True | False |
+-------+-------+-------+
| True | False | False |
| False | False | True |
+-------+-------+-------+
!(A && B) は (!A || !B) に等しい
+-------+-------+-------+
| | True | False |
+-------+-------+-------+
| True | False | True |
| False | True | True |
+-------+-------+-------+
簡単ですね。
プログラミングで役立つ場面
その1: if-else
例えば、以下の処理を考えてみます。
private void logic(boolean a, boolean b){
if (a && b) {
// 処理1
} else {
// 処理2
}
}
ここで、処理1が実行される条件が何かというと**「a が true、かつ b が true のとき」**。
では、処理2が実行される条件は?
else
は if
が成立しないときに実行されます。
つまり、 「NOT(if
条件)」のときです。
「(a が true、かつ b が true のとき)ではないとき」
よくわかりませんね。
そこで、ド・モルガンの法則を使います。
!(a && b)
→ !a || !b
つまり、「a が false、または b が false のとき」。
これならわかりやすいですね。
その2: if - else if
続いて、次の処理を考えてみます。
private void logic(boolean a, boolean b){
if (a && b) {
// 処理1
} else if (b) {
// 処理2
}
}
ここで、処理2が実行される条件は?
「b が true のとき」ではないです。
else if
はそれまでの if
条件が成立しないときに実行されるからです。
つまり、「NOT(if条件)かつ(else if 条件)」のときに実行されます。
「(a が true、かつ b が true のとき)ではないとき、かつ b が true のとき」
よくわかりませんね。
そこで、再びド・モルガンの法則を使います。
!(a && b) && b
→ (!a || !b) && b
さらに論理を展開します。
(!a || !b) && b
→ (!a && b) || (!b && b)
→ (!a && b) || false
→ !a && b
つまり、「a が false かつ b が true のとき」。
最初から、以下のように書いてくれていればわかりやすかったのですが…。1
private void logic(boolean a, boolean b){
if (b) {
if (a) {
// 処理1
} else {
// 処理2
}
}
}
その3: while
ループを考えています。
boolean a = true;
boolean b = true;
while (a && b) {
// 処理(この中で、a, b を変更)
}
このループの継続条件は、 while
式の通り**「a が true、かつ b が true のとき」**。
では終了条件は?
継続条件が満たされないとき、つまり NOT(継続条件)です。
!(a && b)
→ !a || !b
つまり、終了条件は**「a が false、または b が false のとき」**。
else
のときと、考え方は同じですね。
# まとめ
ソースコードには、「else
の実行条件」や「 while
の終了条件」など、直接書かれていない条件が存在します。
特に、いいコードほどこうした論理的に導きだせることは書かれていません。冗長になるからです。
それらを明確に理解しながら読むには、論理演算の法則を適用して処理をひとつづつ読み解いていくことが大事です。
その中でも、ド・モルガンの法則は役に立つことが多い法則です。
覚えておいて損はないと思います。
--
え、ド・モルガンの法則なんて知らなくてもコードは読めるし書ける?
そういう人は、天才です。たまにいます。
-
最初は
if
だけがあって、あとから仕様変更でelse if
を継ぎ足すという経緯があると、最初に提示したようなコードになりがちです。 ↩