Yes - fun isn't it? :-)

Both are "error" because there is no "=" installed that works on non-integer integers. "abc"^^xsd:integer is treated like any unknown datatype. Most value operations are error.


Except for
"abc"^^xsd:integer = "abc"^^xsd:integer

Think of this as

"abc"^^dt:unknown = "abc"^^dt:unknown

Even without knowing anything about the datatype dt:unknown, the fact they are the same lexical form means they must be the same value. A datatype is a functional mapping from lexical form to the value space.

This is the observation behind what Paul says point about RDFTerm-equal and that's captured in the operator dispatch table in the spec.

(as well as covering <uri> = <uri> and bNode = bnode)

        Andy

On 24/01/13 19:21, Paul Gearon wrote:
While the datatype of "abc"^^xsd:integer and "xyz"^^xsd:integer is set to
"xsd:integer", the fact that the values are not in the domain of those
types should make the types "RDF terms" instead of "numeric". In that case,
the appropriate operations are not op:numeric-equal(), but RDFterm-equal
and fn:not(RDFterm-equal).

The definition of RDFterm-equal says that it returns true only if the
compared terms are the same term. If both terms are literals but not the
same term, then they produce a type error. This is consistent with the
cases you show in the first example (unbound), since the compared values
are different terms.

The second example compares values that are literal and are the same term.
This means that RDFterm-equals returns "true", and fn:not(RDFterm-equal)
returns false.

Paul



On Thu, Jan 24, 2013 at 1:57 PM, Rob Vesse <[email protected]> wrote:

Hey All

A colleague was perplexed by some of the behavior mandated in the DAWG
tests (for SPARQL 1.0) which appear to not entirely coincide with the spec.
  The first example I think I can explain so can someone (Andy?) confirm my
understanding.  The second example I am somewhat stumped on so I'll come to
that and my best guess of what is happening in question and hope someone
else can explain why this happens.

Example 1

Consider the malformed literals "abc"^^xsd:integer and "xyz"^^xsd:integer

If you do the following queries both will return false which would seem a
little counter-intuitive

ASK WHERE { FILTER("abc"^^xsd:integer = "xyz"^^xsd:integer) }

ASK WHERE { FILTER("abc"^^xsd:integer != "xyz"^^xsd:integer) }

While this is counter-intuitive (you usually expect = and != to be
reflexive) I understand why this happens.  In both cases we are selecting
which operator to use from the operator mapping and we will be selecting
op:numeric-equals() in the first case and fn:not(op:numeric-equals()) in
the second.  In both cases we try and do numeric equality on the arguments
but they are not valid numbers so this gives a type error.  fn:not() of an
error is still an error.  Since FILTER treats error as false both queries
yield false.

This can perhaps be better demonstrated by the following query:

SELECT (?a = ?b AS ?equals) (?a != ?b AS ?notEquals)
{
   BIND("abc"^^xsd:integer AS ?a)
   BIND("xyz"^^xsd:integer AS ?b)
}

This gives the following:
----------------------

| equals | notEquals |
======================
|        |           |
----------------------

So we can see that both expressions evaluate to error and thus give
unbound in the result set.  As far as I can tell I understand and explain
things fine so far.

Example 2

Now this is where I get stumped, now consider the case where the malformed
literal is just "abc"^^xsd:integer.  Now if I run the equivalent ASK
queries I get different answers.

ASK WHERE { FILTER("abc"^^xsd:integer = "abc"^^xsd:integer) }

ASK WHERE { FILTER("abc"^^xsd:integer != "abc"^^xsd:integer) }

In this case the first query gives true and the second gives false, while
this makes sense from just looking at it this seems to be at odds with the
spec.  Using the same arguments as before we are using op:numeric-equals()
to do the equality check which should give a type error and thus both
filters should receive an error and thus result in false for both queries.

What seems to be happening is that the engine is trying
op:numeric-equals() and if it gets a type error falling back to RDF term
equality and if that gives true returns true/false as appropriate, if it
gives false then it passes the type error upwards.  This doesn't appear to
be mandated by the SPARQL specification but the tests certainly include
this.

Again we can see this with the SELECT form:

SELECT (?a = ?b AS ?equals) (?a != ?b AS ?notEquals)
{
   BIND("abc"^^xsd:integer AS ?a)
   BIND("abc"^^xsd:integer AS ?b)
}

This time we get the following results:
----------------------

| equals | notEquals |
======================
| true   | false     |
----------------------

When if my understanding from Example 1 were to hold I would expect to see
unbound for both of these again.

Am I just missing something in my understanding of the operator mapping
and expression evaluation part of the SPARQL specification or is there
something else going on?

Thanks,

Rob




Reply via email to