【问题标题】:OWL ontology: SPARQL query a range or domain of an ObjectProperty when they're unionOf classesOWL 本体:当 ObjectProperty 是 unionOf 类时,SPARQL 查询范围或域
【发布时间】:2015-10-09 07:59:58
【问题描述】:

我必须使用 SPARQL 1.1 端点查询本体版本 1.4,所以我不能使用 ClassAssertion 等 OWL 2 语义... 本体中的几个属性具有这种格式:

    <owl:ObjectProperty rdf:about="&km4c;hasGeometry">
    <rdfs:comment>some services and all railway elements have a specific geometry like polygons or linestrings</rdfs:comment>
    <rdfs:range rdf:resource="&gis;Geometry"/>
    <rdfs:domain>
        <owl:Class>
            <owl:unionOf rdf:parseType="Collection">
                <rdf:Description rdf:about="&km4c;RailwayElement"/>
                <rdf:Description rdf:about="&km4c;Service"/>
            </owl:unionOf>
        </owl:Class>
    </rdfs:domain>
</owl:ObjectProperty>

域或范围是多个类的联合。问题是我想检索具有特定域和范围的所有类,但使用以下查询:

SELECT DISTINCT ?p
{
    ?p rdfs:range gis:Geometry.
    ?p rdfs:domain km4c:Service
}

我没有得到任何结果,而不是 km4c:hasGeometry。

有没有办法以这种方式查看集合内部?

【问题讨论】:

    标签: sparql owl ontology


    【解决方案1】:

    首先,请注意,union of 域和范围的语义可能不是您所期望的。在 OWL 中,当你说类 D 是属性 P 的域时,这意味着只要你有一个断言 P(x,y),你就可以推断出 D(x)。这意味着如果 P 的域是联合 C &sqcup; D,那么从P(x,y),可以推断出x是C的一个元素&sqcup; D;即,x 是 C 或 D,但您不一定知道哪个。例如,您可以定义:

            hasWings rdfs:domain (Airplane &sqcup; Bird)

    然后,根据 hasWings(x,2),您可以推断出 x 是飞机还是鸟,但您仍然不知道是哪一个。

    无论如何,如果你仍然想要一个联合类作为一个域,你可以这样做。在 OWL 本体映射的 RDF 序列化中,联合的类在一个 RDF 列表中。查询这些有点复杂,但你当然可以做到。由于您没有提供完整的 OWL 本体,我们无法查询您的实际数据(将来,请提供我们可以使用的完整、最小工作数据),但我们可以创建一个简单的本体。有两个类,A 和 B,以及两个属性,p 和 q。 p的域是A,q的域是A或B:

    <rdf:RDF
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns="http://example.org/"
        xmlns:owl="http://www.w3.org/2002/07/owl#"
        xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
      <owl:Ontology rdf:about="http://example.org/"/>
      <owl:Class rdf:about="http://example.org/#A"/>
      <owl:Class rdf:about="http://example.org/#B"/>
      <owl:ObjectProperty rdf:about="http://example.org/#q">
        <rdfs:domain>
          <owl:Class>
            <owl:unionOf rdf:parseType="Collection">
              <owl:Class rdf:about="http://example.org/#A"/>
              <owl:Class rdf:about="http://example.org/#B"/>
            </owl:unionOf>
          </owl:Class>
        </rdfs:domain>
      </owl:ObjectProperty>
      <owl:ObjectProperty rdf:about="http://example.org/#p">
        <rdfs:domain rdf:resource="http://example.org/#A"/>
      </owl:ObjectProperty>
    </rdf:RDF>
    

    SPARQL 语法更类似于 RDF 的 N3/Turtle 序列化,因此查看该序列化也很有帮助。 unionOf 列表在这里更清晰:

    @prefix :      <http://example.org/> .
    @prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix owl:   <http://www.w3.org/2002/07/owl#> .
    @prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
    @prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
    
    <http://example.org/#A>
            a       owl:Class .
    
    <http://example.org/#p>
            a            owl:ObjectProperty ;
            rdfs:domain  <http://example.org/#A> .
    
    <http://example.org/#B>
            a       owl:Class .
    
    <http://example.org/#q>
            a            owl:ObjectProperty ;
            rdfs:domain  [ a            owl:Class ;
                           owl:unionOf  ( <http://example.org/#A> <http://example.org/#B> )
                         ] .
    
    :       a       owl:Ontology .
    

    现在您可以使用这样的查询来查找属性及其域,或者如果其中一个域是联合类,则可以找到联合类:

    prefix :      <http://example.org/>
    prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    prefix owl:   <http://www.w3.org/2002/07/owl#>
    prefix xsd:   <http://www.w3.org/2001/XMLSchema#>
    prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
    
    select ?p ?d where {
      ?p rdfs:domain/(owl:unionOf/rdf:rest*/rdf:first)* ?d
      filter isIri(?d)
    }
    
    -----------------------------------------------------
    | p                       | d                       |
    =====================================================
    | <http://example.org/#q> | <http://example.org/#A> |
    | <http://example.org/#q> | <http://example.org/#B> |
    | <http://example.org/#p> | <http://example.org/#A> |
    -----------------------------------------------------
    

    该查询的有趣部分是:

    ?p rdfs:domain/(owl:unionOf/rdf:rest*/rdf:first)* ?d
    

    这表示您遵循从 ?p 到 ?d 的路径,以及路径:

    • 以 rdfs:domain 开头
    • 后跟零次或多次重复:
      • 猫头鹰:unionOf
      • 后跟零个或多个 rdf:rest
      • 后跟一个 rdf:first

    这与这个问题并不完全相关,但您可能会发现在this answer(披露:我的回答)到Is it possible to get the position of an element in an RDF Collection in SPARQL? 中查询 RDF 列表的讨论很有用。

    然后,我也加了

    filter isIri(?d)
    

    因为否则我们会得到代表联合类的节点,但这是一个您(可能)不想要的空白节点。

    【讨论】:

    • 这对 Joshua 很有帮助。
    猜你喜欢
    • 2014-04-19
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 2014-03-17
    • 1970-01-01
    相关资源
    最近更新 更多