Retrieve the collection of unionOf and intersectionOf for each OWL

不打扰是莪最后的温柔 提交于 2019-12-07 17:40:26

Cleaning up your query a bit, we have:

prefix abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
prefix ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix mno: <http://www.w3.org/2001/XMLSchema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix list: <http://jena.hpl.hp.com/ARQ/list#>

select distinct ?class ?equivalentClass where {
  ?class a owl:Class .
  filter( strstarts(str(?class),str(owl:)) ||     # since "owl:" is an IRI, you can 
          strstarts(str(?class),str(abc:))    )   # use str(owl:) and str(:abc)

  ?x a owl:Class ; 
     owl:intersectionOf ?list .
     ?list rdf:rest*/rdf:first ?equivalentClass .
}
group by ?class ?equivalentClass
order by ?class                                   # ?class, not ?no

Your problem lies in that you're selecting ?class, which can be every owl:Class in the ontology (as long as it starts with an appropriate prefix), and then selecting ?equivalentClass from the list of intersection classes of ?x, and ?x has no connection whatsoever to ?class. (You were also sorting by?no, but I think you meant to sort by?class`.)

Figuring out the right query to write will be easier if we take a look at the data in a more human readable format, e.g., Turtle. In Turtle, the man class is:

ns0:man  a                   owl:Class ;
        owl:equivalentClass  [ a                   owl:Class ;
                               owl:intersectionOf  ( ns0:adult ns0:person ns0:male )
                             ] .

You're looking for things which are owl:Classes, are related by owl:equivalentClass to something else that's an owl:Class, and which has a list value for owl:intersectionOf. This isn't too hard in SPARQL, and the query actually has the same kind of structure as this Turtle text:

prefix abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
prefix ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix mno: <http://www.w3.org/2001/XMLSchema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix list: <http://jena.hpl.hp.com/ARQ/list#>

select distinct ?class ?otherClass where {
  ?class a owl:Class ;
         owl:equivalentClass [ a owl:Class ;
                               owl:intersectionOf [ rdf:rest*/rdf:first ?otherClass ] ] .
  filter( strstarts(str(?class),str(owl:)) ||
          strstarts(str(?class),str(abc:))    )
}
group by ?class ?otherClass
order by ?class

I changed the variable name from equivalentClass to otherClass, because adult, male, and person aren't equivalent to man. Their intersection is. Using Jena's command line sparql tool, you'll get results like this:

$ sparql --data data.rdf --query query.rq
------------------------
| class   | otherClass |
========================
| abc:man | abc:adult  |
| abc:man | abc:male   |
| abc:man | abc:person |
------------------------

This query only retrieves classes that are equivalent to some intersection. Your expected results showed all the classes whose IRIs started with abc: or owl:, which means that the extra structure is actually optional, so we adjust the query accordingly by wrapping the optional parts in optional { … }, and we get the kind of results we're looking for:

prefix abc: <http://owl.cs.manchester.ac.uk/2009/07/sssw/people#>
prefix ghi: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix mno: <http://www.w3.org/2001/XMLSchema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix list: <http://jena.hpl.hp.com/ARQ/list#>

select distinct ?class ?otherClass where {
  ?class a owl:Class .
  optional { 
    ?class owl:equivalentClass [ a owl:Class ;
                                 owl:intersectionOf [ rdf:rest*/rdf:first ?otherClass ] ] .
  }
  filter( strstarts(str(?class),str(owl:)) ||
          strstarts(str(?class),str(abc:))    )
}
group by ?class ?otherClass
order by ?class
$ sparql --data data.rdf --query query.rq
------------------------------------
| class               | otherClass |
====================================
| abc:adult           |            |
| abc:haulage_company |            |
| abc:haulage_worker  |            |
| abc:male            |            |
| abc:man             | abc:adult  |
| abc:man             | abc:male   |
| abc:man             | abc:person |
| abc:person          |            |
| owl:Thing           |            |
------------------------------------
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!