简体   繁体   中英

Inconsistency and satisfiability of an OWL ontology in Java using Pellet reasoner

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, ie, 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?

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());
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM