How to infer a sameAs relation between objects with the same name - relationship

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.

Related

How to get whole <rdf:Description rdf:about=""> tag text from RDF database?

I have an RDF database and I want to get whole tag text I mean whole text which is inside the tag - <rdf:Description rdf:about="tag:stardog:api:0.44585392708185767">
<rdf:Description rdf:about="tag:stardog:api:0.44585392708185767">
<rdf:type rdf:resource="http://www.wdaqua.eu/qa#AnnotationOfAnswerSPARQL"/>
<hasTarget xmlns="http://www.w3.org/ns/openannotation/core/" rdf:resource="http://localhost:8080/question/stored-question__text_573b4a57-cc42-4001-9961-fdde2005f841"/>
<hasBody xmlns="http://www.w3.org/ns/openannotation/core/" rdf:datatype="http://www.w3.org/2001/XMLSchema#string">PREFIX dbr: <http://dbpedia.org/resource/> PREFIX dct: <http://purl.org/dc/terms/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>SELECT * WHERE {?resource foaf:name ?answer . ?resource rdfs:label ?label . FILTER(LANG(?label) = "en") . resource dct:subject dbr:Category:Superhero_film_characters . FILTER(! strStarts(LCASE(?label), LCASE(?answer))). VALUES ?resource { <http://dbpedia.org/resource/Captain_America> } . } ORDER BY ?resource</hasBody> <annotatedAt xmlns="http://www.w3.org/ns/openannotation/core/" rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2021-06-17T22:35:52.067+05:30</annotatedAt>
<annotatedBy xmlns="http://www.w3.org/ns/openannotation/core/" rdf:resource="urn:qanary:QueryBuilderSimpleRealNameOfSuperHero"/>
<score xmlns="http://www.wdaqua.eu/qa#" rdf:datatype="http://www.w3.org/2001/XMLSchema#float">1.0</score>
</rdf:Description>
How can I write sparql query to get the information of tag?

Can GraphDB support inferences based on cardinality?

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!

Unable to infer instances using axioms

I want to gather data via ontology matching and reasoning. To do that, I'd like to first identify relevant Individuals for later use if they fulfill certain criteria (using general class axioms).
Currently however, I am unable to achieve the necessary inferences using Protégé. The data consisting of various individuals looks like this:
# Data
# Common Prefixes omitted for readability
#prefix ns: <http://example.org/underlyingSchema#> .
#prefix data: <http://example.org/data#> .
data:A1 a ns:A .
data:A2 a ns:A .
data:R1 a ns:R .
ns:defines data:A1 ;
ns:definedBy data:P1 .
data:R2 a ns:R .
ns:defines data:A2 ;
ns:definedBy data:P2 .
data:P1 a ns:P ;
ns:hasS data:S1.
data:P2 a ns:P ;
ns:hasS data:S2.
data:S1 a ns:S ;
ns:hasI data:I1 ;
ns:hasV data:B1 .
data:S2 a ns:S ;
ns:hasI data:I1 ;
ns:hasV data:B2 .
data:I1 a ns:I ;
expr:hasString "relevant" .
data:B1 a ns:B ;
expr:hasBoolean "true"^^xsd:boolean .
data:B2 a ns:B ;
expr:hasBoolean "false"^^xsd:boolean .
I want to infer that every instance of A for which the relevant attribute is true is also an instance of my example-class, defined in my own ontology as eg:Example a owl:class.
Unfortunately, since the underlying schema for the data is very cumbersome, I have to do that via A -> R -> P -> S -> I and B. As R however isn't a straightforward definition (A <- R -> P -> S -> I and B is probably a more accurate representation), I can't just do a someValuesFrom chain and (I assume) this is where I fail.
Using Protégé, I loaded the schema which defines the properties and classes (Namespace ns) to be able to use the suggestions/auto-complete in the class expression editor. In my own ontology (containing only the example-class) following a previous suggestion I tried using the axiom:
A and (inverse defines some) and definedBy some (hasS some (hasI some(hasString value "relevant")) and (hasV some(hasBoolean value "true"^^xsd:boolean))) EquivalentTo: Example
I then merged my ontology with the data and ran the reasoner, expecting to see A1 (but not A2) as an instance of my example-class, but didn't get any results. I also tried using just "true" and true as well as "relevant"^^xsd:string to see if datatypes were causing the problem, yet it is only inferred that Example is a subclass of A.
I believe that my understanding of what inverse does is incorrect (I thought it's used since A1 is the object in the triple R1 defines A1; so I also tried inverse defines self), but I cannot figure it out. Any help is greatly appreciated.
Edit:
As Joshua correctly pointed out, my example lacks declarations. In my case, these are made in a different schema ontology, so I forgot about them here. Will add for the sake of completeness:
# Might as well include prefixes
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix expr: <http://purl.org/voc/express#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
# Classes
ns:A a owl:Class .
ns:R a owl:Class .
ns:P a owl:Class .
ns:S a owl:Class .
ns:I a owl:Class .
ns:B a owl:Class .
# Object Properties
ns:defines a owl:ObjectProperty .
ns:definedBy a owl:ObjectProperty .
ns:hasS a owl:ObjectProperty .
ns:hasI a owl:ObjectProperty .
ns:hasV a owl:ObjectProperty .
# Data Properties
expr:hasString a owlDatatypeProperty .
expr:hasBoolean a owlDatatypeProperty .
It doesn't look like that data was generated by Protege. When I copy that content and load it into Protege, everything shows up as annotation properties, which aren't generally handled under OWL reasoning. They show up as annotation properties because there are no property declarations making them object properties or datatype properties. That might be part of your problem. That axiom doesn't look quite right, either. E.g., (inverse defines some) doesn't make sense; that would have to be (inverse defines) some class expression, etc. In general, it helps a lot if you can provide complete working examples that we can work with. See How to create a Minimal, Complete, and Verifiable example.
All that said, I think we can recreate enough of the problem to figure out how to fix it. It sounds like you want to recognize a pattern like
A <--rdf:type-- ?a <--p-- ?b --q--> ?c --r--> 42
and then infer the triple
?a --rdf:type--> Goal
That is achievable in OWL. It requires an axiom of the form:
A and ((inverse p) some (q some (r value 42))) SubClassOf Goal
That says that if something is an A and is the p value of something that has a q value that has an r value of 42, then that first something is also a Goal.
Here's what it looks like in an actual ontology:
Once a reasoner has been started, it correctly infers that a is an instance of Goal:
Here's the actual ontology:
#prefix : <http://example.org/gca#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#base <http://example.org/gca> .
<http://example.org/gca> rdf:type owl:Ontology .
#################################################################
# Object Properties
#################################################################
### http://example.org/gca#p
:p rdf:type owl:ObjectProperty .
### http://example.org/gca#q
:q rdf:type owl:ObjectProperty .
#################################################################
# Data properties
#################################################################
### http://example.org/gca#r
:r rdf:type owl:DatatypeProperty .
#################################################################
# Classes
#################################################################
### http://example.org/gca#A
:A rdf:type owl:Class .
### http://example.org/gca#Goal
:Goal rdf:type owl:Class .
#################################################################
# Individuals
#################################################################
### http://example.org/gca#a
:a rdf:type owl:NamedIndividual ,
:A .
### http://example.org/gca#b
:b rdf:type owl:NamedIndividual ;
:p :a ;
:q :c .
### http://example.org/gca#c
:c rdf:type owl:NamedIndividual ;
:r 42 .
#################################################################
# General axioms
#################################################################
[ owl:intersectionOf ( :A
[ rdf:type owl:Restriction ;
owl:onProperty [ owl:inverseOf :p
] ;
owl:someValuesFrom [ rdf:type owl:Restriction ;
owl:onProperty :q ;
owl:someValuesFrom [ rdf:type owl:Restriction ;
owl:onProperty :r ;
owl:hasValue 42
]
]
]
) ;
rdf:type owl:Class ;
rdfs:subClassOf :Goal
] .
### Generated by the OWL API (version 4.2.5.20160517-0735) https://github.com/owlcs/owlapi

Defined class with annotation property in Protégé

How do I create a defined class using an annotation property in an OWL ontology?
Currently, I have created a defined class by using an object property hasSubject.
The defined class:
I would prefer to create this class by re-using the annotation 'Subject' from the DC-Terms set instead of a custom object property.
Is it possible to create a defined class with an annotation property?
How would I do that in Protégé?
You can't use annotation properties in OWL class restrictions. You can use object properties and datatype properties, but not annotation properties. In particular, the abstract syntax for an existential restriction like
isSubjectOf some Film
is, from 8.2.1 Existenial Quantification:
ObjectSomeValuesFrom := 'ObjectSomeValuesFrom' '(' ObjectPropertyExpression ClassExpression ')'
You won't have an ObjectPropertyExpression when you're working with an annotation property.
What you can do, however, is declare dcterms:subject as an object property in your ontology, and then you'll be able to use it. According to the documentation on dcterms:subject, the IRI is http://purl.org/dc/terms/subject. You'd declare that in Protege like any other object property:
Then you can use it in class expressions:
Do note that the documentation for dcterms:subject says:
Note: This term is intended to be used with non-literal values as
defined in the DCMI Abstract Model
(http://dublincore.org/documents/abstract-model/). As of December
2007, the DCMI Usage Board is seeking a way to express this intention
with a formal range declaration.
That means that that you're actually saying something a bit more restrictive. By declaring dcterms:subject as an object property, you'll be able to infer that whenever "X dcterms:subject Y", both X and Y are instances of owl:Thing, as well as whatever else you might say about the domain and range of the property. Since other people might not use dcterms:subject as an object property, they might not expect those inferences.
Here's what the ontology ends up as:
#prefix : <http://stackoverflow.com/q/29317444/1281433/> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#base <http://stackoverflow.com/q/29317444/1281433/> .
<http://stackoverflow.com/q/29317444/1281433/> rdf:type owl:Ontology .
#################################################################
#
# Object Properties
#
#################################################################
### http://purl.org/dc/terms/subject
<http://purl.org/dc/terms/subject> rdf:type owl:ObjectProperty .
#################################################################
#
# Classes
#
#################################################################
### http://stackoverflow.com/q/29317444/1281433/FilmSubjectComposer
:FilmSubjectComposer rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Class ;
owl:intersectionOf ( <http://stackoverflow.com/q/29317444/1281433/#Composer>
[ rdf:type owl:Restriction ;
owl:onProperty [ owl:inverseOf <http://purl.org/dc/terms/subject>
] ;
owl:someValuesFrom <http://stackoverflow.com/q/29317444/1281433/#Film>
]
)
] .
### http://stackoverflow.com/q/29317444/1281433/#Composer
<http://stackoverflow.com/q/29317444/1281433/#Composer> rdf:type owl:Class .
### http://stackoverflow.com/q/29317444/1281433/#Film
<http://stackoverflow.com/q/29317444/1281433/#Film> rdf:type owl:Class .
### Generated by the OWL API (version 3.5.0) http://owlapi.sourceforge.net

Inconsistency caused by reflexive property

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.

Resources