[英]Jena Rule for Validation af a Ontology
我想验证本体并在出现任何错误时抛出错误。
我必须做的最多验证看起来像这样:我有一个这样的类:
<owl:Class rdf:about="&schema;ExampleClass">
<rdfs:subClassOf rdf:resource="&schema;SuperClass"/>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="&schema;myProperty"/>
<owl:onClass rdf:resource="&schema;OtherClass"/>
<owl:qualifiedCardinality rdf:datatype="&xsd;nonNegativeInteger">1</owl:qualifiedCardinality>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
(有趣的部分是第二个subClassOf。)在Protege中,这意味着ExampleClass is subClass of myProperty exactly 1 OtherClass
。
所以我想验证只有一个myProperty值:一个类型为OtherClass的个体。
是否可以验证这样的规则? 如果有一个规则可以为所有类使用此建模执行此操作(并且可能还至少为1,正好为2,...),那将是完美的。
另一个问题是:是否有一个现成的封闭世界推理器正在为我做这个?
您的示例不依赖于封闭世界原则的使用。 这取决于owl:qualifiedCardinality
的验证规则的引入。
例如,让我们获取以下示例输入文件:
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix owl: <http://www.w3.org/2002/07/owl#>.
@prefix : <urn:x-so:ex#>.
:OtherClass a owl:Class .
:SuperClass a owl:Class .
:myProperty a rdf:Property
; rdfs:range :OtherClass
.
:ExampleClass rdfs:subClassOf :SuperClass
; rdfs:subClassOf [ a owl:Restriction
; owl:onProperty :myProperty
; owl:cardinality 1
# ; owl:onClass :OtherClass
# ; owl:qualifiedCardinality 1
]
.
:o0 a :OtherClass .
:o1 a :OtherClass .
:s0 rdf:type :ExampleClass
; :myProperty :o0
; :myProperty :o1
.
注意注释掉的线和它们上面引入的公理。 这个本体是符合owl-1的,所以它有验证规则。 在以下测试中没有验证错误,为什么? 因为我们可以推断出,例如:o0 owl:sameAs :o1
导致没有矛盾。
final Model baseModel = ModelFactory.createDefaultModel();
try( final InputStream in = this.getClass().getResourceAsStream("/so.ttl") ){
baseModel.read(in, null, "TTL");
}
final OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM_RULE_INF, baseModel);
assertTrue(model.contains(s0, myProperty, o0));
assertTrue(model.contains(s0, myProperty, o1));
final ValidityReport report = model.validate();
assertTrue( report.isValid() );
然而,在下一个例子中,我们证明如果我们引入:o0 owl:differentFrom :o1
,那么我们得出一个矛盾:
final Model baseModel = ModelFactory.createDefaultModel();
try( final InputStream in = this.getClass().getResourceAsStream("/so.ttl") ){
baseModel.read(in, null, "TTL");
}
final OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM_RULE_INF, baseModel);
model.add(o1, OWL.differentFrom, o0); // NOTE!!
assertTrue(model.contains(s0, myProperty, o0));
assertTrue(model.contains(s0, myProperty, o1));
final ValidityReport report = model.validate();
assertFalse( report.isValid() );
鉴于已演示的场景,我建议采用以下解决方案(按难度递增的顺序):
解决方案1:具有OWL 1约束的开放世界
如果可能,根据owl-1约束表达您的本体,然后您可以利用现有规则集进行验证。
解决方案2:使用OWL 2添加的开放世界
这并不容易。 看看etc/owl-fb.rules
jena-core
中的etc/owl-fb.rules
你会注意到一些通用owl结构(最值得注意的是基数)的支持需要开发Jena Builtin来使规则表达式变得简单。 我链接到另一个关于内置的答案,如果这是你打算去的方向。
以下规则来自jena-core
的etc/owl-fb.rules
文件来描述基数。 它们不是完整的基数规则集。
[restriction5: (?C owl:onProperty ?P), (?C owl:cardinality ?X)
-> (?C owl:equivalentClass card(?P, ?X)),
(?C rdfs:subClassOf min(?P, ?X)),
(?C rdfs:subClassOf max(?P, ?X)) ]
[restriction4: (?C owl:onProperty ?P), (?C owl:maxCardinality ?X)
-> (?C owl:equivalentClass max(?P, ?X)) ]
[validationMaxN: (?v rb:validation on()), (?C rdfs:subClassOf max(?P, ?N)) greaterThan(?N, 1) (?P rdf:type owl:DatatypeProperty) ->
[max2b: (?X rb:violation error('too many values', 'Too many values on max-N property (prop, class)', ?P, ?C))
<- (?X rdf:type ?C), countLiteralValues(?X, ?P, ?M), lessThan(?N, ?M) ] ]
restriction5
只根据最小和最大基数定义基数(本例中的min
和max
为Functors)。 validationMaxN
是特定规则(对于N> 1),显示如何识别违规。 它委托内置的CountLiteralValues
来识别属性存在的绑定数。
如果您愿意引入CountQualifiedValues
Builtin,那么您可以定义一组类似于以下的规则来介绍新的公理:
[restriction4: (?C owl:onProperty ?P), (?C owl:maxQualifiedCardinality ?X), (?C owl:onClass ?Y)
-> (?C owl:equivalentClass max(?P, ?X, ?Y)) ]
[validationMaxN: (?v rb:validation on()), (?C rdfs:subClassOf max(?P, ?N, ?Y)) greaterThan(?N, 1) (?P rdf:type owl:ObjectProperty) ->
[max2b: (?X rb:violation error('too many values', 'Too many values on max-QN property (prop, class, qclass)', ?P, ?C, ?Y))
<- (?X rdf:type ?C), countQualifiedValues(?X, ?P, ?Y, ?M), lessThan(?N, ?M) ] ]
解决方案3:封闭世界,增加了OWL 2
这实际上与解决方案2并没有什么不同。但是,您将尝试为OWL构造定义替代语义,这是一个非常重要的问题。 您可以引入一些用于验证的规则(读取etc/owl-fb.rules
以获取示例),捕获您特定的封闭世界假设。 如果强制它们仅限于(?v rb:validation on())
,那么您可以确保在执行验证时只假设一个封闭世界。
侧面讨论
以下是owl 1中表示的基数限制的示例。它与上面输入文件中的基数限制相同。 这用TURTLE
语法表示,并且很容易转换为RDF/XML
或任何其他有效的RDF
序列化。
:ExampleClass rdfs:subClassOf :SuperClass
; rdfs:subClassOf [ a owl:Restriction
; owl:onProperty :myProperty
; owl:cardinality 1
]
.
这对限制在语义上并不等同于owl:qualifiedCardinality
,但是,如果您能够修改域模型,则通常可以解决它。
例如, owl:qualifiedCardinality
非常适合说:People :haveBodyPart exactly 2 :Eyes
。 例如,OWL 1解决方法可能是创建一个:haveEye rdfs:subPropertyOf :haveBodyPart
然后说:People :haveEye exactly 2
(没有合格的基数限制)
听起来你正试图根据一些OWL公理检查一些完整性约束,但重要的是要注意OWL是基于开放世界的假设。 这意味着,即使你有:
人⊑⊑hasParent.Person
这表示每个人都有(至少)hasParent属性的一个值,其值是另一个Person个体,你仍然可以拥有一个不包含任何hasParent断言的一致本体! 因此,您正在寻找的那种“验证”更多地是关于一个封闭的世界和完整的解释。
我可能会使用一些SPARQL查询来检查那些不满足我们期望它们满足的事物的个体,而不是使用基于规则的方法。 例如,在这种情况下,您可以编写一个查看作为限制实例的个人的一般规则,然后您可以检查是否可以在“匹配”限制的数据中找到三元组。
对于这种特殊情况,您可以找到(某些) (myProperty恰好1个OtherClass) (以及一般的合格基数)的实例:
?instance a [ owl:onProperty ?property ;
owl:onClass ?class ;
owl:qualifiedCardinality ?cardinality ] .
当然,如果某个人只能被推断为该类的一个实例,那么该模式将无法找到它,但我们假设您正在使用封闭世界和完整数据,所以这样的事情应该是工作。 (“类似的东西”可以包括?instance a/rdfs:subClassOf* [ ... ]
。)一旦你有了,你可以编写一个子查询来检查数据是否“匹配”:
select ?instance ?property ?class (count(?value) as ?actualCardinality) where {
?instance ?property ?value .
?value a ?class
}
group by ?instance ?property ?class
那么你可以将这些结合起来来识别那些?actualCardinality不匹配的个体?基数:
select ?instance
?property
?class
?cardinality
(count(?value) as ?actualCardinality)
where {
?instance a [ owl:onProperty ?property ;
owl:onClass ?class ;
owl:qualifiedCardinality ?cardinality ] .
?instance ?property ?value .
?value a ?class
}
group by ?instance ?property ?class ?cardinality
having ( ?cardinality != ?actualCardinality )
我还没有测试过任何这个,所以可能有拼写错误,而且你还没有提供完整的数据,所以我也无法对它进行测试,但是这条通用的东西应该是可行的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.