OWL API: как обеспечить ограничения домена и диапазона?

Я пытаюсь использовать OWL API для создания онтологий OWL. Я могу определить классы, индивидов и отношения между ними.

Когда я определял ObjectProperty #hasPart с доменом #A и диапазоном #B, я ожидал, что это свойство может применяться только к представителям этих двух классов. Но на самом деле API не заботится об ограничении, поэтому можно назначить #hasPart также между двумя членами класса #C, например:

import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.*;

public class OwlTest
{
    public static void main(String[] args)
    throws org.semanticweb.owlapi.model.OWLOntologyStorageException, org.semanticweb.owlapi.model.OWLOntologyCreationException, Exception
    {
        OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
        OWLDataFactory df = manager.getOWLDataFactory();
        OWLOntology o = manager.createOntology();

       //------------------------------------------------------------------

        OWLClass clsA = df.getOWLClass( IRI.create("#A") );
        OWLClass clsB = df.getOWLClass( IRI.create("#B") );
        OWLClass clsC = df.getOWLClass( IRI.create("#C") );

        OWLObjectProperty hasPart = df.getOWLObjectProperty( IRI.create("#hasPart") );
        OWLObjectPropertyDomainAxiom domainAxiom = df.getOWLObjectPropertyDomainAxiom(hasPart, clsA);
        OWLObjectPropertyRangeAxiom   rangeAxiom = df.getOWLObjectPropertyRangeAxiom( hasPart, clsB);

        manager.addAxiom(o, domainAxiom);
        manager.addAxiom(o,  rangeAxiom);

       //------------------------------------------------------------------

        OWLNamedIndividual a1 = df.getOWLNamedIndividual( IRI.create("a1") );
        OWLNamedIndividual b1 = df.getOWLNamedIndividual( IRI.create("b1") );
        OWLNamedIndividual c1 = df.getOWLNamedIndividual( IRI.create("c1") );
        OWLNamedIndividual c2 = df.getOWLNamedIndividual( IRI.create("c2") );

        manager.addAxiom(o, df.getOWLClassAssertionAxiom(clsA, a1));
        manager.addAxiom(o, df.getOWLClassAssertionAxiom(clsB, b1));
        manager.addAxiom(o, df.getOWLClassAssertionAxiom(clsC, c1));
        manager.addAxiom(o, df.getOWLClassAssertionAxiom(clsC, c2));

        manager.addAxiom(o, df.getOWLObjectPropertyAssertionAxiom(hasPart, c1, c2));   // ObjectProperty '#hasPart' should only work for objects from Domain 'clsA' and Range 'clsB'

       //------------------------------------------------------------------

        manager.saveOntology(o, IRI.create("file:/tmp/data.owl"));
    }
}

Выход /tmp/data.owl:

...
    <ObjectProperty rdf:about="#hasPart">
        <rdfs:domain rdf:resource="#A"/>
        <rdfs:range rdf:resource="#B"/>
    </ObjectProperty>

    <Class rdf:about="#A"/>
    <Class rdf:about="#B"/>
    <Class rdf:about="#C"/>

    <NamedIndividual rdf:about="a1">
        <rdf:type rdf:resource="#A"/>
    </NamedIndividual>

    <NamedIndividual rdf:about="b1">
        <rdf:type rdf:resource="#B"/>
    </NamedIndividual>

    <NamedIndividual rdf:about="c1">
        <rdf:type rdf:resource="#C"/>
        <p1:hasPart rdf:resource="c2"/>
    </NamedIndividual>
...

Теперь я ищу рекомендуемый способ программно справиться с такими ограничениями..? Спасибо заранее!


person rmv    schedule 02.04.2012    source источник


Ответы (1)


Да, нет ничего плохого в использовании hasPart с C, автор рассуждений просто предположит, что вы в конечном итоге скажете ему, что c1 также является A или что C совпадает с A.

OWL-API не будет навязывать поведение, которое вы хотите, похоже, вы ищете какие-то ограничения целостности, как в обычной реляционной системе. Вам придется либо включить это в свое приложение, либо изучить что-то вроде ограничений целостности Pellet, которые будут доступно в грядущем выпуске Pellet 3 и в настоящее время доступно в Stardog.

person Michael    schedule 03.04.2012
comment
Этот ответ от Майкла правильный, однако он не решает проблему моделирования. Решение для вашего случая: сделать все три класса дизъюнктными. Это говорит системе, что вещи, относящиеся к одному классу, не могут принадлежать ни к одному из других классов. Таким образом, ваш код будет работать так, как вы ожидаете. - person Decrayer; 25.09.2015