Re: LD Patch comments/questions

Hi Gregg,

regarding Bind and paths: I as well implemented the path operator from
scratch, without relying on SPARQL. And after your e-mail, I fiddled a bit
with SPARQL to see how paths could be systematically converted to SPARQL,
but it is quite tricky.

Also, you wrote:

> Thanks for the feedback, m sure I'll have more questions as I go through
> test cases, for example the notion of BNodes exactly matching vs being
> treated as existential quantifiers, which may make using standard BGP more
> difficult.
>

The only part of LDPatch that would produce a BGP are the Bind statements,
and BNodes are not allowed anywere in Bind statements, so that should not
be a problem.

BNodes may appear in Add, AddNew and UpdateList, and that should not be a
problem either, since those would translate to an InsertClause in
SPARQL-Upadte, where BNodes have the same semantics as in LD Patch,
according to Section 3.1.1 in SPARUL
<http://www.w3.org/TR/sparql11-update/#insertData>:

Blank nodes in *QuadData*s are assumed to be disjoint from the blank nodes
> in the Graph Store, i.e., will be inserted with "fresh" blank nodes.
>

It is a trickier for Delete and DeleteExisting. SPARQL-Update forbids blank
nodes in a DeleteClause, arguing that deleting a fresh bnode would do
nothing. LD-Patch does *not* forbid a BNode in a Delete statement, and
specifies that the scope of BNode identifiers is the whole LDPatch
document. So the following patch is correct:

  Add { :a :b _:fresh } .
  Delete { :a :b _:fresh } .

even if it leaves the graph unchanged.
This is a rather pathological case, though...


On Wed, Aug 19, 2015 at 8:54 PM, Gregg Kellogg <gregg@greggkellogg.net>
wrote:

> On Aug 19, 2015, at 10:38 AM, Pierre-Antoine Champin <
> pierre-antoine.champin@liris.cnrs.fr> wrote:
>
> Hi Gregg,
>
> On Fri, Aug 14, 2015 at 3:56 AM, Gregg Kellogg <gregg@greggkellogg.net>
> wrote:
>
>> I’ve been attempting an implementation in Ruby [1], and came up with some
>> observations and questions:
>>
>> # Bind
>>
>> These examples are of more complicated binds which are syntactically
>> correct. The test suite could probably use more pathological examples.
>>
>
> Where does this list come from? Is it a generalization of all the Bind
> statements found in the test suite? If so, I think at least one example is
> missing:  spec_example24_positive.ldpatch contains a variable in the path.
> But surely, more pathologogical examples could be added.
>
>
> It was actually more a consequence of following legal grammar, even though
> it may not be a useful path.
>
>         Bind ?x :a / :b / :c
>>         Bind ?x :a / ^:b / :c
>>         Bind ?x :a [ / :p = "v"] / :c / ^:d
>>         Bind ?x :a / 1 / :b
>>         Bind ?x :a / [ / :c / :d = "bar"] / ^:e
>>         Bind ?x :a / ! / ^:e
>>
>
> The last example is incorrect: "!" should not be preceded by "/".
>
>
> I figured that out implementing my parser, thanks.
>
> Additionally, although ":a" is syntactically correct, I'm guessing what
> you mean is "?a", so it should read
>
>
> Actually, in Turtle, :a would represent the empty prefix, and is often
> used as a shortcut for creating IRIs in examples.
>
>     Bind ?x ?a ! / ^:e
>
> Note that the "!" here is not very interesting since, if ?a is bound, it
> must be bound to a unique value -- and if it is not bound, this is an
> error, see below.
>
>
> Yes, "!" Seems useful mostly as a sieve in the middle of a path.
>
> What is the effect of a bind statement using unbound variables (as values)?
>>
>
> Per the last list item of 4.3.8 Error Handling
> <http://www.w3.org/TR/ldpatch/#error-handling>, If a variable is used
> without being previously bound, then the parsing fails . This applies to
> *any* statement.
>
>
> Yes, that makes the most sense.
>
> You should not think of variable as "logical variables", as in SPARQL, but
> rather as "program variables" (i.e. placeholders containing a value, a node
> of the graph) that are required as an indirection to refer to blank nodes.
>
>
> My system sequences through operations and updates a single solution with
> bound variables, and then binds these within other operations using
> variables, paths, or embedded graphs, triggering an error is something
> remains unbound.
>
> A unicity constraint ("!") at the end of a path seems redundant, but might
>> be used within a path.
>>
>
> That is correct.
>
>>
>> The above Bind statements might be equivalent to the following SPARQL
>> queries.
>>
>>         SELECT ?x WHERE {:a :b / :c ?x}
>>         SELECT ?x WHERE {:a ^:b / :c ?x }
>>         SELECT ?x WHERE {:a :p "v"; :c / ^:d ?x }
>>         SELECT ?x WHERE {:a rdf:rest _:0 . _:0 rdf:first _:1 . _:1 :b ?x}
>>         SELECT ?x WHERE {:a :c/:d "bar"; ^:e ?x}
>>         SELECT ?x WHERE {?a ^:e ?x} GROUP BY ?a HAVING(COUNT(?a) = 1)
>>
>> where each query must have exactly one single result.
>>
>
> Correct, except for the last one, which is not valid SPARQL (according to
> the SPARQL validator <http://sparql.org/query-validator.html>).
> (?x can not be selected directly, as it is not part of the GROUP BY)
>
>
> I actually found it simpler to implant my own path operator and do this
> natively, rather than trying to construct a SPARQL query, but for a large
> graph, this may have some performance implications.
>
> Let us consider a more regular use of "!"
>
>   Bind ?x :a / :b ! / :c
>
> I would translate it that way:
>
>   SELECT ?x WHERE {
>     { SELECT ?v1 { :a :b ?v1 } HAVING (COUNT(?v1) = 1) }
>     ?v1 :c ?x
>   }
>
> where the query must have exactly one single result.
>
> Note also that the 4th query could be simpler:
>
>   SELECT ?x WHERE { :a rdf:rest / rdf:first / :b ?x }
>
>
>> Compiling such queries is non-trivial; any thought about an informative
>> section on turning Bind statements into SPARQL queries? For this to work
>> with indexes would require a hypothetical extension to SPARQL introducing
>> some INDEX-like extension to property-paths.
>>
>
> We have not considered that, but it could indeed be valuable for people
> implementing LD-Patch on top of a SPARQL engine. I don't think that an
> extension to SPARQL is required, considering that numeric indexes can be
> considered as syntactic sugar for property paths of the form
>
>    rdf:rest / rdf:rest / rdf:rest ... / rdf:first
>
> Granted, unicity constraints are trickier to handle in the general case
> (especially when they appear berween square brackets), but I think a
> systematic translation process can be devised...
>
>
> Yes, but UpdateList would create some painful SPARQL; better to get
> first-class list support in some future SPARQL update. RDF.rb has good
> support for lists, basically implementing the Ruby Array paradigm and
> methods.
>
> # Add
>> Can a graph contain unbound variables?
>>
>
> No, same answer as with Bind above.
>
>
>> Are they treated just like BNodes?
>> Do such variables create bindings for subsequent usage?
>>
>> # Delete
>> Same for add, can a delete graph contain unbound variables? Is this an
>> error?
>>
>
> Same answer :)
>
>>
>> # Cut
>> Can the argument of Cut be an IRI? Doc indicates it's a BNode, or
>> variable binding to a BNode.
>> Is it an error to attempt to cut an unbound variable?
>>
>
> Yes, for the same reason as above: *any* use of an unbound variable is an
> error.
>
>  best
>
>
> Thanks for the feedback, m sure I'll have more questions as I go through
> test cases, for example the notion of BNodes exactly matching vs being
> treated as existential quantifiers, which may make using standard BGP more
> difficult.
>
> Gregg
>
>
>> Gregg Kellogg
>> gregg@greggkellogg.net
>>
>> [1]
>> https://github.com/gkellogg/ld-patch/tree/feature/initial-implementation
>>
>>
>>
>

Received on Monday, 24 August 2015 15:09:41 UTC