This notebook documents how to solve the famous zebra puzzle by A. Einstein with the help of semantic web tools for python.
It is based on theses Links/Projects
For installation I did:
pip install owlready
Note there is also https://github.com/RDFLib/OWL-RL/files/1533409/zebra.n3.txt but the N3-Format is not supported by Owlready.
import os
import owlready2 as owl2
Assumption: ontology file has been downloaded to ./ontology_data/<filename>
.
data_path = "ontology_data"
path1 = os.path.join(data_path, "einsteins_riddle.owl.txt")
# get an overview what is inside the Ontology
onto = owl2.get_ontology(path1).load()
print("classes (concepts):\n", list(onto.classes()), "\n"*2)
print("properties (roles):\n", list(onto.properties()), "\n"*2)
print("individuals:\n", list(onto.individuals()))
classes (concepts): [owl.Nothing, einsteins_riddle.owl.txt.Beverage, einsteins_riddle.owl.txt.Man, einsteins_riddle.owl.txt.Color, einsteins_riddle.owl.txt.House, einsteins_riddle.owl.txt.Pet, einsteins_riddle.owl.txt.Cigarette] properties (roles): [einsteins_riddle.owl.txt.drinks, einsteins_riddle.owl.txt.has_color, einsteins_riddle.owl.txt.lives_in, einsteins_riddle.owl.txt.owns, einsteins_riddle.owl.txt.right_to, einsteins_riddle.owl.txt.smokes, 1.1.description, 1.1.date, 1.1.creator] individuals: [einsteins_riddle.owl.txt.orange_juice, einsteins_riddle.owl.txt.tea, einsteins_riddle.owl.txt.water, einsteins_riddle.owl.txt.coffee, einsteins_riddle.owl.txt.milk, einsteins_riddle.owl.txt.Kools, einsteins_riddle.owl.txt.Lucky_Strike, einsteins_riddle.owl.txt.Parliaments, einsteins_riddle.owl.txt.Chesterfields, einsteins_riddle.owl.txt.Old_Gold, einsteins_riddle.owl.txt.green, einsteins_riddle.owl.txt.red, einsteins_riddle.owl.txt.blue, einsteins_riddle.owl.txt.yellow, einsteins_riddle.owl.txt.ivory, einsteins_riddle.owl.txt.house_2, einsteins_riddle.owl.txt.house_3, einsteins_riddle.owl.txt.house_1, einsteins_riddle.owl.txt.house_4, einsteins_riddle.owl.txt.house_5, einsteins_riddle.owl.txt.Ukrainian, einsteins_riddle.owl.txt.Spaniard, einsteins_riddle.owl.txt.Norwegian, einsteins_riddle.owl.txt.Englishman, einsteins_riddle.owl.txt.Japanese, einsteins_riddle.owl.txt.zebra, einsteins_riddle.owl.txt.horse, einsteins_riddle.owl.txt.snails, einsteins_riddle.owl.txt.dog, einsteins_riddle.owl.txt.fox]
list(onto.lives_in.get_relations())
[(einsteins_riddle.owl.txt.Norwegian, einsteins_riddle.owl.txt.house_1)]
list(onto.owns.get_relations())
[(einsteins_riddle.owl.txt.Spaniard, einsteins_riddle.owl.txt.dog)]
%time owl2.sync_reasoner_pellet(infer_property_values=True, infer_data_property_values=True, debug=0)
CPU times: user 30.8 ms, sys: 4.35 ms, total: 35.2 ms Wall time: 4.68 s
rels = list(onto.lives_in.get_relations())
print(rels)
[(einsteins_riddle.owl.txt.Norwegian, einsteins_riddle.owl.txt.house_1), (einsteins_riddle.owl.txt.Englishman, einsteins_riddle.owl.txt.house_3), (einsteins_riddle.owl.txt.Japanese, einsteins_riddle.owl.txt.house_5), (einsteins_riddle.owl.txt.Ukrainian, einsteins_riddle.owl.txt.house_2), (einsteins_riddle.owl.txt.Spaniard, einsteins_riddle.owl.txt.house_4)]
rels = list(onto.owns.get_relations())
print(rels)
[(einsteins_riddle.owl.txt.Spaniard, einsteins_riddle.owl.txt.dog), (einsteins_riddle.owl.txt.Englishman, einsteins_riddle.owl.txt.snails), (einsteins_riddle.owl.txt.Japanese, einsteins_riddle.owl.txt.zebra), (einsteins_riddle.owl.txt.Norwegian, einsteins_riddle.owl.txt.fox), (einsteins_riddle.owl.txt.Ukrainian, einsteins_riddle.owl.txt.horse)]
for r in rels:
print(f"n.{r[0].name}.owns: n.{r[1].name}")
n.Spaniard.owns: n.dog n.Englishman.owns: n.snails n.Japanese.owns: n.zebra n.Norwegian.owns: n.fox n.Ukrainian.owns: n.horse
The puzzle could be solved easily by the reasoner
Note: This Puzzle is also an example of yamlpyowl – an experimental package to represent OWL-Ontologies in YAML:
https://github.com/cknoll/yamlpyowl/blob/main/doc/demo_notebooks/zebra_puzzle.ipynb