uk.ac.manchester.cs.factplusplusad.Modularizer Maven / Gradle / Ivy
package uk.ac.manchester.cs.factplusplusad;
import static org.semanticweb.owlapi.util.OWLAPIStreamUtils.add;
import static uk.ac.manchester.cs.owlapi.modularity.ModuleType.STAR;
import static uk.ac.manchester.cs.owlapi.modularity.ModuleType.TOP;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.List;
import java.util.stream.Stream;
import org.semanticweb.owlapi.atomicdecomposition.ModuleMethod;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLEntity;
import org.semanticweb.owlapitools.decomposition.AxiomWrapper;
import uk.ac.manchester.cs.owlapi.modularity.ModuleType;
/**
* class to create modules of an ontology wrt module type
*/
public class Modularizer {
/**
* pointer to a sig index; if not NULL then use optimized algo
*/
private final SigIndex sigIndex;
/**
* shared signature signature
*/
private final Signature sig = new Signature();
/**
* 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;
/**
* true if no atoms are processed ATM
*/
private boolean noAtomsProcessing = true;
/**
* init c'tor
*
* @param moduleMethod module method
*/
Modularizer(ModuleMethod moduleMethod) {
checker = LocalityChecker.createLocalityChecker(moduleMethod, sig);
sigIndex = new SigIndex(checker);
}
// methods
/**
* update SIG wrt the axiom signature
*
* @param axiomSig signature to add
*/
void addAxiomSig(Stream axiomSig) {
axiomSig.filter(p -> !sig.contains(p)).forEach(p -> {
// new one
workQueue.push(p);
sig.add(p);
});
}
/**
* 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.signature());
}
/**
* @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;
}
/**
* add an axiom if it is non-local (or in noCheck is true)
*
* @param ax axiom to add
* @param noCheck check or not
*/
void addNonLocal(AxiomWrapper ax, boolean noCheck) {
if (noCheck || isNonLocal(ax)) {
addAxiomToModule(ax);
if (noAtomsProcessing && ax.getAtom().isPresent()) {
noAtomsProcessing = false;
addNonLocal(ax.getAtom().get().getModule(), true);
noAtomsProcessing = true;
}
}
}
/**
* Add all the non-local axioms from given axiom-set AxSet.
*
* @param axSet axiom set
* @param noCheck check or not
*/
void addNonLocal(Collection axSet, boolean noCheck) {
for (AxiomWrapper q : axSet) {
if (!q.isInModule() && q.isInSearchSpace()) {
addNonLocal(q, noCheck);
}
}
}
/**
* build a module traversing axioms by a signature
*/
private void extractModuleQueue() {
// init queue with a sig
add(workQueue, 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.pop());
addNonLocal(axioms, false);
}
}
/**
* extract module wrt presence of a sig index
*
* @param list axioms
*/
private void extractModule(Collection list) {
module.clear();
// clear the module flag in the input
list.forEach(p -> {
p.setInModule(false);
if (p.isUsed()) {
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
*/
void extract(Collection axioms, Signature signature, ModuleType type) {
boolean topLocality = type == TOP;
sig.setSignature(signature);
sig.setLocality(topLocality);
extractModule(axioms);
if (type != STAR) {
return;
}
// here there is a star: do the cycle until stabilization
int size;
List oldModule = new ArrayList<>();
do {
size = module.size();
oldModule.clear();
oldModule.addAll(module);
topLocality = !topLocality;
sig.setSignature(signature);
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 == TOP;
sig.setSignature(ax.signature());
sig.setLocality(topLocality);
// axiom is a tautology if it is local wrt its own signature
boolean toReturn = checker.local(ax);
if (type != 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;
}
}