- From: Hugo Mills <hugo@carfax.org.uk>
- Date: Fri, 3 May 2019 16:56:35 +0000
- To: public-json-ld-wg@w3.org
- Message-ID: <20190503165635.GE5426@carfax.org.uk>
Hi, I hope this is the right place to ask this. Please advise if it's not appropriate here. I've been trying to write a JSON-LD serialiser, and I've hit an issue with my code intermittently failing one of the test cases. I wanted to check whether the problem is actually with my code, or if it's an ambiguity in the specification. The serialisation algorithm in §8.4.2 of the draft JSON-LD 1.1 Algorithms spec seems to produce different results for nested lists, depending on the order chosen for iterating over the usages of the rdf:nil node, in part 5.3. My understanding of the algorithm is that it find things that look like an rdf:List, and rolls up the list from the end, while a fairly large number of conditions (5.3.3) is true. This is relatively easy to deal with in the case of a single list, and there are lots of test cases dealing with the various termination conditions. The one I'm having trouble with is t0008: <http://example.com> <http://example.com/property> _:outerlist . _:outerlist <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:lista . _:outerlist <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b0 . _:lista <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "a1" . _:lista <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:a2 . _:a2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "a2" . _:a2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:a3 . _:a3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "a3" . _:a3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . _:c0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:c1 . _:c0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . _:c1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "c1" . _:c1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:c2 . _:c2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "c2" . _:c2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:c3 . _:c3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "c3" . _:c3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . _:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:b1 . _:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:c0 . _:b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "b1" . _:b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b2 . _:b2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "b2" . _:b2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b3 . _:b3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "b3" . _:b3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . which is, in Turtle, fundamentally this graph: <http://example.com> <http://example.com/property> (("a1" "a2" "a3") ("b1" "b2" "b3") ("c1" "c2" "c3")). Now, my implementation of the algorithm behaves differently, depending on whether it decides to roll up any of the sub-lists before or after it decides to roll up the parent list. If it does the parent list first, I get the golden output for test 0008: [ ... { "@id": "_:lista", "http://www.w3.org/1999/02/22-rdf-syntax-ns#first": [ { "@value": "a1" } ], "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest": [ { "@list": [ { "@value": "a2" }, { "@value": "a3" } ] } ] }, { "@id": "http://example.com", "http://example.com/property": [ { "@list": [ { "@id": "_:lista" }, { "@id": "_:b1" }, { "@id": "_:c1" } ] } ] } ] If it does the parent list last, I end up generating the doubly-nested structure: ["@id": "http://example.com", "http://example.com/property": [{"@list": [{"@list": [{"@value": "a1"}, {"@value": "a2"}, {"@value": "a3"}]}, {"@list": [{"@value": "b1"}, {"@value": "b2"}, {"@value": "b3"}]}, {"@list": [{"@value": "c1"}, {"@value": "c2"}, {"@value": "c3"}] }] }] ] If the parent list comes in the middle, I get a hybrid between the two. My problem is that I can't see where in the algorithm this ambiguous behaviour is prevented. There's nothing that I can see which stops the first bnode of a list being rolled into the list if it's also an element in another list. I also can't see anything which guarantees that higher-level lists are processed before lower-level lists, which should also generate the correct output for that test. What have I missed here? [For information, I'm implementing this in Erlang, so I've also been having trouble converting from a very procedural, global-data-and-mutable-variables view on the world into a functional, immutable-variables view. This may be contributing to any misinterpretation of the algorithm as documented.] Thanks, Hugo. -- Hugo Mills | Great films about cricket: The Third Man hugo@... carfax.org.uk | http://carfax.org.uk/ | PGP: E2AB1DE4 |
Received on Friday, 3 May 2019 20:54:48 UTC