org.semanticweb.owlapitools.decomposition.Modularizer Maven / Gradle / Ivy
package org.semanticweb.owlapitools.decomposition;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLEntity;
import uk.ac.manchester.cs.owlapi.modularity.ModuleType;
/**
* class to create modules of an ontology wrt module type
*/
public class Modularizer {
/**
* pointer to a signature index; if not NULL then use optimized algorithm
*/
private final SigIndex sigIndex;
/**
* shared signature signature
*/
private Signature sig;
/**
* internal syntactic locality checker
*/
private final LocalityChecker checker;
/**
* module as a list of axioms
*/
private final List module = new ArrayList<>();
/**
* queue of unprocessed entities
*/
private Deque workQueue;
/**
* number of locality check calls
*/
private long nChecks = 0;
/**
* number of non-local axioms
*/
private long nNonLocal = 0;
/**
* @param c the locality checker
*/
public Modularizer(LocalityChecker c) {
checker = c;
sig = c.getSignature();
sigIndex = new SigIndex(checker);
}
/**
* @return the signature
*/
public Signature getSignature() {
return sig;
}
/**
* update SIG wrt the axiom signature
*
* @param axiom axiom
*/
private void addAxiomSig(AxiomWrapper axiom) {
axiom.getAxiom().signature().filter(sig::add).forEach(workQueue::add);
}
/**
* add an axiom to a module
*
* @param axiom axiom
*/
private void addAxiomToModule(AxiomWrapper axiom) {
axiom.setInModule(true);
module.add(axiom);
// update the signature
addAxiomSig(axiom);
}
/**
* @param ax axiom
* @return true iff an AXiom is non-local
*/
private boolean isNonLocal(AxiomWrapper ax) {
boolean b = !checker.local(ax.getAxiom());
++nChecks;
if (b) {
++nNonLocal;
}
return b;
}
/**
* @param ax axiom add an axiom if it is non-local (or if noCheck is true)
* @param noCheck true if locality check is not to be performed
*/
private void addNonLocal(AxiomWrapper ax, boolean noCheck) {
if (noCheck || isNonLocal(ax)) {
addAxiomToModule(ax);
}
}
/**
* add all the non-local axioms from given axiom-set AxSet
*
* @param axSet collection of axioms
* @param noCheck true if locality check is not to be performed
*/
private void addNonLocal(Collection axSet, boolean noCheck) {
for (AxiomWrapper q : axSet) {
if (!q.isInModule() && q.isInSearchSpace()) {
this.addNonLocal(q, noCheck);
}
}
}
/**
* build a module traversing axioms by a signature
*/
private void extractModuleQueue() {
// init queue with a sig
workQueue.addAll(sig.getSignature());
// add all the axioms that are non-local wrt given value of a
// top-locality
addNonLocal(sigIndex.getNonLocal(sig.topCLocal()), true);
// main cycle
while (!workQueue.isEmpty()) {
// for all the axioms that contains entity in their signature
Collection axioms = sigIndex.getAxioms(workQueue.poll());
addNonLocal(axioms, false);
}
}
/**
* extract module wrt presence of a signature index
*
* @param list axioms
*/
private void extractModule(Collection list) {
module.clear();
// clear the module flag in the input
list.forEach(p -> p.setInModule(false));
list.stream().filter(AxiomWrapper::isUsed).forEach(p -> p.setInSearchSpace(true));
extractModuleQueue();
list.forEach(p -> p.setInSearchSpace(false));
}
/**
* allow the checker to preprocess an ontology if necessary
*
* @param axioms list of wrapped axioms
*/
public void preprocessOntology(Collection axioms) {
checker.preprocessOntology(axioms);
sigIndex.clear();
sigIndex.preprocessOntology(axioms);
workQueue = new ArrayDeque<>(axioms.size());
nChecks += 2 * axioms.size();
}
/**
* extract module wrt SIGNATURE and TYPE from the set of axioms
*
* @param axioms axiom
* @param signature signature
* @param type type
*/
public void extract(List axioms, Signature signature, ModuleType type) {
boolean topLocality = type == ModuleType.TOP;
sig = new Signature(signature.getSignature().stream());
checker.setSignatureValue(sig);
sig.setLocality(topLocality);
extractModule(axioms);
if (type != ModuleType.STAR) {
return;
}
// here there is a star: do the cycle until stabilization
int size;
do {
size = module.size();
List oldModule = new ArrayList<>(module);
topLocality = !topLocality;
sig = new Signature(signature.getSignature().stream());
checker.setSignatureValue(sig);
sig.setLocality(topLocality);
extractModule(oldModule);
} while (size != module.size());
}
/**
* @param ax axiom
* @param type type
* @return true iff the axiom AX is a tautology wrt given type
*/
public boolean isTautology(OWLAxiom ax, ModuleType type) {
boolean topLocality = type == ModuleType.TOP;
sig = new Signature(ax.signature());
sig.setLocality(topLocality);
// axiom is a tautology if it is local wrt its own signature
boolean toReturn = checker.local(ax);
if (type != ModuleType.STAR || !toReturn) {
return toReturn;
}
// here it is STAR case and AX is local wrt BOT
sig.setLocality(!topLocality);
return checker.local(ax);
}
/**
* @return the Locality checker
*/
public LocalityChecker getLocalityChecker() {
return checker;
}
/**
* @return the last computed module
*/
public Collection getModule() {
return module;
}
/**
* @return number of checks made
*/
long getNChecks() {
return nChecks;
}
/**
* @return number of axioms that were local
*/
long getNNonLocal() {
return nNonLocal;
}
/**
* @param axiom axiom
* @param signature signature
* @param type type
*/
public void extract(AxiomWrapper axiom, Signature signature, ModuleType type) {
this.extract(Collections.singletonList(axiom), signature, type);
}
}