- From: Andy Seaborne <andy.seaborne@talis.com>
- Date: Thu, 25 Feb 2010 12:50:43 +0000
- To: Paul Gearon <gearon@ieee.org>
- CC: Steve Harris <steve.harris@garlik.com>, SPARQL Working Group <public-rdf-dawg@w3.org>
On 23/02/2010 4:49 PM, Paul Gearon wrote:
> Responding to both Andy and Steve at the same time...
>
> On Tue, Feb 23, 2010 at 8:33 AM, Steve Harris<steve.harris@garlik.com> wrote:
>> On 23 Feb 2010, at 13:14, Andy Seaborne wrote:
>>
>>> In an effort to progress the syntax issues ...
>>>
>>> http://www.w3.org/2009/sparq/wiki/Design:FunctionLibrary#SPARQL_specific
>>>
>>> We have some built-in functions proposed:
>>>
>>> ** BNODE() -> fresh blank node every call.
>>>
>>> ** BNODE(string) -> same blank node as other use of BNODE(string)
>>>
>>> Scope is per binding (row) so
>>> BNODE("a") is like _:a in CONSTRUCT templates.
>>>
>>> Do we also way bnodes scoped to the whole result set?
>>
>> Ah, maybe, I think I'd thought that's what this function did. Result-set
>> scoped bNodes are not something you can mint currently.
>
> I may be lost here, so I'll ask for clarification.
>
> What do BNODE() and BNODE(str) do exactly? It's not all that useful in
> a WHERE clause, since it's creating a bnode that won't match anything,
> so I mostly see blank nodes in CONSTRUCT. We already have _:label and
> [], so what do BNODE() and BNODE(str) do that these other
> representations do not?
The main use case is putting bnodes into CONSTRUCT results (Axel?). I
can image them being used in result sets in a minor way.
This would be done via sub SELECT to get the variable assignment.
BNODE() generates a new BNode so it's much like [] in a construct
template.
Having a function means you can write:
SELECT (IF(bound(?x), iri(?x), bNode()) AS ?y)
i.e. make the choice dynamically. Same for BNODE("label") scoped to a
result set row.
At the moment, any bnode in a construct template is made a-fresh on each
template instantiation. You can't have bnodes across CONSTRUCT template
instantions unless they are bnode RDF terms from the original data.
BNODE("label") - if scoped to the result set - would provide that
capability.
So there are 3 cases:
1/ New bnode : this is BNODE()
2/ New bnode, scoped to the row
3/ New bnode, scoped to the result set
(3) is something we can't do at the moment.
You can do (3) using (2) by using a subSELECT to join a single value to
every column of an intermediate table.
CONSTRUCT { ?bnode ?p ?o }
WHERE
{
<s> ?p ?o
{ SELECT (BNODE("label") AS ?bnode) {} }
}
>
>> Related: do we have any consensus around a skolemisation function?
>> SKOLEMISE(?bnode) -> URI.
>> I'm not sure how many people want / could support such a thing.
>
> This would be easy to do (at least for me), but for what purpose?
Good question - let's try to articulate the requirement.
For me, it's arisen so that a client can issue a second query after
getting back something from an earlier query that found a bnode.
Repeating patterns to re-find the bnode is ugly - and if there aren't
functional or inverse functional properties around, not very reliable.
Example from SPARQL 1.0: walking down an RDF list, one query per step.
With update it becomes more significant. An app might want to add a
triple with the same subject. Again, does it have to duplicate the
pattern? (Aside: this is one argument for SPARQL Update having the
ability to also make a query and reuse the result set within one request).
Use case: data or ontology editors: want to add triples to places in the
graph which are bNodes. All the UC I know of, there is a tight
relationship of client and server; it's not for publishing data to a
wide audience.
> I
> agree with Andy's later suggestion of using something like
> urn:x-bnode:label (though I liked the notion of "purloining" the urn
> scheme :-)
>
> The only use case I can think of for skolemising would be if a
> de-skolemising function were also available. However, that would be
> highly application specific and non-portable. This would break all
> sorts of notions of what blank nodes are, but OTOH, it's one of the
> most common feature requests I see (one that I've resisted until now).
>
> To summarize, I don't see a use case for skolemising on its own, so I
> wouldn't support it. As for skolemise/deskolemize, I'm against it from
> a modeling perspective, but I also appreciate that it solves a lot of
> practical problems for people, so I'd be willing to support it if it
> had general support.
>
>>> Replace the meaning of BNODE("label") or have another form?
>>
>> We maybe need both forms. Axel has some usecase IIRC?
>>
>>> ** LITERAL(str) ->
>>>
>>> This is a restricted STR(x)
>>> I propose dropping LITERAL/1
>
> How is it restricted? It's the same, isn't it?
STR works on URIs and literals with datatype or language tag.
In LITERAL(str), the 'str' is the lexicial form only.
>
>>> ** LITERAL(str, IRI)
>>>
>>> This is a dynamic cast - currently, casts are done as function calls of
>>> one argument so the datatype IRI is fixed at parse time.
>>>
>>> This would be possible:
>>> ?str = "IV"
>>> ?dt = my:RomanNumeral
>>>
>>> then a call of
>>> LITERAL(?str , ?dt) ==> "IV"^^my:RomanNumeral
>>>
>>> This one is a special case of calling a function dynamically (the IRI is
>>> not known at parse/compile time).
>
> I'm happy with this, since it's easy to construct these things as you
> go. Would the syntax specify that the second parameter has to be a
> variable? Or will a literal IRI for the datatype be an exact
> equivalent of the datatype cast?
Any expression that evaluates to an IRI. Evaluation happens before the
function is chosen by the function dispatch. I was using the signature
notation from sec11.
Andy
Received on Thursday, 25 February 2010 12:51:08 UTC