目次
はじめに
テセウスの船は同一性についての有名なパラドックスです。
ものすごく簡単に説明すると、船をちょっとずつ改造していって、全部違う部品になってしまったらそれは元の船と同じ船と言えるのか?という問題です。
でもちょっと待ってください。
もしあなたがプログラマなら、この問題、すんなりと説明できてしまうんじゃないだろうか?という思考が脳裏をよぎったためこのメモを書き始めることにしました。
船のインスタンスと変数
さて、ここでは、Javaコードでオブジェクト指向を使って説明を進めたいと思います。
まず、テセウスの船をインスタンス化しましょう。
Ship shipOfTheseus = new Ship(); // インスタンス状態1
いいですね。意味合いとしては、shipOfTheseus
(テセウスの船)という変数に新しい船を割り当てた感じです。
交換される部品
では次に交換される部品を表現しましょう。
船(Ship)クラスに部品を交換したり修理したりするようなメソッドがある体でいきましょう。
こんな感じでどうでしょう。
shipOfTheseus.addMast(new Mast()); // インスタンス状態2
shipOfTheseus.repairDeck(new Lumber()); // インスタンス状態3
shipOfTheseus.reRigSails(new Sails()); // インスタンス状態4
船の部品が交換され、状態がどんどん変化している様子が目に浮かびます。
船はどんな状態?
さて、帆を張り直した時点で船インスタンスの状態は4ですね。
状態は1から始まって、その後2、3と変化し、今現在は4という状態になりました。
最初の時よりもマストが増え、甲板の板は修理され、また帆は綺麗に張り直されています。
ここでポイントなのは、どんなに状態が変わろうとも
変数shipOfTheseus
が指すインスタンスである「船」は変数名が示す通り「テセウスの船」であり続けているということです。
「テセウスの船」の実体は船(Ship)クラスのインスタンスとしているのでした。
インスタンスはクラスを基にして生成されるものであり、クラスの概念の範囲内の存在です。
つまり、クラスの概念の範囲内であれば、どんな形態をもとれる、と言い換えることもできます。
今回、船(Ship)クラスは部品を交換したり修理したりするメソッド(機能)があるわけなので、
船のインスタンスについてもそれらを実行できるものということです。
ですから、ある時点で船のインスタンスにマストがあったり、なかったりできるわけです。
そして、マストがある船も、ない船も、「船(Ship)である」と言えそうです。
ちょっと分かりにくいかもしれませんが、どちらであってもそれが「船(Ship)である」と認識できるわけです。
こう考えてみると、我々が船のインスタンスを通して見ているのは、
今の状態のその船自体ではなく、船(Ship)クラスから作られたものである、ということになります。
船自体が交換されたら?
さて、ではもう少し思考を続けましょう。
インスタンスがスッポリ入れ替わってしまった場合はどうでしょうか。
元のテセウスの船のパラドックスでは基本的にはちょっとずつ部品が入れ替わるのですが、
ためしに一気に入れ替えてみました、という話です。
shipOfTheseus = new Ship(); // 新しい別のインスタンス
コードにするとこんな感じですね。
いかがでしょうか。shipOfTheseus
が「テセウスの船」です。
中身は違うインスタンスになりましたが、変数shipOfTheseus
が「テセウスの船」を表しているという意味合いは変化しないため、
この船を観測する側の視点から見ている分には、特段問題はなさそうですね。
パラドックスに回答する
テセウスという英雄が、船で長い旅をしています。
旅の途中で、船の一部が壊れたり、古くなったりすると、その部分を新しいものに取り替えていきます。
時間が経つにつれて、船のすべての部分が一度は取り替えられ、元の部分は一つも残っていない状態になります。
ここで問題が出てきます。すべての部分が取り替えられた後の船は、まだテセウスの船と言えるのでしょうか?
もし答えが「はい」だとすると、それはどの部分がテセウスの船をテセウスの船として定義しているのでしょうか?
もし答えが「いいえ」だとすると、いつテセウスの船はテセウスの船でなくなったのでしょうか?テセウスの船より引用
Q1: すべての部分が取り替えられた後の船は、まだテセウスの船と言えるのでしょうか?
答えは「はい」です。なぜなら「テセウスの船」は変数shipOfTheseus
が参照する船(Ship)クラスのインスタンスであればよいだけであるためです。
Q2: もし答えが「はい」だとすると、それはどの部分がテセウスの船をテセウスの船として定義しているのでしょうか?
答えとしては、部分ではなく変数が指し示す全体(インスタンス)をテセウスの船として定義しているになります。
コードで考えると分かりやすいのですが、これはまさしく、
Ship shipOfTheseus = new Ship(); // テセウスの船を定義した部分
観測者は常に、テセウスの船を変数shipOfTheseus
を通して観測することになるわけです。
おわりに
とうことで、オブジェクト指向で考えられるプログラマであれば、意外とすんなりとテセウスの船を説明できてしまうのではないでしょうか。
現実世界で起こる事象をそのまま理解するのが難しいような場合は、このようにプログラミング言語の視点で考えてみることで、
一段高い次元から物事を捉えられるようになるのではないでしょうか。
この思考は、現実はコンピュータシミュレーションかもしれないという「シミュレーション仮説」にも繋るような気がしており、面白い思考実験となったと思います。
また「シミュレーション仮説」については別の機会にでも。それではまた。