Re: [TF-LIB] Finalizing built-ins

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