Re: hydra:Link (ISSUE-41)

On Mar 19, 2014, at 12:07 PM, Markus Lanthaler <markus.lanthaler@gmx.net> wrote:

> On Wednesday, March 19, 2014 6:35 PM, Gregg Kellogg wrote:
>> On Mar 18, 2014, at 3:13 PM, Markus Lanthaler wrote:
>>>> The problem is, if I add this type to the predicate IRI, I'm making a
>>>> universal assertion, and some other application might not support this
>>>> as a link. In my particular application, In my application, I'm solving
>>>> this (both for hydra:Class and hydra:Link) by asserting that
>>>> information in a named graph, rather than the default graph, but you
>>>> might equally well say that the hydra:Link should go someplace in the
>>>> SupportedProperty description.
>>> 
>>> My current take at this is to put information which is specific to a
> certain
>>> Web API in a ApiDescription document and reference it via an HTTP Link
>>> header:
>>> 
>>> Link: </api-doc>;
> rel="http://www.w3.org/ns/hydra/core#apiDocumentation"
>>> 
>>> It's important to not merge the inferred triples with the data you
> retrieved
>>> from the Web API if you don't want to "pollute" your data.
>>> 
>>> Putting this information in a named graph doesn't have much advantages
> IMO
>>> but, as you know, a couple of quite severe disadvantages. In any case,
> you
>>> need to careful about what data to trust in a given context and how to
>>> process it. Publishing named graphs don't really help here, but using
> them
>>> to partition your data locally might.
>> 
>> Okay, if it's kept separate, then a client could conceivably
>> simultaneously use two different Hydra-based services and not confuse
>> the claims about the first with those of the second. If I were
>> implementing such a system using RDF, I would likely keep information
>> separate by placing either in different datastores, or in different
>> named graphs, but this is different than the provider using named
>> graphs for the same purpose, as it gives more license to the client.
> 
> Right
> 
> 
>>>> Here's an example:
>>>> 
>>>>   </GreggKellogg> a schema:Person;
>>>>     schema:colleagues </GreggKellogg/colleagues>;
>>>>     schema:colleague </MarkusLanthaler>, ...
>>>>   </GreggKellogg/colleagues> a hydra:Collection;
>>>>     hydra:member </MarkusLanthaler>, ...
>>>>   </MarkusLanthaler> a schema:Person .
>>> 
>>> Yeah.. in principle this is quite similar as lists in RDF. They also
>>> introduce intermediary nodes which "break" the direct link between
>>> the nodes. It might make sense to discuss this in the spec.
>> 
>> It's an issue that others will face, so I think it's a good idea to
>> recognize this in the spec, and perhaps suggest some best practices for
>> dealing with the potential confusion.
> 
> I've created ISSUE-41 to track this:
> 
>  https://github.com/HydraCG/Specifications/issues/41

Vering in to N3 syntax (and changing vocabularies), for the moment, an alternative way of referencing a collection could be through a BNode:

</GreggKellogg> a foaf:Person;
  foaf:knows [is hydra:member of </GreggKellogg/colleagues>]

Alternatively, if we mint a hydra:isMemberOf property as the inverse of hydra:member:

</GreggKellogg> a foaf:Person;
  foaf:knows [hydra:isMemberOf </GreggKellogg/colleagues>]

(JSON-LD and RDFa both have nice support for reversed properties, so creating such a property probably isn't necessary.

This ends up using the BNode as an existential quantifier for any member of the colleagues collection, so doesn't create anything which would be inconsistent. Dereferencing the is member of relation gets a collection (or possibly, paged collection), which doesn't assert that it is, itself, a colleague. After pulling in the collection, and performing RDFS entailment, you'd get the following:

</GreggKellogg> a foaf:Person;
  foaf:knows
    [a foaf:Person; is hydra:member of </GreggKellogg/colleagues>],
    </MarkusLanthaler> .

<MarkusLanthaler> a foaf:Person .

These statements are entirely consistent, and the BNode is rather more easily ignored than a collection IRI. In JSON-LD, it could look like the following:

{
  "@context": {
    "foaf": "http://xmlns.com/foaf/0.1/",
    "hydra": "<http://www.w3.org/ns/hydra/",
    "memberOf": {"@reverse": "hydra:member"}
  },
  "@id" "GreggKellogg",
  "foaf:knows": {"memberOf": "GreggKellogg/colleagues"}
}

It does mean that saying foaf:knows is a hydra:Link isn't sufficient, but saying hydra:isMemberOf is a hydra:Link would be, and wouldn't need to be asserted on any other property for an API to be able to perform reasonable dereferencing.

>> However, note the potential for
>> RDFS inference confusion, if the range of schema:colleague is
>> schema:Person, then </GreggKellogg/colleagues> could be inferred to
>> have the type schema:Person, where it might be declared as
>> hydra:Collection. Saying that hydra:Collection is disjoint with
>> schema:Person might solve this, but it might also create a
>> contradiction (Ruben?).
> 
> Yes, it does.
> 
>> (This is not really a problem if using the
>> schema.org vocabulary, as they use schema:rangeIncludes instead of
>> rdfs:range, which has unspecified inference semantics.
> 
> Exactly. In cases like this (and quite a lot of other cases on the open,
> wild Web), it's better to use schema:rangeIncludes instead of rdfs:range
> IMO.

Sure, but we can't pick the vocabularies people will use, and RDFS is pretty well established...

>> Practically
>> speaking, the Structured-data linter treats schema:rangeIncludes as
>> equivalent to rdfs:range, if there is only one such statement on a
>> given predicate, as type inference can be quite powerful, but that's
>> only my own take).
> 
> Hmm.. while reasonable, I think that's a dangerous assumption to make.

In the context of the Linter it's really useful, as I can describe information in the analysis about what the types of otherwise untyped related objects are, which aides in understanding.

Gregg

> --
> Markus Lanthaler
> @markuslanthaler
> 
> 

Received on Wednesday, 19 March 2014 21:44:10 UTC