2

我有很多人的本体,并使用 Jena 推理器来获取有关他们的信息。我的目标是根据规则内的给定信息创建新个体,并为他们分配属性。个人不必命名,但他们需要一个类型并且必须是一些属性的一部分。目前我可以创建匿名个人(在邮件列表帖子的帮助下),但我只能给他们一种类型或一种属性。

这是我的问题的一个小例子;我的规则是这样的(本体和推断结果可以在底部找到):

[test2: (?X rdf:type NS:Test1) ->
    [(?Y rdf:type NS:Test2) <- makeSkolem(?Y, ?X)]]

这意味着当找到一个 Test1 个体时,将创建一个新的空白节点,然后将类型 Test2 赋予该节点。它工作正常,但我想给这个新个体一个分类和一个指向 ?X(Test1 个体)的指针(属性)。

像下面这样的东西是行不通的,因为“向后的规则只允许一个头子句”。但是,它的每个子句都可以正常工作。

[test2: (?X rdf:type NS:Test1) ->
    [(?Y rdf:type NS:Test2), (?Y NS:hasClassification 'test'), <- makeSkolem(?Y, ?X)]]

这是我的本体:

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns="file:/Test#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" > 
  <rdf:Description rdf:about="file:/Test#hasClassification">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#DatatypeProperty"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#TestProp">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ObjectProperty"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#testInd">
    <rdf:type rdf:resource="file:/Test#Test1"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#testInd2">
    <rdf:type rdf:resource="file:/Test#Test1"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#Test1">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#Test2">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Ontology"/>
  </rdf:Description>
</rdf:RDF>

这是第一条规则的结果(具有 ID 的空白节点A0A1新个体):

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns="file:/Test#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" > 
  <rdf:Description rdf:about="file:/Test#hasClassification">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#DatatypeProperty"/>
  </rdf:Description>
  <rdf:Description rdf:nodeID="A0">
    <rdf:type rdf:resource="file:/Test#Test2"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#TestProp">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ObjectProperty"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#testInd">
    <rdf:type rdf:resource="file:/Test#Test1"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#testInd2">
    <rdf:type rdf:resource="file:/Test#Test1"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#Test1">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#Test2">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:nodeID="A1">
    <rdf:type rdf:resource="file:/Test#Test2"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Ontology"/>
  </rdf:Description>
</rdf:RDF>
4

1 回答 1

1

首先,请注意您的规则并没有完全按照您所说的那样做。

[test2: (?X rdf:type NS:Test1) →
    [(?Y rdf:type NS:Test2) ← makeSkolem(?Y, ?X)]]

这意味着当找到一个 Test1 个体时,将创建一个新的空白节点,然后将类型 Test2 赋予该节点。

该规则在找到 NS:Test1 实例时匹配,并添加一个新的反向链接规则,可用于确定某物是否具有 NS:Test2 类型:如果它是 ?X 的 skolem,则它具有该类型。除非您要求,否则它不会给出任何类型 NS:Test2 的内容。(当然,编写整个模型确实需要这样的三元组。)

如果您发现这种行为是可以接受的,您可以简单地使用添加多个反向链接规则的前向链接规则,例如:

[test2:
  (?X rdf:type NS:Test1) →
    [(?Y rdf:type NS:Test2) ← makeSkolem(?Y, ?X)],
    [(?Y NS:hasClassification 'test') ← makeSkolem( ?Y, ?X)]
]

我认为这比它需要的要复杂一些。Skolem 对象只是由一些其他值唯一确定的对象,因此您可以在规则的前置条件以及规则的头部使用 makeSkolem。这意味着您可以这样做:

[test2: (?X rdf:type NS:Test1), makeSkolem(?Y, ?X) →
    (?Y rdf:type NS:Test2), (?Y rdf:type NS:hasClassification 'test')]

值得注意的是 makeSkolem 接受任意数量的参数。添加某种指示器可能是值得的,这样您就不会意外地在多个地方获得相同的 skolem 对象。例如,如果你有类似的东西

[(?child rdf:type :Child), makeSkolem(?mother, ?child) →
    (?mother rdf:type :Mother), (?child :hasMother ?mother)]

[(?child rdf:type :Child), makeSkolem(?father, ?child) →
    (?father rdf:type :Father), (?child :hasFather ?father)]

那么你实际上只会为每个孩子创建一个skolem 对象并将其称为孩子的母亲和父亲,这可能不是你想要的。相反,您可以执行以下操作:

[(?child rdf:type :Child), makeSkolem(?mother, ?child, 'mother') →
    (?mother rdf:type :Mother), (?child :hasMother ?mother)]

[(?child rdf:type :Child), makeSkolem(?father, ?child, 'father') →
    (?father rdf:type :Father), (?child :hasFather ?father)]

因为 ( ?child, 'mother') 和 ( ?child, 'father') 总是不同的,所以你会得到两个 skolem 对象而不是一个。您可以在规则中使用类似的内容来获取,例如,

[test2: (?X rdf:type NS:Test1), makeSkolem(?Y, ?X, 'test2') →
    (?Y rdf:type NS:Test2), (?Y NS:hasClassification 'test')]

于 2014-02-27T17:35:55.980 回答