RE: Bug with @reverse and blank nodes?

On Sunday, October 20, 2013 6:57 PM, Gregg Kellogg wrote:
On Oct 20, 2013, at 2:21 AM, Pierre-Antoine Champin wrote:
> > Hi,
> > I add a surprise today using @reverse with  blank node:
> > 
> > 
> > {
> >   "@context": {
> >     "foo": "http://example.org/foo",
> > 
> >     "bar": { "@reverse": "http://example.org/", "@type": "@id" }
> >   },
> >   "foo": "Foo",
> >   "bar": "http://example.org/origin"
> > 
> > }
> > 
> > produces the following graph:
> > 
> > 
> > <http://example.org/origin> <http://example.org/> _:b1 .
> > 
> > _:b0 <http://example.org/foo> "Foo" .
> > 
> > with *two different bnodes*!...
> > 
> > I have the same behaviour with PyLD and the online playground, so may be
> > this is a deliberate feature of the JSON-LD algorithm (I didn't go and
check
> > the API document, I admit...). But if it is so there should be a big
warning
> > sign in the syntax document, because this is *very* counter-intuitive.

No, it's a bug. Good catch


[...]
> I think the problem comes when in the flattening algorithm, which results
in
> the following node map:
> 
> {
>   "@default": {
>     "_:b0": {"@id": "_:b0"},
>     "http://example.org/origin": {
>       "@id": "http://example.org/origin",
>       "http://example.org/": [{"@id": "_:b1"}]
>     },
>     "_:b1": {"@id": "_:b1"}
>   }
> }
> 
> I believe it comes down to step 6.1 of the Node Map Generation algorithm
> [1], which says to generate a new blanknode identifier. It was previously
> invoked from step 6.8.3.1.2 because of the @reverse keyword. Perhaps there
> is some flag that needs to be passed so that a new blanknode lebel is not
> generated? Markus or Dave might have some other opinions on this.

Exactly. The problem is that the blank node gets relabeled twice in one
instance, but not in the other. The recursiveness of the algorithm makes it
difficult to fix this. The best thing would be to label all blank nodes
during already during expansion as we did before when we still had property
generators but that's a too big change at this point in time. 

The alternative (ugly hack) would be to always relabel the blank node twice
and remember the previous bnode ID so that it can be used to create
"referenced node" that will then be relabeled the same way.

The following changes would be necessary to make this work (all in the node
map generation algorithm):

6.1) If element has an @id member, set id *and old id* to its value and
remove the member from element. If id is a blank node identifier, replace it
with a newly generated blank node identifier passing id for identifier.
6.2) Otherwise, set *old id* to the result of the Generate Blank Node
Identifier algorithm passing null for identifier. *Then, set id to the
result of the Generate Blank Node Identifier algorithm passing old id for
identifier.*

6.8.1) Create a JSON object referenced node with a single member @id whose
value is *old* id.

Unfortunately that would change the output of most flattening/toRdf tests.

Hopefully someone has a better idea to fix this without changing a whole
lot.


--
Markus Lanthaler
@markuslanthaler

Received on Sunday, 20 October 2013 19:23:40 UTC