Ваш пример не зависит от использования принципа замкнутого мира. Это зависит от введения правила проверки для 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
, и вы заметите, что для поддержки некоторых общих конструкций совы (в первую очередь кардинальности) требуется разработка Jena Builtin, чтобы сделать выражение правила простым. Я связался с другим ответом о встроенных функциях, если вы собираетесь двигаться в этом направлении.
Следующие правила взяты из файла etc/owl-fb.rules
jena-core
для описания количества элементов. Они не являются полным набором правил кардинальности.
[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
в этом примере являются функторами). validationMaxN
— это конкретное правило (для N > 1), которое показывает, как можно идентифицировать нарушение. Он делегирует CountLiteralValues
встроен для определения количества привязок, существующих для свойства.
Если вы хотите представить CountQualifiedValues
встроенную функцию, вы можете определить набор правил, подобных приведенным ниже, для введения новых аксиом:
[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
(без квалифицированного ограничения количества элементов)
person
Rob Hall
schedule
21.08.2014