SPARQL algebra: Excluding nodes based on triples they have - sparql

Take this graph:
:thing1 a :Foo ;
:has :A ;
:has :B .
:thing2 a :Foo ;
:has :B ;
:has :A .
:thing3 a :Foo ;
:has :A ;
:has :B ;
:has :C .
I want to select :thing1 and :thing2, but NOT :thing3.
Here is the SPARQL query I wrote that works. Is there a better way to do this?
SELECT ?foo WHERE {
?foo a :Foo ;
:has :A ;
:has :B .
MINUS {
?foo a :Foo ;
:has :A ;
:has :B ;
:has ?anythingElse .
FILTER(?anythingElse != :A && ?anythingElse != :B)
}
}

An alternative to MINUS is FILTER NOT EXISTS:
SELECT ?foo WHERE {
?foo a :Foo ;
:has :A, :B .
FILTER NOT EXISTS {
?foo :has ?other .
FILTER (?other NOT IN (:A, :B))
}
}
which says, loosely, find all ?foo with :A and :B, then check that they have no other :has value.
In terms of execution efficiency, there are optimizations to turn some MINUS patterns into FILTER NOT EXISTS and vice versa and also there is the possibility of shared common sub patterns.
Without an optimizer being that smart, the FILTER NOT EXISTS is likely to be faster because the "?foo a :Foo ; ;has :A, :B ." is not repeated and the FILTER only considers items that already passed the "?foo a :Foo ; ;has :A, :B .".
There is only one way to know which is to try for real on real data when all effects, including caching, come together.

You can do this using using the NOT IN operator instead of a boolean expression, and indeed there is no need to repeat the three triple patterns if you replace the MINUS clause with a FILTER NOT EXISTS clause:
SELECT ?foo WHERE {
?foo a :Foo ;
:has :A, :B .
FILTER NOT EXISTS {
?foo :has ?other .
FILTER (?other NOT IN (:A, :B))
}
}
I doubt there'll be a significant difference in performance, but the query is shorter and easier to read.

Related

Constructing Cartesian product from SPARQL variable

I need some help starting with SPARQL:
I have some individuals (A, B, C). I want to state, that they are all the same. I’ve tried the following:
PREFIX : <http://test.com#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
CONSTRUCT {
?p owl:sameAs ?p
}
WHERE {
} VALUES (?p) {
(:A)
(:B)
(:C)
}
The result is:
:B owl:sameAs :B .
:A owl:sameAs :A .
:C owl:sameAs :C .
What I would like to have is something like this:
:A owl:sameAs :B
:A owl:sameAs :C
:B owl:sameAs :A
:B owl:sameAs :C
:C owl:sameAs :A
:C owl:sameAs :B
Do you have any hints for me, how to do that?

SPARQL Transitive Query with Unique Predicates

I have a number of triples organized like following.
:A :hasB :B
:B :hasC :C
:C :hasD :D
:D :hasE :E
............
:X :hasY :Y
:Y :hasZ :Z
All the predicates are unique.
I need to write two SPARQL queries.
Query 1 will find all the predicates between :A to :Z through a transitive query (something like this :A :has* :Z). Output 1 should look like following.
Output 1:
--------
hasB
hasC
hasD
....
hasZ
Ouery 2 will find triples between :A to :Z through a transitive query. Output 2 should look like following.
Output 2:
--------
:B :hasC :C
:C :hasD :D
:D :hasE :E
............
:X :hasY :Y
Please let me know how to write these transitive SPARQL queries.
SPARQL has some obvious limitations as it's not a graph query language. Possible solutions below:
If there are no other predicates besides has[A-Z]:
Sample Data
#prefix : <http://ex.org/> .
:A :hasB :B .
:B :hasC :C .
:C :hasD :D .
:D :hasE :E .
Query
prefix : <http://ex.org/>
select ?p
where {
values (?start ?end) { (:A :E) }
?start (<p>|!<p>)* ?v1 .
?v1 ?p ?v2 .
?v2 (<p>|!<p>)* ?end .
}
Output
---------
| p |
=========
| :hasB |
| :hasC |
| :hasD |
| :hasE |
---------
If there are other predicates besides has[A-Z]:
Sample Data
#prefix : <http://ex.org/> .
:A :hasB :B .
:B :hasC :C .
:C :hasD :D .
:C :notHasD :D .
:D :hasE :E .
Introduce a super property :has:
Additional Data:
#prefix : <http://ex.org/> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
:hasB rdfs:subPropertyOf :has .
:hasC rdfs:subPropertyOf :has .
:hasD rdfs:subPropertyOf :has .
:hasE rdfs:subPropertyOf :has .
Query:
prefix : <http://ex.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?p
where {
values (?start ?end) { (:A :E) }
?start (<p>|!<p>)* ?v1 .
?v1 ?p ?v2 . ?p rdfs:subPropertyOf :has .
?v2 (<p>|!<p>)* ?end .
}
Output
---------
| p |
=========
| :hasB |
| :hasC |
| :hasD |
| :hasE |
---------
Use REGEX on property URI:
prefix : <http://ex.org/>
select ?p
where {
values (?start ?end) { (:A :E) }
?start (<p>|!<p>)* ?v1 .
?v1 ?p ?v2 .
FILTER(REGEX(STRAFTER(STR(?p), STR(:)), 'has[A-Z]'))
?v2 (<p>|!<p>)* ?end .
}
Note, all the proposed solutions will not work on all kind of data, especially once you have multiple paths and/or cycles. In that case, you should use a proper graph database.

SPARQL is it possible to bind two variables with their labels with a static text?

This is my query
PREFIX : <http://example.org/rs#>
select ?item (SUM(?similarity) as ?summedSimilarity)
(group_concat(distinct ?becauseOf ; separator = " , ") as ?reason) where
{
values ?x {:instance1}
{
?x ?p ?instance.
?item ?p ?instance.
?p :hasSimilarityValue ?similarity
bind (?p as ?becauseOf)
}
union
{
?x a ?class.
?item a ?class.
?class :hasSimilarityValue ?similarity
bind (?class as ?becauseOf)
}
filter (?x != ?item)
}
group by ?item
in my firstbind clause, I would like to not just bind the variable ?p, but also the variable ?instance. Plus, adding a text like that is why.
so the first bind should result the following results:
?p that is why ?instance
is that possible in SPARQL ?
please don't care about if the data makes sence or not, it is just a query to show you my question
If I understand you correctly, you're just looking for the concat function. As I've mentioned before, you should really browse through the SPARQL 1.1 standard, at least through the table of contents. You don't need to memorize it, but it will give you an idea of what things are possible, and an idea of where to look. Additionally, it's very helpful if you provide sample data that we can work with, because it makes it much clearer to figure out what you're trying to do. The phrasing of your title was not particularly clear, and the question doesn't really provide an example of what you're trying to accomplish. Only because I've seen some of your past questions did I have an idea of what you were aiming for. At any rate, here's some data:
#prefix : <urn:ex:>
:p :hasSimilarity 0.3 .
:A :hasSimilarity 0.6 .
:a :p :b ; #-- is is related to :b
a :A . #-- and is an :A .
:c :p :b . #-- :c is also related to :b
:d a :A . #-- :d is also an :A .
:e :p :b ; #-- :e is related to :b
a :A . #-- and is also an :A .
And here's the query and its results. You just use concat to join the str form of your variables with the appropriate strings and then bind the result to the variable.
prefix : <urn:ex:>
select ?item
(sum(?factor_) as ?factor)
(group_concat(distinct ?reason_; separator=", ") as ?reason)
{
values ?x { :a }
{ ?x ?p ?instance .
?item ?p ?instance .
?p :hasSimilarity ?factor_ .
bind(concat("has common ",str(?p)," value ",str(?instance)) as ?reason_) }
union
{ ?x a ?class.
?item a ?class.
?class :hasSimilarity ?factor_ .
bind(concat("has common class ",str(?class)) as ?reason_)
}
filter (?x != ?item)
}
group by ?item
-----------------------------------------------------------------------------------
| item | factor | reason |
===================================================================================
| :c | 0.3 | "has common urn:ex:p value urn:ex:b" |
| :d | 0.6 | "has common class urn:ex:A" |
| :e | 0.9 | "has common urn:ex:p value urn:ex:b, has common class urn:ex:A" |
-----------------------------------------------------------------------------------

Why use owl:Restriction as own:EquivalenceClass's property?

I just start to learn Semantic Web and have a question about restriction class. I dug a while but haven't found any answer yet.. Any help would be much appreciated!
From text book, I see examples of define restriction class, they are all about to define a anonymous owl:Restriction class bnode and link this bnode with property owl:equivalentClass.
example:
example:restrictionClass owl:equivalentClass [
rdf:type owl:Restriction;
owl:onProperty example:resProp;
owl:someValuesFrom example:resValue.
]
My question is can we define a restriction class directly? Like:
example:restrictionClass rdf:type owl:Restriction;
owl:onProperty example:resProp;
owl:someValuesFrom example:resValue.
What's the advantage to define anonymous owl:Restriction?
No, you can't. The RDF you're seeing is the encoding of the OWL axiom like: EquivalentClasses(C ObjectSomeValuesFrom(p D)). It gets encoded as:
:C owl:equivalentClass [
rdf:type owl:Restriction;
owl:onProperty :p;
owl:someValuesFrom :D .
]
Now, suppose you also had the axiom EquivalentClasses(C ObjectSomeValuesFrom(r E)). That gets encoded as:
:C owl:equivalentClass [
rdf:type owl:Restriction;
owl:onProperty :r;
owl:someValuesFrom :E .
]
Now, if you could apply the abbreviation that you want, you'd get:
:C rdf:type owl:Restriction ;
owl:onProperty :p ;
owl:onProperty :r ;
owl:someValuesFrom :D ;
owl:someValuesFrom :E .
Now there's ambiguity. Which of the following would C be equal to?
ObjectSomeValuesFrom(p D)
ObjectSomeValuesFrom(p E)
ObjectSomeValuesFrom(r D)
ObjectSomeValuesFrom(r E)
From the RDF alone, you don't have a way to tell. You actually need to encode the EquivalentClasses axioms.
Addendum
To address questions from the comments: I used C, p, and D to make the text shorter. Your original RDF snippet is the RDF encoding of the axiom
EquivalentClasses(
example:restrictionClass
ObjectSomeValuesFrom(example:resProp example:resValue)
)
That's what
example:restrictionClass owl:equivalentClass [
rdf:type owl:Restriction;
owl:onProperty example:resProp;
owl:someValuesFrom example:resValue.
]
encodes. example:restrictionClass is the same IRI in both places. The entire blank node is the class expression ObjectSomeValuesFrom(example:resProp example:resValue). Then owl:equivalentClass just relates the two. Note that expressions aren't the same; the classes that they denote are the same. The mapping from OWL ontologies to RDF is given in OWL 2 Web Ontology Language: Mapping to RDF Graphs (Second Edition). Specifically, have a look at Table 1 in 2.1 Translation of Axioms without Annotations where you'll find the rules:
EquivalentClasses( CE1 ... CEn )
------------------------------------
T(CE1) owl:equivalentClass T(CE2) .
...
T(CEn-1) owl:equivalentClass T(CEn) .
and
ObjectSomeValuesFrom( OPE CE )
------------------------------
_:x rdf:type owl:Restriction .
_:x owl:onProperty T(OPE) .
_:x owl:someValuesFrom T(CE) .
When you go in the reverse direction, you can read in the RDF and reconstruct your axiom. But support that the mapping let you do the abbreviation that you're talking about, and you had two equivalent class axioms. You'd end up with ambiguous RDF, since you'd have two owl:onProperty triples, and two owl:someValuesFrom triples.
Maybe an example from arithmetic would help. We know that 4, 2+2, and 1+3 are all expressions that denote the same number. So we can have the axioms:
4 = 2 + 2
4 = 1 + 3
Now suppose that we encode that in RDF with something like:
:four :equals [ rdf:type :sum ; :left :two ; :right :two ] .
:four :equals [ rdf:type :sum ; :left :one ; :right :three ] .
That's nice, and we can reconstruct 4 = 2+2 and 4 = 1+3 from it. Now suppose we tried to move those properties to :four, rather than a blank node related by :equals. We'd end up with:
:four rdf:type :sum .
:four :left :two .
:four :right :two .
:four :left :one .
:four :right :three .
But what axioms is this supposed to represent? You have have four ways of picking a left and right from :four. Which of the following is it supposed to encode?
4 = 2 + 2
4 = 2 + 3
4 = 1 + 2
4 = 1 + 3

SPARQL: query for a complete list

I have such a query:
CONSTRUCT {
?p a :IndContainer .
?p :contains ?ind .
} WHERE{
:ClassContainer_1 :contains ?class .
?ind a ?class .
BIND (IRI(...) AS ?p) .
}
An individual ClassContainer_1 relates to some classes. I get this classes and try to find individuals for these classes. Then I try to create an IndContainer that should store found individuals (dots are used only for simplification). So, I want to:
Create individual of IndContainer only when individuals for all bindings of ?class have been found;
Create individuals of IndContainer for all possible sets of individuals from ?ind (i.e. when some of ?class has a nuber of individuals).
Is it possible to create such a SPARQL query? Or it is necessary to use some rule engine?
EDIT (add illustration):
Positive example. Have:
test:ClassContainer_1
rdf:type test:ClassContainer ;
test:contains test:Type1 ;
test:contains test:Type2 ;
.
test:Type1_1
rdf:type test:Type1 ;
.
test:Type1_2
rdf:type test:Type1 ;
.
test:Type2_1
rdf:type test:Type2 ;
.
Want to receive:
test:IndContainer_1
rdf:type test:IndContainer ;
test:contains test:Type1_1 ;
test:contains test:Type2_1 ;
.
test:IndContainer_2
rdf:type test:IndContainer ;
test:contains test:Type1_2 ;
test:contains test:Type2_1 ;
.
Negative example: the same as positive except that there is no individuals of class Type2 and so no individuals of IndContainer should be generated.
EDIT 2 (problem essence):
We may look at this problem from the perspective of combination composing. We have two positions (in my example) in each combination. The number of positions is determined by the number of classes each ClassContainer depends on. Each position must be filled in with one individual of a class that correspond to that position. So in my example first position must be filled with one individual of Type1 class, the second - with Type2 class (but the order does not matter). We have two individuals for the first class and one individual for the second class. To get the number of combinations we may use the rule of product from combinatorics - 2*1 = 2, i.e. {Type1_1,Type2_1} - is the first combination and {Type1_2,Type2_1} - is the second combination. For each combination it is necessary to generate IndContainer individual.
If I understand your question correctly, you want a "container" for each class that is contained in a "class container" that contains the individuals that belong to that class. That's not too hard to do, as long as you can construct the IRI of the container from the IRI of the class. Here's some sample data with two classes, A and B, and a few instances (some of just A, some of just B, and some of A and B):
#prefix : <urn:ex:> .
:container a :ClassContainer ;
:contains :A, :B .
:w a :A . # an :A
:x a :A . # another :A
:y a :B . # a :B
:z a :A, :B . # both an :A and a :B
You query is already pretty close. Here's one that works, along with its result:
prefix : <urn:ex:>
construct {
?indContainer a :IndContainer ;
:contains ?ind .
}
where {
:container a :ClassContainer ;
:contains ?class .
?ind a ?class .
bind(IRI(concat(str(?class),"-container")) as ?indContainer)
}
#prefix : <urn:ex:> .
:B-container a :IndContainer ;
:contains :y , :z .
:A-container a :IndContainer ;
:contains :w , :x , :z .