プログラムのバグとは何か

ゲームやいろんなアプリはプログラムで出来ています。プログラムに問題があることを「バグがある」という言い方をします。では、バグとは何でしょう。

プログラムとは

プログラムは作業手順を示すものです。今回はゆうきカフェ(仮)で働くウェイトレスロボットのプログラムを考えてみましょう。ウェイトレスがやることを作業手順としてプログラムにします。では、ウェイトレスは何をしているでしょうか。基本的にこんな感じでしょうか。

  1. お客さんを空いてる席に連れて行く
  2. 注文を聞く
  3. 注文をキッチンに知らせる
  4. キッチンから食べ物をお客さんのところに運ぶ
  5. 食べ終わったら会計をする
  6. 皿を片付ける

これだけのことができたらウェイトレスとして使えそうですね。そして、これも1つのプログラムです。作業手順を示していますからね。

IF THEN

ただ、もっとプログラムらしくしましょうか。プログラムはIF THEN で書かれています。つまり、このことがあったときにこれをやる。という書き方をします。「ボタンが押されたらモーターを動かす」とかそういうのです。これでいくと、例えば1つめはお客さんが来たら席に連れて行きます。お客さんが来てないのに席に連れて行く必要はないのです 。別のロボットとおしゃべりしててもいいですしね。ですから席に連れて行くって動きをする条件はお客さんが来ることなのですから IF お客さんが来る THEN お客さんを席に連れて行く ということになります。この書き方で全てを書き直すと

  1. IF お客さんが来る THEN お客さんを席に連れて行く
  2. IF お客さんが注文する THEN お客さんの注文を聞く
  3. IF 注文を聞き終わる THEN キッチンに知らせる
  4. IF お客さんの料理ができる THEN 料理を運ぶ
  5. IF 食べ終わる THEN 会計する・皿を片付ける

会計したら即座に皿を片付けできますから5と6は一緒にできますね。このプログラムを書き込んだロボットがいればお客さんにちゃんとサービスできそうです。しかし、このプログラムには問題があります。このロボットは席が空いてなかったらどうするでしょうか。

想定していない事態:限界状態

1のIFを満たすのに、THENの行動ができません。ロボットには想定できていない状況です。ロボットはどう動くでしょうか。それは、空いてる席をどうやって探していたかに大きく影響します。例えば、目を使って周りをとにかく見回すロボットだった場合、空いてる席がないかずっと探して探して探して、、、お客さんが来たとたんに店の中を永遠に探しまわるでしょう。だって、席が空いてないなんて考えてなかったんだから探せばあるわけだからずっと探しますよね。または、「席を窓際から探して空いている席に入れる」とプログラムされていた場合、2つのパターンがありそうです。1つはこれまた永遠に探し続けるパターン、最後まで探してまた窓際に目を向けて探すんです。1つは最後まで探したけど見つからないから最後の席に連れて行ってしまうというパターンです(何故そうなるかはfor文がわかると分かる。今回は割愛)。どちらにしろ、まともな対応はできません。このように、何かの限界というのはプログラムの問題になりやすいです。こういうことを想定する必要があります。だから、1だけちょっと書き直しましょう。

  1. IF (お客さんが来る AND 席が空いている) THEN お客さんを席に連れて行く

変わった書き方をしましたが、これはお客さんが気た時に同時に席も空いていた時だけお客さんを連れて行く というのをANDを使って書いてみたものです。これなら問題なさそうですね。ですが、不親切です。お客さんが来ても席が開いていなければロボットはなにもしないわけです。席が開いていないのかロボットが壊れているのかわかりません。これもプログラムによくあることで、とりあえず問題を避けるだけの対策(めんどくさいのでこれをよくやってしまう)をすると問題はないけど、不親切なプログラムになりがちです。この場合はせめて

  1. IF (お客さんが来る AND 席が空いている) THEN お客さんを席に連れて行く
  2. IF (お客さんが来る AND 席が空いていない) THEN お客さんに席が空いてませんと言う

という条件を増やすべきでしょう。さて、これでとりあえずお客さんを席に誘導できそうです。ロボットは注文をとりはじめました。ここで、また問題があります。注文を聞いてる時に新しいお客さんが来たらどうするでしょう。

想定していない事態:同時発生とロック

人間なら注文を聞いてる途中で新しいお客さんの方に行くのは有り得ません。失礼ですからね。でも、さっきのプログラムには IF (お客さんが来る AND 席が空いている) THEN お客さんを席に連れて行く という条件がありました。この条件を満たしてるかどうかを考えて下さい。どうです?満たしてますよね。だから、ロボットは新しいお客さんを席に連れて行くべきなのです。少なくとも連れて行っても文句は言えません。これもよく起きる問題です。何かの作業をしている時に他の条件が成立してしまうということです 。これは起こっても文句が言えないことです。ではどうしましょう。一番簡単なのは

  1. 作業中は他のIFを無視する

ということです。これでだいたい問題を解決できます。ですが、完璧ではありません。もし、このお客さんが注文にものすごく悩んだらどうなるでしょう。このロボットは全く動くことが出来ません。新しいお客さんが来ても、席にいる人が「お会計お願いします!」と言っても無反応です。ロボットはロックされた状態になります。注文が完了すれば動けるのでまぁ、まだ許せますが一番最悪なのはお客さんが注文の途中で「ちょっとトイレ言ってくる」といって帰ってしまうことです。その場合このロボットは注文の途中なので、この人が戻ってきて何かを注文するまで動くことが出来ません。店長はしぶしぶリセットボタンを押すしかなくなります。よくやる対策が

  1. ある時間経ったら作業を中止する

というプログラムを仕込むことです。これをやれば店長が自分からリセットを押す必要はなくなるし、注文の遅いお客さんから離れてロボットを有効に使うことも出来ます。そのお客さんは、注文したければもう一度呼べるし、その時はいい注文の仕方をしてくれるでしょうしね。これを加えればどこかで同時に発生しても、かりに何かの理由で作業が終わらなくてもなんとかなりそうです。

今回試しにロボットのプログラムを考えてみましたが、注文をとるところまでで既に2つもバグを出してしまいましたね。バグというのはプログラムの問題ですが、別に最初に書いたものがまったくだめだったわけじゃありません。ある条件ならちゃんと動くしね。バグとは基本的には「想定外」なことが起きた時にトラブって初めて気づくものです。今回は忘れがちな「限界」と「同時発生」を扱いました。他にも有名なものが沢山ありますが、そろそろ眠いのでこのへんで。

コメントを残す