- 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