Мое решение для такого рода проблемы заключается в использовании Reasoner (This Pellet fork).
Идея состоит в том, чтобы создать класс, обозначающий «лица, которые имеют свойство данных с диапазоном для проверки», и другой класс, который обозначает «лиц, которые превышают свойство/литерал». Затем, используя аргументатор, вы проверяете, не пересекается ли пересечение двух томов двух классов.
Как есть некоторые уловки, чтобы заставить его работать правильно здесь мое полное решение:
import java.util.function.BiFunction;
import org.semanticweb.owlapi.model.*;
import openllet.owlapi.*;
public class RangeInclusionTest
{
public static void main(final String[] args)
{
try (final OWLManagerGroup group = new OWLManagerGroup())
{
final OWLOntologyID ontId = OWLHelper.getVersion(IRI.create("http://test.org#entail-class-restrict-to-some-range"), 1.0);
final OWLHelper owl = new OWLGenericTools(group, ontId, true);
// This declaration is vital since this reasoner have problems with pure anonymous reasoning.
// You can remove this property after yours tests, (or better use one of your already existing properties).
final OWLDataProperty prop = OWL.DataProperty("http://test.org#dummyProp");
owl.addAxiom(OWL.declaration(prop));
final OWLLiteral un = OWL.constant(1);
final OWLLiteral deux = OWL.constant(2);
final OWLLiteral trois = OWL.constant(3);
final OWLLiteral quatre = OWL.constant(4);
final OWLDataRange dataRange = OWL.dataOr(OWL.oneOf(un), OWL.oneOf(deux), OWL.oneOf(trois));
final BiFunction<OWLDataRange, OWLLiteral, Boolean> isIncludeInRange = //
(range, literal) -> owl.getReasoner().isSatisfiable(//
OWL.and(// You must be of all the following class
OWL.some(prop, OWL.oneOf(literal)), // The class of the 'literal'
OWL.some(prop, range), // The class of the range.
OWL.max(prop, 1))// But you can have the property only once.
);
System.out.println("[A] " + (isIncludeInRange.apply(dataRange, un)));
System.out.println("[B] " + (isIncludeInRange.apply(dataRange, deux)));
System.out.println("[C] " + (isIncludeInRange.apply(dataRange, trois)));
System.out.println("[D] " + (isIncludeInRange.apply(dataRange, quatre)));
} catch (final Exception e)
{
e.printStackTrace();
}
}
}
Сначала вы должны определить ваш диапазоны. Затем используйте метод «isSatisfiable» аргументатора. Один трюк заключается в том, чтобы принудительно использовать только один экземпляр свойства, добавив ограничение «OWL.max (prop, 1)» в класс пересечения.
Выход должен быть
[A] true
[B] true
[C] true
[D] false
Поскольку буквальным 'Quatre' не включают в себя 'dataRange' ответ '[D]' является ложным. Как вы можете видеть, это решение easilly позволяет тестировать включения диапазона в другом.
Решение, не требующее изменения в онтологии, могло заключаться в создании специального правила swrl и проверки того, что онтология (даже пустая) влечет за собой правило, но в настоящее время не требуется поддержка dl-reasoner в swrl.
Как вы можете видеть из документов (http://owlapi.sourceforge.net/javadoc/org/semanticweb/owlapi/model/OWLDataRange.html), существует несколько типов диапазона данных - в вашем случае это ' DATA_UNION_OF', который содержит два 'DATA_ONE_OF'. Таким образом, вы должны обрабатывать эти случаи либо с помощью некоторых ветвей IF-ELSE (или SWITCH-CASE), либо с помощью соответствующего посетителя (http://owlapi.sourceforge.net/javadoc/org/semanticweb/owlapi/model /OWLDataRangeVisitor.html) – AKSW
Где я мог бы прочитать пример реализации интерфейса OWLDataRangeVisitor? – enzom83
И это довольно просто реализовать интерфейс. Для вашего случая, я думаю, достаточно реализовать логические методы, т. Е. Для пересечения, объединения, дополнения и, наконец, для той части, которая является конструкциями, содержащими значения. – AKSW