rmv
rmv

Reputation: 3235

OWL API: How to ensure Domain and Range restrictions?

I try to use the OWL API to create OWL Ontologies. I can define classes, individuals, and relations among them.

When i define an ObjectProperty #hasPart with Domain #A and Range #B, i expected that this property can by applied to individuals of these two classes only. But in fact the API does not care about the restriction, so one can assign #hasPart also between two member of class #C for example:

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"));
    }
}

Output /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>
...

I'm now looking for the recommended way to deal with this kinds of restrictions programmatically..? Many thanks in advance!

Upvotes: 1

Views: 1697

Answers (1)

Michael
Michael

Reputation: 4886

Yes, there's nothing wrong with using hasPart w/ C, the reasoner will just assume that you'll eventually tell it that c1 is also an A, or that C is the same as A.

OWL-API isn't going to enforce the behavior you want, it sounds like you're looking for some sort of integrity constraints like you'd get in a normal relational system. You'll either have to bake that into your application or look into something like Pellet's integrity constraints which will be available in the upcoming Pellet 3 release and is currently available in Stardog.

Upvotes: 3

Related Questions