owl:Thing
is the class that contains individuals (things).
In OWL Direct (DL-Based) Semantics, this excludes classes and properties.
In OWL RDF Based semantics, this includes everything, where classes and properties are also viewed as individuals (and thus owl:Thing
has the same extension as rdfs:Resource
).
rdfs:Class
is the (RDFS) class of classes. Any member is itself a class.
foaf:Group
being a subclass of owl:Thing
means that any instance of foaf:Group
is also an owl:Thing
. In Direct Semantics, it means that the foaf:Group
instances are individuals. In RDF-based semantics, foaf:Group
being a subclass of owl:Thing
means pretty much nothing—instances can be classes, properties or individuals. To define a group, I use:
ex:URQ rdf:type foaf:Group .
...where URQ is the research unit I "work" in. To give a member of the group, I say:
ex:URQ foaf:member ex:Aidan .
I can also use the property foaf:membershipClass
to relate a foaf:Group
and a class of individuals that constitute the group (as definable through standard RDFS/OWL machinery).
ex:URQ foaf:membershipClass [ owl:oneOf (ex:Aidan, ex:Juergen, ... ex:Axel ) ] .
or
ex:URQ foaf:membershipClass [ owl:hasValue ex:Axel . owl:onProperty ex:supervisor ] .
However, FOAF don't define the machinery to infer that an instance of the respective membership-class is a member of the respective FOAF group (e.g., ex:Aidan ex:supervisor ex:Axel
will not directly infer ex:Aidan foaf:member ex:URQ
through RDFS/OWL semantics).
dcterms:AgentClass
being a subclass of rdfs:Class
means that any instance of the former is also a member of rdfs:Class
. In particular, this indicates a certain kind of intended usage which gets rid of the indirection used in FOAF. Let's say that we have a class
ex:URQ rdf:type dcterms:AgentClass .
Now, ex:URQ
is itself class. So, then I can give an instance of ex:URQ
as follows:
ex:Aidan rdf:type ex:URQ .
I use the standard RDF/RDFS machinery for doing this. I can then define ex:URQ
as if it were a class. If I want to define "sub-groups", I can use:
ex:URQ rdfs:subClassOf ex:DERI .
where DERI is my institute. Through standard RDF semantics, I can then infer that:
ex:Aidan rdf:type ex:DERI .
Or, taking an example as above, I can say that:
ex:URQ owl:equivalentClass [ owl:hasValue ex:Axel . owl:onProperty ex:supervisor ] .
Now, OWL semantics will infer ex:Aidan ex:supervisor ex:Axel
from ex:Aidan rdf:type ex:URQ
and vice-versa.
Which you choose is up to you, but hopefully you've a better idea of how both work.
EDIT: Also worth noting that dcterms:AgentClass
is not defined to be a subclass of rdf:Class
, though it's hinted at by the fact that the dcterms:Agent
class is of type
dcterms:AgentClass
.
EDIT2: From your comment, you want to create a class ex:Audience
to represent the general notion of an audience as a group of people (I guess?). You suggest:
ex:Audience rdfs:subClassOf foaf:Group .
seems sound enough in that you're just saying that each instance of ex:Audience
is also an instance of foaf:Group
which intuitively makes sense. You also suggest:
ex:Audience rdf:type dcterms:AgentClass .
which doesn't seem quite right. To me, a specific audience would be a dcterms:AgentClass
, so again I would say instead:
ex:Audience rdfs:subClassOf dcterms:AgentClass .
now, every instance of ex:Audience
is an instance of dcterms:AgentClass
, and so, (informally... as DC intends) each audience is itself a class, and a subclass of dc:Agent
.
If you want to stay compatible with both, the problem then comes when you want to start declaring instances of audience and who was in them, which requires a duplication of effort.
ex:SomeAudience rdf:type ex:Audience .
ex:Person1 rdf:type ex:SomeAudience .
ex:SomeAudience foaf:member ex:Person1 .
Easiest way around this would be to define properties ex:hasAudienceMember
and ex:inAudience
and say the following:
ex:hasAudienceMember rdfs:domain ex:Audience .
ex:hasAudienceMember rdfs:range foaf:Person .
ex:hasAudienceMember rdfs:subPropertyOf foaf:member .
ex:hasAudienceMember owl:inverseOf ex:inAudience .
ex:inAudience rdfs:subPropertyOf rdf:type .
Now given the above, and this from before:
ex:Audience rdfs:subClassOf foaf:Group .
ex:Audience rdfs:subClassOf dcterms:AgentClass .
We can state members of the audience as follows:
ex:Person1 ex:inAudience ex:SomeAudience .
Which will give us:
ex:Person1 rdf:type ex:SomeAudience .
ex:Person1 rdf:type foaf:Person .
ex:Person1 rdf:type foaf:Agent . # inc. FOAF
ex:Person1 rdf:type dc:Agent . # inc. FOAF
ex:SomeAudience rdf:type dcterms:AgentClass .
ex:SomeAudience rdf:type foaf:Group .
ex:SomeAudience ex:hasAudienceMember ex:Person1 .
ex:SomeAudience foaf:member ex:Person1 .
You can go a little further as you see fit. To support foaf:membershipClass
with the above modelling, you could use:
ex:Audience rdfs:subClassOf [ owl:onProperty foaf:membershipClass ; owl:hasSelf true .] .
which is a little weird, but says that each instance of audience has itself as a foaf:membershipClass
. (TBH, I wouldn't bother... you'll end up with boring reflexive foaf:membershipClass
triples whose semantics will buy you nothing at the moment.)
To say that all audiences are subclasses of foaf:Person
, you could say something like:
ex:Audience rdfs:subClassOf [ owl:onProperty rdfs:subClassOf ; owl:hasValue foaf:Person .]
again, I wouldn't be too bothered... up to you.
Finally, AFAIK some parts of the above definitions are OWL Full, in that they have use the restricted vocabulary (?) in atypical positions (e.g., rdfs:subClassOf
, rdf:type
outside of the predicate position). You probably won't need all that stuff, or even to extend both FOAF and DC, but you can pick, choose and tweak as you see fit.
[Man, anything to avoid working on my PhD :)]