On 16/02/12 02:04, Holger Knublauch wrote:
I have a rather advanced question and there may not be a general
solution, but I'll try anyway...

Problem: Given an arbitrary SPARQL WHERE clause, I want to insert a
line

    ?this a ?SOME_TYPE .

so that it always gets executed "first" - I want ?this to be bound to
all instances of a given class before the rest of the WHERE clause
executes. For example if I have

The optimizer will only rearrange things when it does not change the answers.

Putting it first, just after the { should be OK but the algebra is more robust.

BIND operates (like FILTER) after the patterns matched in that particular block so anywhere in the block will work.


WHERE {
     {
         BIND (ex:fun(?this) AS ?result) .
     }
     FILTER (?result != 1)
}

which is:

     (filter (!= ?result 1)
        (extend ((?result (ex:fun ?this)))
          (table unit)))

e.g. filter of
     bind of
     pattern match

(table unit) being the empty basic graph pattern


then I want to programmatically rewrite this to

WHERE {
     {
         ?this a ?SOME_TYPE .
         BIND (ex:fun(?this) AS ?result) .
     }
     FILTER (?result != 1)
}

That is, you want:

      (filter (!= ?result 1)
        (extend ((?result (ex:fun ?this)))
          (bgp (triple ?this rdf:type ?SOME_TYPE))))

Is there any clean way of implementing this? My naive approach would
be to walk the open parentheses until I find the first one with a
matching closing parenthesis (or do the equivalent operation on the
Syntax tree instead of strings. Given the policy that SPARQL is
executed from the inside out, is this a safe assumption? Are there
alternative approaches to achieving the goal (of iterating over all
instances of a class)? Are there cases where I need to repeat the
binding of ?this in multiple sub-blocks? Or will it be more efficient
to do the iteration "outside" and simply ask the same query for each
instance, with ?this pre-bound with initial bindings?

Another suggestion: put a marker pattern into the query and then you can find it again.

Put in the triple
    <tq:holger> <tq:holger> <tq:holger> .

and then you can go and find it again so you know where it is after parsing and algebra generation.

      (filter (!= ?result 1)
        (extend ((?result (ex:fun ?this)))
          (bgp (triple <tq:holger> <tq:holger> <tq:holger>))))

        Andy

Reply via email to