json-ld.org icon indicating copy to clipboard operation
json-ld.org copied to clipboard

How can I express owl:inverseOf in JSON-LD?

Open Radu3000 opened this issue 5 years ago • 5 comments

Let's say I have the famous Library.jsonld example:

{
  "@context": {
    "dc11": "http://purl.org/dc/elements/1.1/",
    "ex": "http://example.org/vocab#",
    "xsd": "http://www.w3.org/2001/XMLSchema#",
    "ex:contains": {
      "@type": "@id"
    }
  },
  "@graph": [
    {
      "@id": "http://example.org/library",
      "@type": "ex:Library",
      "ex:contains": "http://example.org/library/the-republic"
    },
    {
      "@id": "http://example.org/library/the-republic",
      "@type": "ex:Book",
      "dc11:creator": "Plato",
      "dc11:title": "The Republic",
      "ex:contains": "http://example.org/library/the-republic#introduction"
    },
    {
      "@id": "http://example.org/library/the-republic#introduction",
      "@type": "ex:Chapter",
      "dc11:description": "An introductory chapter on The Republic.",
      "dc11:title": "The Introduction"
    }
  ]
}

How can I say express that ex:contains is an inverse of ex:containedIn?

Thanks, Radu

Radu3000 avatar Mar 27 '20 14:03 Radu3000

owl:inverseOf can be used as with any other property in RDF, but it is used when defining a property to indicate it's semantic relationship to another property.

Within a document, you can achieve something similar without resorting to OWL reasoning using the @reverse keyword (see Reverse Properties).

In this case, you could define a "contains" term using @reverse like so:

{
  "@context": {
    "dc11": "http://purl.org/dc/elements/1.1/",
    "ex": "http://example.org/vocab#",
    "xsd": "http://www.w3.org/2001/XMLSchema#",
    "contains": {"@reverse": "ex:containedIn", "@type": "@id"}
  },
  "@graph": [
    {
      "@id": "http://example.org/library",
      "@type": "ex:Library",
      "contains": "http://example.org/library/the-republic"
    },
    {
      "@id": "http://example.org/library/the-republic",
      "@type": "ex:Book",
      "dc11:creator": "Plato",
      "dc11:title": "The Republic",
      "contains": "http://example.org/library/the-republic#introduction"
    },
    {
      "@id": "http://example.org/library/the-republic#introduction",
      "@type": "ex:Chapter",
      "dc11:description": "An introductory chapter on The Republic.",
      "dc11:title": "The Introduction"
    }
  ]
}

gkellogg avatar May 22 '20 19:05 gkellogg

Thought I'd weigh in, as I've wrestled with a similar issue.

If we treat JSON object keys (that are not reserved words for JSON-LD) as OWL properties, we can define a new term with a new JSON-LD object. Note however, that OWL makes a distinction between properties that can be assigned an Object (i.e. owl:ObjectProperty), and ones that can be assigned a Literal (i.e. owl:DatatypeProperty). It's the former you need in this case.

Assuming the ex:containedIn property already exists, you can include a node declaring a new property in OWL and include owl:inverseOf in a node, with a @type of owl:ObjectProperty as follows:

{
  "@context": {
    "dc11": "http://purl.org/dc/elements/1.1/",
    "ex": "http://example.org/vocab#",
    "ex:contains": { "@type": "@vocab" },
    "xsd": "http://www.w3.org/2001/XMLSchema#",
    "owl": "http://www.w3.org/2002/07/owl#",
    "owl:inverseOf" : {"@type": "@vocab"}  
    },
  "@graph": [
    {
      "@id": "http://example.org/vocab#contains",
      "@type": "owl:ObjectProperty",
      "owl:inverseOf": "ex:containedIn"
    },
    {
      "@id": "http://example.org/library",
      "@type": "ex:Library",
      "ex:contains": "http://example.org/library/the-republic"
    },
    {
      "@id": "http://example.org/library/the-republic",
      "@type": "ex:Book",
      "dc11:creator": "Plato",
      "dc11:title": "The Republic",
      "ex:contains": "http://example.org/library/the-republic#introduction"
    },
    {
      "@id": "http://example.org/library/the-republic#introduction",
      "@type": "ex:Chapter",
      "dc11:description": "An introductory chapter on The Republic.",
      "dc11:title": "The Introduction"
    }
  ]
}

Edit: added namespaces. Thanks @pchampin for the correction. Edit: corrections. Plural.

rylabo avatar May 04 '22 06:05 rylabo

Your example answers the original question, but in a very different way than @gkellogg's example above. More precisely, running your example through toRdf produces (among others), the following triples, which @gkellogg's example does not produce:

<http://example.org/library> ex:contains <http://example.org/library/the-republic>.
<http://example.org/library/the-republic> ex:contains <http://example.org/library/the-republic#introduction>.
ex:contains owl:inverseOf ex:containedIn.

On the other hand, the following triples are produced by @gkellogg's example, but not by yours:

<http://example.org/library/the-republic> ex:containedIn <http://example.org/library>.
<http://example.org/library/the-republic#introduction> ex:containedIn <http://example.org/library/the-republic>.

Mind you: from your example, one can infer the two triples above, but that requires extra machinery (namely, an OWL2 compliant inference engine) in addition to the JSON-LD processor. Depending on your use-case, that extra machinery might or might not be available, making one or the other approach preferable.

pchampin avatar May 04 '22 06:05 pchampin

In my particular use case, I wanted objects with references to BOTH ancestors and descendants, but @reverse discarded the inverse predicate. I also wasn't using a triple store, but MongoDB. I thought another may have had a similar use case, so I threw my example out there.

rylabo avatar May 04 '22 07:05 rylabo

In my particular use case, I wanted objects with references to BOTH ancestors and descendants, but @reverse discarded the inverse predicate.

Indeed. JSON-LD's expansion maps every JSON key to at most one RDF property.

I also wasn't using a triple store, but MongoDB. I thought another may have had a similar use case, so I threw my example out there.

Absolutely. I thought it was important to underline the differences between the two examples (for future readers), but as I wrote, both have their pros and cons.

pchampin avatar May 04 '22 07:05 pchampin