はじめに
Hamee Advent Calendar 23日目の記事です
人間が得意な事とコンピュータが得意な事を今更ですが実感しました
道具
ド・モルガンの定理
\neg(P \vee Q) = \neg P \wedge \neg Q \\
\neg(P \wedge Q) = \neg P \vee \neg Q
恐らく数学Aで習うド・モルガンの定理
プログラム的に書くとこうなります
!(P || Q) === !P && !Q
!(P && Q) === !P || !Q
証明はやりませんが、集合論っぽくやるなら左辺の任意の元が右辺に含まれる事
また、右辺の任意の元が左辺に含まれる事を示してあげるといいです
今回はド・モルガンの定理を用いて既存コードのリファクタをしてみます
問題①
下記をド・モルガンを使いリファクタせよ
if ($a === '' || $a === 0) {
// 処理A
} else {
// 処理A
// 処理B
}
回答例
①処理Aを外に出す
if ($a === '' || $a === 0) {
} else {
// 処理B
}
// 処理A
②if文がtrueの際に実行することが無いのでelseを削除
if (!($a === '' || $a === 0)) {
// 処理B
}
// 処理A
③ド・モルガンの定理を利用
if ($a !== '' && $a !== 0) {
// 処理B
}
// 処理A
これくらいならド・モルガンとか使わなくても一発で書けそうですが、
なんとなく書いているとミスが起こりやすいので、使える定理は使った方がバグ撲滅になるかと思います。
問題②
下記をド・モルガンを使いリファクタせよ
if ($a === '' || ($a !== 0 && $a !== 'a')) {
// 処理A
} else {
// 処理A
// 処理B
}
回答例
①処理Aを外に出す
if ($a === '' || ($a !== 0 && $a !== 'a')) {
} else {
// 処理B
}
// 処理A
②if文がtrueの際に実行することが無いのでelseを削除
if (!($a === '' || ($a !== 0 && $a !== 'a'))) {
// 処理B
}
// 処理A
③ド・モルガンの定理をif文全体に利用
if ($a !== '' && !($a !== 0 && $a !== 'a')) {
// 処理B
}
// 処理A
④ド・モルガンの定理をif文の内部で利用
if ($a !== '' && ($a === 0 || $a === 'a')) {
// 処理B
}
// 処理A
1から書く時はこんな冗長な書き方はしないと思いますが、保守とかやっていると変なコードを見かけることもあります
たかだか数行の世界ではなく何万行の世界でやっているとそんな時もありますよね
おわり
群とか環とか体とか集合を扱う研究をしていたので、数学とプログラムを結びつけれたらなと思うのですが、
この程度なら正直数学の「す」の字も必要ないですorz
ただ、なんとなく書くのではなく1行1行の処理でバグを生まないか、数学の証明を書く気持ちでコードを書くとバグは減るかなって思います