Lispで思い出した。

Lispと言えばProlog。つーか、こんな関数論理型言語はPrologくらいしかねー。(Lisp関数型言語。schemaは?)
M.Hiroi's Home Page / Prolog Programmingを見てふと思い出す。
そう言えば昔、プログラマー探偵、なんてネタを考えたなあと。

富豪の老人とその奇々怪々な系図の親族たち。老人には相続に関する奇妙な遺言があり、日本の民法には従わない相続が行われる。真犯人は自分の息のかかった人間が相続できるように、遺言の示すアルゴリズムとおりに相続人を殺していく。
文章に記述された誤解しやすい相続条件から、プログラマー探偵はPrologを用いて真実の相続順を割り出す……。

いやまあ、クリプトノミコンって小説で、Perlのソースが提示されたりしたから、毎回違う言語のソースが出てくるプログラマー小説ってのも面白いんじゃないかなと思ったり。主にプログラマーに。そんで2chで「あの小説を書いた奴はどんだけ駄目か」で論争が起こったりするといーなーなんて。
まあ、そんな訳でさくっとSWI-Prologをインストールして、家系を取り扱うデータベースを作ろうと思ったのだ。
で、ググッた結果Greek Gods Family Tree / Genealogy | ludios.orgなんてページを見つけて、早速ギリシャ神話の神々のどろどろの人間関係をデータベースに落とし込んだ。その上で、日本の民法に従って神々の関係を記述しようとしたのだが、血族と姻族の区別でふと止まってしまった。やべえ、ギリシャ神話の神々って、全部Chaosから生まれた血族じゃねーの、と気付いたのだ。
いきなり挫折である。他の国の系図を、と思ったけど、登場する人間の名前は全てアルファベットがよいので、日本のは面倒くさいし、カタカナ表記された外国の王家の系図なんぞ役に立たんしで困っている。
あーあーと思いながら、ちょっと思考を捻ってみると、なんとPerlPrologが扱えることに気付いたり。Search for "module:Prolog" - metacpan.org
これはもしかしたらutf8を使えば漢字名前を使えるんだろうか、と期待したり。それができなくても、PerlPrologを使ったスタンドアローンなアプリが作れるなあとか考えたりした。
それはさておき、系図を記述するのに必要な関係性は三つしかないと気付いた。

  • 親と子の関係
  • 男か女かの区別
  • 年齢の大小関係

各人間間でこれだけの関係性を定義できれば、後は全て演繹作業で全ての関係性を記述できる。
論理ではこれがわかったが、これを実際に自然言語にすると面倒くさくなる。たとえば日本語では「自分から見て両親のうちどちらかか両方を共有する人間」を意味する言葉が、性別と年齢の大小に合わせて「兄」「弟」「姉」「妹」の四つの単語を用意していたりする。しかし英語ではもうちょっと簡易に「brother」「sister」の二つの単語だけで、それに形容詞「old/elder」「young」を付与することで年齢の大小を表す。逆にアフリカのどっかの部族では性別を無視して年齢の大小にのみ着目した区別があるのだと言う。
実際このデータベースを組もうと思った際、こういった細分化された単語は邪魔になりうる。むしろ「自分から見て両親のうちどちらかか両方を共有する人間」を意味する新しい効率的な単語を設定した方がよいくらいだ。
つまるところ、関係性をまず確定させて、それから性別と年齢の大小を計算するべきだ。
まあ、もうちょっとPrologで遊んでみます。

おまけ

ギリシャ神話の神々の家系図のデータベース

sex( male, abderus ).
sex( female, aero ).
sex( male, aether ).
sex( female, alcmene ).
sex( female, alcyone ).
sex( female, apate ).
sex( female, aphrodite ).
sex( male, apollo ).
sex( male, ares ).
sex( female, artemis ).
sex( female, asterope ).
sex( female, athena ).
sex( male, atlas ).
sex( female, calaeno ).
sex( male, coeus ).
sex( male, cronus ).
sex( female, demeter ).
sex( female, dione ).
sex( male, dionysus ).
sex( female, dryope ).
sex( female, echidna ).
sex( female, electra ).
sex( male, electryon ).
sex( male, epaphus ).
sex( male, epimetheus ).
sex( male, erebus ).
sex( female, eris ).
sex( male, eros ).
sex( female, eunomia ).
sex( female, gaia ).
sex( female, geras ).
sex( male, hades ).
sex( female, hebe ).
sex( female, hemera ).
sex( male, hephaestus ).
sex( female, hera ).
sex( male, heracles ).
sex( male, hermes ).
sex( male, hernaphroditus ).
sex( female, hernaphroditus ).
sex( female, hestia ).
sex( male, hyperion ).
sex( male, hypnos ).
sex( male, iapetus ).
sex( male, inachus ).
sex( female, io ).
sex( female, leto ).
sex( male, licymnius ).
sex( female, maia ).
sex( female, melia ).
sex( female, merope ).
sex( male, momus ).
sex( male, moros ).
sex( female, nemesis ).
sex( female, nyx ).
sex( male, oceanus ).
sex( male, pan ).
sex( female, peitho ).
sex( female, persephone ).
sex( female, philotes ).
sex( female, phoebe ).
sex( female, pleione ).
sex( male, ponos ).
sex( male, pontus ).
sex( male, poseidon ).
sex( male, prometheus ).
sex( female, rhea ).
sex( male, rhodos ).
sex( female, semele ).
sex( male, tartarus ).
sex( female, taygete ).
sex( female, tethys ).
sex( male, thanatos ).
sex( female, the_hesperides ).
sex( female, the_keres_and_fates ).
sex( male, three_thousand_sons_and_daughters ).
sex( female, three_thousand_sons_and_daughters ).
sex( female, tyche ).
sex( male, typhon ).
sex( male, uranus ).
sex( male, zeus ).
parent_child( hermes, abderus ).
parent_child( atlas, aero ).
parent_child( pleione, aero ).
parent_child( erebus, aether ).
parent_child( nyx, aether ).
parent_child( electryon, alcmene ).
parent_child( atlas, alcyone ).
parent_child( pleione, alcyone ).
parent_child( erebus, apate ).
parent_child( dione, aphrodite ).
parent_child( zeus, aphrodite ).
parent_child( leto, apollo ).
parent_child( zeus, apollo ).
parent_child( hera, ares ).
parent_child( zeus, ares ).
parent_child( leto, artemis ).
parent_child( zeus, artemis ).
parent_child( atlas, asterope ).
parent_child( pleione, asterope ).
parent_child( zeus, athena ).
parent_child( iapetus, atlas ).
parent_child( atlas, calaeno ).
parent_child( pleione, calaeno ).
parent_child( gaia, coeus ).
parent_child( uranus, coeus ).
parent_child( gaia, cronus ).
parent_child( uranus, cronus ).
parent_child( gaia, cyclopes ).
parent_child( uranus, cyclopes ).
parent_child( cronus, demeter ).
parent_child( rhea, demeter ).
parent_child( epimetheus, dione ).
parent_child( semele, dionysus ).
parent_child( zeus, dionysus ).
parent_child( atlas, dryope ).
parent_child( pleione, dryope ).
parent_child( gaia, echidna ).
parent_child( uranus, echidna ).
parent_child( atlas, electra ).
parent_child( pleione, electra ).
parent_child( epaphus_child6, electryon ).
parent_child( io, epaphus ).
parent_child( zeus, epaphus ).
parent_child( epaphus, epaphus_child1 ).
parent_child( epaphus_child1, epaphus_child2 ).
parent_child( epaphus_child2, epaphus_child3 ).
parent_child( epaphus_child3, epaphus_child4 ).
parent_child( epaphus_child4, epaphus_child5 ).
parent_child( epaphus_child5, epaphus_child6 ).
parent_child( iapetus, epimetheus ).
parent_child( chaos, erebus ).
parent_child( erebus, eris ).
parent_child( chaos, eros ).
parent_child( aphrodite, eunomia ).
parent_child( hermes, eunomia ).
parent_child( chaos, gaia ).
parent_child( erebus, geras ).
parent_child( cronus, hades ).
parent_child( rhea, hades ).
parent_child( hera, hebe ).
parent_child( zeus, hebe ).
parent_child( gaia, hecatonchires ).
parent_child( uranus, hecatonchires ).
parent_child( erebus, hemera ).
parent_child( nyx, hemera ).
parent_child( hera, hephaestus ).
parent_child( zeus, hephaestus ).
parent_child( cronus, hera ).
parent_child( rhea, hera ).
parent_child( alcmene, heracles ).
parent_child( zeus, heracles ).
parent_child( maia, hermes ).
parent_child( zeus, hermes ).
parent_child( aphrodite, hernaphroditus ).
parent_child( hermes, hernaphroditus ).
parent_child( cronus, hestia ).
parent_child( rhea, hestia ).
parent_child( gaia, hyperion ).
parent_child( uranus, hyperion ).
parent_child( erebus, hypnos ).
parent_child( gaia, iapetus ).
parent_child( uranus, iapetus ).
parent_child( oceanus, inachus ).
parent_child( tethys, inachus ).
parent_child( inachus, io ).
parent_child( melia, io ).
parent_child( coeus, leto ).
parent_child( phoebe, leto ).
parent_child( electryon, licymnius ).
parent_child( atlas, maia ).
parent_child( pleione, maia ).
parent_child( oceanus, melia ).
parent_child( atlas, merope ).
parent_child( pleione, merope ).
parent_child( erebus, momus ).
parent_child( erebus, moros ).
parent_child( gaia, mountains ).
parent_child( erebus, nemesis ).
parent_child( chaos, nyx ).
parent_child( gaia, oceanus ).
parent_child( uranus, oceanus ).
parent_child( aero, pan ).
parent_child( dryope, pan ).
parent_child( hermes, pan ).
parent_child( merope, pan ).
parent_child( aphrodite, peitho ).
parent_child( hermes, peitho ).
parent_child( demeter, persephone ).
parent_child( zeus, persephone ).
parent_child( erebus, philotes ).
parent_child( gaia, phoebe ).
parent_child( uranus, phoebe ).
parent_child( oceanus, pleione ).
parent_child( tethys, pleione ).
parent_child( erebus, ponos ).
parent_child( gaia, pontus ).
parent_child( cronus, poseidon ).
parent_child( rhea, poseidon ).
parent_child( poseidon, poseidon_child1 ).
parent_child( poseidon_child1, poseidon_child2 ).
parent_child( poseidon_child2, poseidon_child3 ).
parent_child( iapetus, prometheus ).
parent_child( gaia, rhea ).
parent_child( uranus, rhea ).
parent_child( aphrodite, rhodos ).
parent_child( hermes, rhodos ).
parent_child( poseidon_child3, semele ).
parent_child( chaos, tartarus ).
parent_child( atlas, taygete ).
parent_child( pleione, taygete ).
parent_child( gaia, tethys ).
parent_child( uranus, tethys ).
parent_child( erebus, thanatos ).
parent_child( erebus, the_hesperides ).
parent_child( erebus, the_keres_and_fates ).
parent_child( oceanus, three_thousand_sons_and_daughters ).
parent_child( tethys, three_thousand_sons_and_daughters ).
parent_child( aphrodite, tyche ).
parent_child( hermes, tyche ).
parent_child( gaia, typhon ).
parent_child( tartarus, typhon ).
parent_child( gaia, uranus ).
parent_child( cronus, zeus ).
parent_child( rhea, zeus ).

father_child(X,Y) :- parent_child(X,Y), sex(male, X).
mother_child(X,Y) :- parent_child(X,Y), sex(female, X).
parent_son(X,Y) :- parent_child(X,Y), sex(male, Y).
parent_daughter(X,Y) :- parent_child(X,Y), sex(female, Y).
grand_parent_child(X,Y) :- parent_child(X,Z), parent_child(Z,Y).
parents_child(X,Y,Z) :- parent_child(X,Z), parent_child(Y,Z).