Retrieve objects from RDF triples - sparql

With the following snippet from the pizza ontology:
<owl:Class rdf:about="http://www.co-ode.org/ontologies/pizza/pizza.owl#Pizza">
<rdfs:subClassOf rdf:resource="http://www.co-ode.org/ontologies/pizza/pizza.owl#Food"/>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="http://www.co-ode.org/ontologies/pizza/pizza.owl#hasBase"/>
<owl:someValuesFrom rdf:resource="http://www.co-ode.org/ontologies/pizza/pizza.owl#PizzaBase"/>
</owl:Restriction>
</rdfs:subClassOf>
<rdfs:label xml:lang="en">Pizza</rdfs:label>
<rdfs:seeAlso rdf:resource="https://en.wikipedia.org/wiki/Pizza"/>
<skos:prefLabel xml:lang="en">Pizza</skos:prefLabel>
</owl:Class>
I see from this that the following triple exists:
<Pizza, hasBase, PizzaBase> representing <subject, predicate, object>
How do I write SPARQL to extract the the PizzaBase object or any object from a triplet when the entity and relation are known?
Note: I am equating subject as entity and predicate as relation
Update:
Let me simplify my question.
Based on the given RDF above and the following RDF graph:
What would be the SPARQL to extract the PizzaBase entity given the Pizza entity and the hasBase relation?

Enclose known subjects in <> tags. It's also possible to use SPARQL BIND to bind the URI to a variable. For predicates just be sure to prefix them, shown below.
Assuming that you know the identifier of the Pizza node, it should be...
PREFIX pizza: <http://www.co-ode.org/ontologies/pizza/pizza.owl#>
SELECT ?pizzaBase WHERE {
<pizza> pizza:hasBase ?pizzaBase .
}
To get all pizza bases from pizzas, you can do...
PREFIX pizza: <http://www.co-ode.org/ontologies/pizza/pizza.owl#>
SELECT ?pizza ?pizzaBase WHERE {
?pizza pizza:hasBase ?pizzaBase .
}

Related

How to query implicit properties of owl:equivalentclass

I want to query an ontology which contains implicit properties hold by owl:equivalentclass objects. How can I achieve this?
The ontology holds triples like this:
<plantURI> rdf:type <http://purl.obolibrary.org/obo/FLOPO_0004148>.
The class <http://purl.obolibrary.org/obo/FLOPO_0004148> has the following definition:
<owl:Class rdf:about="http://purl.obolibrary.org/obo/FLOPO_0004148">
<owl:equivalentClass>
<owl:Restriction>
<owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000051"/>
<owl:someValuesFrom>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<rdf:Description rdf:about="http://purl.obolibrary.org/obo/PO_0009046"/>
<owl:Restriction>
<owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/RO_0000053"/>
<owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/PATO_0000320"/>
</owl:Restriction>
</owl:intersectionOf>
</owl:Class>
</owl:someValuesFrom>
</owl:Restriction>
</owl:equivalentClass>
<rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string">flower green</rdfs:label>
</owl:Class>
However, I don't want to query simply for the URI like this:
SELECT * {
?s rdf:type <http://purl.obolibrary.org/obo/FLOPO_0004148>
}
but I want to query sometimes only for one of its implicit properties, for example the property <http://purl.obolibrary.org/obo/PATO_0000320> ("green") - searching for all plants that are green in any way.
So, the best query would look like this:
SELECT * {
?s ?p <http://purl.obolibrary.org/obo/PATO_0000320>
}
Which gives me the object, because implicitly the object holds this property.
This probably involves reasoning in Virtuoso. However, after some hours I cannot come up with any solution how to do this in SPARQL.
Virtuoso provides reasoning and inference in two forms.
1. Built-in -- this is based on canned rules covering the relations semantics for owl:equivalentClass, owl:equivalentProperty, owl:inverseOf, owl:sameAs, owl:InverseFunctionalProperty, owl:SymmetricProperty, rdfs:subClassOf, rdfs:subPropertyOf (this is supported in both open source and commercial editions)
Custom -- this is based on custom rules crafted using SPARQL and the Rules Language, courtesy of terms from the SPIN Ontology (this is a commercial edition only feature).
You appear right now to simply require owl:equivalentClass reasoning, so you can look at the following built-in inference and reasoning examples:
Equivalent Class Reasoning Enabled
DEFINE input:inference 'urn:owl:equivalent:class:inference:rules'
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX bmo: <http://purl.org/bmo/ns#>
PREFIX fibo: <https://spec.edmcouncil.org/fibo/ontology/FND/AgentsAndPeople/People/Person>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?s
WHERE {
?s a fibo:person .
}
LIMIT 20
Live Query Results Page (solution is produced based on effects of reasoning and inference)
Equivalent Class Reasoning Disabled (notice DEFINE input:inference pragma commented out)
# DEFINE input:inference 'urn:owl:equivalent:class:inference:rules'
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX bmo: <http://purl.org/bmo/ns#>
PREFIX fibo: <https://spec.edmcouncil.org/fibo/ontology/FND/AgentsAndPeople/People/Person>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?s
WHERE {
?s a fibo:person .
}
LIMIT 20
Live Query Results Page (should be empty)
Example source code document from our Github Repository.

SPARQL: Specify datatype in INSERT query

Let's same I want to add via a SPARQL query these triples to my graph
<?xml version="1.0"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:my="http://example.com/ontology#">
<rdf:Description rdf:about="http:/example.com/entity/thisEntity">
<rdf:type rdf:resource="http://example.com/ontology#Identification" />
<my:someID rdf:datatype="http://www.w3.org/2001/XMLSchema#string">003</my:someID>
<my:hasSource rdf:resource="http:/example.com/entity/thisSource" />
</rdf:Description>
</rdf:RDF>
How am I supposed to specify the data type of the third triple?
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX my: <http://example.com/ontology#>
INSERT DATA {
<http:/example.com/entity/thisEntity> rdf:type <http://example.com/ontology#Identification>;
my:hasSource <http:/example.com/entity/thisSource>;
my:someID "003"#xsd:string.
}
You're almost there. The # is for language tags. Datatypes are appended by using the ^^ separator instead. So use "003"^^xsd:string.
You will also need to add the namespace prefix to your update:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
As an aside: in RDF 1.1, xsd:string is the default datatype for any literal that does not have an explicitly defined datatype nor a language tag. So "003" and "003"^^xsd:string are both the same, string-typed, literal.

OWL : how to restrict range with some values in an other property

I have a class Selfie, an objectProperty personPicture (domain Picture, range Person) to explain who is on the picture, and a dc:creator. I want to say that a selfie must have at least 1 personPicture, and the dc:creator should be someone in the list of personPicture. I tried :
<owl:Class rdf:about="http://www.semanticweb.org/leo/ontologies/album#Selfie">
<rdfs:subClassOf rdf:resource="http://www.semanticweb.org/leo/ontologies/album#Picture"/>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="http://www.semanticweb.org/leo/ontologies/album#personPicture"/>
<owl:minQualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:minQualifiedCardinality>
<owl:onClass rdf:resource="http://www.semanticweb.org/leo/ontologies/album#Person"/>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
but it doesn't work. I can have a selfie without personPicture and I absolutely don't know how to do the second trick!
Your axioms are easier to read in Manchester syntax, where they are:
Selfie SubClassOf Picture
Selfie SubClassOf personPicture min 1 Person
The second says that each Selfie is related to at least one Person by the property personPicture. That's consistent with a dataset like:
x a Selfie .
Even though it doesn't specify which Person x is related to by personPicture, a reasoner will correctly infer that there is one. That's part of the open-world assumption that is adopted in OWL. Just because something isn't know does not mean that it is false.
As for your second condition, I'm not sure that you can express it in OWL. You might be able to the axiom that "if a picture's creator is in the picture, then the picture is a Selfie", but that's the other direction from what you're asking.

OWL ontology: SPARQL query a range or domain of an ObjectProperty when they're unionOf classes

I have to query an ontology version 1.4, with a SPARQL 1.1 endpoint, so I can't use the OWL 2 semantic like ClassAssertion etc...
several properties in the ontology have this format:
<owl:ObjectProperty rdf:about="&km4c;hasGeometry">
<rdfs:comment>some services and all railway elements have a specific geometry like polygons or linestrings</rdfs:comment>
<rdfs:range rdf:resource="&gis;Geometry"/>
<rdfs:domain>
<owl:Class>
<owl:unionOf rdf:parseType="Collection">
<rdf:Description rdf:about="&km4c;RailwayElement"/>
<rdf:Description rdf:about="&km4c;Service"/>
</owl:unionOf>
</owl:Class>
</rdfs:domain>
</owl:ObjectProperty>
with domain or range that is a Union of more than one class. The problem is that i want to retrieve all the classes with a certain domain and range, but with the following query:
SELECT DISTINCT ?p
{
?p rdfs:range gis:Geometry.
?p rdfs:domain km4c:Service
}
i get no result, instead of km4c:hasGeometry.
Is there a way to somehow look inside the Collection with this kind of goal?
First, note that the semantics of union of domains and ranges may not be what you expect. In OWL, when you say that class D is a domain of property P, it means that whenever you have an assertion P(x,y), you can infer that D(x). That means that if a domain of P is a union C &sqcup; D, then from P(x,y), you can infer that x is an element of C &sqcup; D; i.e., that x is either a C or a D, but you don't necessarily know which. For instance, you might define:
hasWings rdfs:domain (Airplane &sqcup; Bird)
Then, from hasWings(x,2), you could infer that x is an Airplane or a Bird, but you still wouldn't know which.
Anyhow, if you still want a union class as a domain, you can do that. In the RDF serialization of the mapping of the OWL ontology, the unioned classes are in an RDF list. It's a little bit more complicated to query over those, but you can certainly do it. Since you didn't provide a complete OWL ontology, we can't query over your actual data (in the future, please provide complete, minimal working data that we can use), but we can create a simple ontology. There are two classes, A and B, and two properties, p and q. The domain of p is A, and the domain of q is A or B:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://example.org/"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
<owl:Ontology rdf:about="http://example.org/"/>
<owl:Class rdf:about="http://example.org/#A"/>
<owl:Class rdf:about="http://example.org/#B"/>
<owl:ObjectProperty rdf:about="http://example.org/#q">
<rdfs:domain>
<owl:Class>
<owl:unionOf rdf:parseType="Collection">
<owl:Class rdf:about="http://example.org/#A"/>
<owl:Class rdf:about="http://example.org/#B"/>
</owl:unionOf>
</owl:Class>
</rdfs:domain>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:about="http://example.org/#p">
<rdfs:domain rdf:resource="http://example.org/#A"/>
</owl:ObjectProperty>
</rdf:RDF>
SPARQL syntax is much more like the N3/Turtle serialization of RDF, so it's helpful to see that serialization, too. The unionOf list is much clearer here:
#prefix : <http://example.org/> .
#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 rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
<http://example.org/#A>
a owl:Class .
<http://example.org/#p>
a owl:ObjectProperty ;
rdfs:domain <http://example.org/#A> .
<http://example.org/#B>
a owl:Class .
<http://example.org/#q>
a owl:ObjectProperty ;
rdfs:domain [ a owl:Class ;
owl:unionOf ( <http://example.org/#A> <http://example.org/#B> )
] .
: a owl:Ontology .
Now you can use a query like this to find properties and their domains, or the unioned classes if one of the domains is a union class:
prefix : <http://example.org/>
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 rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?p ?d where {
?p rdfs:domain/(owl:unionOf/rdf:rest*/rdf:first)* ?d
filter isIri(?d)
}
-----------------------------------------------------
| p | d |
=====================================================
| <http://example.org/#q> | <http://example.org/#A> |
| <http://example.org/#q> | <http://example.org/#B> |
| <http://example.org/#p> | <http://example.org/#A> |
-----------------------------------------------------
The interesting parts of that query are:
?p rdfs:domain/(owl:unionOf/rdf:rest*/rdf:first)* ?d
which says you follow a path from ?p to ?d, and the path:
starts with rdfs:domain
and is followed by zero or more repetitions of:
owl:unionOf
followed by zero or more rdf:rest
followed by a single rdf:first
It's not exactly related to this question, but you may find the discussion of querying RDF lists in this answer (disclosure: my answer) to Is it possible to get the position of an element in an RDF Collection in SPARQL? useful.
Then, I also added
filter isIri(?d)
because otherwise we get the node that represents the union class, but that's a blank node that you (probably) don't want.

SPARQL "ASK" query to check if object property exist between two classes (Not b/w individuals)

I want to query, if certain ObjectPropery (OP) exist between two classes inside an OWL2 file. I'm using JENA API to construct the SPARQL queries.
What I have tried till now:
First I used the SELECT query to check the classes for a given OP:
" { SELECT ?domain ?range WHERE {\n" +
":isManagedBy rdfs:domain ?domain; \n" +
" rdfs:range ?range. \n } }" +
"}";
Then I wrapped it with ASK query
" ASK WHERE { \n" +
" { SELECT ?domain ?range WHERE {\n" +
":isManagedBy rdfs:domain ?domain; \n" +
" rdfs:range ?range. \n } }" +
"}";
It seems to give me the answer, but I think, I'm mixing up so many things in this query:
My Goal: Is to query if certain fact exist inside the OWL file or not (Boolean Answer)
Eg: OWL Snippet
<owl:ObjectProperty rdf:ID="isManagedBy">
<rdf:type rdf:resource="owl#FunctionalProperty" />
<rdfs:domain rdf:resource="#FunctionManagement" />
<rdfs:range rdf:resource="#SymposiumPlanner2013"/>
</owl:ObjectProperty>
What I would like to check: isManagedBy(FunctionManagement, SymposiumPlanner2013) exists or not.
I think that the possible duplicate (How to query Classes with Object Property in Sparql) I linked may be close enough to answer your question, but there's no need to wrap a select query in an ask query here. You're asking about whether your data contains the triples:
:isManagedBy rdfs:domain :FunctionManagement .
:isManagedBy rdfs:range :SymposiumPlanner2013 .
You just want a query that asks whether that data is present:
prefix : <…>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
ask {
:isManagedBy rdfs:domain :FunctionManagement .
:isManagedBy rdfs:range :SymposiumPlanner2013 .
}
You can even use some abbreviations to make that a bit more concise:
prefix : <…>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
ask {
:isManagedBy rdfs:domain :FunctionManagement ;
rdfs:range :SymposiumPlanner2013 .
}
It seems to me that you want to get the domain and range for a certain property, and you want to verify that they match some other specific values. If that is the case, and given your sample data, your second query is correct.
One thing to note is that there seems to be a small bit of confusion between the idea of a predicate holding between two classes, and a predicate holding between two members of a class.
What your sample data indicates, is that if you see an instance of :isManagedBy, say in the triple :steve :isManagedBy :bill, then we can infer that :steve rdf:type :FunctionManagement and :bill rdf:type :SymposiumPlanner2013. This doesn't say anything about the classes themselves, only about the subject and object of instances of the property.
If you are trying to see if some property holds about the class, such as "all members of :FunctionManagement :isManagedBy some :SymposiumPlanner2013", then you would use an owl:minCardinality restriction to express that in your data. Your query would then change to reflect the constructs used in explaining it. Below is an example of a small ontology specifying that constraint.
<owl:ObjectProperty rdf:about="#isManagedBy"/>
<owl:Class rdf:about="#FunctionManagement">
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#isManagedBy"/>
<owl:someValuesFrom rdf:resource="#SymposiumPlanner2013"/>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
<owl:Class rdf:about="#SymposiumPlanner2013"/>