How to make property of property in Protégé? - semantic-web

I have a following problem to model in OWL using Protégé:
Multiple Songs could be performed in different Performances. Each Song could be arranged by different Arranger in different Performance.
I already know how to relate a Song to a Performance using object property. Now, how to map a Song-Performance pair to an Arranger? (In relational database, I would call this as a "descriptive attribute" of a many-to-many Song-Performance relationship).
I know that I could use an annotation to an object property, but I would like to be able to infer something from this property. (For example: what Song has an Arranger arranged, and in which Performance?) As far as I know, I am not able to do inference from an annotation.

It's not necessary to add properties of properties to model this scenario, although a property is an object (a uri) and therefore can include any property, not just annotation properties. rdfs:subPropertyOf is a good example. Statement reification isn't necessary either. It's a matter of creating an object that holds information about the song and performance.
Here is a model that represents an Arranger's relationship to a Song-Performance:
ex:SongPerformance a owl:Class .
ex:Arranger a owl:Class .
ex:arranged rdfs:domain ex:Arranger ;
rdfs:range ex:SongPerformance .
ex:songPerformed rdfs:domain ex:SongPerformance ;
rdfs:range ex:Arranger .
ex:performedIn rdfs:domain ex:SongPerformance ;
rdfs:range ex:Arranger .
Given this list, an example instance is:
ex:Arranger-1 ex:arranged ex:SP1 .
ex:SP1 ex:performedIn ex:Performance_1 ;
ex:songPerformed ex:Song1 .
Then you can find which songs has an arranger arranged in a given performance through the following SPARQl query:
SELECT ?arranger ?song ?performance
WHERE {
?arranger a ex:Arranger ;
ex:arranged ?sp .
?sp ex:songPerformed ?song ;
ex:performedIn ?performance .
}

Related

Set default value to property with SPIN

I am new to SPIN. I wonder if it makes sense to use it for the following purpose. Say I have the following class hierarchy:
ex:Vehicle
ex:Car
ex:Sedan
Some classes have the property owl:equivalenClass set to some value, for example:
ex:Vehicle
owl:equivalentClass wd:MeanOfTransportation
ex:Sedan
owl:equivalentClass wd:Sedan
In the case owl:equivalentClass is not set to a value, it should take the value of it's parent class. In the above example:
ex:Car
owl:equivalentClass wd:MeanOfTransportation
Can this be accomplished with SPIN, in my case using TopBraid?
It makes sense to use SPIN for these purposes, because SPIN inference engine is the only inference engine available in TopBraid Composer Free Edition.
In other TopBraid Composer editions, the appropiateness, as well as the result obtained, may vary depending on your inferencing configuration (Inferences > Configure Inferencing).
The rule is:
rdfs:Class spin:rule [
rdf:type sp:Construct ;
sp:text """
CONSTRUCT {
?this owl:equivalentClass ?equivalentClass .
}
WHERE {
?this rdfs:subClassOf ?superClass .
?superClass owl:equivalentClass|^owl:equivalentClass ?equivalentClass .
FILTER NOT EXISTS {
?this owl:equivalentClass|^owl:equivalentClass [] .
}
} """
] .
Please note that this SPIN rule is attached to rdfs:Class : a class that instances all these ex:Car, ex:Vehicle are.
?this is a special variable that refers to the "current" instance of this class.
It seems that the spl:InferDefaultValue SPIN template can not be used in your case, because spl:InferDefaultValue doesn't accept SPARQL variables as its spl:defaultValue argument.

Sub-group and Super-group (Class/Subclass) relation in OWL

I need some help regarding OWL syntax. I have a synthetic population class called 'Person'. Person contains population information, and PersonWithinAdminRegion is another class represents subgroup of person class. For example 'Person' class contains information about all persons in the USA. FloridaPerson or MiamiPerson can be an example of PersonWithinAdminRegion. Basically, PersonWithinAdminRegion is a subgroup of supergroup Person. It not sub-class because sub-class inherits properties of super-class and add some more. It is not the case in my situation. My question is how to show sub-group of a super-group in OWL syntax?
Person a owl:Class.
PersonWithinAdminRegion ? ?
There is no inheritance in OWL. Therefore no properties are inherited by subclasses. The subclass hierarchy is a type of subsumption hierarchy with only one semantic: a member of a subclass is a member of the (super) class. An example:
:Person a owl:Class .
:PersonWithinAdminRegion a owl:Class .
:PersonWithinAdminRegion rdfs:subClassOf :Person .
:FloridaPerson a :PersonWithinAdminRegion .
From this, one can infer:
:FloridaPerson a :Person .
And that is all. No other properties or values will be inferred. E.g. RDFS and OWL semantics are more like set theory (classification) than object-oriented class definition.
So it seems the above will get you the semantics that you want. If you wanted to go deeper into the subsumption hierarchy, let's say:
:PersonInFloridaRegion rdfs:subClassOf :PersonWithinAdminRegion .
:p1 a :PersonInFloridaRegion .
...then you will be able to infer:
:p1 a :PersonWithinAdminRegion .
:p1 a :Person .
...and so on.
Even though I am still not sure of your modelling perspective, and whether there are some properties that Person has, but PersonWithinAdminRegion, doesn't. Here is an idea for solution.
You can create a generic class Person, and a subclass of it USAPerson, then a PersonWithinAdminRegion, which is a subclass of Persons as well and a sibling of PersonWithinAdminRegion. Thus:
Both USAPerosn and PersonWithinAdminRegion are Person;
Persons will include USAPersons, so when make a subset of Person you can still have the control over USAPerosn;
PersonWithinAdminRegion can still not have properties that USAPerson have.
Person a owl:Class
USAPerson a owl:Class
PersonWithinAdminRegion a owl:Class
USAPerson rdfs:subClassOf Peron
PersonWithinAdminRegion rdfs:subClassOf Peron
Hope this helps.

in turtle or RDF can I add a predicate/object on all subjects that match a criteria?

I am doing some experiments with importing triples formulated in the turtle language
within the openrdf-workbench webapp in Tomcat, which has incorporated a SPARQL endpoint.
I wonder if with turtle, or, generally, in RDF / RDFS is it possible to add a certain predicate/object declaration on all (implicit) subjects conditionally to the existence of another predicate/object.
For example, if I have the following triples defined:
foo:a foo:b foo:c
foo:d foo:b foo:c
foo:e foo:b foo:c
foo:f foo:b foo:c
I would like to automatically add the following predicate/subject to all subjects that match predicate=foo:b and object=foo:c:
(implicit subject) foo:g foo:h
in order to automatically produce the following triples:
foo:a foo:g foo:h
foo:d foo:g foo:h
foo:e foo:g foo:h
foo:f foo:g foo:h
Is this possible?
Alternatively: is there any way to define some triples in order to enable SPARQL to find foo:a/d/e/f when queried for subjects that have foo:g foo:h as predicate/object?
Part 1 - Creating additional information
The first part of your question can be solved in one of two ways:
Using Inference
Using SPARQL Update
Inferencing
Inference is a technique whereby you define rules that infer additional triple based on your existing triples. You typically either use a pre-defined set of rules or use your own custom rules. I think Sesame only supports pre-defined rule sets out of the box so you may want to take a look at OWLIM which is an alternative back end that can be used with Sesame and has much more customisable rules AFAIK.
Inferencing can typically be applied in two ways, one where you only store the rules and you compute the additional information every time a rule fires and another where you pre-compute all the additional information and add it to your database. Which you will want to use depends on how you intend to use your system and there are performance trade offs involved. I'm not going into detail because that's really a whole other question - see Forward vs Backward Chaining for some discussion
SPARQL Update
Alternatively if your rules are relatively simple and you are OK with pre-computing the extra information and adding it to your database you can write SPARQL Updates to do this e.g.
PREFIX foo: <http://example.org/foo#>
INSERT
{
?x foo:g foo:h .
}
WHERE
{
?x foo:b foo:c .
}
Part 2 - Querying the Data
I am guessing you are fairly new to SPARQL because from what you've described this sounds trivial to me.
If I wanted to find all subjects which had the predicate foo:g and the object foo:h I would simply write the following:
PREFIX foo: <http://example.org/foo#>
SELECT ?x
WHERE
{
?x foo:g foo:h .
}
You can do this type of inference using OWL with an axiom of the form
p value a &sqsubseteq; q value b
which says that if something has a as a value for property p, then it also has b as a value for property q. As an example, here's an ontology with four individuals (a, b, c, d), two object properties (p, q), and the axiom (p value c &sqsubseteq; q value d).
#prefix : <http://example.org/add-predicate-object#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<http://example.org/add-predicate-object> a owl:Ontology .
:p a owl:ObjectProperty .
:q a owl:ObjectProperty .
[ a owl:Restriction ;
owl:onProperty :p ;
owl:hasValue :c ;
rdfs:subClassOf [ a owl:Restriction ;
owl:onProperty :q ;
owl:hasValue :d ] . ] .
:a a owl:Thing, owl:NamedIndividual ; :p :c .
:b a owl:Thing, owl:NamedIndividual ; :p :c .
:c a owl:Thing, owl:NamedIndividual .
:d a owl:Thing, owl:NamedIndividual .
In Protégé, the axiom looks like this:
You can enable a reasoner and query for instances of q value d and see:
or you can browse to individuals and see the results:

Limit a SPARQL query to one dataset

I'm working with the following SPARQL query, which is an example on the web-based end of my institution's SPARQL endpoint;
SELECT ?building_number ?name ?occupants WHERE {
?site a org:Site ;
rdfs:label "Highfield Campus" .
?building spacerel:within ?site ;
skos:notation ?building_number ;
rdfs:label ?name .
OPTIONAL {
?building soton:buildingOccupants ?occ .
?occ rdfs:label ?occupants .
} .
} ORDER BY ?name
The problem is that as well as getting data from 'Buildings and Places', the Dataset I'm interested in, and would expect the example to use, it also gets data from the 'Facilities and Equipment' dataset, which isn't relevant. You should see this if you follow the link.
I suspect the example may pre-date the addition of the Facilities and Equipment dataset, but even with the research I've done into SPARQL, I can't see a clear way to define which datasets to include.
Can anyone recommend a starting point to limit it to just show 'Buildings', or, more specifically, results from the 'Buildings and Places' dataset.
Thanks
First things first, you really need to use SELECT DISTINCT, as otherwise you'll get repeated results.
To answer your question, you can use GRAPH { ... } to filter certain parts of a SPARQL query to only match data from a specific dataset. This only works if the SPARQL endpoint is divided up into GRAPHs (this one is). The solution you asked for isn't the best choice, as it assumes that things within sites in the 'places' dataset will always be resticted to buildings... That's risky -- as it might end up containing trees and signposts at some time in the future.
Step one is to just find out what graphs are in play:
SELECT DISTINCT ?g1 ?building_number ?name ?occupants WHERE {
?site a org:Site ;
rdfs:label "Highfield Campus" .
GRAPH ?g1 { ?building spacerel:within ?site ;
skos:notation ?building_number ;
rdfs:label ?name .
}
OPTIONAL {
?building soton:buildingOccupants ?occ .
?occ rdfs:label ?occupants .
} .
} ORDER BY ?name
Try it here: http://is.gd/WdRAGX
From this you can see that http://id.southampton.ac.uk/dataset/places/latest and http://id.southampton.ac.uk/dataset/places/facilities are the two relevant ones.
To only look for things 'within' a site according to the "places" graph, use:
SELECT DISTINCT ?building_number ?name ?occupants WHERE {
?site a org:Site ;
rdfs:label "Highfield Campus" .
GRAPH <http://id.southampton.ac.uk/dataset/places/latest> {
?building spacerel:within ?site ;
skos:notation ?building_number ;
rdfs:label ?name .
}
OPTIONAL {
?building soton:buildingOccupants ?occ .
?occ rdfs:label ?occupants .
} .
} ORDER BY ?name
Alternate solutions:
Using rdf:type
Above I've answered your question, but it's not the answer to your problem. This solution is more semantic as it actually says 'only give me buildings within the campus' which is what you really mean.
Instead of filtering by graph, which is not very 'semantic' you could also restrict ?building to be of class 'building' which research facilities are not. They are still sometimes listed as 'within' a site. Usually when the uni has only published what campus they are on but not which building.
?building a rooms:Building
Using FILTER
In extreme cases you may not have data in different GRAPHS and there may not be an elegant relationship to use to filter your results. In this case you can use a FILTER and turn the building URI into a string and use a regular expression to match acceptable ones:
FILTER regex(str(?building), "^http://id.southampton.ac.uk/building/")
This is bar far the worst option and don't use it if you have to.
Belt and Braces
You can use any of these restictions together and a combination of restricting the GRAPH plus ensuring that all ?buildings really are buildings would be my recommended solution.

OWL inferencing question

I am using the Jena semantic web framework version 2.6.3. I have code that creates a model with owl inferencing and then adds the following triples:
_:bnode-3 rdf:type owl:Restriction .
_:bnode-3 owl:onProperty :offspringOf .
_:bnode-3 owl:someValuesFrom :Person .
_:bnode-3 rdfs:subClassOf :Person .
_:bnode-3 is supposed to be a restriction class which, for example, would contain :joe if :bob is a :Person and the following triple were asserted:
:joe :offspringOf :bob .
Then, since the restriction class is a subclass of Person, :joe would also be a person.
And, in fact, this works. What's confusing to me is that after I assert just the 4 triples at the top of this post, the inferencer creates a blank node which is a Person. In other words, the following triple is now in the model:
_:b0 rdf:type :Person
I don't understand why it would do this. Any help in understanding this would be greatly appreciated.
Thanks.
Kent.
I am not sure why the inferencer would do this as I am not an OWL expert - have you tried asking your question on the jena-users lists?
They will usually answer you pretty promptly and they should know why you get the observed behaviour.
Note
I reformatted your question as your code samples were somewhat confusing - please don't write out Triples as [ex:subject ex:predicate ex:object] since it looks rather like some syntactic sugar in Turtle/N3/SPARQL which would result in additional Blank Nodes being created beyond just those you intended