以下の文章内の「RDFがDAGである」という内容は間違いです。
DAGは「無閉回路有向グラフ」を意味し、サイクルを含むことができるRDFグラフは当てはまりません。「RDFは有向グラフである」が正しい表現となります。
お詫びして訂正します。
参照先ページののコメント欄も合わせてご覧ください。
RDFがDAGなのは、それ自体も重要なのだけれど、しかしそれのみでXMLと対比させるのは評価として正しくないと感じる。
僕が人にRDFを説明するときは、「XMLやCSVやYAMLは、情報を直列化するための仕様だけれど、RDFっていうのは情報そのものを記述するための仕様だ」って言うようにしている。RDF自体がDAGとして構築されるために誤解が多いのだけれども、RDFがDAGなのは必然的にそうなってしまっただけで、DAGであることそれ自体はあまり意味がない。
まず、DAGになってしまった必然性というのは、リソースの関係記述を束縛しないためだ。リソースの関係記述というのはつまり、主語が目的語になってその目的語が主語になって、ってやつで、木構造だと当然これが「そのまま」実現できないのはご存じの通りだ。もちろんRDF/XMLのようにGOTO的な方法を使えば書けるけれど、それは木構造「そのまま」ではないはず。
でも、RDFを構成する大切な要素っていのはそれだけじゃない。URIによるリソースの識別を抜きにRDFを語ってしまうと、RDFが本当につまらない物になってしまう。
RDFグラフのリソースはリテラルと匿名ノードをのぞいて全てURIで識別できる。これが何を意味するかというと、RDFで記述すれば、あらゆるリソースが全世界規模で特定可能な存在であることが保証される、ということだ。RDFでは述語部分ですらURIで識別できるので、RDFグラフで記述された「情報」は世界規模で認識できるということになる。ちょっとこの説明は自分でもわかりにくいと思うのだけれども、つまり簡単に言えば、少なくとも仕組み的には、RDFを使えば世界全体で統一されたデータベースを構築できる、ということになる。考えてみて欲しい、例えばXMLやRDBのデータを全世界規模で共有できるだろうか? 当然それは無理だ。用いられる識別子や述語(あるいは要素名とかカラム名)はバラバラだし、バラバラなものを協調させる仕組みもない。XMLやRDBっていうのはすでにある情報をうまくビット列に置き換えるための仕組みであって、情報を構築するための手順を示した物では決してない。それに対して、RDFはResource Description Frameworkという名前が示すとおり、リソースに関する情報を記述するための「手順」そのものを定めている。Semantic Webのレイヤーケーキ(最近ケーキじゃなくなってきたけれど)を見てもらえればわかるとおり、RDFはXMLとかTurtleとかいったシリアライズの規格とはレイヤーがそもそも違うのだ。だから、たとえば、
DAGはより柔軟に表現できるが,木構造の方が簡単で高速に処理できて理解しやすい…そして何よりも木構造でも9割以上の用途がカバーできるという点で命運が決したと思う.
という批判は、残念ながら少し的外れだと思う。高速に処理出来るかどうかはRDFグラフのシリアライズ方法に寄るところだろうし(RDBに格納する方法とか色々研究されている)、RDFはそもそもデータのシリアライズ方法ではないので、直接的にXMLを比較するのは妥当ではない。データ構造として木構造が9割以上の用途をカバー可能なのはその通りで、事実、RDFのグラフもXMLの木構造で記述できる。でも、XMLには情報を共有化するための仕組みなんて当然ながら存在しないし、RDFから見ればXMLはCSVと大差ない。そもそも用途が違うのだ。
世界規模でデータベースが作れるっていうと、本当に夢のような話だと思う。みんなが情報をRDFで記述してくれれば、いろいろな情報を組み合わせる事が簡単になる。適当にサービスから拾ってきた情報を混ぜて、SPARQLで必要な部分だけを引っこ抜くことができれば、それだけでいろいろな応用が可能になる。サービスごとにYAMLだのJSONだのXMLだのについていちいち勉強する必要はないし、APIの動作について(もちろん多かれ少なかれ必要にはなるんだけど)わざわざリファレンスを見る必要も減るだろう。なにより、サービス間の連携をとる上でRDFはとても役に立つ。そこらへんの話については前に書いたので、そちらも参考にして欲しい。
ところで、Semantic Webを取り巻く人たちには、本当にいろいろな種類の分野の人がいるのだけれど、おおむね3種類の勢力に分けられると思う。DB屋さん、AI屋さん、そしてオントロジ屋さんだ。DB屋さんはRDFデーターベースに興味があるらしい。AI屋さんは推論とか、エキスパートシステムとか、そっちの方かな。オントロジ屋さんは、意味論とかなんだか難しそうな話をしているのだけど、彼らはそもそも文学部の人たちだったりする。少なくとも国内において、純粋なWeb屋さんが大学とか研究とかそういう文脈でSemantic Webに言及してくれることは余りない。そして、ここで述べたようなRDFの利点というのは、実際のところWeb屋さんぐらいしか興味がないらしくて、RDFの説明として強調される機会が少ないように思える。これはとても興味深い事なんだけれど、やっぱりたぶん、Semantic Webが委員会主導で進んでいて、実用方面から距離がちょっと遠いのと関係があるとは思う。研究として触るならいいんだけど、実用を重んじる(と思う)Web屋さんはあんまり興味を示してくれないらしい。Webと名前がついているにもかかわらず、Semantic Webは未だに学会が主体で話が進んでいるというのは、ある意味とても現状を反映しているんじゃないかと、最近ちょっと思っている。
ない。ないならつくる?
WikiとIRCチャンネルぐらいは欲しい。Wikibooksのチュートリアルぐらいの内容があればみんなもっとAdaに興味を持ってくれるんじゃないかなぁ。
試しに作ってみたいなぁ。名前とかご意見をお待ちしております。
ヨーロッパだとAda Europeが毎年国際学会をやっていて楽しそうでうらやましい。proceedingsみると明らかに分野があっち方面だけど。
そういえば大分昔に書こうと思っていて、完全に忘れてたのをふと思い出したので書いてみましょう。
PiroさんのJavaScript 1.7のyield文ってなんじゃらほに書かれているフィボナッチ数列を求める例がわかりやすいので、これをAdaで書いてみます。
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Yield is
task type Test is
entry Next (Value: out Integer);
end Test;
task body Test is
A : Integer := 0;
B : Integer := 1;
Temp : Integer;
begin
loop
select
accept Next (Value : out Integer) do
Value := A;
Temp := B;
B := A + B;
A := Temp;
end Next;
or
terminate;
end select;
end loop;
end Test;
Generator : Test;
Value : Integer;
begin
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
end Yield;
AdaのTaskは本当に強力すぎて、正直TaskだけでもAdaを使う価値有りすぎです。or terminateとか素敵すぎます。
あとはYieldとはあんまり関係ないですが、then abortとかもやばいです。10msでフィボナッチ数列を出来るだけ計算してみる、なんて処理がこんなに簡単に書けちゃいます。
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Yield is
task type Test is
entry Next (Value: out Integer);
end Test;
task body Test is
A : Integer := 0;
B : Integer := 1;
Temp : Integer;
begin
loop
select
accept Next (Value : out Integer) do
Value := A;
Temp := B;
B := A + B;
A := Temp;
end Next;
or
terminate;
end select;
end loop;
end Test;
Generator : Test;
Value : Integer;
begin
select
delay 0.01;
then abort
loop
Generator.Next(Value); Put (Value); New_Line;
end loop;
end select;
end Yield;
わぁ、かっこいい。