Inferencing in Protege does not infer types based on `subClassOf` - type-inference

We are developing an ontology, where we need to infer the type of each node, based on some mappings defined in # Test mapping file section. We tried rdfs:subClassOf, as in the below snippet, but it doesn't infer types. Ideally we want to infer Person 1 and Person 2 to NodeTypePerson, also sydney and canberra to NodeTypeCity.
I tried owl:equivalentClass instead but no luck. rdfs:range and rdfs:domain infer types as expected, but having trouble inferring with rdfs:subClassOf. Any advice is highly appreciated.
UPDATE:
owl:equivalentClass works in Protege. (If infers the type). But can't we use rdfs:subClassOf similarly? Actually I want a way to get this done with RDFS inferencing, where owl:equivalentClass doesn't work obviously. Is there any other RDFS property we can use here?
# baseURI: http://www.Test-app.com/ns
#prefix : <http://www.Test-app.com/ns#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#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 acl: <http://www.w3.org/ns/auth/acl#> .
#prefix cc: <http://creativecommons.org/ns#> .
#prefix cert: <http://www.w3.org/ns/auth/cert#> .
#prefix csvw: <http://www.w3.org/ns/csvw#> .
#prefix dc: <http://purl.org/dc/terms/> .
#prefix dcam: <http://purl.org/dc/dcam/> .
#prefix dcat: <http://www.w3.org/ns/dcat#> .
#prefix dctype: <http://purl.org/dc/dcmitype/> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
#prefix ldp: <http://www.w3.org/ns/ldp#> .
#prefix posixstat: <http://www.w3.org/ns/posix/stat#> .
#prefix schema: <https://schema.org/> .
#prefix shacl: <http://www.w3.org/ns/shacl#> .
#prefix skos: <http://www.w3.org/2004/02/skos/core#> .
#prefix skosxl: <http://www.w3.org/2008/05/skos-xl#> .
#prefix solid: <http://www.w3.org/ns/solid/terms#> .
#prefix swapdoc: <http://www.w3.org/2000/10/swap/pim/doc#> .
#prefix ui: <http://www.w3.org/ns/ui#> .
#prefix vann: <http://purl.org/vocab/vann/> .
#prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
#prefix vs: <http://www.w3.org/2003/06/sw-vocab-status/ns#> .
#prefix ws: <http://www.w3.org/ns/pim/space#> .
#base <http://www.Test-app.com/ns> .
<http://www.Test-app.com/ns>
rdf:type owl:Ontology ;
dc:title "Test Ontology"#en ;
owl:versionIRI <http://www.Test-app.com/ns/0.1> .
# Test mapping file
#prefix test: <http://www.Test-app.com/ns#> .
:Person
a rdfs:Class ;
owl:equivalentClass :NodeTypePerson .
:locatedNear
a rdf:Property ;
rdfs:subClassOf :NodeCustomAttribute ;
rdfs:label "Located Near" .
:Location
a rdfs:Class ;
rdfs:label "Location" ;
rdfs:subClassOf :NodeTypeCity ;
rdfs:comment "This represents a geolocation." .
:City
a rdfs:Class ;
rdfs:label "City" ;
rdfs:comment "This represents a city." ;
rdfs:subClassOf :Location .
# Some graph instances data
:sydney
a :City ;
rdfs:label "Sydney" ;
rdfs:comment "Australia's largest city." .
:canberra
a :City ;
rdfs:label "Canberra" ;
rdfs:comment "Australia's national capital." .
:person1
a :Person ;
rdfs:label "Person 1" ;
rdfs:comment "First vertex." ;
:locatedNear :sydney .
:person2
a :Person ;
rdfs:label "Person 2" ;
rdfs:comment "Second vertex." ;
:locatedNear :canberra .
# Types
:NodeTypePerson
rdf:type rdfs:Class ;
rdfs:label "NodeTypePerson" ;
rdfs:comment "" ;
vs:term_status "stable" ;
rdfs:isDefinedBy <http://www.Test-app.com/ns> .
:NodeTypeCity
rdf:type rdfs:Class ;
rdfs:label "NodeTypeCity" ;
rdfs:comment "" ;
vs:term_status "stable" ;
rdfs:isDefinedBy <http://www.Test-app.com/ns> .```

Related

How do I deduce all of a person's descendants?

Here is my example.owl:
#prefix : <#> .
#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#> .
#base <http://ex.org> .
<http://ex.org> rdf:type owl:Ontology .
:hasChild rdf:type owl:ObjectProperty ;
rdfs:subPropertyOf :hasDescendant .
:hasDaughter rdf:type owl:ObjectProperty ;
rdfs:subPropertyOf :hasChild ;
owl:propertyDisjointWith :hasSon .
:hasDescendant rdf:type owl:ObjectProperty .
:hasSon rdf:type owl:ObjectProperty ;
rdfs:subPropertyOf :hasChild .
:Person rdf:type owl:Class .
:Bob rdf:type owl:NamedIndividual , :Person ;
:hasDaughter :Mary ;
:hasSon :John .
:LittleBoy rdf:type owl:NamedIndividual , :Person .
:LittleGirl rdf:type owl:NamedIndividual , :Person .
:John rdf:type owl:NamedIndividual , :Person ;
:hasSon :LittleBoy .
:Mary rdf:type owl:NamedIndividual , :Person ;
:hasDaughter :LittleGirl .
I want to get all of a Bob's descendants or Bob's child by a Sparql query,
How do I write this SPARQL statement?
Thanks for help.

Validating that every subject has a type of class

I have the following Data & Shape Graph.
#prefix hr: <http://learningsparql.com/ns/humanResources#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix schema: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
hr:Employee a rdfs:Class .
hr:BadThree rdfs:comment "some comment about missing" .
hr:BadTwo a hr:BadOne .
hr:YetAnother a hr:Another .
hr:YetAnotherName a hr:AnotherName .
hr:Another a hr:Employee .
hr:AnotherName a hr:name .
hr:BadOne a hr:Dangling .
hr:name a rdf:Property .
schema:SchemaShape
a sh:NodeShape ;
sh:target [
a sh:SPARQLTarget ;
sh:prefixes hr: ;
sh:select """
SELECT ?this
WHERE {
?this ?p ?o .
}
""" ;
] ;
sh:property [
sh:path rdf:type ;
sh:nodeKind sh:IRI ;
sh:hasValue rdfs:Class
] ;
.
Using pySHACL:
import rdflib
from pyshacl import validate
full_graph = open( "/Users/jamesh/jigsaw/shacl_work/data_graph.ttl", "r" ).read()
g = rdflib.Graph().parse( data = full_graph, format = 'turtle' )
report = validate( g, inference='rdfs', abort_on_error = False, meta_shacl = False, debug = False )
print( report[2] )
What I think should happen is the SPARQL based target should select every subject in the Data Graph and then verify that there is a path of rdf:type which has a value of rdfs:Class.
I get the following result:
Validation Report
Conforms: True
The expected validation errors should include only the following subjects:
| <http://learningsparql.com/ns/humanResources#BadOne> |
| <http://learningsparql.com/ns/humanResources#BadTwo> |
| <http://learningsparql.com/ns/humanResources#BadThree> |
| <http://learningsparql.com/ns/humanResources#AnotherName> |
| <http://learningsparql.com/ns/humanResources#name> |
| <http://learningsparql.com/ns/humanResources#YetAnotherName> |
Is this possible with SHACL? If so, what should the shape file be?
What follows results in the expected validation errors, however, there are still several things I do not understand.
The sh:prefixes hr: ; is not needed. It is designed to supply prefixes for the SPARQL target SELECT statement itself and nothing more.
Inference needed to be disabled. It was inserting triples and trying to validate them. In this use case, that is not what is desired. What should be validated is what is in the schema and nothing else.
I was also thinking that it would not be an issue to put everything into a single graph based on what apparently was a misunderstanding of https://github.com/RDFLib/pySHACL/issues/46.
graph_data = """
#prefix hr: <http://learningsparql.com/ns/humanResources#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix schema: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
hr:Employee a rdfs:Class .
hr:BadThree rdfs:comment "some comment about missing" .
hr:BadTwo a hr:BadOne .
hr:YetAnother a hr:Another .
hr:YetAnotherName a hr:AnotherName .
hr:Another a hr:Employee .
hr:AnotherName a hr:name .
hr:BadOne a hr:Dangling .
hr:name a rdf:Property .
"""
shape_data = '''
#prefix hr: <http://learningsparql.com/ns/humanResources#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix schema: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
schema:SchemaShape
a sh:NodeShape ;
sh:target [
a sh:SPARQLTarget ;
sh:prefixes hr: ;
sh:select """
SELECT ?this
WHERE {
?this ?p ?o .
}
""" ;
] ;
sh:property [
sh:path ( rdf:type [ sh:zeroOrMorePath rdf:type ] ) ;
sh:nodeKind sh:IRI ;
sh:hasValue rdfs:Class
] ;
.
'''
data = rdflib.Graph().parse( data = graph_data, format = 'turtle' )
shape = rdflib.Graph().parse( data = shape_data, format = 'turtle' )
report = validate( data, shacl_graph=shape, abort_on_error = False, meta_shacl = False, debug = False, advanced = True )
An alternative using a SPARQL based constraint would look like:
graph_data = """
#prefix hr: <http://learningsparql.com/ns/humanResources#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix schema: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
hr:Employee a rdfs:Class .
hr:BadThree rdfs:comment "some comment about missing" .
hr:BadTwo a hr:BadOne .
hr:YetAnother a hr:Another .
hr:YetAnotherName a hr:AnotherName .
hr:Another a hr:Employee .
hr:AnotherName a hr:name .
hr:BadOne a hr:Dangling .
hr:name a rdf:Property .
"""
shape_data = '''
#prefix hr: <http://learningsparql.com/ns/humanResources#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix schema: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
schema:SchemaShape
a sh:NodeShape ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
SELECT ?this
WHERE {
?this ?p ?o .
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "Node does not have type rdfs:Class." ;
sh:prefixes hr: ;
sh:select """
SELECT $this
WHERE {
$this rdf:type ?o .
FILTER NOT EXISTS {
?o rdf:type* rdfs:Class
}
FILTER ( strstarts( str( $this ), str( hr: ) ) )
}
""" ;
]
.
'''
data = rdflib.Graph().parse( data = graph_data, format = 'turtle' )
shape = rdflib.Graph().parse( data = shape_data, format = 'turtle' )
report = validate( data, shacl_graph=shape, abort_on_error = False, meta_shacl = False, debug = False, advanced = True )

Get MAX result from COUNT in SPARQL

I have this query:
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 curricula: <http://www.semanticweb.org/lsarni/ontologies/curricula#>
SELECT ?topic (COUNT(?x) as ?number_of_courses)
WHERE {
?topic curricula:taughtIn ?x .
}
GROUP BY ?topic
ORDER BY desc(?number_of_courses)
That returns:
Now I want to get the ?topic with the max ?number_of_courses, in this case Engineering
I managed to get the max ?number_of_courses with this query (following this answer):
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 curricula: <http://www.semanticweb.org/lsarni/ontologies/curricula#>
SELECT (MAX(?number_of_courses) AS ?maxc)
WHERE{
{
SELECT ?topic (COUNT(?x) as ?number_of_courses)
WHERE {
?topic curricula:taughtIn ?x .
}
GROUP BY ?topic
}
}
This returns:
But I can't manage to get the ?topic.
How could I fix this?
Update
I tried what I understood from AKSW comment:
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 curricula: <http://www.semanticweb.org/lsarni/ontologies/curricula#>
SELECT ?topic
WHERE {
?topic curricula:taughtIn ?x .
{
SELECT (MAX(?number_of_courses) AS ?max)
WHERE {
{
SELECT ?topic (COUNT(?x) as ?number_of_courses)
WHERE {
?topic curricula:taughtIn ?x .
}
GROUP BY ?topic
}
}
}
}
GROUP BY ?topic
HAVING (COUNT(?x) = ?max)
But it returns nothing.
Example
For this minimal example the result should be Topic_2 since it's taughtIn two courses.
#prefix : <http://www.semanticweb.org/lsarni/ontologies/curricula#> .
#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://www.semanticweb.org/lsarni/ontologies/curricula> .
<http://www.semanticweb.org/lsarni/ontologies/curricula> rdf:type owl:Ontology .
#################################################################
# Object Properties
#################################################################
### http://www.semanticweb.org/lsarni/ontologies/curricula#taughtIn
:taughtIn rdf:type owl:ObjectProperty ;
rdfs:subPropertyOf owl:topObjectProperty .
### http://www.w3.org/2002/07/owl#topObjectProperty
owl:topObjectProperty rdfs:domain :Topic ;
rdfs:range :Course .
#################################################################
# Classes
#################################################################
### http://www.semanticweb.org/lsarni/ontologies/curricula#Course
:Course rdf:type owl:Class ;
owl:disjointWith :Topic .
### http://www.semanticweb.org/lsarni/ontologies/curricula#Topic
:Topic rdf:type owl:Class .
#################################################################
# Individuals
#################################################################
### http://www.semanticweb.org/lsarni/ontologies/curricula#Course_1
:Course_1 rdf:type owl:NamedIndividual ,
:Course .
### http://www.semanticweb.org/lsarni/ontologies/curricula#Course_2
:Course_2 rdf:type owl:NamedIndividual ,
:Course .
### http://www.semanticweb.org/lsarni/ontologies/curricula#Topic_1
:Topic_1 rdf:type owl:NamedIndividual ,
:Topic ;
:taughtIn :Course_1 .
### http://www.semanticweb.org/lsarni/ontologies/curricula#Topic_2
:Topic_2 rdf:type owl:NamedIndividual ,
:Topic ;
:taughtIn :Course_1 ,
:Course_2 .
### Generated by the OWL API (version 4.2.8.20170104-2310) https://github.com/owlcs/owlapi

owl: property domain restriction on property value

I am studying the inference in OWL, currently the restriction in domain definition:
#prefix : <http://www.test.org/2015/4/ontology#> .
#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#> .
#base <http://www.test.org/2015/4/ontology> .
<http://www.test.org/2015/4/ontology> rdf:type owl:Ontology .
:Class1 rdf:type owl:Class .
:Prop1 rdf:type owl:DatatypeProperty ;
rdfs:domain [ rdf:type owl:Class ;
owl:intersectionOf ( :Class1
[ rdf:type owl:Restriction ;
owl:onProperty :Prop1 ;
owl:hasValue "class1"
]
)
] .
:Ind1 rdf:type owl:NamedIndividual ;
:Prop1 "p" .
I've expected that the reasoner (Pellet) infers
:Ind1 rdf:type :Class1
only if there is
:Ind1 :Prop1 "class1"
but it seems to ignore the restriction in the domain definition.
Is it correct to define restrictions in damain definitions? The reasoner (Pellet) does not forbid me to do that.

Fuseki 1.0.1 SPARQL Update returns 404

I'm trying to learn to update data in Fuseki, but when I try I get a 404 error. I am clearly not doing something right. Perhaps it is my INSERT command? I've tried a ton of them though.
I am using the web based SPARQL interface at /sparql.tpl.
I can get SPARQL Queries to work on that same page just fine. But the second form, labeled SPARQL Updates is what I'm using for my update, and that gives me errors:
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX booklet: <http://www.semanticweb.org/cstepnitz/ontologies/booklet>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX ontology: <http://dbpedia.org/ontology/>
INSERT DATA
{ <http://dbpedia.org/resource/Johnny_Got_His_Gun>
rdf:type ontology:Book
}
This is the error I get when the form posts to the url localhost:3030/bookfinder/update:
Error 404: Not Found
Fuseki - version 1.0.1 (Build date: 2014-01-18T19:01:20+0000)
This is my TTL file.
#prefix : <http://www.semanticweb.org/cstepnitz/ontologies/bookreader#> .
#prefix bibo: <http://purl.org/ontology/bibo/> .
#prefix booklet: <http://www.semanticweb.org/cstepnitz/ontologies/booklet> .
#prefix dbp: <http://dbpedia.org/ontology/> .
#prefix dbpedia: <http://dbpedia.org/ontology/> .
#prefix dbpedia-owl: <http://dbpedia.org/ontology/> .
#prefix NS5: <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 rdms: <http://en.wikipedia.org/wiki/Comparison_of_relational_database_management_systems> .
#prefix owlapi: <http://www.semanticweb.org/owlapi#> .
#prefix schema: <http://schema.org/> .
#base <http://www.semanticweb.org/cstepnitz/ontologies/bookreader> .
<http://www.semanticweb.org/cstepnitz/ontologies/bookreader> NS5:type owl:Ontology ;
owl:imports dbp: .
booklet:readbook NS5:type owl:ObjectProperty ;
rdfs:range dbpedia-owl:Book ;
rdfs:domain booklet:Reading ;
rdfs:subPropertyOf owl:topObjectProperty .
booklet:reading NS5:type owl:ObjectProperty ;
rdfs:domain booklet:Bookreader ;
rdfs:range booklet:Reading .
:OWLObjectProperty_18e83c77_09cb_4d9b_90c6_93b2a5095d78 NS5:type owl:ObjectProperty ;
rdfs:label "recommendedBooks"#en ;
rdfs:range dbpedia-owl:Book ;
rdfs:domain booklet:Bookreader .
:OWLObjectProperty_86497b97_bef7_4b9e_80bc_6080ce0cbfe3 NS5:type owl:ObjectProperty ;
rdfs:label "bookrating"#en ;
rdfs:range booklet:Bookrating ;
rdfs:domain booklet:Reading ;
rdfs:subPropertyOf owl:topObjectProperty .
dbpedia-owl:Book NS5:type owl:Class .
schema:Person NS5:type owl:Class .
booklet:Bookrating NS5:type owl:Class .
booklet:Bookreader NS5:type owl:Class ;
rdfs:subClassOf schema:Person .
booklet:Reading NS5:type owl:Class .
:OWLClass_38c67bca_82ba_44b7_85dd_31d0c2883702 NS5:type owl:Class ;
rdfs:label "Poor"#en ;
rdfs:subClassOf booklet:Bookrating .
:OWLClass_5630d470_6dda_4cd5_9596_ddf0eab29cde NS5:type owl:Class ;
rdfs:label "Best"#en ;
rdfs:subClassOf booklet:Bookrating .
:OWLClass_694d8a9e_5fba_45a2_81b3_f47f1a21af4d NS5:type owl:Class ;
rdfs:label "Average"#en ;
rdfs:subClassOf booklet:Bookrating .
:OWLClass_dfb73eb5_8a7c_4628_a423_72056e7ee81f NS5:type owl:Class ;
rdfs:label "Good"#en ;
rdfs:subClassOf booklet:Bookrating .
:OWLClass_f3923184_fbb7_48ec_954e_49e233454099 NS5:type owl:Class ;
rdfs:label "Awful"#en ;
rdfs:subClassOf booklet:Bookrating .
Any guesses?
As explained in the comments on my question, the problem was the "--update" flag needed to be added at startup. See http://jena.apache.org/documentation/serving_data/