はじめに
前回の記事のOntology APIに続いて、Inference APIの解説です。Jenaでは、Ontology APIによるモデルの取り扱いと、推論(Inference, Reasoning)が別のモジュールで提供されているのが特徴です。Jenaで取り扱い可能なReasonerは以下とのこと。他にはPelletなんかが有名で論文なんかにも取り上げられていますが、Stardogのプロダクトに吸収されたようですね。
-
Transitive reasoner : Transive / Reflexiveなプロパティーのみ受け付ける。具体的には
rdfs:subPropertyOf
とrdfs:subClassOf
。 - RDFS rule reasoner : RDFSを含む構成可能なサブセット。
- OWL, OWL Mini, OWL Micro Reasoners : その名の通り。OWLのサブセットなど。
- Generic rule reasoner : ルールベースのReasonerでユーザが自分で実装できる。普通は使わなそう。
Reasoner
推論を行うのはReasonerと呼ばれるコンポーネントです。Reasonerを使って推論モデル(InfModel)を使って、推論のオペレーションをするというのが基本的な流れです。
Reasonerは通常はファクトリーメソッドを介して生成されます。事前に用意されたReasonerがあるようですが、Ontology APIを使っている場合、事前に生成されたOntModelSpecが適当なReasonerを当てはめてくれるようです。例えばシンプルなRDFモデルをRDFSを使って推論する場合、ModelFactory.createRDFSModel
が使われます。以下のような感じです。
String NS = "urn:x-hp-jena:eg/";
// 適当なモデルを作る
Model rdfsExample = ModelFactory.createDefaultModel();
Property p = rdfsExample.createProperty(NS, "p");
Property q = rdfsExample.createProperty(NS, "q");
rdfsExample.add(p, org.apache.jena.vocabulary.RDFS.subPropertyOf, q);
rdfsExample.createResource(NS+"a").addProperty(p, "foo");
// RDFSを使ったReasonerによるInfModel
InfModel inf = ModelFactory.createRDFSModel(rdfsExample);
上記ではpというプロパティにrdfs:subPropertyOf
という述語を記述し、対象をqとしました。そうすると、推論が働いて、qというプロパティを参照するとpの内容(すなわちfoo
)が取得できます。
Resource a = inf.getResource(NS+"a");
System.out.println("Statement: " + a.getProperty(q));
上記のやり方以外にも、Reasonerに対して色々と設定を事前に行いたい場合は、以下のようにResonerを分けてInfModelを作ることもできます。
Reasoner reasoner = RDFSRuleReasonerFactory.theInstance().create(null);
InfModel inf = ModelFactory.createInfModel(reasoner, rdfsExample);
色々なReasoner
The RDFS Reasoner(RDFSRuleReasoner)
Jenaにデフォルトで含まれる推論器で、RDFSをサポートします。3つの適合レベルがあり、設定時に指定できます。以下の例ですと、ReasonerVocabulary.PROPsetRDFSLevel
で指定しているところですね。
Resource config = ModelFactory.createDefaultModel()
.createResource()
.addProperty(ReasonerVocabulary.PROPsetRDFSLevel, "simple");
Reasoner reasoner = RDFSRuleReasonerFactory.theInstance()Create(config);
- Full : すべての公理、規則等を含む。
- Default : 高負荷なチェックを排除したもの。よくわかってませんが、"everything is a resource"と"everything used as a property is one" (rdf1, rdfs4a, rdfs4b)の2つのルールがないようで実用上はこれでほとんど問題ないらしいです。
- Simple :subPropertyOf, subClassOfといった推移的な関係、およびdomain, rangeといった範囲記述などのみを含むもので、公理(axiom)は含まない。最も便利そうな気がするけれど、不完全な実装のためにデフォルトにはなっていない。
The OWL Reasoner
Jenaで提供しているのは、OWL/fullのサブセットであるOWL/Liteの実装で、現状では設定でデフォルトとFaster/Smallerの二つのモードを指定できるとのこと。OWL/Fullの完全な実装を目指しているのではないので、Pellet、Racer、FaCTといった別なエンジンを使ってくれとのこと。使い方としては以下のような感じです。OWLで記述したオントロジー(schema)を読み込んで、reasonerにバインドしてからInfModelを作っています。
Model schema = FileManager.get().loadModel("file:data/owlDemoSchema.owl");
Model data = FileManager.get().loadModel("file:data/owlDemoData.rdf");
Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
reasoner = reasoner.bindSchema(schema);
InfModel infmodel = ModelFactory.createInfModel(reasoner, data);
今日はここまで。
このくらいの情報あれば、オントロジーによる推論を使ったアプリはとりあえず作れるかなと…