如何验证OWLDataRange对象是否包含指定值?

时间:2016-09-07 15:02:43

标签: java rdf owl protege owl-api

我在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.
            // ...

        }
    }
}

1 个答案:

答案 0 :(得分:0)

我对此类问题的解决方案是使用推理器(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]'是错误的。 正如您所看到的,这个解决方案很容易允许在另一个范围内测试范围包含。

不需要对本体进行更改的解决方案可能是创建一个特殊的swrl规则并检查本体(甚至是空的)是否需要该规则,但目前没有dl-reasoner支持对swrl的蕴涵。