/* Copyright 2008, 2009, 2010 by the Oxford University Computing Laboratory
This file is part of HermiT.
HermiT is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
HermiT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with HermiT. If not, see <http://www.gnu.org/licenses/>.
*/
package org.semanticweb.HermiT.examples;
import java.io.File;
import org.semanticweb.HermiT.Configuration;
import org.semanticweb.HermiT.Reasoner;
import org.semanticweb.HermiT.Configuration.TableauMonitorType;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyManager;
/**
* This examples demonstrates how HermiT's debugger can be used to see models or reasons
* for a clash. Note that this uses mainly an internal interface for HermiT that we use
* occasionally for debugging purposes. It assumes some understanding of hypertablau,
* normalisation, and structural transformation and is not meant as a general user
* interface for HermiT. Nevertheless it might be useful to some users, which is why we
* give an example of its use. No further support can, however, be given for this
* HermiT interface.
*/
public class HermiTDebugger {
public static void main(String[] args) throws Exception {
// First, we create an OWLOntologyManager object. The manager will load and
// save ontologies.
OWLOntologyManager manager=OWLManager.createOWLOntologyManager();
// Now, we create the file from which the ontology will be loaded.
// Here the ontology is stored in a file locally in the ontologies subfolder
// of the examples folder.
File inputOntologyFile = new File("examples/ontologies/pizza.owl");
// We use the OWL API to load the ontology.
OWLOntology ontology=manager.loadOntologyFromOntologyDocument(inputOntologyFile);
// Now we create a configuration object that we use to overwrite HermiT's default
// settings.
Configuration config=new Configuration();
// Lets make HermiT open a debugger window from which we can control the
// further actions that HermiT performs.
// DEBUGGER_HISTORY_ON will cause HermiT to save the deriviation tree for
// each derived conclusion.
// DEBUGGER_NO_HISTORY will not save the derivation tree, so no causes for a
// clash can be given, but the memory requirement is smaller.
config.tableauMonitorType=TableauMonitorType.DEBUGGER_HISTORY_ON;
// Now we can start and create the reasoner with the above created configuration.
Reasoner hermit = new Reasoner(config,ontology);
// This will open the debugger window at runtime and it should say:
// Good morning Dr. Chandra. This is HAL. I'm ready for my first lesson.
// Derivation history is on.
// Reasoning task started: ABox satisfiability
// >
// you can press 'c' to make HermiT continue with checking whether the ontology
// is consistent (ABox is satisfiable). HermiT should then say:
// Reasoning task finished: true
// >
// I.e., the ontlogy is consistent. Now, HermiT will work on the reasoning
// tasks that are specified below.
// The debugger window cannot be used to tell HermiT which tests should be performed.
// This has to be done via Java. First, we will ask HermiT to see whether the
// Siciliana pizza is satisfiable (it is).
// Once HermiT is done with testing consistency, you can type 'c' again to make
// HermiT start testing the satisfiability of the Siciliana pizza.
// HermiT will tell you that it started, but before really deriving anything,
// HermiT waits again to see whether you want to set further breakpoints, etc, but
// just type 'c' again for now.
IRI sicilianaIRI=IRI.create("http://www.co-ode.org/ontologies/pizza/pizza.owl#Siciliana");
OWLClass siciliana=manager.getOWLDataFactory().getOWLClass(sicilianaIRI);
hermit.isSatisfiable(siciliana);
// HermiT should now have said 'Reasoning task finished: true' in the debugger window.
// Now, you can type 'showModel' to see all the assertions in the ABox that HermiT generated.
// You should see several assertions of the form ':AnchoviesTopping[8]' or
// ':hasIngredient[6,7]'. This means that in the model abstractions that HermiT
// constructed there is an individual '8' that belongs to the class AnchoviesTopping and
// the individual '6' is related to the individual '7' via the property 'hasIngredient'.
// There are also assertions of the form 'all:n[m]', where 'm' is an individual in the
// model abstraction and 'all:n' with n an integer is a HermiT internal concept. Similarly
// there are internal concepts of the form nnq:n, def:n, and nom2:xxx, where xxx is a
// nominal in the ontology.
// You can also type 'showSubtree 6' to see the part of the model for the siciliana pizza.
// You have to ask for individul '6' because there are 5 nominals and we are not
// interested in the subtrees rooted in the nominals. If there are n nominals in the
// ontology, individuals 1...n will be nominal nodes as you can also see from the
// assertions of the form nom2:xxx[n].
// The showSubtree command uses a kind of folder view to visualise the part of the
// model abstraction. The colors of the nodes have the following meaning:
// black: root node
// green: blockable node (not blocked)
// light gray: inactive node
// cyan: blocked node
// red: node with unprocessed existentials
// magenta: description graph node
// blue: concrete/data value node
// Lets continue and see whether HermiT finds that the CheeseyVegetableTopping class is
// unsatisfiable (I know it is).
IRI cheeseyVegetableToppingIRI=IRI.create("http://www.co-ode.org/ontologies/pizza/pizza.owl#CheeseyVegetableTopping");
OWLClass cheeseyVegetableTopping=manager.getOWLDataFactory().getOWLClass(cheeseyVegetableToppingIRI);
hermit.isSatisfiable(cheeseyVegetableTopping);
// Type 'c' twice to start the task and continue to the end.
// You can still type 'showModel', but what you will get is just the last state of the
// model abstraction before HermiT had to give up because there is a clash and
// no further backtracking is possible.
// You can now type 'dertree clash'. This opens a window that shows the derivation
// history of the clash. This uses HermiT's internal clause form, so you might not
// recognise the axioms in you ontology anymore. The original axioms are modified by
// HermiT to get to the internal clause form, e.g., A implies B and C
// (SubClassOf(:A ObjectIntersectionOf(:B :C))) becomes
// A(x) -> B(x) and A(x) -> C(x), written in the debugger as
// B(x) :- A(x) and C(x) :- A(x)
// More complex axioms are split even further, e.g., A implies exists r.(exists s.B)
// (SubClassOf(:A ObjectSomeValuesFrom(:r ObjectSomeValuesFrom(:s :B))))
// becomes
// >=1r.Q(x) :- A(x) and >=1s.B(x) :- Q(x)
// with Q a fresh concept/class.
// In the derivation history you will see something like:
// (yellow icon) :CheeseTopping(6) <-- :CheeseTopping(X) :- :CheesyVegetableTopping(X)
// (pink icon) :CheesyVegetableTopping(6)
// This means that the base fact (pink) ':CheesyVegetableTopping(6)' (this fact was
// given because we test the satisfiability of CheesyVegetableTopping and 6 is the
// first non-nominal individua) has been used in the clause
// ':CheeseTopping(X) :- :CheesyVegetableTopping(X)'
// to derive
// ':CheeseTopping(6)'
// Similarly, the fact
// ':VegetableTopping(6)'
// was derived. Now, the clause
// ' :- :CheeseTopping(x), :VegetableTopping(x)'
// can be used to derive a clash. The clause says that CheeseTopping and
// VegetableTopping disjoint, i.e., they imply owl:Nothing/bottom/a clash as denoted
// by the empty head of the clause.
// The color codes in te derivation tree view have the following meaning:
// yellow: DL clause application
// cyan: disjunct application (choose and apply a disjunct)
// blue: merged two nodes
// dark grey: description graph checking
// black: clash
// red: existential expansion
// magenta: base/given fact
// If you want more debugging adventures, try to type 'help' in the debugger window
// to see more commands and options that can be used. Otherwise just close the window
// or type 'exit'. Have fun with HermiT!
}
}