You can do some of what you're talking about, but it's important to remember that OWL is based on open world reasoning. This means that if you haven't explicitly said something, and you don't have a way to infer whether it's true or false, OWL doesn't assume either way; it's just unknown. For instance, if you only say "John loves Mary", then you haven't said that "John loves Sue" (obviously), but you also haven't says that "John does not love Sue."
For instance, you might say that: "Man ⊑ ∀ owns.Hat" ("Men own only hats."). Now, that's not a definition, so you can't just say that because something only owns hats, it's a man. You can find some violations, if you can find something that claims to be a Man, but owns something that is not a hat. (Of course, finding something that's definitely not a hat requires some reasoning, because with the open-world assumption, it's often hard to know what something is not than to know what it is.)
All that said, you can do some kinds of things with your ontology and SPARQL. Let's recreate some of the data first:
@prefix : <http://stackoverflow.com/q/28812904/1281433/> .
@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#> .
: a owl:Ontology .
:A a owl:Class .
:C a owl:Class .
:D a owl:Class .
:E a owl:Class .
:F a owl:Class .
:G a owl:Class .
:H a owl:Class .
:isConfirmedBy a owl:ObjectProperty .
:B a owl:Class ;
rdfs:subClassOf :A ;
rdfs:subClassOf [ a owl:Restriction ;
owl:onProperty :isConfirmedBy ;
owl:someValuesFrom [ a owl:Class ;
owl:intersectionOf ( :E :F :G :H )
]
] ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom [ a owl:Class ;
owl:intersectionOf ( :C :D )
] ;
owl:onProperty :isConfirmedBy
] .
First, lets look at how you can find (possible) violations. You could find a violation if you found something claiming to be a Man that was confirmed by something that's not a C and a D, or that is not confirmed by an E, F, G, or H. Again, I have to stress that this is very difficult, because usually what happens is that you'd say something like:
B ⊑ ∀ isConfirmedBy.(C ⊓ D)
β : B
isConfirmedBy(β,x)
This isn't inconsistent, even if you don't know that x is a C and that x is a D. Instead, from this, you can infer that
x : (C ⊓ D)
and then from that, you can infer that:
x : C
x : D
So, based on:
I am trying to write a query on a class with a restriction defined on
it, that will determine whether the restriction has been satisfied
and, if it has, return it.
it sounds like you're asking for a query that would return candidate instances of B. These would be things that so far as we know don't violate the negative conditions of membership, and meet the positive conditions of membership. In this case, you'd be looking for things that:
- are not confirmed by any things that are not both C's and D's
- are confirmed by something that is an E, F, G, or H.
You can write that like:
select ?candidate where {
#-- find candidates that are confirmed by
#-- by something that's an E, F, G, or H.
values ?type { :E :F :G :H }
?candidate :isConfirmedBy/rdf:type ?type
#-- But remove any that are confirmed by
#-- by something that's is *not* both a C
#-- and a D.
filter exists {
?candidate :isConfirmedBy ?x
filter not exists { ?x a :C, :D }
}
}
Note that this does not ensure that each candidate is actually a B, since there are still things that could be true about the candidate that we do not know yet.