jsonld.js icon indicating copy to clipboard operation
jsonld.js copied to clipboard

Compact IRI using a prefix with @container=@list does not expand to a list but to a set

Open iridiankin opened this issue 5 years ago • 0 comments

Some jest-style code to illustrate the issue:

const context = { "@context": { p: { "@id": "e:", "@container": "@list" } } };
const dupSeq = ["r", "r"];
const listExpansion = [{ "@list": [{ "@value": "r" }, { "@value": "r" }] }];
const setExpansion = [{ "@value": "r" }, { "@value": "r" }];

// Fails unexpectedly:
expect(await jsonld.expand({ ...context, "p:s": dupSeq })).toEqual([{ "e:s": listExpansion }]);
// Passes unexpectedly:
expect(await jsonld.expand({ ...context, "p:s": dupSeq })).toEqual([{ "e:s": setExpansion }]);
// Passes expectedly:
expect(await jsonld.expand({ ...context, p: dupSeq })).toEqual([{ "e:": listExpansion }]);

Practical hard problem is that triple normalization for the "p:s" dupSeq loses duplicates: _:c14n0 <e:s> "r" . There's also the soft problem of lost ordering.

From reading the json-ld-api spec I can't determine whether my expectation or the actual behavior is correct. Some analysis follows.

The expansion algorithm 5.1.2 defines the container mapping in terms of the key's term definition and its container mapping:

9.5. If key's term definition in active context has a local context, set term context to the result of the Context Processing algorithm, passing active context and the value of the key's local context as local context. Otherwise, set term context to active context.
9.6. Set container mapping to key's container mapping in term context.

But I'm unsure how the key's term definition is defined for compact IRI's expansions. IRI expansion 'forgets' the compact IRI prefix term history knowledge, so to speak:

9.2. Set expanded property to the result of using the IRI Expansion algorithm, passing active context, key for value, and true for vocab.

After this step the now-expanded IRI of course no longer has a exactly matching entry in the active context. This is also how the json-ld implementation behaves. But strictly speaking the wording key's term definition has only one reference in the document, so it's a bit under-specified. It could be interpreted to also include the prefix extended term definition.

Consider the Create Term Definition entry:

If the given term is a compact IRI, it may omit an IRI mapping by depending on its prefix having its own term definition

Also consider how Compact IRI's definition is intended specifically intended to avoid the need to define multiple identical term definitions:

A compact IRI is has the form of prefix:suffix and is used as a way of expressing an IRI without needing to define separate term definitions for each IRI contained within a common vocabulary identified by prefix.

While it is true that these two quotes only talk about the non-expanded term definitions my naive personal intuition and my concrete use case is that it should be inclusive to expanded defs as well.

I would like to have string sequences be mapped into ordered, non-deduplicated triple lists, with potentially multiple sections, from a single, flat non-array node, like so:

{
  "block:0#initial": ["sentence", "", "another", ""],
  complex_sub_element: { "after:0", ... },
  "block:1#followup": ["more", "duplicates", "other", "duplicates"],
}

A context rule like { "block": { "@id": "http://whatever.org/block#", "@container": "@list" } } would be a perfectly minimal and generic solution. But as it is now it doesn't work, and I can't make sense whether it is intended or not to work in now or in the future.

iridiankin avatar May 07 '19 02:05 iridiankin