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

owl_api.services.concrete.ExplanationOWLAPI Maven / Gradle / Ivy

There is a newer version: 1.0.5
Show newest version
package owl_api.services.concrete;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;

import org.semanticweb.owl.explanation.impl.blackbox.BlackBoxExplanationGenerator2;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.slf4j.LoggerFactory;

import com.clarkparsia.pellet.owlapiv3.PelletReasonerFactory;

import fr.boreal.component_builder.api.IInputDataScenario;
import fr.boreal.io.dlgp.DlgpParser;
import fr.boreal.io.dlgp.ParserResult;
import fr.boreal.model.logicalElements.api.Atom;
import fr.boreal.model.logicalElements.factory.api.PredicateFactory;
import fr.boreal.model.logicalElements.factory.api.TermFactory;
import fr.boreal.model.logicalElements.factory.impl.SameObjectPredicateFactory;
import fr.boreal.model.logicalElements.factory.impl.SameObjectTermFactory;
import owl_api.binding.OWLAPIAlgorithmParameterConfig;
import owl_api.binding.OWLAPIExplanatorBuilder;
import owl_api.services.OWLAPIOperations;
import owl_api.utils.DLGPToOWLTranslation;
import tools.service.AbstractService;
import tools.service.CommonOps;
import tools.service.metadata.IOperationMetadata;
import tools.service.metadata.OperationMetadataFactory;

/**
 * Service calling the OWL API for fact entailment explanation
 */
public class ExplanationOWLAPI extends AbstractService {

	OWLOntologyManager manager;
	OWLDataFactory dataFactory;
	PelletReasonerFactory reasonerFactory;
	OWLOntology ontology;
	OWLReasoner reasoner;
	BlackBoxExplanationGenerator2 generator;

	PredicateFactory predicateFactory = SameObjectPredicateFactory.instance();
	TermFactory termFactory = SameObjectTermFactory.instance();
	Collection FactEntailmentsToExplain = new ArrayList<>();
	private OWLAxiom owlAPIEntailment;

	/**
	 * 
	 * Constructor
	 * 
	 * @param ids
	 * @param iap
	 */
	public ExplanationOWLAPI(IInputDataScenario ids, OWLAPIAlgorithmParameterConfig iap) {

		super(ids, iap);

		LOG = LoggerFactory.getLogger(ExplanationOWLAPI.class);

	}

	@Override
	protected void prepareServiceSpecificOperations() {

		setup(OWLAPIOperations.LOAD_OWL_ONTOLOGY, this::loadData);

		setup(OWLAPIOperations.BUILD_REASONER_FOR_ENTAILMENT_CHECKING, this::initializeReasoner);

		setup(CommonOps.BUILD_EXPLANATOR, this::buildExplanator);

		setup(CommonOps.QUERY_LOADING, this::loadQueries);

		queries().forEach(query -> prepareServiceOperationsForExplanation(query));

	}

	public void loadData() {

		manager = OWLManager.createOWLOntologyManager();

		try {

			ontology = manager.loadOntologyFromOntologyDocument(new File(getRuleBasePath()));

		} catch (OWLOntologyCreationException e) {
			e.printStackTrace();

			throw new RuntimeException(e);
		}
	}

	public void loadQueries() {

		var parsed = DlgpParser.parseFiles(inputDataScenario.getQuerybasePath().get());

		checkParsedQueries(parsed);

		FactEntailmentsToExplain.addAll(parsed.atoms());

	}

	public void initializeReasoner() {

		reasonerFactory = new com.clarkparsia.pellet.owlapiv3.PelletReasonerFactory();
		reasoner = reasonerFactory.createReasoner(ontology);
		dataFactory = manager.getOWLDataFactory();
	}

	/**
	 * Builds the explanator form the input configuration
	 */
	public void buildExplanator() {

		this.generator = new OWLAPIExplanatorBuilder(inputAlgorithmParameters, ontology.getAxioms(), reasonerFactory)
				.build();

	}

	private void prepareServiceOperationsForExplanation(Atom a) {

		operation(translateOperationMetadata(a), () -> dlgpQueriesToOWLAxioms(a));

		operation(explainOperationMetadata(a), this::explain);
	}

	private void checkParsedQueries(ParserResult parsed) {

		if (!parsed.queries().isEmpty() || !parsed.rules().isEmpty() || !parsed.views().isEmpty()) {
			LOG.warn(
					"The query file contains elements that are not facts, but only fact entailment is supported for explanations.");
		}

		if (parsed.atoms().isEmpty()) {
			LOG.warn("No atoms to explain.");
		}

	}

	public void dlgpQueriesToOWLAxioms(Atom a) {

		this.owlAPIEntailment = DLGPToOWLTranslation.atomToClassAssertionAxiom(a);

		// LOG.info("Atom {} is translated to: {}", a, this.owlAPIEntailment);

	}

	private void explain() {

		Set> owlexplanations = generator
				.getExplanations(this.owlAPIEntailment);

		LOG.debug("Explanation size: " + owlexplanations.size());

	}

	private String getRuleBasePath() {

		if (this.inputDataScenario.getRulebasePath().isEmpty()
				|| this.inputDataScenario.getRulebasePath().get().stream().findAny().isEmpty()) {

			var e = new IllegalArgumentException("Missing ontology file in " + inputDataScenario);

			LOG.error("", e);

			throw e;

		}

		return this.inputDataScenario.getRulebasePath().get().stream().findAny().get();

	}

	private IOperationMetadata explainOperationMetadata(Atom a) {
		var description = CommonOps.EXPLAIN_FACT.description() + " for " + a;
		var serializationKey = CommonOps.EXPLAIN_FACT.serializationKey();

		return OperationMetadataFactory.createMetadata(description, serializationKey);
	}

	private IOperationMetadata translateOperationMetadata(Atom a) {
		var description = OWLAPIOperations.TRANSLATE_DLGP_FACTS_TO_OWL_AXIOM.description() + " for " + a;
		var serializationKey = OWLAPIOperations.TRANSLATE_DLGP_FACTS_TO_OWL_AXIOM.serializationKey();

		return OperationMetadataFactory.createMetadata(description, serializationKey);
	}

	private Iterable queries() {

		loadQueries(); // we need to load to the queries to define the test protocol

		return this.FactEntailmentsToExplain;

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy