- 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