On 30/11/2009 15:56, Steve Harris wrote:
On 30 Nov 2009, at 13:44, [email protected] wrote:
Hello there,
I have an object property which can appear more than once. It defines min
and max values for prices which should not overlap and I need to check
it.
...
I think I can do it with SPARQL and loops. For each price I need to look
at the others and see if values are overlapping so I coudl get the set of
all overlapping elements. Something like:
...
Is something like that possible? How can I accomplish this check? do I
have to do it programatically, perhaps in Java, with regular loops?
The easiest way would be in Java with regular loops, but it may also be
possible to do it in SPARQL.
In the proposed SPARQL 1.1 I think you could do it with a subSELECT, but
I don't have an implementation to hard to try it on.
- Steve
Do you really need a loop? Forming a set of pairs of relevant items,
then filtering the cases of interest should work.
Something like:
PREFIX : <http://example>
SELECT DISTINCT ?sub WHERE {
# Get the prices
?sub :hasPrice ?obj .
?obj :hasMinPrice ?min . ?obj :hasMaxPrice ?max .
# Get the prices for each ?sub again
# forming the local cross product of prices per ?sub
?sub :hasPrice ?obj1 .
?obj1 :hasMinPrice ?min1 . ?obj1 :hasMaxPrice ?max1 .
# Now have rows like (sub, price, price1) where
# the "price" are obj/min/max.
# Redundancy:
# For every (sub, price, price1) also have:
# (sub, price, price) and (sub, price1, price)
# Eliminate things :
# Remove same price in cross product
FILTER ( ?obj != ?obj1 )
# Removed duplicates because that has the cross product
# objects so if (A,B) occurs, does (B,A)
# Assumes min1 != min - too risky
# Use the DISTINCT above instead
# FILTER ( ?min1 < ?min )
# Test for overlapping ranges.
# Either min1 is between min and max or max1 is between min and max
FILTER ( ( ( ?max1 >= ?min ) && ( ?max1 < ?max ) ) ||
( ( ?min1 >= ?min ) && ( ?min1 <= ?max ) ) )
} ORDER BY ?sub
-----------------------
@prefix : <http://example> .
:car1 :hasPrice [ :hasMinPrice 300.0 ; :hasMaxPrice 450.0 ] .
:car1 :hasPrice [ :hasMinPrice 100.0 ; :hasMaxPrice 200.0 ] .
# Has overlap
:car2 :hasPrice [ :hasMinPrice 200.0 ; :hasMaxPrice 450.0 ] .
:car2 :hasPrice [ :hasMinPrice 100.0 ; :hasMaxPrice 400.0 ] .
-----------------------
---------
| sub |
=========
| :car2 |
---------