I am trying to use an OWL reasoner on an RDF graph which I have created using rdflib
as follows:
ex = Namespace('http://example.org#')
g = Graph()
g.bind("ex", ex)
g.add((ex.Bob, ex.drives, ex.Car))
g.add((ex.Car, RDF.type, ex.Truck))
g.add((ex.Truck, RDFS.subClassOf, ex.Vehicle))
(A car is not really a type of truck, but I am just trying out the reasoner).
After running the reasoner, my aim is to be able to infer that if Bob drives a car, and a car is a type of truck, and a truck is a subclass of vehicle, then Bob drives a vehicle.
When I ask if a car is a type of vehicle, the result is True
:
b = g.query("""
PREFIX ex: <http://example.org#>
ASK {
ex:Car rdf:type ex:Vehicle .
}
""")
print('Car is a type of Vehicle:', bool(b)) # prints True
But when I ask if Bob drives a vehicle, I get a False
:
b = g.query("""
PREFIX ex: <http://example.org#>
ASK {
ex:Bob ex:drives ex:Vehicle .
}
""")
print('Bob drives a vehicle:', bool(b)) # prints False
I realize from this question that I can write some code to add the kind of triples I want after reasoning is done. But if the behavior I want is already supported by OWL/RDF semantics, I would prefer to correct my approach and let the reasoning semantics do its work. I feel like I may be missing a fundamental principle in how the inference is supposed to work, but I am a novice in this area and I'm not sure what I'm doing wrong. Any help would be appreciated.
(I used owlrl
for reasoning by running DeductiveClosure(OWLRL_Semantics).expand(g)
).