Your example is interesting and likely a very useful application of VALUES and
COALESCE.
In thinking more about my specific case, I might be thinking about the problem
incorrectly, or perhaps I’m overloading the VALUES mechanism.
To state the problem succinctly, I’d like to match a particular resource E to
any T in { T1, T2, … }, such that ?E a ?T.
Failing a match, I’d like to bind a default for T, e.g. owl:Thing. But I don’t
want to bind to owl:thing if there’s a match in the set.
The VALUES mechanism lets me do the basic matching, but assigning a default
presents problems.
VALUES ?T { :Person :Place :Organization }
?E a ?T.
If ?E is of one of the types in ?T, then ?T is bound, as far as subsequent
references to ?T are concerned. And it’s bound for each solution (although I
can’t think of any things that have multiple type matches in { :Person :Place
:Organization } ).
The trouble comes when trying to determine a match failure and act on ?T.
In a few tests (at least with DBPedia Virtuoso), testing for BOUND(?T) when
there’s no match to the VALUES set results in a “true”. But in the resultset
the value of ?T appears to be undefined.
I confirmed this using:
VALUES ?T { :Person :Place :Organization }
?E a ?T.
BIND(IF(BOUND(?T), :argh, owl:thing) as ?TB)
If ?E is or is not of a type ?T in { :Person :Place :Organization }, ?TB
is bound to :argh (!)
In a way that makes sense - I’m thinking of ?T as both a variable to be bound
and as a value generator. I can see where that might present confusion for
implementers.
I tried binding ?T to another variable, but that just kicked the same can down
the road, so to speak.
So how could I handle a non-match of I can’t determine whether a binding was
found?
> On Sep 29, 2015, at 7:42 AM, Neubert, Joachim <[email protected]> wrote:
>
> Hi Mark,
>
> I had a similar problem in the past: I wanted to have the possiblity to set
> an input variable via VALUES, and use some default derived from the data if
> the variable is not set. I solved it this way:
>
> values ( ?input ) ( {undef} )
> ?x ?y ?default
> bind(coalesce(?input, $default) as ?actualVariableUsed )
>
> For an example, see
> https://github.com/jneubert/skos-history/blob/master/sparql/added_concepts.rq,
> where it is possible to pass two version numbers to the query via VALUES. If
> not set, the latest and the version before are derived from the data. (The
> query is executable against Fuseki via a link on the readme page).
>
> Hope that some of that could be helpful in your case - cheers, Joachim
>
> -----Ursprüngliche Nachricht-----
> Von: Mark Feblowitz [mailto:[email protected]]
> Gesendet: Dienstag, 29. September 2015 01:54
> An: [email protected]
> Betreff: Need to bind a "default" type when no type matched in a VALUES set
>
> I have need to identify 0 or more type resources from a given set as having
> been asserted as types of a given subject entity; if none matches, I’d like
> to bind some default resource to symbol a non-match.
>
> So, I have a set of “whitelisted” types
>
> VALUES ?entType { ex:T1 ex:T2 ex:T3 }
>
> and I’m looking to match an entity against those types in this way:
>
> ?E a ?entType.
>
> It’s fine to match more than one (although I’d rather not, but that’s a
> separate discussion).
>
> In cases where there’s no match, I’d then like to force bind ?entType to,
> e.g., ex:T0 or owl:Thing.
>
> To survive a non-match, the type match would likely need to be wrapped in an
> OPTIONAL block, likely with the VALUES statement in there too(?):
>
> OPTIONAL {
> VALUES ?entTypeS { ex:T1 ex:T2 ex:T3 }
> ?E a ?entTypeS.
> }
>
> (Note the “S” in ?entTypeS - that’s for the next bit).
>
> I’ve tried a conditional BIND
> BIND(IF(BOUND(?entType), ?entType, ex:T0) as ?entType)
>
> and also s COALESCE
> BIND(COALESCE(?entTypeS, ex:T0) as ?entType)
>
>
> But it seems that neither works as I’d like. I appears that, even though
> optional, the test against the VALUES set acts as a constraint.
>
> I’ve also tried a FILTER, with
>
> FILTER ( ?E1T in ( ex:T1, ex:T2, ex:T3 ))
> BIND(COALESCE(?E1T, ex:T0) as ?E1Type)
>
> That’s not even getting to executing (yet) - some non-parsing error on
> DBPedia Live.
>
> Have I stated the problem clearly enough? What might be other ways to address
> this?
>
> Thanks,
>
> Mark
>