package uk.ac.manchester.cs.jfact.split; /* This file is part of the JFact DL reasoner Copyright 2011-2013 by Ignazio Palmisano, Dmitry Tsarkov, University of Manchester This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*/ import java.io.Serializable; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import uk.ac.manchester.cs.jfact.kernel.Ontology; import uk.ac.manchester.cs.jfact.kernel.dl.interfaces.AxiomInterface; import conformance.Original; import conformance.PortedFrom; /** atomical decomposer of the ontology */ @PortedFrom(file = "AtomicDecomposer.h", name = "AtomicDecomposer") public class AtomicDecomposer implements Serializable { private static final long serialVersionUID = 11000L; /** atomic structure to build */ @PortedFrom(file = "AtomicDecomposer.h", name = "AOS") private AOStructure AOS = null; /** modularizer to build modules */ @PortedFrom(file = "AtomicDecomposer.h", name = "pModularizer") private final TModularizer Modularizer; /** tautologies of the ontology */ @PortedFrom(file = "AtomicDecomposer.h", name = "Tautologies") private final List<AxiomInterface> Tautologies = new ArrayList<AxiomInterface>(); /** progress indicator */ @PortedFrom(file = "AtomicDecomposer.h", name = "PI") private ProgressIndicatorInterface PI = null; /** fake atom that represents the whole ontology */ @PortedFrom(file = "AtomicDecomposer.h", name = "rootAtom") private TOntologyAtom rootAtom = null; /** module type for current AOS creation */ @PortedFrom(file = "AtomicDecomposer.h", name = "type") private ModuleType type; /** * @param c * modularizer */ public AtomicDecomposer(TModularizer c) { Modularizer = c; } /** restore all tautologies back */ @PortedFrom(file = "AtomicDecomposer.h", name = "restoreTautologies") private void restoreTautologies() { for (AxiomInterface p : Tautologies) { p.setUsed(true); } } /** * @param pi * progress indicator to use */ @PortedFrom(file = "AtomicDecomposer.h", name = "setProgressIndicator") public void setProgressIndicator(ProgressIndicatorInterface pi) { PI = pi; } /** * remove tautologies (axioms that are always local) from the ontology * temporarily * * @param O * O */ @PortedFrom(file = "AtomicDecomposer.h", name = "removeTautologies") private void removeTautologies(Ontology O) { // we might use it for another decomposition Tautologies.clear(); long nAx = 0; for (AxiomInterface p : O.getAxioms()) { if (p.isUsed()) { // check whether an axiom is local wrt its own signature Modularizer.extract(p, p.getSignature(), type); if (Modularizer.isTautology(p, type)) { Tautologies.add(p); p.setUsed(false); } else { ++nAx; } } } if (PI != null) { PI.setLimit(nAx); } } /** * build a module for given axiom AX; use parent atom's module as a base for * the module search * * @param sig * sig * @param parent * parent * @return new atom */ @PortedFrom(file = "AtomicDecomposer.h", name = "buildModule") private TOntologyAtom buildModule(TSignature sig, TOntologyAtom parent) { // build a module for a given signature Modularizer.extract(parent.getModule(), sig, type); List<AxiomInterface> Module = Modularizer.getModule(); // if module is empty (empty bottom atom) -- do nothing if (Module.isEmpty()) { return null; } // here the module is created; report it if (PI != null) { PI.incIndicator(); } // check if the module corresponds to a PARENT one; modules are the same // iff their sizes are the same if (parent != rootAtom && Module.size() == parent.getModule().size()) { return parent; } // create new atom with that module TOntologyAtom atom = AOS.newAtom(); atom.setModule(Module); return atom; } /** * create atom for given axiom AX; use parent atom's module as a base for * the module search * * @param ax * ax * @param parent * parent * @return new atom */ @PortedFrom(file = "AtomicDecomposer.h", name = "createAtom") private TOntologyAtom createAtom(AxiomInterface ax, TOntologyAtom parent) { // check whether axiom already has an atom if (ax.getAtom() != null) { return ax.getAtom(); } // build an atom: use a module to find atomic dependencies TOntologyAtom atom = buildModule(ax.getSignature(), parent); // no empty modules should be here assert atom != null; // register axiom as a part of an atom atom.addAxiom(ax); // if atom is the same as parent -- nothing more to do if (atom == parent) { return parent; } // not the same as parent: for all atom's axioms check their atoms and // make ATOM depend on them for (AxiomInterface q : atom.getModule()) { if (!q.equals(ax)) { atom.addDepAtom(createAtom(q, atom)); } } return atom; } /** @return all tautologies */ @Original public List<AxiomInterface> getTautologies() { return new ArrayList<AxiomInterface>(Tautologies); } /** @return the atom structure */ @PortedFrom(file = "AtomicDecomposer.h", name = "getAOS") public AOStructure getAOS() { return AOS; } /** * @param O * O * @param t * t * @return the atomic structure for given module type T */ @PortedFrom(file = "AtomicDecomposer.h", name = "getAOS") public AOStructure getAOS(Ontology O, ModuleType t) { // remember the type of the module type = t; // prepare a new AO structure AOS = new AOStructure(); // init semantic locality checker Modularizer.preprocessOntology(O.getAxioms()); // we don't need tautologies here removeTautologies(O); // init the root atom rootAtom = new TOntologyAtom(); rootAtom.setModule(new HashSet<AxiomInterface>(O.getAxioms())); // build the "bottom" atom for an empty signature TOntologyAtom BottomAtom = buildModule(new TSignature(), rootAtom); if (BottomAtom != null) { for (AxiomInterface q : BottomAtom.getModule()) { BottomAtom.addAxiom(q); } } // create atoms for all the axioms in the ontology for (AxiomInterface p : O.getAxioms()) { if (p.isUsed() && p.getAtom() == null) { createAtom(p, rootAtom); } } // restore tautologies in the ontology restoreTautologies(); rootAtom = null; AOS.reduceGraph(); return AOS; } /** @return number of performed locality checks */ @PortedFrom(file = "AtomicDecomposer.h", name = "getLocChekNumber") public long getLocChekNumber() { return Modularizer.getNChecks(); } }