data-interoperability-panel
data-interoperability-panel copied to clipboard
Add a predicate to link `AccessDescriptionSet` with `AccessNeedGroupDescription` and `AccessNeedDescription`
This issue is very close to another one I pointed out regarding TypeIndexes.
There is no predicate linking a AccessDescriptionSet
with AccessNeedGroupDescription
and AccessNeedDescription
.
So if you don't want to store all these resources on the same file (as it should be allowed, according to Linked Data philosophy), you have no way to find where they are.
IMO the spec should include a interop:hasAccessNeedGroupDescription
and a interop:hasAccessNeedDescription
predicates, which would be the reverse relationships of interop:inAccessDescriptionSet
.
Another possibility could be to use the skos:member predicate. But since SKOS is not used elsewhere, it probably doesn't make much sense.
Hi, could you explain why interop:inAccessDescriptionSet
seems insufficient? While the direction of the predicate is
arbitrary, it is a common practice to use them regardless of that direction. It is also often considered as anti-pattern to define inverse predicates in vocabularies. We can take the example from the spec and split it into distinct resources:
<set>
a interop:AccessDescriptionSet ;
interop:usesLanguage "en"^^xsd:language .
<en-need-group-pm>
interop:inAccessDescriptionSet <set> .
<en-need-group-pm>
a interop:AccessNeedGroupDescription ;
interop:inAccessDescriptionSet <set> ;
interop:hasAccessNeedGroup projectron:need-group-pm ;
skos:prefLabel "Read and Contribute to Projects"@en ;
skos:definition "Allow Projectron to read the Projects you select, and create new ones. Projectron won't modify existing data, but can add more."@en .
If I assume a AccessDescriptionSet
in a dedicated resource/file, then when looking at this resource/file, I expect to find links to the AccessNeedGroupDescription
and AccessNeedDescription
this set contains, no ?
LDP containers, ActivityStreams collections, WAC groups, all work this way. The "container" resource is where we define the "contained" resources (through ldp:contains
, as:items
, vcard:hasMember
...)
Of course, I can also go through all the AccessNeedGroupDescription
and AccessNeedDescription
resources/files and filter the ones which are part of this set, but this seems less intuitive ?
I expect to find links to the AccessNeedGroupDescription and AccessNeedDescription this set contains, no ?
My example has those links
<set>
a interop:AccessDescriptionSet ;
interop:usesLanguage "en"^^xsd:language .
<en-need-group-pm>
interop:inAccessDescriptionSet <set> .
<en-need-task>
interop:inAccessDescriptionSet <set> .
Both en-need-group-pm
and en-need-task
are separate resources.
Sometimes <set>
appears in the subject position in the statement, sometimes in object but that is to be expected.
Some serializations allow hiding it by syntactic sugar, for example @reverse
in JSON-LD or is ... of
in N3.
The only place where this could cause problem is if predicate is to be used in HTTP Link headers, since rev
has been deprecated and only rel
is available now. One could still work around it by using anchor
to provide explicit subject and place requested url as the object (target).
@srosset81 I've reread through your comments to double-check if I'm somehow missing your point.
IMO the spec should include a
interop:hasAccessNeedGroupDescription
and ainterop:hasAccessNeedDescription
predicates, which would be the reverse relationships ofinterop:inAccessDescriptionSet
.
Especially this paragraph confirms to me my understanding that we are talking about the difference in the ontology that defines inverse properties and one that prefers having predicates defined only in one of the possible directions.
The drawback of defining inverse properties relates to the impact on future queries, one would either need to depend on a reasoner creating inferences based on owl:inverseOf
, or have to always check in the queries for both predicates defined as inverse of one another.
I often recall this old post when it comes to this topic http://richard.cyganiak.de/blog/2006/06/an-rdf-design-pattern-inverse-property-labels/
I think there is a misunderstanding, I'm talking about having each resource in separate files. So, with the current spec, if I open the AccessDescriptionSet
file, I would see only these informations:
<set>
a interop:AccessDescriptionSet ;
interop:usesLanguage "en"^^xsd:language .
By looking at this file, I wouldn't know what AccessNeedGroupDescription
and AccessNeedDescription
is contained in the set. In fact, it would look like the set is empty (and pretty useless) ! As I said, I could of course "go through all the AccessNeedGroupDescription and AccessNeedDescription files and filter the ones which are part of this set" based on interop:inAccessDescriptionSet
... but this is less efficient and less intuitive.
I understand that inverse relationships may be a bad practice, and that they are generally not used in Solid project.
So my proposal would be to:
- Remove
interop:inAccessDescriptionSet
- Use instead the
interop:hasAccessNeedDescription
andinterop:hasAccessNeedGroupDescription
predicates ininterop:AccessDescriptionSet
This way, we would conform with what is done with other similar data (LDP containers, WAC groups, ActivityStreams collections...)
By looking at this file, I wouldn't know what
AccessNeedGroupDescription
andAccessNeedDescription
is contained in the set. In fact, it would look like the set is empty (and pretty useless) !
Please notice that in my examples, I did include the needed links
<set>
a interop:AccessDescriptionSet ;
interop:usesLanguage "en"^^xsd:language .
<en-need-group-pm>
interop:inAccessDescriptionSet <set> .
<en-need-task>
interop:inAccessDescriptionSet <set> .
The resource describing the AccessDescriptionSet
doesn't include any other statements about AccessNeedGroup
or AccessNeed
other than the single statement for each one relating it to the AccessDescriptionSet
.
So the other two separate resources would include the following statements
<en-need-group-pm>
a interop:AccessNeedGroupDescription ;
interop:inAccessDescriptionSet <set> ;
interop:hasAccessNeedGroup projectron:need-group-pm ;
skos:prefLabel "Read and Contribute to Projects"@en ;
skos:definition "Allow Projectron to read the Projects you select, and create new ones. Projectron won't modify existing data, but can add more."@en .
and
<en-need-project>
a interop:AccessNeedDescription ;
interop:inAccessDescriptionSet <set> ;
interop:hasAccessNeed projectron:need-project ;
skos:prefLabel "Access to Projects is essential for Projectron to perform its core function of Project Management"@en .
As we see the statements <en-need-group-pm> interop:inAccessDescriptionSet <set> .
and <en-need-task> interop:inAccessDescriptionSet <set> .
each is repeated twice, once when describing the AccessDescriptionSet
and the other time when describing the AccessNeedGroup
or AccessNeed
.
I think the misunderstanding shows in those two specific snippets:
In your snippet showing the document describing the AccessDescriptionSet
you only have
<set>
a interop:AccessDescriptionSet ;
interop:usesLanguage "en"^^xsd:language .
Which indeed misses the information about relationships.
In my snippet the relationship statements are included.
<set>
a interop:AccessDescriptionSet ;
interop:usesLanguage "en"^^xsd:language .
<en-need-group-pm>
interop:inAccessDescriptionSet <set> .
<en-need-task>
interop:inAccessDescriptionSet <set> .
All the other details about those related resources are in separate documents describing them.
This way, we would conform with what is done with other similar data (LDP containers, WAC groups, ActivityStreams collections...)
Solid doesn't support LDP Directed and Indirected containers. If it did, one could do:
<set> a ldp:DirectContainer, interop:AccessDescriptionSet ;
ldp:membershipResource <set>;
ldp:isMemberOfRelation interop:inAccessDescriptionSet .
From https://www.w3.org/ns/ldp
hasMemberRelation
rdf:Property - Indicates which predicate is used in membership triples, and that the membership triple pattern is< membership-constant-URI , object-of-hasMemberRelation, member-URI >.
isMemberOfRelation
rdf:Property - Indicates which predicate is used in membership triples, and that the membership triple pattern is< member-URI , object-of-isMemberOfRelation, membership-constant-URI >.
We can see that LDP can use a predicate regardless of its direction from container to contained or vice versa.
OK I see, thanks for the clarifications... But then why do you prefer:
<set>
a interop:AccessDescriptionSet ;
interop:usesLanguage "en"^^xsd:language .
<en-need-group-pm>
interop:inAccessDescriptionSet <set> .
<en-need-task>
interop:inAccessDescriptionSet <set> .
over the more straightforward:
<set>
a interop:AccessDescriptionSet ;
interop:usesLanguage "en"^^xsd:language .
interop:hasAccessNeedGroupDescription: <en-need-group-pm> .
interop:hasAccessNeedDescription: <en-need-task> .
? That looks like a preference to me. And one I don't understand...
Solid doesn't support LDP Directed and Indirected containers.
I'm talking about Basic Containers, and the simple ldp:contains
predicates it uses to link to contained resources.
I also mentionned ActivityStreams collections (which use as:items
predicate) and WAC groups (which use vcard:hasMember
predicate). And I could mention many other ontologies... all of them have this simple pattern of a container describing what it contains, instead of the contained children describing what container they are inside.
I don't see a problem with defining it in the other direction; there are a few things we would need to keep in mind, though.
- deprecate
interop:inAccessDescriptionSet
- make a similar change to shape tree descriptions https://shapetrees.org/TR/specification/#description
We should probably do another pass on access needs and descriptions keeping in mind change from #303