(s,p,o) とリストを想定して、Sesame のモデル構造を使用して、主語 s、述語のリストを使用し、最後に o に到達できるかどうかを確認したいと思います。
たとえば、(s,p,o) と {p1,p2,p3} に対して次のトリプルが存在する場合、パスがあると言います: (s,p1,o1) , (o1,p2,o2), (o2、p3、o)
セサミやモデルの構造に可能性はありますか?
おそらく、これを行う最も簡単な方法は、SPARQL クエリを使用することです。
クエリは、プロパティ パス式を使用してこのパスを表現します。与えられた始点と終点にパスが存在するかどうかを知りたいので、「はい」または「いいえ」の答えで十分だと思います。したがって、ブール ASK クエリを実行できます。
ASK WHERE { :s (:p1|:p2|:p3)+ :o . }
これは、プロパティ、、およびの組み合わせで構成される と の間true
に任意の長さのパスが存在する場合に返されます。:s
:o
:p1
:p2
:p3
SPARQL クエリを で直接実行することはできないため、次のように、クエリを実行する前Model
にインメモリを作成してそれにRepository
追加する必要があります。Model
Model model = ...; // your model
// create and initialize a temporary in-memory store
Repository rep = new SailRepository(new MemoryStore());
rep.initialize();
try (RepositoryConnection conn = rep.getConnection()) {
// load the model into the repository
conn.add(model);
// execute the query
String query = "ASK WHERE { :s (:p1|:p2|:p3)+ :o . }";
boolean pathExists = conn.prepareBooleanQuery(query).evaluate();
}
または、単純な再帰的な方法を使用して、パス トラバーサルを自分で実装することもできます。
Model model = ...; // your model
IRI start = ... ; // your start point :s
IRI end = ...; // your end point :o .
IRI p1 = ...;
IRI p2 = ...;
IRI p3 = ... ;
boolean pathExists = pathExists(model, start, end, p1, p2, p3);
実際の方法は次のようになります。
boolean pathExists(Model m, IRI start, IRI end, IRI... properties) {
for(IRI p: properties) {
Model fromStart = m.filter(start, p, null);
if (fromStart.contains(start, p, end)) {
return true;
}
else {
for (Value obj: fromStart.objects()) {
if (obj instanceof Resource) {
if(pathExists(m, obj, end, properties)) {
return true;
}
}
}
}
}
return false;
}
...それを少し拡張する必要があるかもしれません (無限ループを避けるために、訪問した中間ノードのリストを使用して)、それは私が望む基本原則を示しています。いずれにせよ、SPARQL クエリを使用する方がはるかに簡単です。