3 レベルの深さの階層を持つ RDF グラフがあります。owl:Thing
推論を使用せずに、クラス階層のルート (つまり ) から第 3 レベルのクラスまでのすべてのパスを取得したいと考えています。たとえば、パス C 1 → C 2 → C 3
はパスであり、各 C i
は階層の i番目のレベルのクラスです。
グラフ内のオブジェクト プロパティを考慮せずに幅優先探索アルゴリズムを使用して、RDF グラフ内のすべてのパスを取得する必要があります。
3 レベルの深さの階層を持つ RDF グラフがあります。owl:Thing
推論を使用せずに、クラス階層のルート (つまり ) から第 3 レベルのクラスまでのすべてのパスを取得したいと考えています。たとえば、パス C 1 → C 2 → C 3
はパスであり、各 C i
は階層の i番目のレベルのクラスです。
グラフ内のオブジェクト プロパティを考慮せずに幅優先探索アルゴリズムを使用して、RDF グラフ内のすべてのパスを取得する必要があります。
次のようなデータが与えられた場合 (クラス名の長さは、階層内のクラスの深さを示します):
@prefix : <http://example.org/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
:a a rdfs:Class .
:aa rdfs:subClassOf :a .
:ab rdfs:subClassOf :a .
:ac rdfs:subClassOf :a .
:aaa rdfs:subClassOf :aa .
:aab rdfs:subClassOf :aa .
:aac rdfs:subClassOf :aa .
:aaba rdfs:subClassOf :aab .
:aabb rdfs:subClassOf :aab .
:aba rdfs:subClassOf :ab .
:abb rdfs:subClassOf :ab .
SPARQL クエリを使用して、探しているパスを選択できます。
次のような SPARQL クエリを記述して、次の結果を得ることができます。
prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?c1 ?c2 ?c3 where {
values ?c1 { :a }
?c1 ^rdfs:subClassOf ?c2 .
OPTIONAL {
?c2 ^rdfs:subClassOf ?c3 .
}
}
order by ?c3 ?c2 ?c1
-------------------
| c1 | c2 | c3 |
===================
| :a | :ac | |
| :a | :aa | :aaa |
| :a | :aa | :aab |
| :a | :aa | :aac |
| :a | :ab | :aba |
| :a | :ab | :abb |
-------------------
このアプローチは、コメントで言及されているカメラ オントロジーで機能しますが、より深いクラス パスを処理するにはクエリを少し拡張する必要があります。したがって:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX : <http://www.xfront.com/owl/ontologies/camera/#>
select * where {
values ?c1 { owl:Thing }
?c1 ^rdfs:subClassOf ?c2 .
OPTIONAL {
?c2 ^rdfs:subClassOf ?c3 .
OPTIONAL {
?c3 ^rdfs:subClassOf ?c4 .
}
}
}
order by ?c4 ?c3 ?c2
-----------------------------------------------------------
| c1 | c2 | c3 | c4 |
===========================================================
| owl:Thing | :Money | | |
| owl:Thing | :Range | | |
| owl:Thing | :Window | | |
| owl:Thing | :PurchaseableItem | :Body | |
| owl:Thing | :PurchaseableItem | :Lens | |
| owl:Thing | :PurchaseableItem | :Camera | :Digital |
| owl:Thing | :PurchaseableItem | :Camera | :Large-Format |
-----------------------------------------------------------
上記の SPARQL クエリは、幅優先トラバーサルから期待される順序でパスを生成しますが、実際には、ARQ が結果を生成する方法について保証はありません。サブクラスを取得するために Jena Model API を使用して、幅優先検索を直接実装することもできます。簡単な実装を次に示します。
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDFS;
public class BFSInRDFWithJena {
public static List<List<Resource>> BFS( final Model model, final Queue<List<Resource>> queue, final int depth ) {
final List<List<Resource>> results = new ArrayList<>();
while ( !queue.isEmpty() ) {
final List<Resource> path = queue.poll();
results.add( path );
if ( path.size() < depth ) {
final Resource last = path.get( path.size() - 1 );
final StmtIterator stmt = model.listStatements( null, RDFS.subClassOf, last );
while ( stmt.hasNext() ) {
final List<Resource> extPath = new ArrayList<>( path );
extPath.add( stmt.next().getSubject().asResource() );
queue.offer( extPath );
}
}
}
return results;
}
public static void main( final String[] args ) throws IOException {
final Model model = ModelFactory.createDefaultModel();
try ( final InputStream in = BFSInRDFWithJena.class.getClassLoader().getResourceAsStream( "camera.owl" ) ) {
model.read( in, null );
}
// setup the initial queue
final Queue<List<Resource>> queue = new LinkedList<>();
final List<Resource> thingPath = new ArrayList<>();
thingPath.add( OWL.Thing );
queue.offer( thingPath );
// Get the paths, and display them
final List<List<Resource>> paths = BFS( model, queue, 4 );
for ( List<Resource> path : paths ) {
System.out.println( path );
}
}
}
[http://www.w3.org/2002/07/owl#Thing]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Window]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Range]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#Money]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Lens]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Body]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera, http://www.xfront.com/owl/ontologies/camera/#Digital]
[http://www.w3.org/2002/07/owl#Thing, http://www.xfront.com/owl/ontologies/camera/#PurchaseableItem, http://www.xfront.com/owl/ontologies/camera/#Camera, http://www.xfront.com/owl/ontologies/camera/#Large-Format]