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.
Related
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.
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.
I tried working with the OWL2-RL rules build into graphdb. I am obviously doing something wrong or understood something wrong. Here is my toy ontology.
<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.semanticweb.org/rlehmann/ontologies/2017/10/untitled-ontology-182#"
xml:base="http://www.semanticweb.org/rlehmann/ontologies/2017/10/untitled-ontology-182"
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:untitled-ontology-182="http://www.semanticweb.org/rlehmann/ontologies/2017/10/untitled-ontology-182#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:ontology="http://www.some/ontology/">
<owl:Ontology rdf:about="http://www.semanticweb.org/rlehmann/ontologies/2017/10/untitled-ontology-182"/>
<!-- http://www.some/ontology/hasValue -->
<owl:DatatypeProperty rdf:about="http://www.some/ontology/hasValue">
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
</owl:DatatypeProperty>
<!-- http://www.some/ontology/ClassA -->
<owl:Class rdf:about="http://www.some/ontology/ClassA"/>
<!-- http://www.some/ontology/InvA -->
<owl:NamedIndividual rdf:about="http://www.some/ontology/InvA">
<rdf:type rdf:resource="http://www.some/ontology/ClassA"/>
<ontology:hasValue rdf:datatype="http://www.w3.org/2001/XMLSchema#string">StringValue</ontology:hasValue>
</owl:NamedIndividual>
<!-- http://www.some/ontology/InvB -->
<owl:NamedIndividual rdf:about="http://www.some/ontology/InvB">
<ontology:hasValue rdf:datatype="http://www.w3.org/2001/XMLSchema#string">FooBar</ontology:hasValue>
</owl:NamedIndividual>
<owl:Restriction>
<owl:onProperty rdf:resource="http://www.some/ontology/hasValue"/>
<owl:someValuesFrom rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
<rdfs:subClassOf rdf:resource="http://www.some/ontology/ClassA"/>
</owl:Restriction>
</rdf:RDF>
If I did not misunderstand Table 2 in OWL2-Profiles this ontology should be in OWL2 RL profile. I would expect "InvB" to be classified as type ClassA. But it doesn't. It actually does with reasoners (HermiT, Pellet, ...) but not with Rules (Drools, Graphdb) is this a gap in the specification.
How can my Ontology be "repaired" or is there any workaround?
Cheers,
Robert
Not using anonymous classes on the left-hand side of the GCI is not an option for our application. And yes object properties work perfectly.
After some research we actually found out, that it can never work that way. In the GraphDB .pie file that corresponds to the RL-Profile there is only a notion to some rules "// These are not implemented (and probably not implementable)". This includes the rule "dt-type2" defined in OWL2 RL Section 4.3 Table 8. RDF section 3.1 gives the actual answer why this is not supposed to work.
RDF Graphs
An RDF graph is a set of RDF triples.
3.1 Triples
An RDF triple consists of three components:
the subject, which is an IRI or a blank node
the predicate, which is an IRI
the object, which is an IRI, a literal or a blank node
"FooBar"^^xsd:string rdf:type xsd:string this is simply not allowed but obviously required.
We are quite uncertain what the guys at w3c had in mind besides RDF?!
As it is now, this kind of inference will not work in GraphDB at all (and on no rule engines in general?). But it is not the fault of GraphDB but merely a gap in the specification chain.
However, we did a workaround in our ontology that solves the problem and is working for us. We simply
defined new concepts for the data types we use
Transformed all DataProperties to ObjectProperties
introduces new DataType properties with domain one of the new datatype concepts and range xsd:xyz. For example Property:hasStringValue Domain:string Range:xsd:string
This works for us.
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>
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>