Как проверить, содержит ли объект OWLDataRange указанное значение?

У меня есть онтология, созданная в Protege 4.3.0 и сохраненная в файле OWL. Некоторые свойства данных этой онтологии имеют свои диапазоны, определенные как в следующем выражении:

({"absent"} or {"value1" , "value2" , "value3"})

Я бы искал свойства данных, которые могут иметь указанное значение в своих диапазонах, поэтому я написал следующий пример кода, но я не знаю, как запросить объект OWLDataRange, чтобы узнать, содержит ли он указанное значение (например, строка "value1" ).

final OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
final OWLOntology ontology = manager.loadOntologyFromOntologyDocument(file);
final OWLReasonerFactory rf = new StructuralReasonerFactory();
final OWLReasoner reasoner = rf.createReasoner(ontology);

// ...

// iterate over all data properties
for (OWLDataProperty topDataProperty : reasoner.getTopDataPropertyNode()) {
    for(OWLDataProperty property: reasoner.getSubDataProperties(topDataProperty, false).getFlattened()) {

        // iterate over all data ranges for the current data property
        for (OWLDataRange dataRange : property.getRanges(ontology)) {

            // I would check if the current data property contains a specified value in their ranges.
            // ...

        }
    }
}

person enzom83    schedule 07.09.2016    source источник
comment
Как видно из документации (owlapi.sourceforge.net/ javadoc/org/semanticweb/owlapi/model/) существует несколько типов диапазона данных — в вашем случае это DATA_UNION_OF, который содержит два DATA_ONE_OF. Таким образом, вы должны обрабатывать эти случаи либо с помощью некоторых ветвей IF-ELSE (соответственно SWITCH-CASE), либо путем реализации соответствующего посетителя (owlapi.sourceforge.net/javadoc/org/semanticweb/owlapi/model/)   -  person UninformedUser    schedule 07.09.2016
comment
Где я могу прочитать пример реализации интерфейса OWLDataRangeVisitor?   -  person enzom83    schedule 07.09.2016
comment
И это довольно легко реализовать в интерфейсе. Для вашего случая, я думаю, достаточно реализовать логические методы, то есть для пересечения, объединения, дополнения, а затем, наконец, для той части, которая является конструкциями, содержащими значения.   -  person UninformedUser    schedule 08.09.2016


Ответы (1)


Мое решение для такого рода проблем состоит в том, чтобы использовать причину (эта вилка Pellet).

Идея состоит в том, чтобы создать класс, который обозначает «лиц, у которых есть свойство данных с диапазоном для проверки», и другой класс, который обозначает «лиц, у которых есть точное свойство/литерал». Затем, используя аргумент, вы проверяете, не является ли пересечение этих двух классов непустым.

Поскольку есть некоторые приемы, чтобы заставить его работать правильно, вот мое полное решение:

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]» неверен. Как видите, это решение легко позволяет тестировать включение одного диапазона в другой.

Решением, которое не требует изменений в онтологии, могло бы быть создание специального правила swrl и проверка того, влечет ли онтология (даже пустая) правило, но в настоящее время ни один dl-reasoner не поддерживает следование за swrl.

person Galigator    schedule 06.03.2017