Skip to content

Disjointness of reified classes (as:Link, as:Relationship, rdf:Statement, as:Activity) could be refined/reconsidered #666

@trwnh

Description

@trwnh

Preamble

This is next version stuff. You have been warned.

tl;dr

Don't these look very similar? Too similar, in fact?

<foo> <bar> <baz>.

_:b1 a rdf:Statement;
  rdf:subject <foo>;
  rdf:predicate <bar>;
  rdf:object <baz>.

_:b2 a as:Link;
  _:anchor <foo>;
  as:rel "bar";  # the normative context defines this WITHOUT @type: @id, so it is a Literal.
  as:href <baz>.  # the normative context defines this WITH @type: @id, so it is a Resource/Reference.

_:b3 a as:Relationship;
  as:subject <foo>;
  as:relationship <bar>;
  as:object <baz>.  # currently ambiguous with as:object on as:Activity...

_:b4
  as:actor <foo>;
  a as:Activity;
  as:object <baz>.

They are probably not as disjoint as one would initially think... and it is possible for a reification to be more than one of these. For example:

  • <foo> <bar> <baz> can be reified as an rdf:Statement pretty much always.
  • <foo> <bar> <baz> can be reified as an as:Link in... some unclear circumstances where a property has a range including as:Link. (There are so many issues regarding various aspects of this...)
    • With a slight modification to the activitystreams context, as:rel is isomorphic to rdf:predicate.
  • <foo> <bar> <baz> can be reified as an as:Relationship when it represents a relationship between two individuals.
    • as:relationship is isomorphic to rdf:predicate, but we can refine it like so:
      • the rdfs:domain is as:Relationship.
      • it is an rdfs:subPropertyOf rdf:predicate.
  • <foo> <bar> <baz> can be reified as an as:Activity when it represents something being done. rdf:type is used instead of rdf:predicate, or we could say that rdf:type is derived from an rdf:predicate.

More concretely:

  • The triple "John liked an article" can be reified as the Activity "this is an as:Like as:Activity; the as:actor is John; the as:object is an article".
  • The triple "This article's author is John" can be reified as "this is an as:Link; the _:anchor is (inferred to be -- see AS2 Link's anchor/context is unclear #665 for more) this article; the as:rel is "author"; the as:href is John".
    • This could be done more generally for any RDF statement, particularly when the object is not a literal value. RDF statements and Web links are both directed graphs, after all!
  • The triple "John is following Sally" can be reified as "this is an as:Relationship; the as:subject is John; the as:relationship is as:IsFollowing; the as:object is Sally".

as:rel being a literal by default should be reconsidered

as:rel should maybe be @type: @vocab (like #593 proposes for as:relationship as used by as:Relationship) which would make its value a URIRef.

How to refer to IANA link relations is an open question, but it is a tractable one: pick a namespace and make it the default @vocab in a scoped context (nested within the definition of as:rel in the normative activitystreams context).

{
  "@context": {
    "rel": {
      "@id": "https://www.w3.org/ns/activitystreams#rel",
      "@type": "@vocab",
      "@context": {
        "@vocab": "https://www.w3.org/ns/iana/link-relations/relation#"
      }
    }
  }
}

This is actually more accurate and more useful than just a string literal value. https://json-ld.org/playground/#startTab=tab-expanded&json-ld=%7B%22%40context%22%3A%7B%22rel%22%3A%7B%22%40id%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%23rel%22%2C%22%40type%22%3A%22%40vocab%22%2C%22%40context%22%3A%7B%22%40vocab%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Fiana%2Flink-relations%2Frelation%23%22%7D%7D%7D%2C%22rel%22%3A%22alternate%22%7D

Candidate namespaces:

  • https://www.w3.org/ns/iana/link-relations/relation# (provides an N-Triples graph; i'm not sure if it's up-to-date or out-of-date... it could theoretically drift out-of-sync with the IANA registry, but this might not be a problem?)
  • https://www.iana.org/assignments/link-relations/ (or some variant of it)

potential conflict between "Link and Object are disjoint" and "Relationship is an Object"

either as:Link might not be as disjoint with as:Object as previously thought, or as:Relationship is not an as:Object.

The idea of which classes are disjoint with each other in AS2 should be reconsidered.

Rationale

What is reification?

Reification is more or less when you "make something real". In RDF, we can use reification to bundle related statements together.

For example, we might say that "John visited Dr. Lucy", or we might reify the concept of a "Visit" to be able to make additional statements within that reified context, such as "the visit occurred at 2:00PM US Eastern Time on January 15, 2026". A new type of reification introduced in RDF 1.2 is "triple terms", which is a type of quotation that lets you make statements about statements.

In Turtle 1.2, we can say:

<< <John> <visited> <Dr. Lucy> >> <on> "2026-01-15T14:00:00-05:00".

This expands to:

<this> <is a> <Statement>;
  <the subject of the statement is> <John>;
  <the predicate of the statement is> <visited>;
  <the object of the statement is> <Dr. Lucy>;
  # and the information in the statement was true
  <on> "2026-01-15T14:00:00-05:00".

We can refine this reification further by saying <this> is also a <Visit> or <DoctorVisit>.

Reification of rdf:Statement

The previous example used concepts like "Statement", "the subject of...", "the predicate of...", and "the object of...". These concepts have names, in the form of identifiers -- rdf:Statement, rdf:subject, rdf:predicate, and rdf:object, as defined in https://www.w3.org/1999/02/22-rdf-syntax-ns# and where "rdf:" is a prefix expanding to that base URI. So the canonical URIRef of rdf:Statement is https://www.w3.org/1999/02/22-rdf-syntax-ns#Statement.

The data model here is pretty straightforward: you can take the rdf:subject, rdf:predicate, and rdf:object, and you can reconstruct an rdf:Statement in triple form, which is used to assert the statement, or in other words, to claim/believe that the statement is true.

Reification of as:Activity

If this looks familiar, it's because AS2 reifies the concept of an Activity! We say that an actor performed an Activity of some type on some object, maybe from some origin or to some target, maybe using some instrument, maybe having some result.

If we didn't reify an activity, we might say something like "John liked an Article". Once we reify, we instead say: "this is a Like activity; the actor is John; the object is an Article."

Reification of as:Link

AS2 also reifies the concept of a Link, which closely tracks Web linking as defined in https://datatracker.ietf.org/doc/html/rfc8288 to have the following model:

Link model
  • The link's context is denoted by anchor, defaulting to the current resource in a browsing context.
  • The link's target is denoted by href, and is a URI-Reference. Relative targets can be resolved against a base per https://datatracker.ietf.org/doc/html/rfc3986#section-5.1
  • The link's relation is denoted by rel.
  • Each link serialization can define additional parameters to apply to the link target (href), most commonly:

In AS2, we follow this Web linking model pretty closely, with some minor tweaks:

  • anchor is not defined and it is unclear how to determine what the value should be. Split issue: AS2 Link's anchor/context is unclear #665
  • type conflicts with the term defined to mean @type, so we use as:mediaType for that.
  • title is replaced with as:name.

A Link is actually very close to an rdf:Statement. The difference between as:Link and rdf:Statement is simply that as:rel is not a URIRef. It could be if we defined it as such, but we currently don't.

Reification of as:Relationship

AS2 also defines the concept of a "Relationship", which is intended to describe more precise relationships between two individuals. For example, where we might say "John is following Sally", we instead say "this is a Relationship; the subject is John; the object is Sally; the relationship is being a follower of".

A Relationship like this is also similar to a Link or Statement. In fact, the vocabulary of AS2 reuses 2/3 of the property names!

Membership in multiple classes

It is normal and useful for the same thing to belong to multiple sets or classes. This is how you can cleanly combine data models or processing models.

We can say that Garfield is a Cat, but Garfield is also a Pet. The biological taxonomy is separate from the ontology of pet ownership, and it does no favors to try and unify these two models in their entirety.

Perhaps Jon manages his pet registration using an application that primarily works with the Pet class and only incidentally uses a Cat class... and perhaps when Jon takes Garfield to the vet, Liz will use an application that imports classes like Cat and Feline and Mammal and Animal.

The important thing is that any given processing model works with the concepts defined within its semantic model. The main tool for dealing with this across multiple data models is equivalence:

  • Equivalent classes. If every X is a Y, and every Y is an X, then X and Y are equivalent classes. Example: we might say that every as:Person is also a foaf:Person, and every foaf:Person is also an as:Person.
  • Equivalent properties. If every value of X is always also the value of Y, and vice versa, then X and Y are equivalent properties. Example: we might say that your as:name is also your foaf:name, and your foaf:name is also your as:name.
  • The same thing. Going beyond implication of classes or values, we might say that two concepts are actually exactly the same. This is like a stronger version of equivalence.

We can also go broader or narrower with subclasses and subproperties, which are like a limited form of one-way equivalence:

  • Subclass. If every X is a Y, but not every Y is an X, then X is a subclass of Y. Example: All Cats are Animals, but not all Animals are Cats. Some of them are Dogs.
  • Subproperty. If the value of X is always also a value of Y, but not vice-versa, then X is a subproperty of Y. Example: "owns a pet cat" implies "owns a pet", but "owns a pet" does not imply "owns a pet cat". It might be that one "owns a pet dog".

Using equivalence lets us describe resources that adhere to multiple semantic models and processing models. Instead of creating multiple separate documents or records for various facets of a thing, possibly with highly duplicated data, we can associate them all together.

Related issues

Past issues

Current issues

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions