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