trinity
Trinity は、 Wikidata のシステムを極限まで一般化する試みです。トリプルという構造で、ユーザーや記事や投稿記録などのありとあらゆるものを表すことを試みます。実用性は考慮していません。
Trinity のモデル (1)
Trinity は、最初に、次のような原理を立てて設計しました。
- 全ては ID で表される。
- 全ての関係はトリプルで表される。
- 全ては、物理的に削除したり上書きすることは出来ず、ただ一方向に増えていく。
- 全ては、論理的に削除でき、論理的に上書きでき、秘匿できる。
ID
ID は、 Trinity において扱う全てに割り当てられる識別番号です。
Trinity は、全ての物事に ID を割り当てます。これは連番でも UUID でもよいのですが、とにかく重複がないようにします。
全てというのは、文字通りの全てです。ユーザーや、記事や、投稿記録や、そして、それらが変化したというイベントの全てに ID が割り当てられます。
ID セット
ID セットは、 Trinity において発行された全ての ID を記録する集合です。
本来はトリプルセットと統一したかったのですが、そうすると無限後退が発生してしまうので、やむを得ずに独立させています。ここでいう無限後退は、次のようなものであり、セミコロンで付け加えられているように、全てのトリプルへ ID を与えているために発生するものです。
x, ID [X] が登録されているかは [A] である, true; y.
y, ID [X] が登録されているかは [A] である, true; z.
z, ID [X] が登録されているかは [A] である, true; w.
……
トリプル
トリプルは、 x, p, a
という三つ組です。 x
は主語であり、 p
は述語であり、 a
は目的語です。主語は ID です。述語は ID です。目的語は ID かバイト列です。
トリプルは、三つの補助情報を含みます。一つ目はトリプル自体の ID で、二つ目はトリプルが作られた時間で、三つ目はトリプルを作ったユーザーの ID です。
トリプルが作られた時間も、本来は x, [X] が作られた時間は [A] である, 2020-03-20
というようなトリプルとして表したかったのですが、無限後退を発生させてしまうため、やむを得ずにトリプルに組み入れました。ここでいう無限後退は、次のようなものであり、全てのトリプルに作成時刻を与えているために発生するものです。
x, [X] が作られた時間は [A] である, 2020-03-20; y.
y, [X] が作られた時間は [A] である, 2020-03-20; z.
z, [X] が作られた時間は [A] である, 2020-03-20; w.
……
トリプルを作ったユーザーの ID も、本来は x, [X] を作ったユーザーの ID は [A] である, a
というようなトリプルとして表したかったのですが、無限後退を発生させてしまうため、やむを得ずにトリプルに組み入れました。ここでいう無限後退は、次のようなものであり、全てのトリプルに作成者を与えているために発生するものです。
x, [X] を作ったユーザーは [A] である, a; y.
y, [X] を作ったユーザーは [A] である, a; z.
z, [X] を作ったユーザーは [A] である, a; w.
……
Trinity においては、全てのトリプルにも ID が割り当てられます。これが Resource Description Framework を超える Trinity の特色です。このようにすることで、極度なまでの一般性を獲得しましたが、その代わりに無限後退と戦わなければならなくなりました。
トリプルセット
トリプルセットは、 Trinity が扱う全てのトリプルを記録する集合です。トリプルセットに現れる全ての ID は、 ID セットにも含まれていなければなりません。
System User
System User は、システムそのものをユーザーとしたものです。そもそも、トリプルにはユーザーの欄がありますが、そうなると最初のトリプルは誰が作るのかという問題が出てきます。これを解決するのが System User です。
[X] は ID [A] を ID セットに追加した
"[X] は ID [A] を ID セットに追加した" は、その字の通りの述語です。最も始めにあるイベントです。この述語は、全ての ID に適用しようとすると無限後退を引き起こします。そのため、ある ID x
は、次の二つの場合に分かれているというルールがあります。
?user, [X] は ID [A] を ID セットに追加した, x
というトリプルがある。?user, [X] は ID [A] を ID セットに追加した, ?id
というトリプルで、その ID がx
であるものが存在する。
ブートストラップ
System User で指摘したように、どこかで輪は閉じないといけない訳です。その閉じ方をブートストラップとします。
System User の ID を x
として、 "[X] は ID [A] を ID セットに追加した" の ID を y
として、ある時刻を t
として、ブートストラップは次のようになります。
x, y, x; z, t, x.
x, y, y; w, t, x.
z
と w
は、トリプルを表す新しい ID です。これを実装したのが generate_initial_model
です。
無限後退
無限後退は、全ての ID が持つ属性を、あるいは全てのトリプルが持つ属性を、モデルの内部で扱おうとした時に発生します。
全ての ID が持つことになるような属性は、単純に排除しました。これは、 ID セットを単純な集合に保ちたいためです。
全てのトリプルが持つことになるような属性は、必要性を考えて、作成日時と作成ユーザーの二つだけを取り入れました。これは、ブートストラップの大きさを最小限にするためです。