Keeping the simple case simple (was Re: optimizing container pages serialization to enable streaming)

What we need to focus on is on the use of a blank node to group the 
different predicates associated with membership and whether it does allow 
us to reintroduce defaults without creating a non-monotonicity issue.
The fact that sending that info to the client early on rather late would 
be advantageous for streaming is just a side note that I propose to leave 
aside for now.

I'll give some background for those who need it. If you know what 
non-monotonicity is about and how we got where we are you may skip that 
part.

== Background ==

The specification we started from only had membershipSubject and 
membershipPredicate and stated that you only needed to specify them if 
they were different from the container and rdfs:member respectively. This 
had the advantage of keeping the simple case simple:

<http://example.org/container1>
   a ldp:Container;
   dcterms:title "A very simple container";
   rdfs:member
      <http://example.org/container1/member1>,
      <http://example.org/container1/member2>,
      <http://example.org/container1/member3>.

Note that neither membershipSubject nor membershipPredicate are set 
explicitly. The default values are used.

Two things changed:
1. We added two more predicates: membershipPredicateInverse and 
membershipObject.
2. Henry pointed out that the use of default values created a 
non-monotonicity issue

The non-monotonicity issue is this: In an open world, you can't assume to 
know what you don't know. Therefore you can't assume that 
membershipPredicate is rdfs:member because you haven't seen/you don't know 
what membershipPredicate is.

Practically speaking this problem exhibits itself particularly when you're 
streaming, which is why Eric talked about it, but more generally when you 
start processing data and then discover additional data that impacts your 
understanding of the "world".

Imagine you start processing the above and assume membershipPredicate is 
rdfs:member. You would then process member1, member2, member3 as being 
members of the container. But on receiving new data you get:

<http://example.org/container1>
        ldp:membershipPredicate o:asset.

This contradicts your assumption that the membershipPredicate is 
rdfs:member and invalidates all your prior processing. With that 
additional info, based on what you now know, you can no longer say that 
member1, member2, member3 are members of the container. This is the 
non-monotonicity issue.

To solve this issue we agreed not to use default values. Unfortunately the 
combination with #1 means the simple case is no longer so simple because 
one has to specify all predicates all the time. This gives us what we now 
have in the spec, where everything has to be specified:

<>
   a ldp:Container;
   ldp:membershipSubject <> ;
   ldp:membershipPredicate rdfs:member;
   ldp:membershipObject ldp:MemberSubject;
   dcterms:title "A very simple container";
   rdfs:member <member1>, <member2>, <member3>.

== Question at hand ==

Henry proposed to use a blank node, described below by Eric, stating that 
we can then have default values without non-monotonicity.

> To Henry's point, we could [...] enable defaults by
> adding a ldp:membershipRule along with a change to 5.3.1 (and tweaks
> to the pending mods to Membership triples):
>   s[[
> 5.3.1 The representation of a LDPC MUST contain a set of membership
> triples following one of the consistent patterns from that
> definition. The membership-constant-URI of the triples MAY be the
> container itself or MAY be another resource (as in the example).  See
> also 5.2.3.
> ]][[
> 5.3.1 The representation of a LDPC MUST contain exactly one
> ldp:membershipRules statement with the subject of the
> membership-constant-URI and an object a blank node. All membership
> triples use this blank node as the subject. The
> membership-constant-URI of the triples MAY be the container itself or
> MAY be another resource (as in the example).  See also 5.2.3.
> ]]

I believe this does indeed address our problem. And the difference with 
the previous situation we were in is that you don't know what the 
membershipPredicate and Co are until you receive ldp:membershipRule but 
once you receive that node you know everything there is to know.

In the simple case you can then have:

<http://example.org/container1>
   a ldp:Container;
   dcterms:title "A very simple container";
   ldp:membershipRule [];
   rdfs:member
      <http://example.org/container1/member1>,
      <http://example.org/container1/member2>,
      <http://example.org/container1/member3>.

An empty blank node means: all default values are in use.
Any membership related predicate can then be specified when needed, 
leaving the unspecified ones with their default values:

<http://example.org/netWorth/nw1/assetContainer>
   a ldp:Container;
   ldp:membershipRule [ ldp:membershipSubject <
http://example.org/netWorth/nw1>;
                                ldp:membershipPredicate o:asset. ].

<http://example.org/netWorth/nw1>
   a o:NetWorth;
   o:asset
      <http://example.org/netWorth/nw1/assetContainer/a1>,
      <http://example.org/netWorth/nw1/assetContainer/a2>.

This does achieve the goal of keeping the simple case simple.

Again, the one "downside" with this is the use of blank node. Some WG 
members have said they don't have a problem with it but the WG has in the 
past decided against relying on the use of blank nodes so this would be a 
change in our position.

Note that this is orthogonal to 1) ldp:created, 2) the names used for each 
predicate, 3) what the default values are. Please, don't get into any of 
these here.

Thanks.
--
Arnaud  Le Hors - Software Standards Architect - IBM Software Group

Received on Monday, 11 November 2013 23:13:52 UTC