How to define a class that does not have two equivalent predicate objects? - semantic-web

I'm trying to define class of intervals. Each interval object may have (optionally) at most two boundary points. One of them - lower boundary, and another - upper boundary. How can I restrict my class of intervals, so that lower and upper individual boundary points must be different (if provided)?

You can declare that the hasLowerBound and hasUpperBound properties are disjoint. This means that an individual with values for both cannot have the same value for both. Here's an example. I've used an object property here, but you can use disjoint property axioms with datatype properties, too.
#prefix : <http://stackoverflow.com/q/36043590/1281433/> .
#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://stackoverflow.com/q/36043590/1281433/#hasLowerBound>
a owl:ObjectProperty ;
owl:propertyDisjointWith <http://stackoverflow.com/q/36043590/1281433/#hasUpperBound> .
<http://stackoverflow.com/q/36043590/1281433/#hasUpperBound>
a owl:ObjectProperty .
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://stackoverflow.com/q/36043590/1281433/"
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:ObjectProperty rdf:about="http://stackoverflow.com/q/36043590/1281433/#hasUpperBound"/>
<owl:ObjectProperty rdf:about="http://stackoverflow.com/q/36043590/1281433/#hasLowerBound">
<owl:propertyDisjointWith rdf:resource="http://stackoverflow.com/q/36043590/1281433/#hasUpperBound"/>
</owl:ObjectProperty>
</rdf:RDF>

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.

Relates OWL individual with OWL axiom

I have to related the owl:axiom with the owl:individual.
My RDF is as follows:
<owl:NamedIndividual rdf:about="http://www.sab.org/abbeys#Abbaye_Notre-Dame_de_Maizières_Saint-Loup-de-la-Salle,_Saône-et-Loire">
<rdf:type rdf:resource="http://www.sab.org/abbeys#Monastery"/>
<rdfs:label>Abbaye Notre-Dame de Maizières Saint-Loup-de-la-Salle, Saône-et-Loire</rdfs:label>
<abbeys:hasFoundationDate rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1132</abbeys:hasFoundationDate>
</owl:NamedIndividual>
<owl:Axiom>
<owl:has_trusted_certainty_degree rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.9</owl:has_trusted_certainty_degree>
<owl:annotatedTarget rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1132</owl:annotatedTarget>
<owl:annotatedProperty rdf:resource="http://www.sab.org/abbeys#hasFoundationDate"/>
<owl:annotatedSource rdf:resource="http://www.sab.org/abbeys#Abbaye_Notre-Dame_de_Maizières_Saint-Loup-de-la-Salle,_Saône-et-Loire"/>
</owl:Axiom>
I need to relate the has_trusted_degree with the foundation date in owl:individual.
I tried the following query but it returns nothing:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX : <http://www.sab.org/abbeys#>
PREFIX xds: <http://www.w3.org/2001/XMLSchema#>
SELECT DISTINCT ?label ?trust
WHERE {
?monastery rdfs:label ?label.
FILTER(lang(?label) = '')
OPTIONAL{?monastery :has_trusted_certainty_degree ?trust}
ORDER BY ?label
Can anyone help me in figuring this out?
Thanks in Advance
Your ontology has a wrong prefix for the property, see this line:
<owl:has_trusted_certainty_degree rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.9</owl:has_trusted_certainty_degree>
I assume that owl is the prefix for the OWL vocabulary and not for your user defined namespace. Thus, it shouldn't be owl:has_trusted_certainty_degree but the prefix for the namespace http://www.sab.org/abbeys#.

How to write a SPARQL query to take the values from an OWL file

I've got an OWL file with a subclass of owl:Thing "Objects".
<rdf:RDF xmlns="http://www.semanticweb.org/PredefinedOntology#"
xml:base="http://www.semanticweb.org/PredefinedOntology"
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:swrlb="http://www.w3.org/2003/11/swrlb#"
xmlns:swrl="http://www.w3.org/2003/11/swrl#"
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/PredefinedOntology"/>
This subclass has three individuals (Door1, Coridor1, Window1) with DataProperty assertions (X and Y coordinates with the values). One of the individuals looks like this:
<!-- http://www.semanticweb.org/PredefinedOntology#Door1 -->
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/PredefinedOntology#Door1">
<rdf:type rdf:resource="http://www.semanticweb.org/PredefinedOntology#Objects"/>
<X rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">2</X>
<Y rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">20</Y>
</owl:NamedIndividual>
I need to get the values of the individual (let's say Door1).
How can I do this with SPARQL? I was trying:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?X ?datatype
WHERE {?X rdf:datatype ?datatype}
But it seems like my query is completely wrong. Could some one please explain to me how to write (or even more important how to read or think) this query to find the values X=2 and Y=20 from the ontology?
Thank you
OK, step 1 is to lose the RDF/XML text serialization. Use anything else, but Turtle is closest to SPARQL. Any RDF editor can be used to convert to Turtle. The equivalent text serialization for Door1 in Turtle is:
:Door1
rdf:type :Objects ;
rdf:type owl:NamedIndividual ;
:X 2 ;
:Y 20 .
One part of this syntax that may not be obvious is that each line is a triple (subject, predicate, object), and the ; means that the subject from the previous line is used. An advantage of this syntax is that RDF resources can be viewed as an object with properties.
Step 2 is that the SPARQL query becomes obvious because you can line up the triple patterns with the triples specified in Turtle:
SELECT ?X ?Y ?inst
WHERE {
?inst rdf:type owl:NamedIndividual ;
:X ?X ;
:Y ?Y .
}

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.