Re: Loops and conditionals with SPARQL

On 30/11/2009 15:56, Steve Harris wrote:
> On 30 Nov 2009, at 13:44, leyla.garcia@ebusiness-unibw.org 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 |
---------

Received on Monday, 30 November 2009 16:51:20 UTC