RE: Questions about new collection design

On 3 Feb 2015 at 14:38, Dietrich Schulten wrote:
> Am 25.01.2015 um 23:31 schrieb Markus Lanthaler:
>> On 25 Jan 2015 at 22:08, Dietrich Schulten wrote:
>>>>> But is there a way to express that the above also entails
>>>>> 
>>>>> </alice> foaf:knows </bob>
>>>>> </alice> foaf:knows </zelda>
>>>>> 
>>>>> ?
>>>> 
>>>> Sure, just add those triples :-)
>>> 
>>> Yay, I'll gladly duplicate all members :o)
>> 
>> You don't duplicate anything here. Depending on how you look at it, you
add
>> new statements (triples) or you draw new connections into the graph.
>> 
> 
> I am still unsure how to implement the new collection design in
> hydra-java. I have three questions, I hope you can help to clarify my
> doubts.

I'll at least try :-)


> 1. On the Alice resource, how do I express that she has friends assuming
> that I want to have an Alice resource and a separate resource containing
> a list of her friends represented as a hydra:Collection? I think the
> answer is to say that Alice has collections, and each collection states
> that it manages a property for a subject or an object:
> 
> {
>   "@id": "/alice",
>   "collection": [
>     {
>     "@id": "/alice/friends",
>     "@type": "Collection",
>     "manages": {
>       "property": "foaf:knows",
>       "subject": "/alice"
>     }
>   }
>   ]
> }

Right


> However, it breaks the :knows relationship if I would say the following,
> given that /alice/friends points to a hydra:Collection rather than a
> plain set of foaf:Person.
> 
> {
>   "@id": "/alice",
>   "foaf:knows": { "@id": "/alice/friends" }
> }
> 
> Correct?

Yep, in case of FOAF this is correct. foaf:knows has a range of foaf:Person
which would imply that /alice/friends is a person.


> 2. What I could do is to embed the friends using the :knows property.
> What I gain by this is that I can express information about the :knows
> collection such as a search property or supported operations on
> /alice/friends. At the same time, we also state that Alice :knows someone.
> 
> {
>   "@id": "/alice",
>   "foaf:name": "Alice",
>   "collection": [
>     {
>     "@id": "/alice/friends",
>     "@type": "Collection",
>     "manages": {
>       "property": "foaf:knows",
>       "subject": "/alice"
>     },
>     "search" : ... an iritemplate,
>     "operation" : ... supportedOperations
>   ],
>   "foaf:knows": [
>     {"@id":"/bob", "foaf:name": "Robert Rumbaugh"},
>     {"@id":"/zelda", "foaf:name": "Zelda Zackney"}
>   ]
> }

Haven't thought about this one yet, but looks reasonable.


> As an alternative, I could also use hydra:member on the :Collection to
> embed the friends, but in that case I do not assert that Alice :knows
> someone - unless I use an additional construct which makes that
connection.
> 
> Correct?

Yes. We *could* change the semantics of collection to entail those triples
but we haven't decided to do so (yet). In general, I think it is much easier
to not depend on reasoning if possible.


> 3. On to the other side of the picture, the separate collection of
> friends. The Alice resource points to it using the construct from 1.
above.
> 
> {
>   "@id": "/alice/friends",
>   "@type": "Collection",
>   "manages": {
>     "property": "foaf:knows",
>     "subject": "/alice"
>   },
>   "member": [
>     {"@id":"/bob", "foaf:name": "Robert Rumbaugh"},
>     {"@id":"/zelda", "foaf:name": "Zelda Zackney"}
>   ]
> }
> 
> Question: How to materialize the :knows relationship?

It would look somewhat like this (please note the additional knownBy
property):

  {
     "@context": { "knownBy": { "@reverse": "foaf:knows", "@type": "@id" }
},
     "@id": "/alice/friends",
     "@type": "Collection",
     "member": [
       {"@id":"/bob", "foaf:name": "Robert Rumbaugh", "knownBy": "/alice" },
       {"@id":"/zelda", "foaf:name": "Zelda Zackney", "knownBy": "/alice" }
     ]
  }

Would be interesting to see how well compression works here


> When pointing to a separate resource which looks like the one above, I
> understood that I can leave the value of Alice :knows undefined "because
> it is trivial for the server to materialize those triples". Or, as an
> alternative: "We *could* also define "manages" in a way that would allow
> a reasoner to infer these triples automatically".
> 
> Did you in fact mean that as an alternative a) server materializes the
> :knows triples - or b) we define :manages so that the reasoner can infer
> the :knows triples ?

Yes. I prefer the former though as it is trivial for the server and
simplifies clients a lot.


> ad a) Exactly how would that work? Example: Client has /alice without a
> :knows attribute and it wants to find out if :knows has any value. How
> does the client learn which request it should send to the server? What
> is the server response which materializes the :knows triples for the
client?
> It would have the advantage that clients do not need a reasoner to work
> with hydra responses.

1) Client retrieves /alice which the intent to find /alice foaf:knows
relationships
2) Client doesn't find any /alice foaf:knows in the retrieved response but
sees that /alice has a collection /alice/friends which manges /alice
foaf:knows
3) Client retrieves /alice/friends
4) Client finds /alice foaf:knows relationships in the response (which would
look somewhat like the example above)


> ad b) If we do not define :manages in that way, we leave it as an
> exercise to server implementers to add these assertions in their
> ApiDocumentation. OTOH, even if we do define it that way, clients would
> have to fire up a reasoner to work with collection properties, so it
> won't always help.

Exactly. The complexity of clients would be vastly increased.


> To me, a) appears preferable, although I have no idea what you mean by
> "materialize triples". Outside the world of Linked Data, and based on
> the Web Linking RFC alone, it would mean the server offers an extension
> rel such as ex:knows on the Alice resource which has a href that returns
> a list of people. But that is exactly what I cannot do, hence my
confusion.

Have a look at the example in the playground:

   http://json-ld.org/playground/#/gist/a6fcd5b6034daeb71243

You'll see that all the triples you need are there. You probably just forgot
about reverse properties [1]. You can also define them on the fly without
having to give it a different name - that probably simplifies your
implementation - even though you could always use a convention such as
"!foaf:knows" or "^foaf:knows".


HTH,
Markus


[1] http://www.w3.org/TR/json-ld/#reverse-properties


--
Markus Lanthaler
@markuslanthaler

Received on Tuesday, 3 February 2015 20:26:46 UTC