w3c / json-ld-framing

JSON-LD 1.1 Framing Specification
https://w3c.github.io/json-ld-framing/
Other
25 stars 20 forks source link

infinite recursion in @reverse properties #5

Closed gkellogg closed 5 years ago

gkellogg commented 6 years ago

From json-ld/json-ld.org#653

It would be nice to have the same possiblity of infinite recursion in the @reverse properties as there are in non-reverse ones (example), currently recursion only works as many times as the frame defines it (example).

Copy/pasting the examples (and removing @contexts):

in the working case, I have

{
  "@graph": [
    {
      "@id": "bdr:O9TAXTBRC201605",
      "@type": "Taxonomy",
      "taxHasSubClass": [
        {
          "@id": "bdr:O9TAXTBRC201605_0001"
        },
        {
          "@id": "bdr:O9TAXTBRC201605_0010"
        }
      ]
    },
    {
      "@id": "bdr:O9TAXTBRC201605_0001",
      "@type": "Taxonomy",
      "taxHasSubClass": {
        "@id": "bdr:O9TAXTBRC201605_0002"
      }
    },
    {
      "@id": "bdr:O9TAXTBRC201605_0002",
      "@type": "Taxonomy"
    },
    {
      "@id": "bdr:O9TAXTBRC201605_0010",
      "@type": "Taxonomy"
    }
  ]
}

and frame

{ 
  "@id" : "bdr:O9TAXTBRC201605",
  "@context" : {
    "children": { "@reverse": "http://purl.bdrc.io/ontology/core/taxSubclassOf" }, 
    "taxSubclassOf" : {
      "@id" : "http://purl.bdrc.io/ontology/core/taxSubclassOf",
      "@type" : "@id"
    },
    "@vocab" : "http://purl.bdrc.io/ontology/core/",
    "bdr" : "http://purl.bdrc.io/resource/"
  }
}

that produces the nice

{
  "@graph": [
    {
      "@id": "bdr:O9TAXTBRC201605",
      "@type": "Taxonomy",
      "taxHasSubClass": [
        {
          "@id": "bdr:O9TAXTBRC201605_0001",
          "@type": "Taxonomy",
          "taxHasSubClass": {
            "@id": "bdr:O9TAXTBRC201605_0002",
            "@type": "Taxonomy"
          }
        },
        {
          "@id": "bdr:O9TAXTBRC201605_0010",
          "@type": "Taxonomy"
        }
      ]
    }
  ]
}

but for the opposite:

{
  "@graph": [
    {
      "@id": "bdr:O9TAXTBRC201605",
      "@type": "Taxonomy"
    },
    {
      "@id": "bdr:O9TAXTBRC201605_0001",
      "@type": "Taxonomy",
      "taxSubclassOf": "bdr:O9TAXTBRC201605"
    },
    {
      "@id": "bdr:O9TAXTBRC201605_0002",
      "@type": "Taxonomy",
      "taxSubclassOf": "bdr:O9TAXTBRC201605_0001"
    },
    {
      "@id": "bdr:O9TAXTBRC201605_0010",
      "@type": "Taxonomy",
      "taxSubclassOf": "bdr:O9TAXTBRC201605"
    }
  ]
}

and the frame

{
  "@id": "bdr:O9TAXTBRC201605",
  "@context": {
    "children": {
      "@reverse": "http://purl.bdrc.io/ontology/core/taxSubclassOf"
    },
    "taxSubclassOf": {
      "@id": "http://purl.bdrc.io/ontology/core/taxSubclassOf",
      "@type": "@id"
    },
    "@vocab": "http://purl.bdrc.io/ontology/core/",
    "bdr": "http://purl.bdrc.io/resource/"
  },
  "children": {}
}

I'm not getting all the recursion, only

{
  "@graph": [
    {
      "@id": "bdr:O9TAXTBRC201605",
      "children": [
        {
          "@id": "bdr:O9TAXTBRC201605_0001",
          "@type": "Taxonomy",
          "taxSubclassOf": "bdr:O9TAXTBRC201605"
        },
        {
          "@id": "bdr:O9TAXTBRC201605_0010",
          "@type": "Taxonomy",
          "taxSubclassOf": "bdr:O9TAXTBRC201605"
        }
      ],
      "@type": "Taxonomy"
    }
  ]
}
azaroth42 commented 6 years ago

:+1: to the use case. Have you tried implementing a solution to this, @gkellogg ?

gkellogg commented 6 years ago

I generally implement things before considering a specification update, and I'll take a look, in due course. (Unless, of course @dlongley or @davidlehn beat me to it!).

azaroth42 commented 5 years ago

Resolution on the WG call of 2018-09-14 was to accept this issue as valid and valuable, and to seek additional implementation experience for potential solutions.

gkellogg commented 5 years ago

So, this ends up running afoul of the general framing algorithm. When framing a property with a node value, it looks for a frame associated with the property, if there is none, it constructs one using @embed, @explicit and @requireAll:

From Framing 4.4.2.3.2:

... If frame does not exist, create a new frame using a new dictionary with properties for @embed, @explicit and @requireAll taken from embed, explicit and requireAll.

The requested logic would require us to construct a new frame based on properties of the existing frame, which could have wide implications.

The best we can do without radical changes would be to make the sub-frames explicit (playground):

{ 
  "@context" : {
    "@vocab" : "http://purl.bdrc.io/ontology/core/",
    "taxSubclassOf" : {
      "@id" : "http://purl.bdrc.io/ontology/core/taxSubclassOf",
      "@type" : "@id"
    },
    "bdr" : "http://purl.bdrc.io/resource/",
    "children": { "@reverse": "http://purl.bdrc.io/ontology/core/taxSubclassOf" }
  },
  "@id" : "bdr:O9TAXTBRC201605",
  "children": {
    "children": {
      "children": {}
    }
  }
}

This generates the following, with backwards and forwards links:

{
  "@context" : {
    "@vocab" : "http://purl.bdrc.io/ontology/core/",
    "taxSubclassOf" : {
      "@id" : "http://purl.bdrc.io/ontology/core/taxSubclassOf",
      "@type" : "@id"
    },
    "bdr" : "http://purl.bdrc.io/resource/",
    "children": { "@reverse": "http://purl.bdrc.io/ontology/core/taxSubclassOf" }
  },
  "@id" : "bdr:O9TAXTBRC201605",
  "children": [{
    "@id": "bdr:O9TAXTBRC201605_0001",
    "@type": "Taxonomy",
    "taxSubclassOf": "bdr:O9TAXTBRC201605",
    "children": {
      "@id": "bdr:O9TAXTBRC201605_0002",
      "@type": "Taxonomy",
      "taxSubclassOf": "bdr:O9TAXTBRC201605_0001"
    }
  }, {
    "@id": "bdr:O9TAXTBRC201605_0010",
    "@type": "Taxonomy",
    "taxSubclassOf": "bdr:O9TAXTBRC201605"
  }]
}

(Note that unused repetitions of "children" are ignored if there are no children).

This seems like an acceptable solution to me requiring no change.

iherman commented 5 years ago

This issue was discussed in a meeting.

azaroth42 commented 5 years ago

Moved to Editorial given Resolution above.