Re: class hierarchy of containers

On 25 Feb 2014, at 18:50, Arnaud Le Hors <lehors@us.ibm.com> wrote:

> [I think you figured it out but I apologize, I have evidently messed up the end of my previous email by accidentally inserted a copy of another section, in the following: 
> 
> So, maybe the actual hierarchy we need is this: 
> <delete>Now, the question is whether this makes more sense than if we flipped the whole tree up-side-down. This requires thinking in terms of expanded capabilities instead of restrictions. We start from the simplest class and add to it as we go down. This gives us: </delete>
> 
> Container (aka BasicContainer) 
>   | 
>   ------- IndirectContainer (adds membershipResource, hasMemberRelation, isMemberOfRelation, and insertedContentRelation properties) 
>                | 
>                 ------- DirectContainer (restricts insertedContentRelation property to ldp:MemberSubjec 
> 
> 
> ] 
> 
> This being said, I expected you to barf at my proposal that " if a client only knows how/wants to deal with BasicContainers, with this model they would simply ignore the whole membership stuff and be fine just looking at the containment (container ldp:contains resource)" for exactly the reason you mention ("volunteering to the army"). 
> 
> Given that, I think we're better off going back to a simple, flat hierarchy with an abstract base class Container and three independent subclasses: BasicContainer, DirectContainer, and IndirectContainer. 

yes that seems reasonable. Note that those three Containers need not be exhaustive of what an ldp:Container is.
I can imagine lots of other Containers that have much more complex effects than the ones currently being envisaged.

To illustrate we can spring imaginatively into a future LDP2 space, where one may want to create a relation 
ldp:bindingRule from an ldp:Container to a rule.

ldp:bindingRule a rdf:Property;
   rdfs:domain ldp:Container;
   rdfs:range ldp:Rule .

One could use this like this:

<> a ldp:Container;
   ldp:bindingRule [ a DirectBindingRule;
                     ldp:bindingSubject <financial#it>;
                     ldp:bindingRelation finance:ownershipDocument ],
                   [ some other binding rule ] , ...

It would be easy to map the current containers to this construct and then invent new ones. For example
 • ldp:DirectContainer is a LDPC that only has one ldp:bindingRule of type ldp:DirectBindingRule.
 • ldp:IndirectContainer is a LDPC that has only one ldp:bindingRule of type ldp:IndirectBindingRule

But one would then be able to have many more complex bindingrules, perhaps even a special binding 
rule language.
 

> 
> Introducing any form of inheritance between these three containers seem to bring more undesirable effects than gain. Does anyone actually have a use case for having one of those classes derive from another? 

If there is an inheritance between DirectContainer and IndirectContainer, we can always add that to the ontolgoy later.
It's just one triple to add.


> 
> Regards.
> --
> Arnaud  Le Hors - Software Standards Architect - IBM Software Group
> 
> 
> 
> 
> From:        "henry.story@bblfish.net" <henry.story@bblfish.net> 
> To:        Arnaud Le Hors/Cupertino/IBM@IBMUS, 
> Cc:        "Linked Data Platform (LDP) Working Group" <public-ldp-wg@w3.org>, Sandro Hawke <sandro@w3.org> 
> Date:        02/25/2014 03:30 AM 
> Subject:        Re: class hierarchy of containers 
> 
> 
> 
> 
> On 25 Feb 2014, at 06:25, Arnaud Le Hors <lehors@us.ibm.com> wrote:
> 
> Thanks Henry for taking a crack at this. 
> 
> However, this doesn't quite match what's in the current draft. The current draft actually has BasicContainer as a subclass of DirectContainer rather than Container. 
> 
> Container (aka IndirectContainer) 
>   | 
>   ------- DirectContainer (restricts insertedContentRelation property to ldp:MemberSubject) 
>                | 
>                 ------- BasicContainer (restricts membershipResource property to <> and hasMemberRelation property to ldp:contains) 
> 
> The whole idea behind this hierarchy being that we just add more constraints as we go down the hierarchy. 
> 
> yes. That's the point of trying to describe the BasicContainer in terms of owl:Restriction-s. 
> Btw I discovered that owl2 has the restriction hasSelf ( see: http://www.w3.org/TR/owl2-quick-reference/ ) 
> so that we can now I think correctly write the restrictions like this: 
> 
> ldp:DirectContainer 
>     owl:subClassOf ldp:Container,
>                   [ a owl:Restriction;
>                     owl:onProperty ldp:insertedContentRelation; 
>                      owl:hasValue ldp:MemberSubject
>                   ] . 
> 
> ldp:BasicContainer 
>     owl:subClassOf ldp:DirectContainer, 
>                    [ a owl:Restriction;
>                     owl:onProperty ldp:membershipResource;
>                     owl:hasSelf "true"^^xsd:boolean ],
>                   [ a owl:Restriction;
>                     owl:onProperty ldp:hasMemberRelation;
>                     owl:hasValue ldp:contains ] . 
> 
> As I mentioned in my original e-mail this is a bit weird, because each LDPC can only have one ldp:membershipResource, 
> ldp:hasMemberRelation, ldp:insertedContentRelation property ( they are all owl:FunctionalProperties as I added to the 
> ontology below) and yet we are saying that  the superclass ldp:Container also has an ldp:contains relation and 
> these other relations too. But if an ldp:BasicContainer should be thought of as an ldp:Container with the 
> above restrictions meaning that ldp:contains is then a "membership property", then what are the ldp:contains relations 
> on the ldp:Container classes that are not ldp:BasicContainers? Why would these not also be membership properties? 
> 
> I think this may reveal another way of approaching the doubt that Sandro Hawke has with the current model 
> as he expressed in this e-mail http://lists.w3.org/Archives/Public/public-ldp-wg/2014Feb/0097.html 
> 
> 
> You're missing the isMemberOfRelation property (formerly known as membershipPredicateInverse). I think it would look something like that in your model: 
> 
> ldp:isMemberOfRelation a rdf:Property; 
>   rdfs:domain  ldp:Container; 
>   rdfs:range rdf:Property. 
> 
> 
> yes. That makes the owl restrictions a bit more complex to write out. But it should not 
> make much difference as if you recall there was a simple proposal by Richard Cyganiak to 
> have just one relation -  ldp:memberRelation  - which could do the job for inverse 
> properties by using owl:inverseOf as in this example: 
> 
>  <> a ldp:DirectContainer; 
>     ldp:memberRelation [ owl:inverseOf accounting:ows ]; 
>     ldp:membershipResource <#me> . 
> 
> ( perhaps people now have less problem with owl, and would be willing to reconsider that decision ) 
> 
> With that notation my above restrictions remain simple, otherwise I'd need to use the owl:union 
> construct I think. 
> 
> Here is the version that takes your above comments into account, and adds labels for Kingsley.
> 
> ~~~~~~~~~~~~~~~~~ ldp ontology as accepted by group before last week ~~~~~~~~~~~~~~~~~~~~~~ 
> 
> @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
> @prefix owl: <http://www.w3.org/2002/07/owl#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> @prefix skos: <http://www.w3.org/2004/02/skos/core#> .
> 
> ldp:Resource a rdfs:Class;
>  rdfs:label "ldp Resource";
>  rdfs:comment """
>     A HTTP resource whose state is represented in any way that conforms to the simple 
>     lifecycle patterns and conventions in section 5. Linked Data Platform Resources.
>  """ .
> 
> ldp:Container a rdfs:Class;
>  rdfs:label "ldp Container";
>  owl:subClassOf ldp:Resource;
>  rdfs:comment """
>    An LDPR representing a collection of member resources and/or contained documents 
>    (RDF Document [rdf11-concepts]  or information resources [WEBARCH]) that responds 
>    to client requests for creation, modification, and/or enumeration 
>    of its members and documents, and that conforms to the simple lifecycle patterns 
>    and conventions in section6. Linked Data Platform Containers.
>  """;
>  skos:editorialNote """
>    This used to be known as the ldp:IndirectContainer. A client successfully posting 
>  to an ldp:Container will create a new resource that is linked to this ldp:container 
>  via an ldp:contains relation, but may also create what are currently known as membership
>  properties.
>  """ . 
> 
> 
> ldp:DirectContainer a rdfs:Class;
>   owl:subClassOf ldp:Container;
>   rdfs:comment """
>   A LDPC that has the flexibility of choosing what form its membership triples take, 
>   and allows members to be any resources [WEBARCH], not only documents.
>   """ .
> 
> 
> ldp:BasicContainer a rdfs:Class;
>  rdfs:label "BasicContainer";
>  owl:subClassOf ldp:DirectContainer;
>  rdfs:comment """
>  A LDPC that uses a single pre-defined predicate to link to both its contained and 
>  member documents (information resources)
>  """ .
> 
> ldp:contains a rdf:Property;
>  rdfs:label "contains";
>  rdfs:domain ldp:Container;
>  rdfs:range ldp:Resource;
>  rdfs:comment """
>    the ldp:contains relation relates an ldp:Container to an information r
>  """ .
> 
> ldp:membershipResource a rdf:Property, owl:FunctionalProperty;
>  rdfs:label "membershipResource";
>  rdfs:domain ldp:Container;
>  rdfs:range  rdf:Resource .
> 
> ldp:hasMemberRelation a rdf:Property, owl:FunctionalProperty; 
>   rdfs:label "hasMemberRelation";
>  rdfs:domain ldp:Container;
>  rdfs:range  rdf:Property .
> 
> ldp:isMemberOfRelation a rdf:Property, owl:FunctionalProperty; 
>    rdfs:label "isMemerOfRelation"
>   rdfs:domain  ldp:Container; 
>   rdfs:range rdf:Property.
> 
> ldp:insertedContentRelation a rdf:Property, owl:FunctionalProperty; 
>   rdfs:label "insertedContentRelation";
>  rdfs:domain ldp:Container;
>  rdfs:range  rdf:Resource .
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
> 
> (Of course I just cut and pasted the text from the spec, and a better ontology would
> have to adapt these.) 
> 
> 
> Now, the question is whether this makes more sense than if we flipped the whole tree up-side-down. 
> This requires thinking in terms of expanded capabilities instead of restrictions. We start from the 
> simplest class and add to it as we go down. This gives us: 
> 
> Container (aka BasicContainer) 
>   | 
>   ------- DirectContainer (adds membershipResource, hasMemberRelation, isMemberOfRelation properties) 
>                | 
>                 ------- IndirectContainer (adds insertedContentRelation property) 
> 
> 
> 
> 
> I think you could express it this way in OWL (I'm really no OWL expect so I apologize if there are mistakes in there):
> 
> ~~~~~~~~~~~~~~~~~definition of the well known classes and relation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
> @prefix owl: <http://www.w3.org/2002/07/owl#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> @prefix skos: <http://www.w3.org/2004/02/skos/core#> .
> @prefix ldp: <http://www.w3.org/ns/ldp#> .
> 
> ldp:Resource a rdfs:Class;
>  rdfs:comment """
>     A HTTP resource whose state is represented in any way that conforms to the simple 
>     lifecycle patterns and conventions in section 5. Linked Data Platform Resources.
>  """ .
> 
> ldp:Container a rdfs:Class;
>  owl:subClassOf ldp:Resource;
>  rdfs:comment """
>  An LDPR representing a collection of contained documents 
>    (RDF Document [rdf11-concepts] or information resources [WEBARCH]) that responds 
>    to client requests for creation, modification, and/or enumeration 
>    of its documents, and that conforms to the simple lifecycle patterns 
>    and conventions in section6. Linked Data Platform Containers.
>  """;
>  skos:editorialNote """
>    This used to be known as the ldp:BasicContainer. A client successfully posting 
>    to an ldp:Container will create a new resource that is linked to this container
>    via an ldp:contains relation.
>  """ .
> 
> ldp:contains a rdf:Property;
>  rdfs:domain ldp:Container;
>  rdfs:range ldp:Resource;
>  rdfs:comment """
>    the ldp:contains relation relates an ldp:Container to an information resource.
>  """ . 
> 
> 
> ldp:DirectContainer a rdfs:Class;
>   owl:subClassOf ldp:Container;
>   rdfs:comment """
>   A Container that also manages a configurable list of members. A client successfully posting 
>   to an ldp:DirectContainer will create a new resource that is linked to this container
>   via an ldp:contains relation and will also add a membership triple of either form: 
>      membershipResource hasMemberRelation member 
>    or 
>      member isMemberOfRelation membershipResource. 
>    in which the member is the created resource.
> """ .
> 
> ldp:membershipResource a rdf:Property;
>  rdfs:domain ldp:DirectContainer;
>  rdfs:range  rdf:Resource .
> 
> ldp:hasMemberRelation a rdf:Property;
>  rdfs:domain ldp:DirectContainer;
>  rdfs:range  rdf:Property .
> 
> ldp:isMemberOfRelation a rdf:Property;
>  rdfs:domain ldp:DirectContainer;
>  rdfs:range  rdf:Property .
> 
> 
> ldp:IndirectContainer a rdfs:Class;
>  owl:subClassOf ldp:DirectContainer;
>  rdfs:comment """
>    A DirectContainer providing the additional flexibility to have non information resources 
>     [WEBARCH]) as members. A client successfully posting to an ldp:IndirectContainer will create 
>     a new resource that is linked to this container via an ldp:contains relation and will also add 
>     a membership triple of either form:
>     membershipResource hasMemberRelation member 
>    or 
>      member isMemberOfRelation membershipResource. 
>    in which the member is the object of the insertedContentRelation in the created resource.
>  """.
> 
> ldp:insertedContentRelation a rdf:Property;
>  rdfs:domain ldp:Container;
>  rdfs:range  rdf:Property .
> 
> As I said on the call I've managed to convince myself that both ways make sense. 
> 
> I think what's key is that if a client only knows how/wants to deal with BasicContainers, with this model they would simply ignore the whole membership stuff and be fine just looking at the containment (container ldp:contains resource). 
> 
> What we loose here is the notion we had with the ldp:BasicContainer, namely that a client that 
> POSTs to an  ldp:BasicContainer would know that  it does not have to worry about the membership 
> triples it might create. We loose this because in the above ontology if something is an 
> ldp:Container, it could also be an  ldp:IndirectContainer  or an ldp:DirectContainer. This 
> follows from the two statements: 
> 
>  { 
>    ldp:IndirectContainer owl:subClassOf ldp:DirectContainer . 
>    ldp:DirectContainer owl:subClassOf ldp:Container . 
>  } 
> 
> But following my arguments from the "volunteering to the army" counter use case - this means that a 
> client does not know  if by POSTing a simple foaf Profile it may not be volunteering its user to the 
> army too.  That is why a client can NOT "simply ignore the whole membership stuff".  After all the whole point 
> of these "membership predicates" is that they tell the client what other things are going to be done 
> if some content is POSTed to the LDPC. A client knowing this and POSTing is bound to know about those 
> consequenecs, and so is bound to them. A client is not bound to consequences that are not mentioned 
> explicitly - say if someone wires a LDPC so that it bombs a bank on POSTing there. 
> 
> Without paging it would be just a case of the client searching the graph for the membership properties. 
> With paging though, things get more complicated as a client would need to page through all the pages 
> to find out if those relations existed. 
> 
> I think that all that will happen is that if we accept this ontology, we'll end up wanting to define 
> a ldp:BasicContainer as follows 
> 
> ldp:BasicContainer 
>     owl:equivalentClass [ 
>            owl:intersection ( ldp:Container 
>                               [ owl:complementOf [ owl:unionOf ( ldp:IndirectContainer ldp:DirectContainer ) ]   
>                             ) 
>                          ] . 
> 
> This seems different from the ontology I suggested above in that here the ldp:BasicContainer 
> is non overlapping any members of the ldp:IndirectContainer or the ldp:DirectContainer. 
> In the ontology I suggested above ldp:DirectContainer was a subclass of ldp:DirectContainer - though 
> we did note that there was something a bit awkward about that too, as it made ldp:contains be a membership 
> triple only in the case where ldp:contains was a attached to a ldp:BasicContainer ! 
> 
> I'm not as sure that a client that only knows how/wants to deal with DirectContainers can deal with IndirectContainers as if they were DirectContainers. For one thing I would expect them to get confused about not finding the contained resources in the list of members. 
> 
> So, maybe the actual hierarchy we need is this: 
> Now, the question is whether this makes more sense than if we flipped the whole tree up-side-down. This requires thinking in terms of expanded capabilities instead of restrictions. We start from the simplest class and add to it as we go down. This gives us: 
> 
> Container (aka BasicContainer) 
>   | 
>   ------- IndirectContainer (adds membershipResource, hasMemberRelation, isMemberOfRelation, and insertedContentRelation properties) 
>                | 
>                 ------- DirectContainer (restricts insertedContentRelation property to ldp:MemberSubject) 
> 
> 
> I think this way round makes more sense 
> 
>  { 
>    ldp:IndirectContainer owl:subClassOf ldp:Container . 
>    ldp:DirectContainer owl:subClassOf ldp:IndirectContainer . 
>  } 
> 
> as it fits nicely the following owl rule 
> 
> ldp:DirectContainer 
>     owl:equivalentClass [ 
>         owl:intersection  ( 
>              ldp:IndirectContainer,
>             [ a owl:Restriction;
>               owl:onProperty ldp:insertedContentRelation; 
>                owl:hasValue ldp:MemberSubject
>             ] 
>          ) 
>     ] . 
> 
> But here we have this odd ldp:MemberSubject that is very ad-hoc, and that feels 
> like it was created just to make the class hierarchy work as shown. Things look less 
> ad-hoc if instead of ldp:MemberSubject we use owl:sameAs. Since owl:sameAs relates every 
> thing to itself then this should give the correct results. 
> 
> 
> I'd love for someone more fluent in this type of stuff to tell me which way is right. 
> 
> I hope the above helps. 
> 
> What does this lead us to? 
> 
> 1) The "volunteering for the army" counter use case brings to light that whatever we do we need a 
>    ldp:BasicContainer for which the following has to be true: 
> 
> ldp:BasicContainer owl:disjointWith [ owl:unionOf ( ldp:IndirectContainer ldp:DirectContainer ) ] . 
> 
> 2) we also want ldp:contains have as domain any of those containers 
> 
>    ldp:contains rdfs:domain ldp:Container . 
> 
> 3) what distinguihes the IndirectContainer and the DirectContainer are just the types of "membership triples" 
>    that posting to such a container will create. 
> 
> 
> 
> 
> Best regards.
> --
> Arnaud  Le Hors - Software Standards Architect - IBM Software Group
> 
> 
> Social Web Architect 
> http://bblfish.net/ 
> 

Social Web Architect
http://bblfish.net/

Received on Tuesday, 25 February 2014 18:08:53 UTC