I am trying to learn about semantic web technology to see if it can replace the current Relational model in an application. I am using protege to design the ontology and Jena for the application which will be hosted on Apache TomEE.
I have created a simplified ontology to explain the query I am having. In people.owl (turtle below) there is only one class People. The object property hasChild links a person individual to his children who are also Person. Now I want to know the order of the children for a person.
For example, individual john has two children, with anne being first and jack being second. So to the hasChild object property of john I have added sequence annotation. The sequence is a number which tells the order in which the child was born for that person. So hasChild anne has sequence 1 and hasChild jack has sequnce 2. Similarly jane's hasChild jack has sequence 1.
The SPARQL I have to write is to get all the children of a given Person's name in the order they were born. So if I query children of "John Doe", I should get
|sequence | childname|
| 1 | Anne Doe |
| 2 | Jack Doe |
Below is the Ontology in turtle format.
#prefix : <http://www.semanticweb.org/abhishek/ontologies/people#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix people: <http://www.semanticweb.org/abhishek/ontologies/people#> .
#base <http://www.semanticweb.org/abhishek/ontologies/people> .
<http://www.semanticweb.org/abhishek/ontologies/people> rdf:type owl:Ontology .
### http://www.semanticweb.org/abhishek/ontologies/people#sequence
people:sequence rdf:type owl:AnnotationProperty .
### http://www.semanticweb.org/abhishek/ontologies/people#hasChild
people:hasChild rdf:type owl:ObjectProperty .
### http://www.semanticweb.org/abhishek/ontologies/people#hasParent
people:hasParent rdf:type owl:ObjectProperty .
### http://www.semanticweb.org/abhishek/ontologies/people#hasSpouse
people:hasSpouse rdf:type owl:ObjectProperty .
### http://www.semanticweb.org/abhishek/ontologies/people#name
people:name rdf:type owl:DatatypeProperty .
### http://www.semanticweb.org/abhishek/ontologies/people#Person
people:Person rdf:type owl:Class .
### http://www.semanticweb.org/abhishek/ontologies/people#anne
people:anne rdf:type owl:NamedIndividual ,
people:Person ;
people:name "Anne Doe"^^xsd:string .
### http://www.semanticweb.org/abhishek/ontologies/people#jack
people:jack rdf:type owl:NamedIndividual ,
people:Person ;
people:name "Jack Doe"^^xsd:string .
### http://www.semanticweb.org/abhishek/ontologies/people#jane
people:jane rdf:type owl:NamedIndividual ,
people:Person ;
people:hasChild people:jack ;
people:hasSpouse people:john ;
people:name "Jane Doe"^^xsd:string .
[ rdf:type owl:Axiom ;
owl:annotatedSource people:jane ;
owl:annotatedProperty people:hasChild ;
owl:annotatedTarget people:jack ;
people:sequence "1"^^xsd:int
] .
### http://www.semanticweb.org/abhishek/ontologies/people#john
people:john rdf:type owl:NamedIndividual ,
people:Person ;
people:hasChild people:anne ,
people:jack ;
people:hasSpouse people:jane ;
people:name "John Doe"^^xsd:string .
[ rdf:type owl:Axiom ;
owl:annotatedSource people:john ;
owl:annotatedProperty people:hasChild ;
owl:annotatedTarget people:anne ;
people:sequence "1"^^xsd:int
] .
[ rdf:type owl:Axiom ;
owl:annotatedSource people:john ;
owl:annotatedProperty people:hasChild ;
owl:annotatedTarget people:jack ;
people:sequence "2"^^xsd:int
] .
### Generated by the OWL API (version 4.2.6.20160910-2108) https://github.com/owlcs/owlapi
I have the query till now:
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 xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX ppl: <http://www.semanticweb.org/abhishek/ontologies/people#>
SELECT ?sequence ?childname
WHERE { ?person rdf:type ppl:Person .
?person ppl:name ?name .
?person ppl:hasChild ?child .
#Get the ?sequence for the current child. sequence is annotated to hasChild.
?child ppl:name ?childname .
FILTER regex(?name, "John Doe") }
So I have two questions:
Should I change the ontology design to assign the sequence number to a child?
If the above approach is correct, how do I get the sequence for a child?
I posted the same question on Jena user list and got the recommendation to use RDF Collections. But from google search I found collections don't work with OWL (and hence Protege).
Thanks,
Abhishek
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 xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX ppl: <http://www.semanticweb.org/abhishek/ontologies/people#>
SELECT ?sequence ?childname
WHERE { ?person rdf:type ppl:Person .
?person ppl:name ?name .
?person ppl:hasChild ?child .
#Get the ?sequence for the current child. sequence is annotated to hasChild.
?child ppl:name ?childname .
?annotation owl:annotatedSource ?person ;
owl:annotatedTarget ?child ;
ppl:sequence ?sequence .
FILTER regex(?name, "John Doe") }
Related
Question: is this a correct query to select all used classes which are mandatory defined in <http://www.w3.org/2002/07/owl> or am I missing something?
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT DISTINCT ?class
FROM <http://www.w3.org/2002/07/owl>
WHERE {
{ ?class a owl:Class } UNION {?class a rdfs:Class} .
{ ?instance a ?class} .
}
Output:
1 owl:DatatypeProperty
2 owl:Class
3 owl:ObjectProperty
4 owl:Ontology
5 owl:AnnotationProperty
6 owl:OntologyProperty
I m trying to make a SPARQL query that returns the number of distinct values of each data property of a Turtle file. I would like to know what the name of each value is and how many time each were repeated. I have created a simple ontology to test:
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix uni: <http://www.example.com/university#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#base <http://www.example.com/university> .
<http://www.example.com/university> rdf:type owl:Ontology .
#################################################################
# Classes
#################################################################
### http://www.example.com/university#Lecturer
:Lecturer rdf:type owl:Class ;
rdfs:subClassOf :Person .
### http://www.example.com/university#Person
:Person rdf:type owl:Class .
#################################################################
# Individuals
#################################################################
### http://www.example.com/university#Lecturer1
:Lecturer1 rdf:type owl:NamedIndividual ,
:Lecturer ;
:first_name "John"^^xsd:string ;
:last_name "Coles"^^xsd:string ;
:staffID "234"^^xsd:int .
### http://www.example.com/university#Lecturer2
:Lecturer2 rdf:type owl:NamedIndividual ,
:Lecturer ;
:first_name "John"^^xsd:string ;
:last_name "Doe"^^xsd:string ;
:staffID "89387"^^xsd:int .
### http://www.example.com/university#lecturer3
:lecturer3 rdf:type owl:NamedIndividual ,
:Lecturer ;
:first_name "John"^^xsd:string ;
:last_name "Doe"^^xsd:string ;
:staffID "7658"^^xsd:int .
#################################################################
# General axioms
#################################################################
[ rdf:type owl:AllDisjointClasses ;
owl:members (
:Lecturer
)
] .
And this is the SPARQL query I m using:
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 xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX uni: <http://www.example.com/university#>
select distinct ?ind ?property ?value (count(?value) as ?noOfDistinctValues) where {
?ind rdf:type uni:Lecturer .
?ind ?property ?value .
?property a owl:DatatypeProperty
}
group by ?ind ?property ?value
and here is the results (The counts does not make sense to me) and I m sure there is something wrong with my query:
ind property value noOfDistinctValues
------------------------------------------------------------
lecturer2 staffID 89387 6
lecturer2 first_name John 8
lecturer2 last_name Doe 8
lecturer1 staffID 234 6
lecturer1 first_name John 8
lecturer1 last_name Coles 8
lecturer3 staffID 7658 6
lecturer3 first_name John 8
lecturer3 last_name Doe 8
What I am looking for:
property value noOfDistinctValues
------------------------------------------
staffID 89387 1
first_name John 3
last_name Doe 2
staffID 234 1
last_name Coles 1
staffID 7658 1
I m not even sure what is count that its being returned. I m also new to Ontology and SPARQL
I appreciate your help greatly
Thanks to #AKSW I was able to solve my problem. This worked:
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 xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX uni: <http://www.example.com/university#>
select ?property (str(?value) as ?valueLiteral) (str(count(distinct ?ind)) as
?noOfValueOccurrences)
where { ?ind rdf:type uni:Lecturer.
?ind ?property ?value.
?property a owl:DatatypeProperty .}
group by ?property ?value
order by ?property
Here's my query:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX : <http://dbpedia.org/resource/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT DISTINCT ?resource ?parentOrSpouse
WHERE {
?resource a dbo:Royalty ;
rdfs:label ?label ;
dbo:parent ?parent ;
dbo:birthDate ?bd ;
dbo:birthPlace ?bp .
?bp dbo:isPartOf :England .
FILTER(?bd < '1900-01-01'^^xsd:dateTime) .
FILTER(?bd > '1800-01-01'^^xsd:dateTime) .
FILTER(LANGMATCHES(LANG(?label), 'en')) .
{ ?resource dbo:parent ?parentOrSpouse } UNION { ?resource dbo:spouse ?parentOrSpouse }
?parentOrSpouse dbo:birthPlace ?psbp .
?psbp dbo:isPartOf :England .
}
ORDER BY(?bd)
This searches for all royals born in England between 1800 and 1900 that have a spouse or parent that is born in England.
Result
In the result list I get
http://dbpedia.org/page/George_V with http://dbpedia.org/page/Mary_of_Teck listed as a spouse, but not Mary_of_Teck listed while George is clearly born in England.
Why is Mary disappearing? There are a lot of other people disappearing that should clearly be on the list when I look at the data.
So the solution to Mary not showing up is to use dbo:parent|dbo:spouse/dbo:wikiPageRedirects?, since George is refered by Mary via a redirect.
The other problem was dbo:birthPlace/dbo:location?/dbo:isPartOf dbr:England throwing an error that is probably(?) related to a bug in the compiler. Using ?parentOrSpouse dbo:birthPlace|dbo:birthPlace/dbo:location/dbo:isPartOf :England . instead seems to work fine.
Credit goes to #AKSW.
Using the following sample triples:
#prefix : <http://www.me.org/me_schema#> .
#prefix dc: <http://purl.org/dc#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix skos: <http://www.w3.org/2004/02/skos/core#> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://www.me.org/content/me_schema>
rdf:type owl:Ontology ;
owl:imports <http://www.w3.org/2004/02/skos/core> ;
.
:a
rdf:type owl:ObjectProperty ;
rdfs:label "A" ;
rdfs:subPropertyOf :b ;
.
:b
rdf:type owl:ObjectProperty ;
rdfs:label "B" ;
rdfs:subPropertyOf :c ;
.
:c
rdfs:label "C"^^xsd:string ;
.
This query returns two rows as expected (both b and c in column ?o):
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select *
from <test>
where
{
?s rdfs:label 'A' .
?s rdfs:subPropertyOf+ ?o
}
However, I expect the following to return 1 row but it returns empty result. Tested in query console:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select *
from <test>
where
{
?s rdfs:label 'A' .
?s rdfs:subPropertyOf+ <http://www.me.org/me_schema#c>
}
I expect that it returns one row for "a". Is this a bug or am I missing something obvious?
I tried a similar query with DBPedia and it appears to return data as I expected. For example, the following query returns two rows for "star" although neither are direct subClassOf owl:Thing.
select *
where
{
?s rdfs:label "star"#en .
?s rdfs:subClassOf+ owl:Thing
} LIMIT 100
I came up with the following work around in case anyone is having same problem:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select *
from <test>
where
{
?s rdfs:label 'A' .
?s rdfs:subPropertyOf ?s2 .
?s2 rdfs:subPropertyOf* <http://www.me.org/me_schema#c>
}
(I would put this in a comment, but I don't have the reputation needed to do that.)
I just tried your null-result example on MarkLogic 8.0-3, and I do indeed get [{"s":"<http://www.me.org/me_schema#a>"}], as you expected. Are you using an earlier version of MarkLogic (you can see the version in the upper-left corner of localhost:8001)?
To verify this, I went to the MarkLogic query console at localhost:8000/qconsole/, set the 'Content Source' to my database (with the triple index turned on) changed the query type to 'SPARQL Update', and entered this SPARQL insert code:
PREFIX : <http://www.me.org/me_schema#>
prefix dc: <http://purl.org/dc#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
INSERT DATA { GRAPH <test> {
<http://www.me.org/content/me_schema> rdf:type owl:Ontology .
<http://www.me.org/content/me_schema> owl:imports <http://www.w3.org/2004/02/skos/core> .
:a rdf:type owl:ObjectProperty .
:a rdfs:label "A" .
:a rdfs:subPropertyOf :b .
:b rdf:type owl:ObjectProperty .
:b rdfs:label "B" .
:b rdfs:subPropertyOf :c .
:c rdfs:label "C"^^xsd:string .
}}
I then opened a new tab within the Query Console, set the Query Type to "SPARQL Query", and ran your exact query:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select *
from <test>
where
{
?s rdfs:label 'A' .
?s rdfs:subPropertyOf+ <http://www.me.org/me_schema#c>
}
If you are using an earlier version of MarkLogic, try updating to the latest on the MarkLogic download page.
I have an ontology that defines a new data type as pattern restriction on string type. This data type is then used as a property range restriction. Then a class is defined as a restriction on this property:
#prefix : <http://test.com/prop#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#base <http://test.com/prop> .
<http://test.com/prop> rdf:type owl:Ontology .
:MyType rdf:type rdfs:Datatype ;
owl:equivalentClass [ rdf:type rdfs:Datatype ;
owl:onDatatype xsd:string ;
owl:withRestrictions ( [ xsd:pattern "[a-zA-Z]*"
]
)
] .
# Properties
:hasProperty rdf:type owl:ObjectProperty .
:hasValue rdf:type owl:DatatypeProperty .
# Classes
:BaseClass rdf:type owl:Class .
:BaseProperty rdf:type owl:Class .
:MyClass rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Class ;
owl:intersectionOf ( :BaseClass
[ rdf:type owl:Restriction ;
owl:onProperty :hasProperty ;
owl:someValuesFrom :MyProperty
]
)
] ;
rdfs:subClassOf :BaseClass .
:MyProperty rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Class ;
owl:intersectionOf ( :BaseProperty
[ rdf:type owl:Restriction ;
owl:onProperty :hasValue ;
owl:someValuesFrom :MyType
]
)
] ;
rdfs:subClassOf :BaseProperty .
# Individuals
:Ind1 rdf:type :BaseClass ,
owl:NamedIndividual ;
:hasProperty :Prop1 .
:Prop1 rdf:type :BaseProperty ,
owl:NamedIndividual ;
:hasValue "Maier" .
The Protege crashes while classifying this ontology with Pellet reasoner:
UnsupportedOperationException: null
com.clarkparsia.pellet.datatypes.types.text.RestrictedTextDatatype.applyConstrainingFacet(RestrictedTextDatatype.java:93)
com.clarkparsia.pellet.datatypes.DatatypeReasonerImpl.getDataRange(DatatypeReasonerImpl.java:440)
The FaCT++ reasoner failed with exception:
ReasonerInternalException: Unsupported datatype 'http://test.com/prop#MyType'
uk.ac.manchester.cs.factplusplus.FaCTPlusPlus.getBuiltInDataType(Native Method)
The Pellet seems only to have trouble with the pattern as a restriction. The FaCT++ seems to have trouble with a user defined datatype.
Do I have errors in the ontology or the reasoners are not able to classify such pattern restriction?
The current version of FaCT++ does not support user-defined datatypes. So the report from FaCT++ is correct.
Pellet should support user-defined datatypes, but your definition is incorrect. The owl:equivalentClass construction is a) from the obsolete OWL 1 syntax, that doesn't support datatype definitions, and b) is only valid for classes, not datatypes. I would suggest to use OWL 2 syntax http://www.w3.org/TR/2012/REC-owl2-syntax-20121211/ in your datatype definition.