Lee seems to have a particular skill with this kind of thing. Its
clear that
not everyone else does, which I take to mean that the SPARQL language
needs
some kind of extension to make this easier for others.
The semantics needed here is a universal quantifier combined with
a negation-as-failure assumption. I'm not recommending a fix, because,
while I'm a fan of negation as failure, I'm also partial to leaving
universal quantification out of SPARQL.
But for comparison, we implement a version of OWL that assumes
negation-as-failure semantics for the ALLVALUESFROM (which
we abbreviate as "ALL"). So we would write
CLASS ex:OnlyA = (all rdf:type ex:A)
to get the desired semantics. Simple; easy for users to understand.
The query would be
select ?x
where {?x rdf:type ex:OnlyA}
The expansion into rules yields a doubly-nested negation, which
is pretty much the same as Lee's solution.
Cheers, Bob
On Feb 1, 2008, at 1239, Leigh Dodds wrote:
>
>> This should work:
>>
>> SELECT ?x {
>> ?x a ex:A .
>> OPTIONAL {
>> ?x a ?type .
>> FILTER(?type != ex:A)
>> }
>> FILTER(!bound(?type))
>> }
>>
>> The OPTIONAL here tries to find a different type for the same
>> resource
>> (?x). If it succeeds then ?type is bound to a second class, so we
>> filter
>> out that case at the top-level.
>
> And it does. I just ran it twinkle and it produces the expected
> single result.
>
> Nice work. I spent a long time scratching my head with that one.
> Didn't occur to me to split the FILTERs into the separate OPTIONAL
> patterns.
>
> Fun!
>
> L.
>
Bob MacGregor
Chief Scientist
Siderean Software, Inc.
310.647.5690
bmacgregor@siderean.com