Following the definition of symmetric and asymmetric properties in OWL 2 and the explanation in Inheritance of property characteristic by sub-properties I would assume that the declaration of an asymmetric property as sub-property to a symmetric property would result in an inconsistency detected by the reasoner (HermiT 1.3.8.413), but that is not the case in Protégé 5.2.0. Any explanations for this?
HermiT infers from the assertions below correctly the range of :isNeighbourto be :Word and :W1 :isNeighbour :W2, and detects an inconsistency when :W1 :folllows :W2. The same is true for Pellet and Fact++ 1.6.5 in Protégé 5.2.0.
:isNeighbour a owl:SymmetricProperty; rdfs:domain :Word .
:follows a owl:AsymmetricProperty; rdfs:subPropertyOf :isNeighbour .
:W1 a :Word .
:W2 a :Word .
:W2 :follows :W1 .
This code seems to be a sensible formal representation of text (words are (symmetric) neighbours when they follow each other (asymmetric)), but in the definition of OWL it seems to be inconsistent as every assertion using the property :follows should consistently allow the assertions made with the superclass :isNeighbour.
I'm not sure if the Reasoners are just less strict than OWL or I've a misunderstanding of OWL.
Some property characteristics are "top-down inherited" through property hierarchy, whereas some are not:
P rdfs:subPropertyOf Q means ∀x∀y(P(x,y) → Q(x,y)) (1)
Q a owl:SymmetricProperty means ∀x∀y(Q(x,y) → Q(y,x)) (2)
Do (1) and (2) entail ∀x∀y(P(x,y) → P(y,x))? You have already find a countermodel. You could replace "words" with "natural numbers" for solidity.
Actually, symmetricity is "down-top inherited".
P.S. Demystifying OWL for the Enterprise by M. Uschold says that the subproperty of a symmetric property is symmetric, which is not correct.
Related
I have a simple OWL ontology that I have loaded into a GraphDB repo (standard prefixes omitted for clarity):
#prefix s: <urn:sample:> .
s:Fruit a owl:Class;
owl:oneOf (s:Apple s:Banana s:Pear) .
[a owl:AllDifferent;
owl:distinctMembers (s:Apple s:Banana s:Pear)] .
s:eats a owl:ObjectProperty .
s:Fruitivore owl:equivalentClass
[a owl:Restriction;
owl:onProperty s:eats;
owl:allValuesFrom s:Fruit].
s:Henry a s:Fruitivore .
s:LimitedDiet owl:equivalentClass
[a owl:Restriction;
owl:onProperty s:eats;
owl:maxCardinality 3].
I'm asserting that there are only 3 types of fruit, and that Henry is someone who eats only Fruit.
Finally I've defined a class (LimitedDiet) of those individuals that eat no more than 3 different things.
If I load this, I see all 6 expected owl:differentFrom inferences (fruitA owl:differentFrom fruitB) as long as I choose owl-max as my ruleset.
However, regardless of which precanned ruleset type I choose for my repository, I never see the inference that Henry is an individual belonging to the class LimitedDiet.
Is this expected, given the available rulesets? If I wanted to define my own ruleset that could support this type of inference, are there any pointers anyone could direct me to that could help?
Also - should I have expected to see all:differentFrom assertions inferred in OWL-RL and OWL-QL as well as OWL-MAX? I thought they were both extensions of the latter.
Many thanks!
I have owl file containing some axioms :
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="namespace#Gender"/>
<owl:hasValue>M</owl:hasValue>
</owl:Restriction>
</rdfs:subClassOf>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="namespace#Address"/>
<owl:minQualifiedCardinality rdf:datatype="&xsd;nonNegativeInteger">1</owl:minQualifiedCardinality>
<owl:onDataRange rdf:resource="&xsd;string"/>
</owl:Restriction>
</rdfs:subClassOf>
For above two axioms protege shows readable string as :
Gender value "M"
Address min 1 xsd:string
The question is how protege generates these readable strings from OWL file ?
Also if I want to create new axiom from these strings how to do that ? (converting axiom to readable string and then convert readable string to axiom back)
The readable format you show is Manchester OWL syntax.
In order to output an ontology in this format, you can use owl api code:
OWLOntology ontology = ...// load or create the ontology
OutputStream out = ... // any output stream will do
ontology.getOWLOntologyManager().saveOntology(ontology, new ManchesterSyntaxDocumentFormat(), out);
out.close();
Parsing a full ontology in Manchester syntax format happens like any other ontology: ontologyManager.loadOntologyFromOntologyDocument() with an input file.
Parsing single axioms is possible but much harder, because the format relies on prefixes set once for a whole ontology; so a lot of setup code is required. I would not recommend doing that as a starter project.
I want to infer a owl:sameAs relation between objects that have the same value for a property using RDF reasoning.
i.e.
object1 dc:title someTitle
object2 dc:title someTitle
What would be the code to infer the relation between all objects with matching titles?
Also, can I do that when the properties are not the same?
i.e.
object1 dc:title someTitle
object2 rdf:title someTitle
Regards
Not in RDF or RDFS
RDF doesn't have a whole lot of semantics built in, and while RDFS provides some, I don't think that either is enough to get you the kind of reasoning that you're looking for. However, since you're looking to create owl:sameAs links, you might be using an OWL reasoner, in which case this isn't too hard, and it's very easy in SPARQL too. The rest of the answer covers these two cases.
In OWL
You just need to declare that the property at hand is an inverse functional (object) property:
9.2.8 Inverse-Functional Object Properties
An object property inverse functionality axiom
InverseFunctionalObjectProperty( OPE ) states that the object property
expression OPE is inverse-functional — that is, for each individual x,
there can be at most one individual y such that y is connected by OPE
with x.
A classic example of this is for any type of unique identifier, such as a taxpayer ID number. E.g.,
ex:hasSSN a owl:InverseFunctionalProperty .
:JohnDoe :hasSSN :ssnXXX-XX-XXXX .
:JDoe :hasSSN :ssnXXX-XX-XXXX .
From these, we can infer with OWL reasoning that
:JohnDoe owl:sameAs :JDoe .
Note that only object properties can be inverse functional (though I think that some reasoners will handle inverse functional datatype properties); this means that you may have to "wrap" some values as I did above, creating an IRI individual :ssnXXX-XX-XXX rather than using the string "XXX-XX-XXXX". See
What's the problem with inverse-functional datatype properties? for some discussion about why.
Now, if you have two different properties, then you could make them both subproperties of some new property, and make the new property inverse functional. For instance
:hasSSN rdfs:subPropertyOf :hasTaxpayerIDOrSSN .
:hasTaxpayerID rdfs:subPropertyOf :hasTaxpayerIDOrSSN .
:hasTaxpayerIDOrSSN a owl:InverseFunctionalProperty .
Then from
:JohnDoe :hasSSN :ssnXXX-XX-XXXX .
:JDoe :hasSSN :ssnXXX-XX-XXXX .
you could infer
:JohnDoe :hasTaxpayerIDOrSSN :ssnXXX-XX-XXXX .
:JDoe :hasTaxpayerIDOrSSN :ssnXXX-XX-XXXX .
and from that, that
:JohnDoe owl:sameAs :JDoe .
In SPARQL
In SPARQL this is pretty easy, too. First, some data to query:
#prefix : <urn:ex:> .
:JohnDoe :hasSSN :ssnXXX-XX-XXX .
:JDoe :hasSSN :ssnXXX-XX-XXX .
Then we can define a simple construct query:
prefix : <urn:ex:>
prefix owl: <http://www.w3.org/2002/07/owl#>
construct { ?x owl:sameAs ?y }
where { ?z ^:hasSSN ?x, ?y }
#prefix : <urn:ex:> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
:JDoe owl:sameAs :JohnDoe , :JDoe .
:JohnDoe owl:sameAs :JohnDoe , :JDoe .
If you want to use multiple properties, you can just use an alternation in the property path. Here's data, a query, and the results:
#prefix : <urn:ex:> .
:JohnDoe :hasSSN :ssnXXX-XX-XXX .
:JDoe :hasTaxpayerID :ssnXXX-XX-XXX .
prefix : <urn:ex:>
prefix owl: <http://www.w3.org/2002/07/owl#>
construct { ?x owl:sameAs ?y }
where { ?z ^(:hasSSN|:hasTaxpayerID) ?x, ?y }
#prefix : <urn:ex:> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
:JDoe owl:sameAs :JDoe , :JohnDoe .
:JohnDoe owl:sameAs :JDoe , :JohnDoe .
You can try using the SILK framework: http://wifo5-03.informatik.uni-mannheim.de/bizer/silk/
I have used it successfully several times to find owl:sameAs relationships between entities from different datasets (e.g., if you have a dataset with provinces and you want to find which entities from DBpedia have the same province name). As far as I know you can use it to match elements from the same dataset as well.
The advantage of using SILK is that you have several algorithms to compare entities with similar value (e.g., someTitle, some Title, Sometitle and SOMETITLE would be matched). You can play with the filters to get the results you want. The only disadvantage is that if you lower the distance value to compare SILK could match values like "some Title" and "som Title", which could be wrong depending on your use case.
Hello I'm totally newbie in ontology.
I downloaded dbpedia ontology .owl file and open it using topbraid composer.
Topbraid composer shows dbpedia class( owl:Thing -> Activity, Agent, .. etc). Each class also has its own instances.
However, yago2s only provides many .ttl files( yagoSchema.ttl, yagoFact.ttl .. etc).
Cause I think these ttl files are similar to owl file, I also open it using topbraid composer. I expected to see the structure like dbpedia owl file, but it wasn't similar to dbpedia owl file..
They provide schema ttl file, instances ttl file, ... files respectively, but i wanna see the whole thing at once.
Should I get yago2s owl file? or is there any ways to see yago ttl files like dbpedia owl??
Thanks in advance.
The error message when I tried to open yagoTypes.ttl file is
java.lang.reflect.InvocationTargetException
at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:421)
at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:507)
at org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog.run(ProgressMonitorJobsDialog.java:275)
at org.eclipse.ui.internal.progress.ProgressManager$3.run(ProgressManager.java:960)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
at org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:995)
at org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:970)
at org.topbraidcomposer.core.io.TBCIO$3.run(TBCIO.java:501)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4145)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3762)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1113)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:997)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:140)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:611)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:567)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
at org.eclipse.equinox.launcher.Main.run(Main.java:1450)
at org.eclipse.equinox.launcher.Main.main(Main.java:1426)
Caused by: java.lang.NullPointerException
at org.topbraid.core.model.Classes.getMetaClasses(Classes.java:548)
at org.topbraid.core.model.Classes.computeMetaClasses(Classes.java:45)
at org.topbraidcomposer.core.session.AbstractSessionWithCache.getCachedMetaClasses(AbstractSessionWithCache.java:67)
at org.topbraid.core.model.Classes.getMetaClasses(Classes.java:166)
at org.topbraidcomposer.editors.ResourceEditorLauncher.checkVisibility(ResourceEditorLauncher.java:270)
at org.topbraidcomposer.editors.ResourceEditorLauncher.access$4(ResourceEditorLauncher.java:269)
at org.topbraidcomposer.editors.ResourceEditorLauncher$5.run(ResourceEditorLauncher.java:577)
at org.topbraidcomposer.core.io.TBCIO$2.run(TBCIO.java:482)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
and this same error occurs when I concatenate yagoTypes.ttl and yagoFacts.ttl using cat command, and try to open this concatenated file..
Where to get the data
If you got the data from YAGO2s Downloads, it says right at the beginning of the page:
You can download the entire YAGO2s ontology in one piece. (Extracted
from 2012-12-01 version of Wikipedia.)
Download YAGO2s ontology in
.ttl format! (2.2 Gb compressed, 18.5 Gb uncompressed)
That sounds like what you want. If you just want to see the class hierarchy, though, then you might want the yagoTaxonomy files:
yagoTaxonomy The entire YAGO taxonomy. These are all rdfs:subClassOf facts derived from Wikipedia and from WordNet.
The format of the data
OWL is a ontology language with an abstract structure that can be serialized in a number of different ways including OWL/XML, the OWL Functional Syntax, the Manchester Syntax, and encoded as RDF. Now, RDF is also an abstract format, and can be serialized in a number of ways, including N-Triples, N3, Turtle (ttl), and RDF/XML. Most .owl files that you find are actually RDF/XML files that are serializations of the RDF encoding of an OWL ontology. That's probably what your .owl file is. The .ttl files you're seeing are the Turtle serialization of the RDF encoding of an OWL ontology. Standard RDF processing tools should be able to process it.
The following ontology is inconsistent. Can you explain why?
:Ingredient a owl:Class.
:Car a owl:Class;
owl:disjointWith :Ingredient.
:MyCar a :Car.
:Cheese a :Ingredient.
:Milk a :Ingredient.
:containsIngredient a owl:ReflexiveObjectProperty, owl:TransitiveObjectProperty;
rdfs:domain :Ingredient;
rdfs:range :Ingredient;
:Cheese :containsIngredient :Milk.
The reasoner is inferring that :MyCar :containsIngredient :MyCar
which means that :MyCar a :Ingredient
and since :MyCar a :Car and :Car :disjointWith :Ingredient, my ontology is inconsistent.
The question is: why is the reflexive property :containsIngredient true for :MyCar, although it has :Ingredient as range and domain?
Apparently an owl:ReflexiveObjectProperty applies to all things (owl:Thing) regardless of the domain and range of the property. By setting a rdfs:domain and a rdfs:range to the property, you are implicitly asserting that all owl:Thing individuals are also individuals of the range and domain classes. In my opinion this renders the owl:ReflexiveObjectPropery useless.
What I should have done in the ontology above is to make :Ingredient equivalent to containsIngredient Self (Protégé class expression syntax), instead of using owl:ReflexiveObject property which ignores the domain and range of the property.