All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.semanticweb.owl.simpleowlapi.SimpleOWLReasoner Maven / Gradle / Ivy

package org.semanticweb.owl.simpleowlapi;

import java.util.Set;

import org.semanticweb.owl.explanation.api.Explanation;
import org.semanticweb.owl.explanation.api.ExplanationGenerator;
import org.semanticweb.owl.explanation.impl.blackbox.checker.InconsistentOntologyExplanationGeneratorFactory;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.parameters.Imports;
import org.semanticweb.owlapi.reasoner.InconsistentOntologyException;
import org.semanticweb.owlapi.reasoner.InferenceType;
import org.semanticweb.owlapi.reasoner.Node;
import org.semanticweb.owlapi.reasoner.NodeSet;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;

import com.clarkparsia.owlapi.explanation.DefaultExplanationGenerator;
import com.clarkparsia.owlapi.explanation.util.SilentExplanationProgressMonitor;

import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl;

/**
simpleOWLAPI is a light-weight wrapper for the OWLAPI enabling more concise OWL ontology development.

Copyright (C) <2020>  Kody Moodley

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program 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 Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see .
*/

/** Class for simpleOWLAPI which provides access to methods for reasoning with OWL ontologies. 
 * @author Kody Moodley
 * @author https://sites.google.com/site/kodymoodley/
 * @version 0.0.1
*/
public class SimpleOWLReasoner
{
    /** the OWLOntology object being reasoned with
    */
    public OWLOntology ontology;
    /** the IRI of the ontology being reasoned with
    */
    public IRI ontologyIRI;
    /** the OWLReasoner object which is responsible for reasoning
    */
    public OWLReasoner reasoner;
    /** Parser instance
    */
    public Parser parser;
    /** OWLDataFactory instance
    */
    public static OWLDataFactory dataFactory = new OWLDataFactoryImpl();
    /** SelectedReasoner instance
    */
    public SelectedReasoner selectedReasoner;
    /** OWLReasonerFactory instance
    */
    public OWLReasonerFactory reasonerFactory;
    /** An instance of a default explanation generator for computing justifications for entailments
    */
    public DefaultExplanationGenerator explanationGenerator;
    /** An instance of Matthew Horridge's explanation generator factory for inconsistent ontologies
    */
    public InconsistentOntologyExplanationGeneratorFactory inconsistencyExpFac;
    /** An instance of Matthew Horridge's explanation generator for inconsistent ontologies
    */
    public ExplanationGenerator inconsistencyExplanationGenerator;
    
    /** SimpleOWLReasoner constructor
     * @param reasonerFactory reference to a specific OWLReasonerFactory implementation
     * @param ontology an OWLOntology object representing the ontology to be reasoned with
     * @param parser a Parser instance (Manchester OWL Syntax)
     * @param selectedReasoner a SelectedReasoner instance holding metadata about the selected OWL reasoner 
    */
    public SimpleOWLReasoner(OWLReasonerFactory reasonerFactory, OWLOntology ontology, Parser parser, SelectedReasoner selectedReasoner) {
        this.selectedReasoner = selectedReasoner;
        this.reasonerFactory = reasonerFactory;
        this.ontology = ontology;
        this.ontologyIRI = this.ontology.getOntologyID().getDefaultDocumentIRI().get();
        this.reasoner = reasonerFactory.createNonBufferingReasoner(this.ontology);
        try {
        	this.reasoner.precomputeInferences(InferenceType.CLASS_HIERARCHY);
        }
        catch (org.mindswap.pellet.exceptions.InconsistentOntologyException ioe1) {
        	System.out.println("SimpleOWLAPI ERROR: <" + ontologyIRI.toString() + ">" + " is inconsistent!");
        }
        catch (org.semanticweb.owlapi.reasoner.InconsistentOntologyException ioe2) {
        	System.out.println("SimpleOWLAPI ERROR: <" + ontologyIRI.toString() + ">" + " is inconsistent!");
        }
        this.parser = parser;
    }
    
//    public static synchronized SimpleOWLReasoner getInstance(OWLReasonerFactory reasonerFactory, OWLOntology ontology, Parser parser, SelectedReasoner selectedReasoner) 
//    { 
//        if (obj==null){
//            obj = new SimpleOWLReasoner(reasonerFactory, ontology, parser, selectedReasoner); 
//        }
//        return obj; 
//    }
//    
//    public void updateReasoner(OWLOntology ontology) {
//    	reasoner.dispose();
//        this.reasoner = reasonerFactory.createNonBufferingReasoner(ontology);
//        this.ontologyIRI = ontology.getOntologyID().getDefaultDocumentIRI().get();
//        reasoner.precomputeInferences(InferenceType.CLASS_HIERARCHY);
//    }
    
    // Get all atomic subclasses for the given class expression (both inferred by the reasoner and asserted)
    
    /** prints all atomic subclasses (both direct and indirect) of a given class expression string to console output
     * @param classEx a class expression string in Manchester OWL Syntax 
    */
    public void getSubClasses(String classEx)
    {
        reasoner.flush();
        try {
	        NodeSet subclasses = reasoner.getSubClasses(parser.createClassExpression(classEx), false);
	        for (Node nc: subclasses){
	            for (OWLClass c: nc){
	                if (!c.isOWLNothing() && !c.isOWLThing())
	                    System.out.println(Parser.renderer.render(c));
	            }
	        }
	        System.out.println();
        }
        catch (InconsistentOntologyException ioe) {
        	System.out.println("SimpleOWLAPI ERROR: <" + ontology.getOntologyID().getDefaultDocumentIRI().get().toString() + ">" + " is inconsistent!");
        }
    }

    /** prints all atomic superclasses (both direct and indirect) of a given class expression string to console output
     * @param classEx a class expression string in Manchester OWL Syntax 
    */
    public void getSuperClasses(String classEx)
    {
        reasoner.flush();
        try {
	        NodeSet supclasses = reasoner.getSuperClasses(parser.createClassExpression(classEx), false);
	        for (Node nc: supclasses){
	            for (OWLClass c: nc){
	                if (!c.isOWLNothing() && !c.isOWLThing())
	                    System.out.println(Parser.renderer.render(c));
	            }
	        }
	        System.out.println();
        }
        catch (InconsistentOntologyException ioe) {
        	System.out.println("SimpleOWLAPI ERROR: <" + ontology.getOntologyID().getDefaultDocumentIRI().get().toString() + ">" + " is inconsistent!");
        }
    }

    /** prints all unsatisfiable class names in the ontology associated with this SimpleOWLReasoner instance to console output
    */
    public void getUnsatisfiableClasses(){
        reasoner.flush();
        try {
	        Node classes = reasoner.getUnsatisfiableClasses();
	        for (OWLClass c: classes){
	            if (!c.isOWLNothing())
	                System.out.println(Parser.renderer.render(c));
	        }
        }
        catch (InconsistentOntologyException ioe) {
        	System.out.println("SimpleOWLAPI ERROR: <" + ontology.getOntologyID().getDefaultDocumentIRI().get().toString() + ">" + " is inconsistent!");
        }
    }

    /** prints Yes to console output if the ontology associated with this SimpleOWLReasoner instance is consistent, prints No otherwise 
    */
    public void isConsistent(){
        reasoner.flush();
        if (reasoner.isConsistent())
            System.out.println("Yes");
        else
            System.out.println("No");
    }

    /** prints all atomic classes to console output, such that the individual (represented by the given string) is an instance of these classes 
     * @param ind string representation of an individual name in the ontology 
    */
    public void getTypes(String ind){
        this.reasoner.flush();
        try {
	        NodeSet typesC = this.reasoner.getTypes(dataFactory.getOWLNamedIndividual(IRI.create(ontologyIRI.toString()+ind)), false);
	        for (Node c: typesC){
	            for (OWLClass c2: c){
	                if (!c2.isOWLThing())
	                    System.out.println(Parser.renderer.render(c2));
	            }
	        }
	        System.out.println();
        }
        catch (InconsistentOntologyException ioe) {
        	System.out.println("SimpleOWLAPI ERROR: <" + ontology.getOntologyID().getDefaultDocumentIRI().get().toString() + ">" + " is inconsistent!");
        }
    }

    /** for each individual in the ontology, prints all atomic classes to console output, such that the individual is an instance of these classes 
    */
    public void getAllTypes(){
        this.reasoner.flush();
        try {
	        for (OWLIndividual i : ontology.getIndividualsInSignature(Imports.EXCLUDED)){
	            System.out.println(Parser.renderer.render(i));
	            System.out.println("-----------");
	            getTypes(Parser.renderer.render(i));
	            System.out.println();
	        }
	        System.out.println();
        }
        catch (InconsistentOntologyException ioe) {
        	System.out.println("SimpleOWLAPI ERROR: <" + ontology.getOntologyID().getDefaultDocumentIRI().get().toString() + ">" + " is inconsistent!");
        }
    }

    /** for a given object property, print all object property assertions it is involved in, to console output
     * @param opropStr string representing an object property   
    */
    public void getOPropertyAssertions(String opropStr){
        this.reasoner.flush();
        try {
	        System.out.println(opropStr);
	        System.out.println("-----------");
	        Set inds = ontology.getIndividualsInSignature(Imports.EXCLUDED);
	        for (OWLNamedIndividual i :inds){
	            NodeSet indP = this.reasoner.getObjectPropertyValues(i, dataFactory.getOWLObjectProperty(IRI.create(ontologyIRI.toString()+opropStr)));
	            for (Node n: indP) {
	                for (OWLNamedIndividual ai : n){
	                    System.out.println(Parser.renderer.render(i) + "," + Parser.renderer.render(ai));
	                }
	            }        
	        }
	        System.out.println();
        }
        catch (InconsistentOntologyException ioe) {
        	System.out.println("SimpleOWLAPI ERROR: <" + ontology.getOntologyID().getDefaultDocumentIRI().get().toString() + ">" + " is inconsistent!");
        }

        System.out.println();
    }

    /** for each object property in the ontology, print all object property assertions they are involved in to console output   
    */
    public void getAllOPropertyAssertions(){
        this.reasoner.flush();
        try {
	        for (OWLObjectProperty o : ontology.getObjectPropertiesInSignature(Imports.EXCLUDED)){
	            getOPropertyAssertions(Parser.renderer.render(o));
	            System.out.println();
	        }
	        System.out.println();
        }
        catch (InconsistentOntologyException ioe) {
        	System.out.println("SimpleOWLAPI ERROR: <" + ontology.getOntologyID().getDefaultDocumentIRI().get().toString() + ">" + " is inconsistent!");
        }
    }
    
    /** print the name of the selected OWL reasoner to console output   
    */
    public void getName() {
    	System.out.println(selectedReasoner.getName());
    }
    
    /** print the name of the OWL 2 profile that this reasoner supports to console output   
    */
    public void getOWLProfile() {
    	System.out.println(selectedReasoner.getProfile());
    }

    /** prints Yes to console output if the given string represents an OWLAxiom in Manchester OWL Syntax that is entailed by the ontology. Prints No, otherwise
     * @param axiomStr a string representation of an OWLAxiom in Manchester OWL Syntax   
    */
    public void isEntailed(String axiomStr){
        parser.setString(axiomStr);
        OWLAxiom axiom = parser.getParser().parseAxiom();
        this.reasoner.flush();
        try {
	        if (this.reasoner.isEntailed(axiom))
	            System.out.println("Yes");
	        else
	            System.out.println("No");
	        System.out.println();
        }
        catch (InconsistentOntologyException ioe) {
        	System.out.println("SimpleOWLAPI ERROR: <" + ontology.getOntologyID().getDefaultDocumentIRI().get().toString() + ">" + " is inconsistent!");
        }
    }
    
    /** prints Yes to console output if the given string represents an OWLClassExpression in Manchester OWL Syntax that is satisfiable w.r.t. the ontology. Prints No, otherwise
     * @param clsStr a string representation of an OWLClassExpression in Manchester OWL Syntax   
    */
    public void isSatisfiable(String clsStr){
    	OWLClassExpression cls = parser.createClassExpression(clsStr);
        reasoner.flush();
        try {
        	if (reasoner.isSatisfiable(cls))
        		System.out.println("Yes");
        	else
        		System.out.println("No");
	        System.out.println();
        }
        catch (InconsistentOntologyException ioe) {
        	System.out.println("SimpleOWLAPI ERROR: <" + ontology.getOntologyID().getDefaultDocumentIRI().get().toString() + ">" + " is inconsistent!");
        }
    }
    
    /** prints to console output the explanations (justifications) for the unsatisfiability of a class expression (represented by the given string in Manchester OWL Syntax). Prints 'NOT unsatisfiable' if the class expression is satisfiable.
     * @param clsStr a string representation of an OWLClassExpression in Manchester OWL Syntax   
    */
	public void explainUnsatisfiability(String clsStr)
	{
		reasoner.flush();
		try {
			explanationGenerator = new DefaultExplanationGenerator(ontology.getOWLOntologyManager(), reasonerFactory, ontology, new SilentExplanationProgressMonitor());
			OWLClassExpression cls = parser.createClassExpression(clsStr);
			if (!reasoner.isSatisfiable(cls)) {
	        	System.out.println();
				Set> explanations = explanationGenerator.getExplanations(cls);
		
				int count = 1;
				for (Set exp: explanations){
					System.out.println("Explanation " + count);
					System.out.println("--------------");
					for (OWLAxiom ex: exp){
						System.out.println(Parser.renderer.render(ex));
					}
					count++;
					System.out.println();
				}
			}
			else {
				System.out.println(Parser.renderer.render(cls) + " is NOT unsatisfiable!");
			}
		}
		catch (InconsistentOntologyException ioe) {
			System.out.println("SimpleOWLAPI ERROR: <" + ontology.getOntologyID().getDefaultDocumentIRI().get().toString() + ">" + " is inconsistent!");
		}
	}
	
    /** prints to console output the explanations (justifications) for the inconsistency of the ontology. Prints 'NOT inconsistent' if the ontology is consistent
    */
	public void explainInconsistency()
	{
		reasoner.flush();
        inconsistencyExpFac = new InconsistentOntologyExplanationGeneratorFactory(reasonerFactory, Long.MAX_VALUE);
        inconsistencyExplanationGenerator = inconsistencyExpFac.createExplanationGenerator(ontology);
		if (!reasoner.isConsistent()) {
        	System.out.println();
			OWLAxiom axiom = dataFactory.getOWLSubClassOfAxiom(dataFactory.getOWLThing(), dataFactory.getOWLNothing());
			Set> explanations = inconsistencyExplanationGenerator.getExplanations(axiom);
			int count = 1;
			for (Explanation exp: explanations)
			{
				printExplanation(exp, count);
				count++;
			}
		}
		else {
			System.out.println("SimpleOWLAPI ERROR: <" + ontology.getOntologyID().getDefaultDocumentIRI().get().toString() + ">" + " is NOT inconsistent!");
		}
	}

    /** prints to console output the explanations (justifications) for the entailment of the axiom (represented by the given string in Manchester OWL Syntax)
     * @param axiomStr a string representation of an OWLAxiom in Manchester OWL Syntax
    */
	public void explainEntailment(String axiomStr)
	{
		reasoner.flush();
		explanationGenerator = new DefaultExplanationGenerator(ontology.getOWLOntologyManager(), reasonerFactory, ontology, new SilentExplanationProgressMonitor());
		OWLAxiom axiom = parser.createAxiom(axiomStr);
		Set> explanations = explanationGenerator.getExplanations(axiom);
		
    	System.out.println();
		int count = 1;
		for (Set exp: explanations)
		{
			printExplanation(exp, count);
			count++;
		}
	}
	
    /** prints a single explanation with a given integer id
     * @param explanation a set of OWLAxiom objects
     * @param idx an integer representing an ID or number for this explanation in a sequence
    */
	public void printExplanation(Set explanation, int idx) {
		System.out.println("Explanation " + idx);
		System.out.println("--------------");
		for (OWLAxiom axiom: explanation){
			System.out.println(Parser.renderer.render(axiom));
		}
		System.out.println();
	}
	
    /** prints a single explanation with a given integer id
     * @param explanation an Explanation object which contains a set of OWLAxiom objects
     * @param idx an integer representing an ID or number for this explanation in a sequence
    */
	public void printExplanation(Explanation explanation, int idx) {
		System.out.println("Explanation " + idx);
		System.out.println("--------------");
		for (OWLAxiom axiom: explanation.getAxioms()){
			System.out.println(Parser.renderer.render(axiom));
		}
		System.out.println();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy