Is object property functional? - owl

I am using the OWL-API 5 to load all the object property axioms in my ontology as follows:
File ontology = new File("examples/ontology.owl");
File individual = new File("examples/individuals.owl");
OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
IRI documentIRI = IRI.create(ontology);
IRI ontologyIRI = IRI.create("http://www.semanticweb.org/2020/0/test");
SimpleIRIMapper mapper = new SimpleIRIMapper(ontologyIRI, documentIRI);
manager.getIRIMappers().add(mapper);
OWLOntology kb = manager.loadOntologyFromOntologyDocument(individual);
Stream<OWLObjectPropertyAssertionAxiom> objectPropertyAxioms = kb.axioms(AxiomType.OBJECT_PROPERTY_ASSERTION);
objectPropertyAxioms.forEach(axiom -> {
System.out.println("Found object property axiom " + axiom);
OWLIndividual object = axiom.getObject();
OWLIndividual subject = axiom.getSubject();
OWLObjectPropertyExpression property = axiom.getProperty();
});
Returns:
Found object property axiom ObjectPropertyAssertion(<http://www.semanticweb.org/2020/0/test#Q> <http://www.semanticweb.org/2020/0/test#x> <http://www.semanticweb.org/2020/0/test#y>)
Now, I'd like to determine if the property is functional. This is what I tried so far:
if (EntitySearcher.isFunctional(property, kb)) {
LOGGER.debug("Property " + property + " is declared as functional");
} else {
LOGGER.debug("Property " + property + " is NOT declared as functional");
}
Returns:
Property <http://www.semanticweb.org/2020/0/test#Q> is NOT declared as functional
I think that EntitySearcher.isFunctional(p,o) is looking for functional object property axioms that make the specified object property functional, which doesn't seems to exist in my ontology (i.e., ontology.axioms(AxiomType.FUNCTIONAL_OBJECT_PROPERTY) returns nothing).
This is what I have in my ontology:
<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.semanticweb.org/2020/0/test#" xml:base="http://www.semanticweb.org/2020/0/test" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<owl:Ontology rdf:about="http://www.semanticweb.org/2020/0/test"/>
<owl:ObjectProperty rdf:about="http://www.semanticweb.org/2020/0/test#Q">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
</owl:ObjectProperty>
</rdf:RDF>
And individuals:
<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.semanticweb.org/2020/0/test#" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<owl:Ontology rdf:about="">
<owl:imports rdf:resource="http://www.semanticweb.org/2020/0/test"/>
</owl:Ontology>
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/2020/0/test#x">
<Q rdf:resource="http://www.semanticweb.org/2020/0/test#y"/>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/2020/0/test#y"/>
</rdf:RDF>
(Both files were created using Prótegé 5.5.0). Any suggestions? Thank you.

To answer the implicit question about EntitySearcher::isFunctional, yes, it checks if there are functional property axioms for the property received in input.
I believe your ontology has enough information for that.
To provide a complete example:
<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.semanticweb.org/2020/0/test#" xml:base="http://www.semanticweb.org/2020/0/test" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:test="http://www.semanticweb.org/owlapi/test#">
<owl:Ontology rdf:about="http://www.semanticweb.org/2020/0/test"/>
<owl:ObjectProperty rdf:about="http://www.semanticweb.org/owlapi/test#Q">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
</owl:ObjectProperty>
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/owlapi/test#x">
<test:Q rdf:resource="http://www.semanticweb.org/owlapi/test#y"/>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/owlapi/test#y"/>
</rdf:RDF>
With this ontology, EntitySearcher returns true when checking for functional properties.
Edit: in your updated question, you're using kb.axioms(AxiomType), you need to tell it to include imports.

Related

How to represent maps in OWL?

This is a simplified extract from my ontology:
<owl:Class rdf:ID="Role" />
<owl:Class rdf:ID="Location" />
<owl:Class rdf:ID="SalaryRange">
<rdfs:subClassOf rdf:resource="#HasLocation" />
</owl:Class>
<owl:Class rdf:ID="HasLocation" />
<owl:ObjectProperty rdf:ID="location">
<rdfs:domain rdf:resource="#HasLocation" />
<rdfs:range rdf:resource="#Location" />
</owl:ObjectProperty>
<owl:DataProperty rdf:ID="salaryRangeOfRole">
<rdfs:domain rdf:resource="#Role" />
<rdfs:range rdf:resource="#SalaryRange" />
</owl:DataProperty>
How can I ensure now that the Locations in the SalaryRanges are unique per Role?
I have read about FunctionalPropertys, but do not see how to use this in this case.
The challenge you have here is that you basically want a unique constraint on Role and Location for SalaryRange. Funtional properties really is defined for a single property - except if you do model some functional property through class expressions.
A simple way to achieve this (if you are using OWL) is through key constraints. I battle a bit to understand your example. I therefore simplified your example further to assuming you have a SalaryRange for which the Role and Location need to be unique. I think if you understand the general idea you will be able to modified it to fit your example exactly.
We have the classes Location and Role as you defined it.
<owl:Class rdf:about="Location"/>
<owl:Class rdf:about="Role"/>
Then I defined object properties role and location follows:
<owl:ObjectProperty rdf:about="location">
<rdfs:domain rdf:resource="SalaryRange"/>
<rdfs:range rdf:resource="Location"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:about="role">
<rdfs:domain rdf:resource="SalaryRange"/>
<rdfs:range rdf:resource="Role"/>
</owl:ObjectProperty>
Then to ensure that SalaryRange will have unique roles and locations, you can enforce it as follows:
<owl:Class rdf:about="SalaryRange">
<owl:hasKey rdf:parseType="Collection">
<rdf:Description rdf:about="location"/>
<rdf:Description rdf:about="role"/>
</owl:hasKey>
</owl:Class>
You can test this with the following individuals:
<owl:NamedIndividual rdf:about="location1">
<owl:sameAs rdf:resource="location2"/>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="location2"/>
<owl:NamedIndividual rdf:about="role1">
<owl:sameAs rdf:resource="role2"/>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="role2"/>
<owl:NamedIndividual rdf:about="salaryRange1">
<location rdf:resource="location1"/>
<role rdf:resource="role1"/>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="salaryRange2">
<location rdf:resource="location2"/>
<role rdf:resource="role2"/>
</owl:NamedIndividual>
With these individuals a reasoner like Hermit will infer that salaryRange1 and salaryRange2 are the same individual. However, if you state that salaryRange1 and salaryRange2 are different individuals, you will get an inconsistency.
<rdf:Description>
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#AllDifferent"/>
<owl:distinctMembers rdf:parseType="Collection">
<rdf:Description rdf:about="salaryRange1"/>
<rdf:Description rdf:about="salaryRange2"/>
</owl:distinctMembers>
</rdf:Description>
To resolve the inconsistency you can state that either role1 and role2 are different individuals OR location1 and location2 are different individuals.

Owl class rdf in dotnetrdf

What is the best way to generate below using dotnetrdf? Assuming I have defined al the namespaces, I am trying to output the following:
<owl:Class rdf:about = "http://my.taxonomies.com/myModel/Lion" >
<rdfs:label xml:lang = "en"> Lion </ rdfs:label>
<rdfs:subClassOf> <owl:Class rdf:about = "http://my.taxonomies.com/myModel/Animals" />
<rdfs:subClassOf>
</owl:Class>
The tutorials I went through did not have an owl class example.
Thanks
You have two options when creating OWL ontologies in dotNetRDF. You can create a graph and use the Assert methods to assert the triples you want in your ontology graph (this is the low-level API if you like); or you can use the helper classes and methods in the VDS.RDF.Ontology namespace which abstract away some of the steps you need to take when making an ontology graph.
There are docs for the basic operations of the low-level API here, and for the ontology API here
This is an example of creating your graph using the low-level APIs:
var g = new Graph();
// Add namespaces (RDF and RDFS are already declared)
g.NamespaceMap.AddNamespace("owl", UriFactory.Create("http://www.w3.org/2002/07/owl#"));
// Create nodes (this could be done inline in the Assert code if you prefer
var lion = g.CreateUriNode(UriFactory.Create("http://my.taxonomies.com/myModel/Lion"));
var animals = g.CreateUriNode(UriFactory.Create("http://my.taxonomies.com/myModel/Animals"));
var a = g.CreateUriNode("rdf:type");
var owlClass = g.CreateUriNode("owl:Class");
var rdfsLabel = g.CreateUriNode("rdfs:label");
var rdfsSubclassOf = g.CreateUriNode("rdfs:subclassOf");
// Assert triples
g.Assert(lion, a, owlClass);
g.Assert(lion, rdfsLabel, g.CreateLiteralNode("Lion", "en"));
g.Assert(lion, rdfsSubclassOf, animals);
When this graph is serialized as RDF/XML the output you get is:
<?xml version="1.0" encoding="utf-16"?>
<rdf:RDF xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<owl:Class rdf:about="http://my.taxonomies.com/myModel/Lion">
<rdfs:label xml:lang="en">Lion</rdfs:label>
<rdfs:subclassOf rdf:resource="http://my.taxonomies.com/myModel/Animals" />
</owl:Class>
</rdf:RDF>
And this code creates the same graph, using the Ontology helpers:
var o = new OntologyGraph();
var lion = o.CreateOntologyClass(UriFactory.Create("http://my.taxonomies.com/myModel/Lion"));
lion.AddType(UriFactory.Create(OntologyHelper.OwlClass));
lion.AddLabel("Lion", "en");
var animals = o.CreateOntologyClass(UriFactory.Create("http://my.taxonomies.com/myModel/Animals"));
lion.AddSuperClass(animals);
The RDF/XML generated for this graph is the same as before:
<?xml version="1.0" encoding="utf-16"?>
<rdf:RDF xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<owl:Class rdf:about="http://my.taxonomies.com/myModel/Lion">
<rdfs:label xml:lang="en">Lion</rdfs:label>
<rdfs:subClassOf rdf:resource="http://my.taxonomies.com/myModel/Animals" />
</owl:Class>
</rdf:RDF>
The OntologyGraph class actually extends Graph so you can mix-and-match these modes, using either the low-level or the higher-level APIs on it.

Unable to create DataPropertyAssertion with OWL API

CODE:
OWLDataProperty prop = factory.getOWLDataProperty(IRI.create(getOntologyIRI() + "#" + owlDataProp));
OWLNamedIndividual ind = factory.getOWLNamedIndividual(IRI.create(getOntologyIRI() + "#" + owlNamedIndividual));
OWLLiteral lit = factory.getOWLLiteral(val);
OWLDataPropertyAssertionAxiom axiom = factory.getOWLDataPropertyAssertionAxiom(prop, ind, lit);
if(manager.addAxiom(this.ontology, axiom) == ChangeApplied.SUCCESSFULLY)
return saveOntology();
return false;
creates:
and
But expected result is (manually created):
I try to create OWLNegativeDataPropertyAssertionAxiom and it works fine. Also if I create getOWLNegativeDataPropertyAssertionAxiom first and then create OWLDataPropertyAssertionAxiom - it works.
OWLAPI: owlapi-distribution-4.1.4.jar
EDIT:
Created ontologies:
<?xml version="1.0"?>
<rdf:RDF xmlns="gunkoFB.owl#"
xml:base="gunkoFB.owl"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:gunkoFB="gunkoFB.owl#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<owl:Ontology rdf:about="gunkoFB.owl"/>
<owl:DatatypeProperty rdf:about="gunkoFB.owl#hasFirstName"/>
<owl:NamedIndividual rdf:about="gunkoFB.owl#Michal_Joštiak">
<hasFirstName rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Michal</hasFirstName>
</owl:NamedIndividual>
<?xml version="1.0"?>
<rdf:RDF xmlns="gunkoFB.owl#"
xml:base="gunkoFB.owl"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<owl:Ontology rdf:about="gunkoFB.owl"/>
<owl:DatatypeProperty rdf:about="gunkoFB.owl#hasFirstName"/>
<owl:NamedIndividual rdf:about="gunkoFB.owl#Michal_Joštiak"/>
<rdf:Description>
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NegativePropertyAssertion"/>
<owl:sourceIndividual rdf:resource="gunkoFB.owl#Michal_Joštiak"/>
<owl:assertionProperty rdf:resource="gunkoFB.owl#hasFirstName"/>
<owl:targetValue rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Michal</owl:targetValue>
</rdf:Description>
Looks like missed declarations. Can you try this with 4.2.5? There have been bugs fixed in this area in the last few versions.
Edit: after checking the code in the OWLAPI issue tracker, it turns out the issue is the ontology IRI, which needs to be absolute. The relative IRI means that, when saving to a file, the file location is used to disambiguate the declaration IRIs; however this is not done uniformly, causing missed declarations - which is the root issue.
As a workaround while the bug is fixed, use absolute IRIs for the ontology IRI.

Inferencing DataType Properties

I'm new to this ontology. I m using protege now. I have 2 classes BT and Document. I have created 2 Object Property 1. topic (Domain:Document , Range:BT) 2. hasDocument (Inverse property of topic).
I have created 1 DataType Property called title (Domain:Document Range:Literal).
Following are the Samples for the properties which I have created
BT hasDocument Document
Document topic BT
Document title "TestingName"
I dont know how to create a property which infers the following result
BT newProperty "TestingName"
If I understand your question, you're looking to be able to infer from
docX topic someTopic
docX title "SampleTitle"
someTopic hasDocumentWithTitle "SampleTitle"
You could almost do this with an property chain, by asserting that hasDocumentWithTitle has as a subproperty the chain (inverse topic) o title. Unfortunately, in OWL property chains can't end with datatype properties, so you can't do this. However, you can use SWRL rules, and many OWL2 reasoners process SWRL rules. You'd use a rule of the form:
topic(?doc,?topic) ∧ title(?doc,?title) → hasDocumentWithTitle(?topic,?title)
For instance we can get the following result in Protege with the following ontology:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rule-example="http://www.example.org/rule-example#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:swrl="http://www.w3.org/2003/11/swrl#"
xmlns:swrlb="http://www.w3.org/2003/11/swrlb#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<owl:Ontology rdf:about="http://www.example.org/rule-example"/>
<owl:Class rdf:about="http://www.example.org/rule-example#Document"/>
<owl:Class rdf:about="http://www.example.org/rule-example#Topic"/>
<owl:ObjectProperty rdf:about="http://www.example.org/rule-example#hasTopic"/>
<owl:DatatypeProperty rdf:about="http://www.example.org/rule-example#hasTitle"/>
<owl:DatatypeProperty rdf:about="http://www.example.org/rule-example#hasDocumentWithTitle"/>
<owl:NamedIndividual rdf:about="http://www.example.org/rule-example#doc42">
<rdf:type rdf:resource="http://www.example.org/rule-example#Document"/>
<rule-example:hasTitle>Document Number Forty-Two</rule-example:hasTitle>
<rule-example:hasTopic>
<owl:NamedIndividual rdf:about="http://www.example.org/rule-example#topic101">
<rdf:type rdf:resource="http://www.example.org/rule-example#Topic"/>
<rule-example:hasTopic rdf:resource="http://www.example.org/rule-example#topic101"/>
</owl:NamedIndividual>
</rule-example:hasTopic>
</owl:NamedIndividual>
<swrl:Imp>
<swrl:head>
<swrl:AtomList>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="http://www.example.org/rule-example#hasDocumentWithTitle"/>
<swrl:argument2>
<swrl:Variable rdf:about="urn:swrl#title"/>
</swrl:argument2>
<swrl:argument1>
<swrl:Variable rdf:about="urn:swrl#topic"/>
</swrl:argument1>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
</swrl:AtomList>
</swrl:head>
<swrl:body>
<swrl:AtomList>
<rdf:rest>
<swrl:AtomList>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
<rdf:first>
<swrl:DatavaluedPropertyAtom>
<swrl:propertyPredicate rdf:resource="http://www.example.org/rule-example#hasTitle"/>
<swrl:argument1>
<swrl:Variable rdf:about="urn:swrl#doc"/>
</swrl:argument1>
<swrl:argument2 rdf:resource="urn:swrl#title"/>
</swrl:DatavaluedPropertyAtom>
</rdf:first>
</swrl:AtomList>
</rdf:rest>
<rdf:first>
<swrl:IndividualPropertyAtom>
<swrl:propertyPredicate rdf:resource="http://www.example.org/rule-example#hasTopic"/>
<swrl:argument1 rdf:resource="urn:swrl#doc"/>
<swrl:argument2 rdf:resource="urn:swrl#topic"/>
</swrl:IndividualPropertyAtom>
</rdf:first>
</swrl:AtomList>
</swrl:body>
</swrl:Imp>
</rdf:RDF>

How to add OWL:imports to a .owl file by jena

I am new to Jena. I want to create a new OntModel and need to imports some other ontology to this model.If I write it to file, I expect the file can show something like follow:
<owl:Ontology rdf:about="">
<owl:imports rdf:resource="http://test.owl#"/>
</owl:Ontology>
Right now, I dont know how to import other ontology to the model by jena. Can any one give me some advices?
Thank you
See jena's Ontology API (which sits over the RDF api) and in particular the imports section.
To make something like you want, try:
String base = "http://www.example.com/ont";
OntModel model = ModelFactory.createOntologyModel();
Ontology ont = model.createOntology("");
ont.addImport(model.createResource("http://test.owl#"));
model.write(System.out, "RDF/XML-ABBREV", base);
Result:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xml:base="http://www.example.com/ont">
<owl:Ontology rdf:about="">
<owl:imports rdf:resource="http://test.owl#"/>
</owl:Ontology>
</rdf:RDF>

Resources