- From: Arnaud Le Hors <lehors@us.ibm.com>
- Date: Tue, 25 Feb 2014 09:50:35 -0800
- To: "henry.story@bblfish.net" <henry.story@bblfish.net>
- Cc: "Linked Data Platform (LDP) Working Group" <public-ldp-wg@w3.org>
- Message-ID: <OF1D167367.6DDE4836-ON88257C8A.005F81EB-88257C8A.0062048B@us.ibm.com>
[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. 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? 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/
Received on Tuesday, 25 February 2014 17:51:07 UTC