On 11/09/15 19:48, Mark Feblowitz wrote:
I do have need for a predicate, ?r to be tested as being absent from a set of
values and another, ?r2, to be tested in the same way against the same values.
Is there any way to consolidate those tests?
Getting a bit abstract.
There is also EXISTS for testing whether some pattern is true
(effectively, EXISTS is a ASK subquery and NOT EXISTS is ! EXISTS)
There are times when you'll have to repeat the list of values when you
need it in two places in a query.
Andy
On Sep 11, 2015, at 10:48 AM, Mark Feblowitz <[email protected]> wrote:
Good -
I have 3 options now:
FILTER ( ?x NOT IN ( a, b, c, d))
FILTER NOT EXISTS { ?x ?q ?v . VALUES ?x ( a b c d ) }
MINUS { ?x ?q ?v . VALUES ?x ( a b c d ) }
I like the first two because they read like proper declarative formal
expressions.
As I’m using a few UNIONed blocks and any one could contribute an objectionable
?x, I’m leaning toward the first.
Any ?x not in S
But if I end up distributing the FILTER to be applied within the UNIONed
blocks, I’d much prefer the NOT EXISTS form:
All ?x ?q ?v where ?x not in S
Either way, my notion of consolidating potentially many replicated sets of
values into a single, easily-maintained declaration S seems doomed, and likely
also to have some relatively unpleasant side effects, based on how the queries
are processed/optimized.
Perhaps the right way of thinking about this is to not not make multiple uses
of a single VALUES set S but to instead think about the application scope for a
single use (apply the test once, to a larger block of statements).
As I don’t know what optimizations are being applied, it’s not clear to me what
the performance tradeoffs might be. Guess I’ll just have to see/test.
Thanks,
Mark
On Sep 11, 2015, at 8:38 AM, Andy Seaborne <[email protected]> wrote:
On 10/09/15 22:32, Mark Feblowitz wrote:
I’m trying to understand the semantics and implementation of the VALUES clause,
specifically with respect to testing a “blacklist” of values.
I have used VALUES for whitelists, whereby I can match a bound variable to one
of the values:
VALUES ?WL ( a b c d)
FILTER ( ?V = ?WL)
This is nice, in that I can refer to ?WL in several graphs in a query that
UNIONs various graphs
{ stmt1 .
stmt2.
FILTER (?V = ?WL)
}
UNION
{ ….
FILTER (?W = ?WL)
}
….
What I’d like to do is to use a similar approach for blacklisting, where if the
value is in the VALUES list ?BL, the filter expression is false.
The obvious ( FILTER (?X != ?BL)) doesn’t work, as the semantics are wrong -
that is, if there’s just one item that’s not equal to ?X, the expression is
true.
Use of "NOT IN" doesn’t work, as there just one expression (?BL) to compare
against, and this reduces to the ?X != ?BL problem.
The only thing that’s worked for me is:
FILTER ( ?X NOT IN ( e, f, g, h, i))
It’s not as good, since the list has to be replicated in each context it’s
being used.
Is there something I’m missing ( usually is :-S ) or have I found the least bad
option?
There are two other negation features in SPARQL
FILTER NOT EXISTS { pattern }
and MINUS { pattern }
In each case, pattern is a graph pattern. It can involved VALUES. The VALUES
must be inside the {}
1/ FILTER NOT EXISTS
Remove solutions where the graph pattern does not match.
Something like:
# Pattern involving ?x
?x ?p ?o .
FILTER NOT EXISTS { ?x ?q ?v . VALUES ?x ( a b c d ) }
2/
# Pattern involving ?x
?x ?p ?o .
MINUS { ?x ?q ?v . VALUES ?x ( a b c d ) }
They are similar but not identical. Details matter. Personally, I find FILTER
NOT EXISTS easier to think about.
Andy