2012-04-02 11 views
1

Ich versuche, OWL API zu verwenden, um OWL-Ontologien zu erstellen. Ich kann Klassen, Individuen und Beziehungen zwischen ihnen definieren.OWL API: Wie stellen Sie sicher, Domain und Range-Einschränkungen?

Wenn ich definieren eine Object #hasPart mit Domain #A und Range #B, erwartete ich, dass diese Eigenschaft nur für Personen dieser beiden Klassen angewendet durch. Aber in der Tat ist die API über die Beschränkung sich nicht, so kann man #hasPart zuweisen auch zwischen zwei Member der Klasse #C zum Beispiel:

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

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

ich jetzt bin auf der Suche nach der empfohlene Weg, um diese Art von Einschränkungen programmatisch zu behandeln ..? Vielen Dank im Voraus!

Antwort

3

Ja, es ist nichts falsch mit der Verwendung von hasPart w/C, die reasoner werden einfach davon ausgehen, dass Sie schließlich, dass c1 sagen werden, ist auch ein A, oder dass C ist die gleiche wie A.

OWL API wird nicht das gewünschte Verhalten erzwingen, es klingt, als ob Sie nach einer Art von Integritätsbedingungen suchen, wie Sie es in einem normalen relationalen System tun würden. Sie müssen das entweder in Ihre Anwendung einarbeiten oder in etwas wie Pellets integrity constraints schauen, das in der kommenden Version von Pellet 3 verfügbar sein wird und derzeit in Stardog verfügbar ist.

+2

Diese Antwort von Michael ist richtig, jedoch löst es nicht das Modellierungsproblem. Die Lösung für Ihren Fall: machen Sie alle drei Klassen disjunkt. Das sagt dem System, dass Dinge, die in einer Klasse sind, in keiner der anderen Klassen sein können. Auf diese Weise würde Ihr Code funktionieren, wie Sie es erwarten. – Decrayer