I'm trying to create a simple ontology, following the tutorial on the official website. The code runs smoothly and everything seems fine when running this code:
import owlready2
owlready2.JAVA_EXE = r"my-path-to-java-exe"
# new.owl is a non-existing file and therefore onto has no pre-defined classes
# if you know of any nicer way to define an ontology, I'd appreciate it
onto = get_ontology("new.owl")
with onto:
class Drug(Thing): pass
class number_of_tablets(Drug >> int, FunctionalProperty): pass # Creating some properties
class price(Drug >> float, FunctionalProperty): pass
class price_per_tablet(Drug >> float, FunctionalProperty): pass
rule = Imp()
# Rule: "Drug instance ?d AND price of ?d is ?p AND drug ?d has number_of_tablets = ?n
# AND ?r = ?p/?n -> Drug ?d has price_per_tablet = ?r"
rule.set_as_rule("""Drug(?d), price(?d,?p), number_of_tablets(?d,?n), divide(?r, ?p, ?n) -> price_per_tablet(?d, ?r)""")
# Create an instance "drug" with properties defined in brackets
drug = Drug(number_of_tablets = 10, price = 25.0)
#print(drug.iri)
# Syncing the reasoner infers new info
sync_reasoner_pellet(infer_property_values = True, infer_data_property_values = True)
# New property price_per_tablet is now added to drug and we can use it normally:
print(drug.price_per_tablet)
# Save this ontology with rules in the same folder, filename: test
onto.save(file = "test", format = "rdfxml")
Problem: When I open the resulting file "test" in Protégé, my instance "drug1" is not a part of the previously defined class Drug but of a new class of the same name Drug (I'll always denote this one in italic so it doesn't get confusing). Interestingly, this new class Drug is not even a subclass of owl:Thing class.
I'm not sure what's the problem. According to Protégé, the defined class Drug has IRI: file:/C:/.../new#Drug, and the other class Drug has IRI: new#Drug.
When I checked IRIs of all the described objects in Python, they were all synchronized.
I'm very confused about what happened here.
I checked the "test" file and the part concerning this instance is:
<Drug rdf:about="#drug1">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
<number_of_tablets rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">10</number_of_tablets>
<price rdf:datatype="http://www.w3.org/2001/XMLSchema#decimal">25.0</price>
<price_per_tablet rdf:datatype="http://www.w3.org/2001/XMLSchema#decimal">2.5</price_per_tablet>
</Drug>
This is confusing because when I opened the file PizzaTutorial.owl from the famous Pizza tutorial, an instance was defined like this:
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#AmericanaHotPizza2">
<rdf:type rdf:resource="http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#AmericanaHotPizza"/>
<hasCaloricContent rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">675</hasCaloricContent>
</owl:NamedIndividual>
What happened?!
Another question: When I inspected the individual in Protégé, I noticed that the properties number_of_tablets and price were added as Annotations, and not as Data Properties. I assume that this is the reason why my SWRL rule (which was correctly exported) doesn't conclude the price_per_tablet property for this individual when I remove the sync_reasoner line.
Please comment on anything you notice is wrong, I'm a beginner in ontology programming and in both tools and I would very much appreciate your help!