0

I am trying to see whether an ontology is consistent or not. The ontology can be consistent, but still, it might have some unsatisfiable classes. Let’s call it Case A.

But my problem is, when the ontology can not pass the consistency test, i.e., it is inconsisetnt (Case B). My problem is even I cannot get unsatifiable classes of the ontology in Case B.

My final aim is to process the unsatisfiable classes to make some changes to them and make the inconsistent ontology to the consistent ones. So, I can achieve my aim in Case A (I have access to the unsatisfiable classes), I process them and revise some of them. But, now, what can I do for Case B?

The following code shows these two cases.

   OWLReasonerFactory reasonerFactory = new PelletReasonerFactory();
   OWLReasoner reasoner = reasonerFactory.createNonBufferingReasoner(myOntology);

    if (reasoner.isConsistent()) {
        if (reasoner.getUnsatisfiableClasses().getEntitiesMinusBottom().size() > 0) {
            System.out.println("ontology is consistent but has unsatisfiable classes! FAILED");
                    // CASE A
        } else {
            System.out.println("ontology is consistent and safe without any unsatisfiable classes! PASSED");
        }

    } else {
        System.out.println("ontology is inconsistent!FAILED");
                // CASE B
    }

For Case B, What can I do? In here, it wrote:

If you want to find the unsatisfiable classes, you just need to call the isSatisfiable method on all the classes: reasoner.isSatisfiable(className);

I put the following code in Case B:

    Iterator<OWLClass> cAll = myOntology.getClassesInSignature().iterator();
    while (cAll.hasNext()) {
            OWLClass c = cAll.next();
            if (!reasoner.isSatisfiable(c)) {
                System.out.println("class " + c + "is not satisfibale");
            }
    }

but I get an error, as:

Exception in thread "main" org.semanticweb.owlapi.reasoner.InconsistentOntologyException: Inconsistent ontology
    at com.clarkparsia.pellet.owlapiv3.PelletReasoner.convert(PelletReasoner.java:360)
    at com.clarkparsia.pellet.owlapiv3.PelletReasoner.isSatisfiable(PelletReasoner.java:890)

So how can I process the ontology in Case B?

Update

Based on the comments of @Ignazio, in the code of my question, in the place of //CASE B, I call this new function:

public static void run(OWLOntology myOnt) {
    // save the Tbox and Abox of the original ontology
    Set<OWLAxiom> originalTboxAxioms = myOnt.getTBoxAxioms(true);
    Set<OWLAxiom> originalAboxAxioms = myOnt.getABoxAxioms(true);

    // create new empty ontology
    String name = "local_path//name.owl";
    OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
    File fileM = new File(name);
    OWLOntology newOntology = null;

    try {
        newOntology = manager.createOntology(IRI.create(fileM));
    } catch (OWLOntologyCreationException e) {
        e.printStackTrace();
    }

    // add only Tboxes from the orginal ontology to the new one
    manager.addAxioms(newOntology, originalTboxAxioms);

    // checking the consistency of the new ontology which contain only tbox
    OWLReasonerFactory reasonerFactory = new PelletReasonerFactory();
    Configuration configuration = new Configuration();
    configuration.throwInconsistentOntologyException = false;
    OWLReasoner reasoner = reasonerFactory.createNonBufferingReasoner(newOntology, configuration);

    if (reasoner.isConsistent()) {
       Set<OWLClass> unSat = reasoner.getUnsatisfiableClasses().getEntitiesMinusBottom();        
       if (unSat.size() > 0) {
            Iterator<OWLClass> unClassList = unSat.iterator();

            Set<OWLClass> listOfUnsatisfiableClasses = new HashSet<OWLClass>();
            while (unClassList.hasNext()) {
                /*
                 * if the unsatisfiable class appear in the original Abox,
                 * we mark it as an unsatisfiable class
                 */
                OWLClass myClass = unClassList.next();
                Iterator<OWLAxiom> iter = originalAboxAxioms.iterator();
                    while (iter.hasNext()){
                        OWLAxiom ax = iter.next();
                        if (ax.getClassesInSignature().contains(myClass)){
                            listOfUnsatisfiableClasses.add(myClass);    
                        }
                    }
            }
            System.out.println("number of unsatisfiable classes: " + listOfUnsatisfiableClasses.size());
        }
    }
    System.out.println("The ontology is inconsistent but does not have any unsatisfiable classes!!!!!");
}

Even with this new function, no unsatisfiable calsses can be found!

I also tried the code in here that @Ignazio posted. For the given exmple there, that code will be run in a few seconds, but for my small inconsistent ontology even after 1 day, no result would be printed.

Any more idea how to get unsatisfiable classes alongside with their justification sets?

Sami
  • 1
  • 1
  • More than a day runtime without any output means the reasoner got stuck retrieving all unsatisfiable classes - which suggests a really large ontology. Is it a publicly available ontology? If so please link it so we can see the same data you're using. I've reviewed the code and pointed out a couple of improvements, but they won't change the results if the ontology is so complex that the reasoner cannot retrieve unsatisfiable classes. – Ignazio Apr 25 '20 at 08:40
  • Thanks, I update the code as you suggested it. My ontology is not available, and it is big, it has near 150,000 axioms. One more question: If the ontology is inconsistent, it means it does not have any model. If it is coherent, it means, it does not have any unsatisfiable classes and justification. For this situation, when the ontology does not have any model and no unsatisfiable classes, what can I do? Could you provide more explanations for the ontology without any model (inconsistent)? – Sami Apr 25 '20 at 16:16
  • For a big complex ontology, no available reasoner can retrieve the unsatisfiable classes, or this is the problem of Pellet reasoner? – Sami Apr 25 '20 at 16:22
  • There are many variables about complexity of an ontology, as well as potential bugs in reasoners. I can't tell whether another reasoner might work better, depends also on what version you're using and the ontology profile. For an EL++ ontology, ELK might be the best choice; for OWL 2 DL you could try Konclude or Openllet. – Ignazio Apr 25 '20 at 17:47
  • 'It does not have unsatisfiable classes' is not too useful a definition - all ontologies have owl:Nothing, as it's part of the language. Mostly, unsatisfiable classes might be modeling mistakes - there's little other reason to have them. – Ignazio Apr 25 '20 at 17:53
  • thanks, my last question: According to this [paper](https://link.springer.com/chapter/10.1007/978-3-642-04388-8_11), An inconsistent ontology, is an ontology that, by virtue of what has been stated in the ontology, cannot have any models. When a reasoner said `reasoner.isConsistent()== false` , it means the ontology does not have any model. It means we do not have access to the ontology’s model, and what else can be the description of it? – Sami Apr 26 '20 at 11:28
  • "model" in that context is not an object model, it's a logical model, i.e., an interpretation without contradictions. Formally defined here https://www.w3.org/2007/OWL/wiki/Direct_Semantics#Models basically if an ontology is inconsistent there's no interpretation of its terms that make sense (there's a contradiction). – Ignazio Apr 26 '20 at 11:35

1 Answers1

0

Inconsistent ontology means there are instances of unsatisfiable classes, or there are instances of two or more classes that are declared disjoint.

(Possibly, there might be individuals declared to be of type owl:Nothing, but that's easy to detect and probably an error.)

To figure out whether the inconsistency depends on unsatisfiable classes or not, you can try separating the abox and tbox - then check the tbox alone. You can list the axiom types that belong to the tbox with the convenience methods in AxiomType.

Update: Looking at the code, there are a few things to fix:

    if (reasoner.getUnsatisfiableClasses().getEntitiesMinusBottom().size() > 0) {
        ^^^^^^^^^^^^^^ you're calling reasoner.getUnsatisfiableClasses() twice,
                       forcing the reasoner to do more work than necessary.
                       Store this set in a local variable, or skip the size check
                       (if the set is empty, the iterator will be empty
                       and you'll skip the while anyway.
      Iterator<OWLClass> unClassList = reasoner.getUnsatisfiableClasses().getEntitiesMinusBottom().iterator();


        Set<OWLClass> listOfUnsatisfiableClasses = new HashSet<OWLClass>();
        while (unClassList.hasNext()) {
            /*
             * if the unsatisfiable class appear in the original Abox,
             * we mark it as an unsatisfiable class
             */
            OWLClass myClass = unClassList.next();
            if (originalAboxAxioms.contains(myClass))
                listOfUnsatisfiableClasses.add(myClass);
            ^^^^^^ this code is not doing what the comment is saying.
                   originalAboxAxioms contains abox axioms, not classes,
                   so you'll never get true as a result of this lookup.
                   Also, the classes will necessarily be part of the ontology,
                   so you can skip this altogether.
        }
        System.out.println("number of unsatisfiable classes: " + listOfUnsatisfiableClasses.size());
    }
Ignazio
  • 10,504
  • 1
  • 14
  • 25
  • Thanks. I can get `Tbox` like `myOnt..getTBoxAxioms(true)`. But what can I do with them? could you please explain more. I also can get special types of axioms like `myOnt.getAxioms(AxiomType.CLASS_ASSERTION);`. but which type of entities or axioms should I check? – Sami Apr 21 '20 at 11:11
  • I also get all my classes and check them whether they are equivalent to OLW:Nothing. Is that correct? `if (myClass.isBottomEntity()){System.out.println(c + " is equivalent to OWL:Nothing, thus we mark it as an unsatisfiable class." );}` if yes, then I can say, my ontology is inconsistent and include these unsatisfiable classes. If so, how can I get their explanation and justification set of them (reasoner can't process them) – Sami Apr 21 '20 at 11:12
  • To check if a class is unsatisfiable you need to ask the reasoner - checking if it is a bottom entity is only the OWLAPI checking that the IRI is the same as owl:Nothing but it does no reasoning. – Ignazio Apr 23 '20 at 21:26
  • Class assertions are abox axioms that state which individuals belong to which classes; in your case, I would take the tbox axioms and store them in a separate ontology, then check the new ontology for consistency (I would expect it to be consistent at this point) and hunt for unsatisfiable classes. If you find unsatisfiable classes, check if they appear in class assertions in the original ontology. If they do, they're the cause of your inconsistency. – Ignazio Apr 23 '20 at 21:28