Re: a few patch challenges

On 08/12/2014 07:38 AM, Alexandre Bertails wrote:
> On Mon, Aug 11, 2014 at 9:18 PM, Sandro Hawke <sandro@w3.org> wrote:
>> On 08/11/2014 04:12 PM, Alexandre Bertails wrote:
>>
>> On Mon, Aug 11, 2014 at 11:39 AM, Sandro Hawke <sandro@w3.org> wrote:
>>
>> Arguably we should have made a patch test suite years ago.
>>
>> Off the top of my head, here are a few patch challenges.    It's not
>> necessarily a requirement that they all be done, but I think it would help
>> show the differences to see how they are done in ldpatch, etc.
>>
>> You can find the result at [1].
>>
>>
>> Impressive, thanks.
>>
>> Do you have code to generate patches?    I gather you made these ones by
>> hand.
> I did them by hand. TimBL said he had something doing that, and I
> believe one can do a decent job at generating an LD Patch document
> from a diff.
>
> That being said, I am not planning to take on this approach as my
> applications don't manipulate RDF directly. Instead of manipulating
> triples directly, you usually manipulate datastructures/objects in
> your favourite language. There are many ways to track effects
> happening to them, either a priori or a posteriori. Generating the
> patch is much easier in that case. But I digress.

I'm not sure it is easier, in the general case, since the patch in some 
cases needs to work backwards through the graph from multiple 
literals.   I don't see how non-graph-away tools will manage that.

This sounds like a good programming contest / hackathon / hiring puzzle 
problem.  :-)

>> Some syntactic concerns which I've mentioned before.  My apologies if
>> there's been a response I missed.   Also, the attendeeOf bug is still there
>> in the spec.
>>
>> 1.  Why these seemingly gratuitous differences from SPARQL path expression:
>>
>> - instead of ^ for inverse path operator
> As we discussed once, nobody is against that change. I proposed that
> we'd make that kind of change as a group resolution, after we get the
> FPWD.

Why would you make a change like this after FPWD instead of before? A WD 
should contain the best we've got, and what we want public feedback on.

>
> As we want to save some bits, I would also propose \ (backslash) which
> could combine "/-".

Uh, no.    -1.   Backslash has its meanings across languages and 
systems, and this is a very poor match for them.
>> paths start with / instead of having it be an infix operator
> Actually, it is meant to be infix, where the left operand is a
> concrete node (or a set of node). I agree it is a bit awkward in the
> path constraints, as the current node(s) is(are) implicit.
>
> Maybe the intent is better understood with a few more spaces: `<node>
> /<foo> /-<bar>`.
>
> That plus the path constraints, it has different semantics than SPARQL Path.

This needs to be justified.   I don't see why it can't be SPARQL Paths 
that only use "/" and "^" and which also include filtering.

>> ?
>>
>> 2.  Why > as the slice operator?   It looks like the vast majority [1] of
>> languages use colon, and the the rest use "..".   I think either of those
>> would be familiar to experienced programmers, unlike >.    I suppose I'd
>> pick .. because colon seems too much like a pname, but I'm fine with colon,
>> too.
>>
>> [1] http://en.wikipedia.org/wiki/Array_slicing
> Actually, Pierre-Antoine wanted to change that but like other things,
> we ultimately decided to stick again to his own original proposal
> (that was the plan), so that we can decide as a group which syntax
> would be better.

How do you propose we decide?

I see two main options: (1) the editors make the change requested by the 
commenter if they like it and don't think anyone else will object to the 
change, or (2) someone raises it as an Issue.

If the editors are agreed, it seems like much less work to just change it.

> At the end of the day, it doesn't really matter :-)

Certainly not as much as ... many other things in life.   :-)

>> 3.  Why square brackets for filter?   I'd think parens for grouping, then =
>> for filter would do it.     Doing that and making / infix (as in sparql)
>> instead of prefix, we'd get:
> That part just felt quite similar to xpath. Actually the whole path
> thing is much closer to xpath than to SPARQL.

Hm.    I've spent about a week writing xpath than did my best for forget 
it again, so I've no idea about that.

>> Bind ?event <#> schema:attendeeOf/(schema:url =
>> <http://conferences.ted.com/TED2009/>)
>>
>> Alternatively, if you keep square brackets, there's no need for the equal
>> sign, either for parsing, or for looking familiar.
>>
>> --
>>
>> I think my biggest advice, and this is what keeps making me raise my voice
>> during meetings -- for which I'm sorry -- is to understand that you've
>> created a new language here, and you have to teach it to your audience.  You
>> can't just say "it's just patch".  Your audience is going to take a while to
>> learn it, as they do any new language.
> It's not just Patch. It is "just" RDF diff + node bindings + support
> for rdf:list  :-)

But the path expressions used in node bindings is a new language, with a 
new way of thinking, and a new syntax that people need to learn to 
understand ld-patch.   It's a relatively simple new language, but to act 
like it's trivial is sweeping stuff under a rug.

> By the way, I am surprised that you didn't come up with more examples
> involving rdf:list, because this is a very important part of LD Patch.

The list stuff happens to feel obvious and trivial to me.

There are some test cases to be had there, too, in terms of odd 
constructions using rdf:first and rdf:rest, and showing the rdf:Seq, 
etc, aren't touched.  (or are they...?    maybe they should be? As long 
as you're always touching an EXISTING structure, that wouldn't require 
the patch to be any different.)

>> I'd suggest giving them a series of increasing examples, such as the test
>> cases I posed to you, so they can see that blank nodes get selected from the
>> nearest node via forward or backward arcs, then filtered if necessary.
> I completely agree. If we decide to move forward with this approach,
> it is my very intention that the specification will double as
> documentation.
>
>> Which makes me think....
> You can find the new tests at [2].
>
> [2] https://github.com/betehess/banana-rdf/blob/efe9ba1a522768ec81649c281f5433096fb90a1d/ldpatch/src/test/scala/SandrosChallenge.scala#L248
>

Awesome.

I see an error in how I posed Test11.  It should be changing Bob A Smith 
not Bob A Jones, btw, otherwise the firstname isn't needed to locate the 
blank node.

>> == TEST 9
>> == FROM
>> <alice> <knows >
>>       [ <first> "Bob", <last> "Smith" ],
>>       [ <first> "Bob", <last> "Jones" ],
>>       [ <first> "Charlie", <last> "Smith" ],
>>       [ <first> "Charlie", <last> "Jones" ].
>> == TO
>> <alice> <knows >
>>       [ <first> "Bob", <last> "Smith" ],
>>       [ <first> "Bob", <last> "Jones" ],
>>       [ <first> "Charlie", <last> "Smith" ],
>>       [ <first> "Chuck", <last> "Jones" ].
>> == END
>>
>> Every language features needs a test in the test suite, and really should be
>> motivated by a use case.   If you allow multiple filters in one path,
>> provide an example where that's necessary.  (I think that's what Test 9 is.)
> Yes.
>
>> And just to push a tiny bit more, to make sure we can step after the filter:
>>
>> == TEST 10
>> Somewhat artificial use of <text> but surely there are situations like this
>> == FROM
>> <alice> <knows >
>>       [ <first> [ <text> "Bob"], <last> [ <text> "Smith"] ],
>>       [ <first> [ <text> "Bob"], <last> [ <text> "Jones"] ],
>>       [ <first> [ <text> "Charlie"], <last> [ <text> "Smith"] ],
>>       [ <first> [ <text> "Charlie"], <last> [ <text> "Jones"] ].
>> == TO
>> <alice> <knows >
>>       [ <first> [ <text> "Bob"], <last> [ <text> "Smith"] ],
>>       [ <first> [ <text> "Bob"], <last> [ <text> "Jones"] ],
>>       [ <first> [ <text> "Charlie"], <last> [ <text> "Smith"] ],
>>       [ <first> [ <text> "Chuck"], <last> [ <text> "Jones"] ].
>> == END
>>
>> Is the value of Bind unique, or can it be a set?
> We (the editors) talked a lot about that. The very first draft was
> actually binding variables to sets of nodes, and so did my initial
> implementation.
>
> In the end, we went back to something much closer to the RDF Patch
> solution. That is: Add and Delete only touch one triple at a time.

Do remember what tipped the balance in this direction?

>>    That is, is ! implicit in bind?
> Completely spot on. It is part of the semantics. (still not flushed
> but I hope you're now convinced that it is not difficult)
>
>>   If not, can every path expression be re-written as a sequence of
>> single-step Bind operations?
> Well, you could, but don't want to do that: if you could actually
> split your path in two, it means that you had a shorter path in the
> first place, and that you are better off using that one.
>
>> To try my understanding, how's this:
>>
>> Bind ?CharlieJones "Charlie" /-<text>/-<first>/[/<last>/<text> = "Jones"]!
> As you guessed, the trailing ! is not needed.
>
>> How about three properties being needed:
>>
>> == TEST 11
>> == FROM
>> <alice> <knows >
>>       [ <first> "Bob", <middle> "A", <last> "Smith" ],
>>       [ <first> "Bob", <middle> "B", <last> "Smith" ],
>>       [ <first> "Bob", <middle> "A", <last> "Jones" ],
>>       [ <first> "Bob", <middle> "B", <last> "Jones" ],
>>       [ <first> "Charlie", <middle> "A", <last> "Smith" ],
>>       [ <first> "Charlie", <middle> "B", <last> "Smith" ],
>> == TO
>> == END
>>
>> Then I guess we'd use something like:
>>
>> Bind ?BobASmith <alice> /<knows>[/<first> = "Bob"][/<middle> = "A"][/<last>
>> = "Jones"]!
>>
>> Right?
> I used your bind in test11 and it worked right away :-)

:-)

         - s

>
> Alexandre
>
>>         - s
>>
>>
>> All tests that are not about pathological graphs pass with the
>> implementation matching the current spec.
>> It works both with Jena, and Sesame, and the pure Scala implementation.
>>
>> Please read the comments inside the code for more information.
>>
>> Alexandre
>>
>> [1]
>> https://github.com/betehess/banana-rdf/blob/d49e417c6c5560a6a852e587318da4493d25f5b1/ldpatch/src/test/scala/SandrosChallenge.scala
>>
>>
>>        -- Sandro
>>
>>
>> ==TEST 1
>> ==FROM
>> <alice> <knows> <bob>, <charlie>.
>> ==TO
>> <alice> <knows> <bob>, <dave>.
>> ==END
>>
>>
>> ==TEST 2
>> ==FROM
>> <alice> <knows> ( <bob> <charlie> )
>> ==TO
>> <alice> <knows> ( <bob> <dave> )
>> ==END
>>
>>
>>
>> ==TEST 3
>> ==FROM
>> <alice> <knows> [ <knows> <bob> ], [<knows> <charlie>].
>> ==TO
>> <alice> <knows> [ <knows> <bob> ], [<knows> <dave>].
>> ==END
>>
>> ==TEST 4
>> ==FROM
>> <alice> <knows>
>>     [ <name> "Bob" ],
>>     [ <name> "Charlie"].
>> ==TO
>> <alice> <knows>
>>     [ <name> "Bob" ],
>>     [ <name> "Dave"].
>> ==END
>>
>> ==TEST 5 (two changes: the secound count, and the second street addr)
>> ==FROM
>> [ a <Order>;
>>    <items> (
>>       [ <code> "4343"; <count> 1 ]
>>       [ <code> "4344"; <count> 3 ]
>>       [ <code> "4347"; <count> 3 ]
>>    );
>>    <shipTo> [
>>       a <Address>;
>>       <street> [ <num> 32; <name> "Vassar St" ];
>>       <city> "Cambridge";
>>       <state> "MA";
>>       <zip> 02139
>>    ];
>>    <billTo> [
>>       a <Address>;
>>       <street> [ <num> 32; <name> "Vassar St" ];
>>       <city> "Cambridge";
>>       <state> "MA";
>>       <zip> 02139
>>    ]
>> ].
>> ==TO
>> [ a <Order>;
>>    <items> (
>>       [ <code> "4343"; <count> 1 ]
>>       [ <code> "4344"; <count> 2 ]
>>       [ <code> "4347"; <count> 3 ]
>>    );
>>    <shipTo> [
>>       a <Address>;
>>       <street> [ <num> 32; <name> "Vassar St" ];
>>       <city> "Cambridge";
>>       <state> "MA";
>>       <zip> 02139
>>    ];
>>    <billTo> [
>>       a <Address>;
>>       <street> [ <num> 36; <name> "Vassar St" ];
>>       <city> "Cambridge";
>>       <state> "MA";
>>       <zip> 02139
>>    ]
>> ].
>> ==END
>>
>>
>>
>> ==TEST 6
>> ==FROM
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 1
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 2
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 3
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 4
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 5
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 6
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 7
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 8
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 9
>> ]]]]]]]]].
>> ==TO
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 1
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 2
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 3
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 4
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 5
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 6
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 7
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 8
>> ]]]]]]]]].
>> <node> <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> [ <p> 0
>> ]]]]]]]]].
>> ==END
>>
>> ==TEST 7
>> ==FROM
>> _:x <a> _:y.
>> _:y <a> _:z.
>> _:z <a> _:x.
>> ==TO
>> _:x <a> _:y.
>> _:y <a> _:z.
>> _:x <a> _:z.
>> ==END
>>
>> ==TEST 8
>> ==FROM
>> <node> <p> [ <p> [ <p> [ <p> "1" ],
>>                         [ <p> "1" ]] ,
>>                   [ <p> [ <p> "1" ]]],
>>             [ <p> [ <p> [ <p> "1" ]  ,
>>                         [ <p> "1" ]],
>>             [ <p> [ <p> [ <p> "1" ]]].
>> ==TO
>> <node> <p> [ <p> [ <p> [ <p> "1" ],
>>                         [ <p> "1" ]] ,
>>                   [ <p> [ <p> "1" ]]],
>>             [ <p> [ <p> [ <p> "1" ]  ,
>>                         [ <p> "1" ], [ <p> "1" ],
>>             [ <p> [ <p> [ <p> "1" ]]].
>> ==END
>>
>>
>>

Received on Tuesday, 12 August 2014 18:01:07 UTC