{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "CWPK \\#26: Introduction to Knowledge Graph Reasoners\n", "=======================================\n", "\n", "Two Standards Come Pre-packaged with Owlready2\n", "--------------------------\n", "\n", "
PATH
statement in your environmental variables to find the Java executable. If you encounter such problems, please consult third-party sources to get Java properly configured for your system before continuing with this installment."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Test Ontology\n",
"To make sure that your system is configured properly, go ahead and shift+enter
or Run this cell that enters a small example ontology from the [owlready2 documentation](https://owlready2.readthedocs.io/en/latest/reasoning.html):"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from owlready2 import *\n",
"\n",
"onto = get_ontology(\"http://test.org/onto.owl\")\n",
"\n",
"with onto:\n",
" class Drug(Thing):\n",
" def take(self): print(\"I took a drug\")\n",
"\n",
" class ActivePrinciple(Thing):\n",
" pass\n",
"\n",
" class has_for_active_principle(Drug >> ActivePrinciple):\n",
" python_name = \"active_principles\"\n",
"\n",
" class Placebo(Drug):\n",
" equivalent_to = [Drug & Not(has_for_active_principle.some(ActivePrinciple))]\n",
" def take(self): print(\"I took a placebo\")\n",
"\n",
" class SingleActivePrincipleDrug(Drug):\n",
" equivalent_to = [Drug & has_for_active_principle.exactly(1, ActivePrinciple)]\n",
" def take(self): print(\"I took a drug with a single active principle\")\n",
"\n",
" class DrugAssociation(Drug):\n",
" equivalent_to = [Drug & has_for_active_principle.min(2, ActivePrinciple)]\n",
" def take(self): print(\"I took a drug with %s active principles\" % len(self.active_principles))\n",
"\n",
"acetaminophen = ActivePrinciple(\"acetaminophen\")\n",
"amoxicillin = ActivePrinciple(\"amoxicillin\")\n",
"clavulanic_acid = ActivePrinciple(\"clavulanic_acid\")\n",
"\n",
"AllDifferent([acetaminophen, amoxicillin, clavulanic_acid])\n",
"\n",
"drug1 = Drug(active_principles = [acetaminophen])\n",
"drug2 = Drug(active_principles = [amoxicillin, clavulanic_acid])\n",
"drug3 = Drug(active_principles = [])\n",
"\n",
"close_world(Drug)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then, run the HermiT reasoner with the single command:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"* Owlready2 * Running HermiT...\n",
" java -Xmx2000M -cp C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\hermit;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\hermit\\HermiT.jar org.semanticweb.HermiT.cli.CommandLine -c -O -D -I file:///C:/Users/mike/AppData/Local/Temp/tmpbnxf7755\n",
"* Owlready2 * HermiT took 0.4851553440093994 seconds\n",
"* Owlready * Reparenting onto.drug2: {onto.Drug} => {onto.DrugAssociation}\n",
"* Owlready * Reparenting onto.drug1: {onto.Drug} => {onto.SingleActivePrincipleDrug}\n",
"* Owlready * Reparenting onto.drug3: {onto.Drug} => {onto.Placebo}\n",
"* Owlready * (NB: only changes on entities loaded in Python are shown, other changes are done but not listed)\n"
]
}
],
"source": [
"sync_reasoner()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The feedback you get to screen should indicate that you are 'Reparenting' the three drugs from one class (Drug
) to their appropriate sublasses. By the way, you could also place this argument in the command to turn off the debug reports to screen: $ sync_reasoner(debug = 0)
.\n",
"\n",
"You can also confirm this move for drug2
: "
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"drug2 new Classes: onto.DrugAssociation\n"
]
}
],
"source": [
"print(\"drug2 new Classes:\", drug2.__class__)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And, then, in the next three cells, confirm how you took those three drugs:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"I took a drug with a single active principle\n"
]
}
],
"source": [
"drug1.take()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"I took a drug with 2 active principles\n"
]
}
],
"source": [
"drug2.take()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"I took a placebo\n"
]
}
],
"source": [
"drug3.take()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And, last, in the next two cells discover if any inconsistent classes remain (they do not), which is equivalent to a class being assigned to the Nothing
class in OWL:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(default_world.inconsistent_classes())"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"if Nothing in Drug.equivalent_to:\n",
" print(\"Drug is inconsistent!\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### General Load Method\n",
"OK, so now we see the HermiT reasoner is configured properly and working, we are now ready to test our KBpedia knowledge graph. Go ahead and select Kernel → Restart & Clear Output from the main menu to begin the next activities from a clean slate.\n",
"\n",
"Then execute what has become our standard load procedure:\n",
"\n",
"#
) out.infer_property_values = True
:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"* Owlready2 * Running HermiT...\n",
" java -Xmx2000M -cp C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\hermit;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\hermit\\HermiT.jar org.semanticweb.HermiT.cli.CommandLine -c -O -D -I file:///C:/Users/mike/AppData/Local/Temp/tmpxkc92ws4 -Y\n",
"* Owlready2 * HermiT took 0.416165828704834 seconds\n",
"* Owlready * (NB: only changes on entities loaded in Python are shown, other changes are done but not listed)\n"
]
}
],
"source": [
"sync_reasoner(infer_property_values = True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We see that the ontology is consistent, which we can confirm with this additional command:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(world.inconsistent_classes())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Pellet Reasoner\n",
"The second of our reasoners, Pellet, operates under a similar set of arguments. We invoke Pellet through the modified reasoner command:."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"* Owlready2 * Running Pellet...\n",
" java -Xmx2000M -cp C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\antlr-3.2.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\antlr-runtime-3.2.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\aterm-java-1.6.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\commons-codec-1.6.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\httpclient-4.2.3.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\httpcore-4.2.2.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jcl-over-slf4j-1.6.4.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jena-arq-2.10.0.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jena-core-2.10.0.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jena-iri-0.9.5.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jena-tdb-0.10.0.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jgrapht-jdk1.5.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\log4j-1.2.16.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\owlapi-distribution-3.4.3-bin.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\pellet-2.3.1.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\slf4j-api-1.6.4.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\slf4j-log4j12-1.6.4.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\xercesImpl-2.10.0.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\xml-apis-1.4.01.jar pellet.Pellet realize --loader Jena --input-format N-Triples --ignore-imports C:\\Users\\mike\\AppData\\Local\\Temp\\tmp7_rotl4_\n",
"* Owlready2 * Pellet took 1.017836093902588 seconds\n",
"* Owlready * (NB: only changes on entities loaded in Python are shown, other changes are done but not listed)\n"
]
}
],
"source": [
"sync_reasoner_pellet()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Pellet, too, is configured to run in a debug mode. If you wish, you may turn it off with $ sync_reasoner(debug = 0)
.\n",
"\n",
"Like HermiT we can also infer_property_values
. But, different than HermiT, we may also infer_data_property_values = True
using Pellet:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"* Owlready2 * Running Pellet...\n",
" java -Xmx2000M -cp C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\antlr-3.2.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\antlr-runtime-3.2.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\aterm-java-1.6.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\commons-codec-1.6.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\httpclient-4.2.3.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\httpcore-4.2.2.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jcl-over-slf4j-1.6.4.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jena-arq-2.10.0.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jena-core-2.10.0.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jena-iri-0.9.5.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jena-tdb-0.10.0.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\jgrapht-jdk1.5.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\log4j-1.2.16.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\owlapi-distribution-3.4.3-bin.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\pellet-2.3.1.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\slf4j-api-1.6.4.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\slf4j-log4j12-1.6.4.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\xercesImpl-2.10.0.jar;C:\\1-PythonProjects\\Python\\lib\\site-packages\\owlready2\\pellet\\xml-apis-1.4.01.jar pellet.Pellet realize --loader Jena --input-format N-Triples --infer-prop-values --infer-data-prop-values --ignore-imports C:\\Users\\mike\\AppData\\Local\\Temp\\tmpcr2dw8yi\n",
"* Owlready2 * Pellet took 0.6863009929656982 seconds\n",
"* Owlready * (NB: only changes on entities loaded in Python are shown, other changes are done but not listed)\n"
]
}
],
"source": [
"sync_reasoner_pellet(infer_property_values = True, infer_data_property_values = True)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(world.inconsistent_classes())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### SWRL\n",
"As long as we are introducing these capabilities, we should also mention that Owlready2 also supports the use of [SWRL](https://en.wikipedia.org/wiki/Semantic_Web_Rule_Language) (the Semantic Web Rule Language) \"if . . . then\" type statements. To the best of my knowledge, Owlready2 supports all of the standard SWRL constructs. It is also possible to mix Python and OWL code together, but that, too, is a topic we will not be addressing further in this CWPK series."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Save and Exit\n",
"\n",
"When we are finished with our tests, we can File → Save and Checkpoint, Rename our output file, or specify it at the command line:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"kb.save(file = 'files/kbpedia_reference_concepts-pellet.owl', format = 'rdfxml')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Additional Documentation\n",
"\n",
"Here are links to appropriate Owlready2 documentation:\n",
"- [Reasoners](https://owlready2.readthedocs.io/en/latest/reasoning.html)\n",
"- [SWRL](https://owlready2.readthedocs.io/en/latest/rule.html)\n",
"- [Python + OWL](https://owlready2.readthedocs.io/en/latest/mixing_python_owl.html).\n",
"\n",
"\n",
"\n",
" *.ipynb
file. It may take a bit of time for the interactive option to load.