ソフトウェアは現実をどう捉えるべきか ─ モデリングという抽象化の技術

@Panda_Program

現実、ソフトウェア、モデリングの関係

この記事は、現実とソフトウェアとモデリングの関係を哲学の観点から整理する試論です。この記事を通して、読者の方のモデリングという行為に対する理解が深まれば幸いです。

なお、哲学といっても特定の哲学者の思想には触れないので前提知識は不要なので気楽に読み進めてください。

ソフトウェアが絶えざる変更に晒されるのは、現実と乖離するためである

ソフトウェアがいつも変更に晒されているということはソフトウェア開発者にとって常識です。では、なぜソフトウェアは変更に晒されているのでしょうか。立ち止まって考えてみましょう。

ソフトウェアが対象にしている現実が絶えず変化しているため、対象の変化に応じてソフトウェアも変化する必要があると言えるでしょう。これを仮の結論とします。

しかし、ソフトウェアは本当にそのもの現実を対象としているのでしょうか。そうではないように思えます。

例えば、配送管理システムを考えてみましょう。あなたは荷物を会社宛に配送し、2日後に担当者から荷物を受け取った旨の連絡が来ました。しかし、ネットで確認できる追跡情報上では何らかの手違いで荷物がまだ会社には未着だと表示されています。担当者のところに荷物が届いたことは現実であるのに、ソフトウェア上では荷物が届かないままです。

つまり、ソフトウェアはこの荷物の現在地そのものと連動しているわけではないのです。ここに現実とソフトウェアの管理するデータのズレがあります。

ソフトウェアは計算機上で動くデータ加工のロジック群である

ではソフトウェアの対象とは実際のところ何でしょうか。

そもそもソフトウェアとは、データを受け付け(入力)、データを加工し、加工したデータを出力するロジックであり、このロジックはコンピュータ上で動作するという特徴を備えています。

計算ロジックは現実そのものではありません。ソフトウェアは「配送先に届ける荷物のバーコードを配達員が読み取ったら、荷物の配送ステータスを『届け済み』にする」というロジックを実行しているだけです。

荷物を受け取ったタイミングで配達員が間違ってこの操作をしたら、荷物は即座に届け済みになってしまいます。これも現実に反します。このため、ソフトウェアの対象は現実そのものではないということができます。

ソフトウェアの対象は計算可能なもの、つまりデータです。そして、ソフトウェアを構成するものは計算ロジックです。何らかのデータがハードウェアを通してソフトウェアという計算ロジックに送られた結果、ソフトウェアはデータを計算(加工)してハードウェアに出力します。

つまり、ソフトウェアを単なる関数とみなすとf(input) = outputと書けます。

ソフトウェアエンジニアは、このソフトウェアという巨大な関数f(x)を構築し、書き換え続けています。ソフトウェアの計算ロジックをコンピュータ上で実行するためにソフトウェアエンジニアはプログラムを書いているのです。

改めて、ソフトウェアが対象しているものは何か

さて、ここからが本題です。先ほどソフトウェアは現実そのものを扱うわけではないと書きました。次にソフトウェアの役割を大きな視点から捉えました。すると次のことが自然と導かれます。

それは、ソフトウェアの対象とは現実の中の計算可能な側面であるということです。現実を計算可能なものとするためにはデータ化が必要です。

例えば、宅配便の荷物であればダンボールで包んで送るでしょう。ダンボールの大きさに焦点を当てると、立方体の縦横高さの数値が重要になります。極端に書くと縦横高さの3つの数値こそが荷物を表現しているのです。

ここでは、ダンボールの色や角がへこんでいることやガムテープがなぜか側面に貼られていることなどの現実は関心外でデータ化されません。このように不要な部分を扱わないことを捨象といいます。

ソフトウェアにおけるモデリングとは何か

現実から何らかの要素を抽出してソフトウェア上で計算可能なデータとして扱うこの行為こそが、ソフトウェア文脈におけるモデリングというものです。モデリングのプロセスとは、現実の物事を数値化(デジタル化)してデータを抽出するという現実の抽象化と呼ぶことができます。

例えば、人間というものを考えてみましょう。実のところ人間一般というものをソフトウェアで扱うことはありません。ソフトウェアには目的があるためです。そこで人間というものを特定のソフトウェアのためにモデリングすると一人の人間は「飛行機の搭乗者」「患者」「ライター」「家族の一員」などとされるわけです。

これらは全て私という一人の人間でもあります。飛行機で東京から北海道に行ったり、風邪を引いて病院で受診したり、今このように記事を書いていたり、家ではそれに当たるというようなある側面を切り取ったものです。

飛行機のチケット予約サービスであれば出発時刻や目的地、飛行機の便や座席の位置をデータ化します。電子カルテであれば受診歴や病歴、このサイトのブログシステムなら書いた文章や公開した時間、戸籍管理システムなら本籍地や家族関係をデータとして扱います。

深く多様な現実の中から、ある事物のある側面を抽出するのがモデリングという行為です。モデリングはまた、現実に存在する物事の豊穣なディテールを余分なものとして切り落とし(捨象)、本質というコアを探し出すためにある特定の視点から役に立つデータを画一的に抜き出すこと(抽象)でもあります。

端的に書くと、ソフトウェア文脈のモデリングとは、現実の物事をソフトウェアが計算できるように、ソフトウェアの目的に関する要素だけデータの塊として抽出することと言えるでしょう。

現実の物事をデータ化するだけでは何のことかわかりません。100, 70, 40というデータだけがあっても何を指しているかわかりません。これをそれぞれ縦横高さと名付けることで荷物として送るダンボールのサイズだとわかるのです。ただのデータを集めて、人間が意味ある情報として扱えるようにすることもまたモデリングの役割です。

ソフトウェアは計算ロジックの集まりであるが、なぜ現実とは連動しないのか

ソフトウェアは計算ロジックの集まりだと書きました。計算ロジックで大事なことは何でしょうか。それは、間違ったロジックを差し込まないことです。ソフトウェアのバグとはプログラマが間違ったロジックを仕込むことなのです。

ソフトウェアのバグとはレトリックであり、ソフトウェアは与えられた式通りに計算しているのですからソフトウェアにはバグはありません。プログラマが間違った計算ロジックを差し込むだけなのです。

では、そもそも計算ロジックにおける間違いとは何でしょうか。計算ロジックに間違いがなければ、ソフトウェアの計算結果は常に現実と一致するのでしょうか。

ここで哲学議論の考え方を借りてみましょう。以下は、How to Argue - Philosophical Reasoning: Crash Course Philosophy #2 というYouTubeの動画を参考にしています。

論理的に正しいことと現実的に正しいことを区別する

ここでは演繹的推論(deductive reasoning。または演繹的な論証 deductive argument)を取り上げます。演繹的推論とは、ある前提を元に論理的に結論を導き出す方法です。全ての前提が正しければ結論も正しいと考えます。有名なのはアリストテレスが定式化した三段論法です。

前提1: すべての人は死ぬ(大前提)
前提2: ソクラテスは人である(小前提)
結論 : よって、ソクラテスは死ぬ

これは valid(有効な、妥当な)な議論です。人は死ぬという誰にでも起きる普遍的な事象をソクラテスという個人に当てはめることで、ソクラテスという人間が将来死んでしまうことを推測し、結論づけています。

次にこの議論はどうでしょうか。

前提1: すべての人は死ぬ
前提2: ソクラテスは人である
結論 : よって、ソクラテスはプラトンの師匠である

これは前提は正しいものの結論が間違っています。これは invalid (有効ではない、不当な)な議論です。二つの前提だけではこの結論は導き出せないからです。しかし、歴史に照らし合わせると確かにソクラテスはプラトンの師匠ではあります。

さらにもう一つの議論を検討します。

前提1: 全ての人間には尻尾がある
前提2: 私は人間である
結論 : よって、私には尻尾がある

この議論は直感的におかしいと思われるでしょう。ただし、論理の世界に閉じるとこれは valid な議論なのです。ロジックだけを見ると、普遍的な前提と個別の前提を元に正しい結論を導き出しているからです。

一方、現実的にこの議論は間違っています。人間に尻尾はありません。前提1の「全ての人間には尻尾がある」が間違っているのです。つまり、論理的に正しいということと、現実的に正しいということは異なるのです。そこで前者は valid と呼び、後者は true と呼び分けます。

この考え方を使うと、今までの議論の違和感を説明できます。例えば議論2の「よって、ソクラテスはプラトンの師匠である」という結論は、論理的に invalid であるが現実では true です。一方、「よって、私には尻尾がある」は論理的に valid だが、現実的には false でありそんな事実は現実にありません。

総合すると、健全な演繹的推論は「論理的に間違っていないこと(validity)と全ての前提が現実的に正しいこと(all true premises)」が必要なのです。

ソフトウェアは論理の計算式である

ソフトウェアの議論に戻りましょう。ソフトウェアは計算ロジックの集まりだと書きました。ここまでの議論を踏まえると、ソフトウェアは validity の化身と呼べます。計算自体は計算式に沿って順番に間違いなく(= valid に)処理されるからです。

「ソフトウェアは書いた通りに動くのだから、バグが出たらソフトウェアの不具合ではなく自分の書いたコードをまずは疑え」というデバッグにおける有名な格言もこのことを暗に示しています。ソフトウェアは書いた通りにしか動かず、「今日はハロウィンだからお菓子をくれないと計算結果にイタズラしちゃうぞ」などとは考えないわけです。

ただし、ソフトウェアは常に valid だといえども常に現実のモデルと一致しているわけではありません。ソフトウェアが true を保証することはないのです。

まさにこれが冒頭の荷物の配達の例です。荷物は会社に届いているのにバーコードが読み取られずシステム上は未配達であるケースです。このとき荷物は届いているか改めて確認してみましょう。荷物は担当者の手元にあるのでこの回答は true であり、かつバーコードが読み取られていないのでソフトウェア上では未配達であるということもまた valid なのです。

現実は様々な要因によって変わります。現実が変わるとソフトウェアで扱うモデルも変わります。荷物の配送にドローンという選択肢が加わることを想像してみてください。今までの荷物の配達経路の計算ロジックはドローン配送には適用できません。

現実が変わり、モデリングが変わればソフトウェアという計算ロジックも変わります。この true と valid のズレを揃えていくこと、変わりゆく現実に対してソフトウェアを追従させ続ける力学こそ、ソフトウェアが絶えざる変更に晒される理由なのです。

Happy Coding 🎉

パンダのイラスト
パンダ

記事が面白いと思ったらツイートやはてブをお願いします!皆さんの感想が執筆のモチベーションになります。最後まで読んでくれてありがとう。

  • Share on Hatena
  • Share on Twitter
  • Share on Line
  • Copy to clipboard