I have an object property partOf which is transitive.
And I want to say that:
a partOf Year then a is a Term
b partOf Term then b is a Course
And simultaneously:
a partOf Knowledge_Group then a is a Knowledge_Area
b partOf Knowledge_Area then b is a Course
For that I'm using this to say b partOf Term or Knowledge_Area then b is a Course:
:Course rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Restriction ;
owl:onProperty :partOf ;
owl:someValuesFrom [ rdf:type owl:Class ;
owl:unionOf ( :Knowledge_Area
:Term
)
]
] .
But when I run the reasoner I get all the courses listed as instances of the class Term and same for Knowledge_Area:
If I don't use the or and set that Course is equivalent only to partOf some Term or partOf some Knowledge_Area (separately and one at a time) I don't get this issue.
Is there a way I can say what I explained at the beginning and not get the courses inferred to be of type Term?
Here there is a minimal example:
#prefix : <http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#> .
#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/lucia/ontologies/2018/5/untitled-ontology-27> .
<http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27> rdf:type owl:Ontology .
#################################################################
# Object Properties
#################################################################
### http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#partOf
:partOf rdf:type owl:ObjectProperty ,
owl:TransitiveProperty .
#################################################################
# Classes
#################################################################
### http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#Course
:Course rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Restriction ;
owl:onProperty :partOf ;
owl:someValuesFrom [ rdf:type owl:Class ;
owl:unionOf ( :Knowledge_Area
:Term
)
]
] .
### http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#Knowledge_Area
:Knowledge_Area rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Restriction ;
owl:onProperty :partOf ;
owl:someValuesFrom :Knowledge_Group
] .
### http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#Knowledge_Group
:Knowledge_Group rdf:type owl:Class ;
owl:disjointWith :Year .
### http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#Term
:Term rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Restriction ;
owl:onProperty :partOf ;
owl:someValuesFrom :Year
] .
### http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#Year
:Year rdf:type owl:Class .
#################################################################
# Individuals
#################################################################
### http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#Course_1
:Course_1 rdf:type owl:NamedIndividual ;
:partOf :Knowledge_Area_1 ,
:Term_1 .
### http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#Knowledge_Area_1
:Knowledge_Area_1 rdf:type owl:NamedIndividual ;
:partOf :Knowledge_Group_1 .
### http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#Knowledge_Group_1
:Knowledge_Group_1 rdf:type owl:NamedIndividual ,
:Knowledge_Group .
### http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#Term_1
:Term_1 rdf:type owl:NamedIndividual ;
:partOf :Year_1 .
### http://www.semanticweb.org/lucia/ontologies/2018/5/untitled-ontology-27#Year_1
:Year_1 rdf:type owl:NamedIndividual ,
:Year .
### Generated by the OWL API (version 4.2.8.20170104-2310) https://github.com/owlcs/owlapi
The semantics of transitive roles are if (x, y) \in R and (y, z) \in R then (x, z) \in R. Based on this from your ontology you have that:
(1) Course_1 partOf Knowledge_Area_1 partOf Knowledge_Group_1 which means Course_1 partOf Knowledge_Group_1 which is equivalent to Knowledge_Area.
(2) Course_1 partOf Term_1 partOf partOf Year_1 which means Course_1 partOf Year_1 which is equivalent to Term.
Hence Course_1 is a Term and a Knowledge_Area and since Course is equivalent to Term or Knowledge_Area, Course_1 is also a Course, which is pretty much what an explanation says for why Course_1 is a Term.
In my opinion the key thing to realize here is that you in actual fact are dealing with different partOf relations, not a single one. The clue to this fact is that in different contexts you want to infer different type information from your partOf relation. Type information from relations in OWL is inferred mostly from domain and range restrictions. Here is a possible solution to your problem:
ObjectProperty: partOf
ObjectProperty: partOfKA
SubPropertyOf: partOf
Domain: Course
ObjectProperty: partOfKG
SubPropertyOf: partOf
Domain: Knowledge_Area
ObjectProperty: partOfTerm
SubPropertyOf: partOf
Domain: Course
ObjectProperty: partOfYear
SubPropertyOf: partOf
Domain: Term
Class: Course
Class: Knowledge_Area
Class: Knowledge_Group
DisjointWith: Year
Class: Term
Class: Year
DisjointWith: Knowledge_Group
Individual: Course_1
Facts:
partOfKA Knowledge_Area_1,
partOfTerm Term_1
Individual: Knowledge_Area_1
Facts: partOfKG Knowledge_Group_1
Individual: Knowledge_Group_1
Types: Knowledge_Group
Individual: Term_1
Facts: partOfYear Year_1
Individual: Year_1
Types: Year
Strictly speaking you do not need the partOf property in my example ontology. I merely added it for conceptual clarity. Moreover, in my example ontology there is no need for transitive properties.
Related
For example 1 :
Classes : A and B.
Property : hasValue.
Axiom : hasValue some A disjointWith hasValue some B.
Individual : user1.
user1 hasValue A.
user1 hasValue B.
Protege reasoner (HermiT) throws no error.
For example 2 :
Classes : A and B.
A disjoint with B.
Property : hasValue.
Axiom : hasValue some A disjointWith hasValue some B.
Individual : user1.
user1 hasValue A.
user1 hasValue B.
Protege reasoner (HermiT) throws error.
Shouldn't "hasValue some A disjointWith hasValue some B" alone be sufficient to throw error in eg 1's case?
EDIT : example 1's reasoner result is wrong. As #Henriette Harmse showed below reasoner will throw error.
I was doing declaring Axiom a little differently than what I wrote above. I declared axiom as "hasValue some B DisjointWith hasValue some
(P and (not (B)))", where P is parent class of both A and B. (Full sample ontology below.) If you import it in protege and run, you'll not get error.
It seems :
"hasValue some B DisjointWith hasValue some A"
"hasValue some B DisjointWith hasValue some (P and (not (B)))"
are not equivalent statements.
Sample ontology :
#prefix : <http://test.org/#> .
#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.org/> .
<http://test.org/> rdf:type owl:Ontology .
#################################################################
# Object Properties
#################################################################
### http://test.org/#hasValue
:hasValue rdf:type owl:ObjectProperty .
#################################################################
# Classes
#################################################################
### http://test.org/#A
:A rdf:type owl:Class ;
rdfs:subClassOf :P .
### http://test.org/#B
:B rdf:type owl:Class ;
rdfs:subClassOf :P .
### http://test.org/#P
:P rdf:type owl:Class .
### http://test.org/#USER
:USER rdf:type owl:Class .
#################################################################
# Individuals
#################################################################
### http://test.org/#A
:A rdf:type owl:NamedIndividual ,
:A .
### http://test.org/#B
:B rdf:type owl:NamedIndividual ,
:B .
### http://test.org/#user1
:user1 rdf:type owl:NamedIndividual ;
:hasValue :A ,
:B .
#################################################################
# General axioms
#################################################################
[ rdf:type owl:Restriction ;
owl:onProperty :hasValue ;
owl:someValuesFrom :A ;
owl:disjointWith [ rdf:type owl:Restriction ;
owl:onProperty :hasValue ;
owl:someValuesFrom [ owl:intersectionOf ( :P
[ rdf:type owl:Class ;
owl:complementOf :A
]
) ;
rdf:type owl:Class
]
]
] .
[ rdf:type owl:Restriction ;
owl:onProperty :hasValue ;
owl:someValuesFrom :B ;
owl:disjointWith [ rdf:type owl:Restriction ;
owl:onProperty :hasValue ;
owl:someValuesFrom [ owl:intersectionOf ( :P
[ rdf:type owl:Class ;
owl:complementOf :B
]
) ;
rdf:type owl:Class
]
]
] .
### Generated by the OWL API (version 4.5.9.2019-02-01T07:24:44Z) https://github.com/owlcs/owlapi
I have tried this now myself and for your first example I get an inconsistency with the following explanation:
Here is the actual ontology giving the inconsistency. I will need to see your actual ontology to understand why you are not getting an inconsistency.
<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#"
xml:base="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:untitled-ontology-9="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#">
<owl:Ontology rdf:about="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9"/>
<owl:ObjectProperty rdf:about="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#hasValue"/>
<owl:Class rdf:about="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#A"/>
<owl:Class rdf:about="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#B"/>
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#a">
<rdf:type rdf:resource="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#A"/>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#b">
<rdf:type rdf:resource="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#B"/>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#user1">
<hasValue rdf:resource="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#a"/>
<hasValue rdf:resource="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#b"/>
</owl:NamedIndividual>
<owl:Restriction>
<owl:onProperty rdf:resource="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#hasValue"/>
<owl:someValuesFrom rdf:resource="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#A"/>
<owl:disjointWith>
<owl:Restriction>
<owl:onProperty rdf:resource="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#hasValue"/>
<owl:someValuesFrom rdf:resource="http://www.semanticweb.org/henri/ontologies/2022/6/untitled-ontology-9#B"/>
</owl:Restriction>
</owl:disjointWith>
</owl:Restriction>
</rdf:RDF>
Update after reviewing ACTUAL ontology
The main problem is that you stated the GCI you used incorrectly. What you said you used are substantially different from what you actually used.
What you said used: hasValue some A disjointWith hasValue some B
What you actually used:
hasValue some A DisjointWith hasValue some (P and (not (A)))
hasValue some B DisjointWith hasValue some (P and (not (B)))
To understand why your GCIs do not have the desired effect, I have drawn an example Venn diagram:
Note that hasValue some A DisjointWith hasValue some (P and (not (A))) states that there is no individual x that belongs to both the set hasValue some A and the set hasValue some (P and (not (A))). It does however allow for the possibility that you have an individual user1 that is related via hasValue to an individual in set A and that is related via hasValue to an individual in set B. This is because nothing prohibits the sets hasValue some A (to which user1 hasValue A belongs) and hasValue some B (to which user1 hasValue B belongs)` to overlap. To prohibit this, you have to add the following GCI:
hasValue some A DisjointWith hasValue some B
How to get a inconsistency using you GCIs
To get an inconsistency using your GCIs, you have to have an individual that actually belong to the disjoint sets you defined. I.e.,
Define individual x as follows:
:x rdf:type owl:NamedIndividual ,
[ owl:intersectionOf ( :P
[ rdf:type owl:Class ;
owl:complementOf :A
]
) ;
rdf:type owl:Class
] .
and then define user2:
:user2 rdf:type owl:NamedIndividual ;
:hasValue :A ,
:x .
You will get an inconsistency with the following explanation:
Please I have two questions ;
Q1: I have implemented the ChildlessPerson class in Protege 5.5.0 and defined an individual of type person with no haschild property. I tried with Hermet, Pellet, ontop, none derives that the individual is a ChildlessPerson.
:ChildlessPerson rdf:type OWL:Class ;
rdfs:subClassOf [ rdf:type OWL:Class ; OWL:intersectionOf ( :Person
[ rdf:type OWL:Class ;
OWL:complementOf [ rdf:type OWL:Restriction ;
OWL:onProperty :hasChild ; OWL:someValuesFrom OWL:Thing]
] ) ] .
Q2 : In the ontology I have Parent subclassOf Person and Father subclassOf Parent. I defined an individual of typefather, it is inferred that it is a parent, but the fact that is a person is not inferred. I checked also with Pellet incremental. Why ?
:Father rdf:type OWL:Class ; rdfs:subClassOf :Parent; OWL:disjointWith :Mother.
:Mother rdf:type OWL:Class ; rdfs:subClassOf :Parent.
:Parent rdf:type OWL:Class ; rdfs:subClassOf :Person.
:Person: rdf:type OWL:Class ; rdfs:comment "Represents the set of all people."
Thanks in advance.
I need to check the violations to the OWL2DL profile in this simplified ontology:
#prefix : <http://www.onto.com/test#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#base <http://www.onto.com/test#> .
<http://www.onto.com/test#> rdf:type owl:Ontology ;
rdfs:label "Test"#en .
xsd:date rdf:type rdfs:Datatype .
<http://www.onto.com/test#hasPart2> rdf:type owl:ObjectProperty .
<http://www.onto.com/test#isPartOf> rdf:type owl:ObjectProperty ,
owl:TransitiveProperty ;
rdfs:domain <http://www.onto.com/test#TestRestriction> .
<http://www.onto.com/test#isPartOf2> rdf:type owl:ObjectProperty ;
rdfs:subPropertyOf owl:topObjectProperty ;
rdf:type owl:TransitiveProperty ;
rdfs:domain <http://www.onto.com/test#A2PartOfClass> .
<http://www.onto.com/test#maxCardinality0> rdf:type owl:ObjectProperty .
<http://www.onto.com/test#A2PartOfClass> rdf:type owl:Class .
<http://www.onto.com/test#TestRestriction> rdf:type owl:Class ;
rdfs:subClassOf [ rdf:type owl:Restriction ;
owl:onProperty <http://www.onto.com/test#isPartOf2> ;
owl:minQualifiedCardinality "0"^^xsd:nonNegativeInteger ;
owl:onClass <http://www.onto.com/test#A2PartOfClass>
] ;
rdfs:comment "A1 PartOf Class Comment"#en ;
rdfs:label "A1PartOfClass"#en .
<http://www.onto.com/test#isPartOf2> rdf:type owl:Class .
To this end, I have the following code in the OWL API to check for the violations of the given ontology to the OWL2DL profile.
OWL2DLProfile profile = new OWL2DLProfile();
OWLProfileReport report = profile.checkOntology(ontology);
for(OWLProfileViolation v:report.getViolations()) {
System.out.println(v);
}
In the console I'm getting this:
Use of non-simple property in a restriction: ObjectMinCardinality(0 <http://www.onto.com/test#isPartOf2> <http://www.onto.com/test#A2PartOfClass>) [SubClassOf(<http://www.onto.com/test#TestRestriction> ObjectMinCardinality(0 <http://www.onto.com/test#isPartOf2> <http://www.onto.com/test#A2PartOfClass>)) in OntologyID(OntologyIRI(<http://www.onto.com/test#>) VersionIRI(<null>))]
And I would like to retrieve the URIs involved, i.e., http://www.onto.com/test#isPartOf2, http://www.onto.com/test#A2PartOfClass
as well as the message of the violation, i.e., Use of non-simple property in a restriction.
How can I achieve this?
You can get the signature of the axiom involved in the violation as follows:
violation.getAxiom()
.signature()
.forEach(System.out::println);
There is no easy way to get the type of the violation besides doing the following:
violation.getClass().getSimpleName()
which will return UseOfNonSimplePropertyInCardinalityRestriction.
I have defined an object property that requires two individuals. However, Protege do not let me to add these two but only one. The question could be summarised as follows: I have A and B belonging to a class (instances of that class). I have one object property, say proper, I would like to express: proper A, B. Here it is the code I wrote up to know.
#prefix : <http://stackoverflow.com/q/24188632/1281433/people-have-exactly-one-age#> .
#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://stackoverflow.com/q/24188632/1281433/people-have-exactly-one-age> .
<http://stackoverflow.com/q/24188632/1281433/people-have-exactly-one-age> rdf:type owl:Ontology .
#################################################################
# Object Properties
#################################################################
### http://stackoverflow.com/q/24188632/1281433/people-have-exactly-one-age#Interact2
:Interact2 rdf:type owl:ObjectProperty ,
owl:FunctionalProperty ;
rdfs:domain :Person ;
rdfs:range :Person .
#################################################################
# Data properties
#################################################################
### http://stackoverflow.com/q/24188632/1281433/people-have-exactly-one-age#Interact
:Interact rdf:type owl:DatatypeProperty .
### http://stackoverflow.com/q/24188632/1281433/people-have-exactly-one-age#hasAge
:hasAge rdf:type owl:DatatypeProperty .
#################################################################
# Classes
#################################################################
### http://stackoverflow.com/q/24188632/1281433/people-have-exactly-one-age#Person
:Person rdf:type owl:Class ;
rdfs:subClassOf [ rdf:type owl:Restriction ;
owl:onProperty :Interact2 ;
owl:qualifiedCardinality "2"^^xsd:nonNegativeInteger ;
owl:onClass :Person
] ,
[ rdf:type owl:Restriction ;
owl:onProperty :hasAge ;
owl:cardinality "1"^^xsd:nonNegativeInteger
] .
#################################################################
# Individuals
#################################################################
### http://stackoverflow.com/q/24188632/1281433/people-have-exactly-one-age#Pallino
:Pallino rdf:type owl:NamedIndividual ,
:Person .
### http://stackoverflow.com/q/24188632/1281433/people-have-exactly-one-age#Pinco
:Pinco rdf:type owl:NamedIndividual ,
:Person .
### http://stackoverflow.com/q/24188632/1281433/people-have-exactly-one-age#Pinco_Pallino
:Pinco_Pallino rdf:type owl:NamedIndividual ,
:Person ;
:Interact2 :Pinco .
### Generated by the OWL API (version 4.2.8.20170104-2310) https://github.com/owlcs/owlapi
I have an ontology with Person and City classes. People travel to cities and this travel is represented in the traveledTo object property. I'd like to add a WorldTraveler class. People are world travelers if they have traveled to 2 or more cities. How can I do this in my ontology?
#prefix : <http://www.semanticweb.org/chris/ontologies/2017/9/untitled-ontology-64#> .
#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/chris/ontologies/2017/9/untitled-ontology-64> .
<http://www.semanticweb.org/chris/ontologies/2017/9/untitled-ontology-64> rdf:type owl:Ontology .
:traveledTo rdf:type owl:ObjectProperty ;
rdfs:domain :Person ;
rdfs:range :City .
:City rdf:type owl:Class .
:Person rdf:type owl:Class .
:Bob rdf:type owl:NamedIndividual ,
:Person ;
:traveledTo :London ,
:Ottawa ,
:Paris .
:Brussels rdf:type owl:NamedIndividual ,
:City .
:London rdf:type owl:NamedIndividual ,
:City .
:Ottawa rdf:type owl:NamedIndividual ,
:City .
:Paris rdf:type owl:NamedIndividual ,
:City .
:Ralph rdf:type owl:NamedIndividual ,
:Person ;
:traveledTo :Rome .
:Rome rdf:type owl:NamedIndividual ,
:City .
:Washington rdf:type owl:NamedIndividual ,
:City .
I tried adding the following Class but it didn't seem to work:
:WorldTraveler rdf:type owl:Class ;
owl:equivalentClass [ owl:intersectionOf ( :Person
[ rdf:type owl:Restriction ;
owl:onProperty :traveledTo ;
owl:minQualifiedCardinality "2"^^xsd:nonNegativeInteger ;
owl:onClass :City
]
) ;
rdf:type owl:Class
] .
I believe that my reasoner may not be able to infer that Ralph is not a WorldTraveler because of the open world assumption. However, it should be able to infer that Bob is a WorldTraveler because he has traveled to 3 cities.
Thanks for your help.
Chris
In addition to the open world assumption (OWA), there exists the unique name assumption (UNA). OWL does make the former (OWA) and does not make the latter (UNA).
You should explicitely make individuals different.
In the Turtle syntax, it should look like this:
:London owl:differentFrom :Paris .
or
[ rdf:type owl:AllDifferent ;
owl:distinctMembers ( :Brussels :London :Ottawa :Paris :Rome :Washington )
] .