/**
* SPINdle (version 2.2.2)
* Copyright (C) 2009-2012 NICTA Ltd.
*
* This file is part of SPINdle project.
*
* SPINdle 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 3 of the License, or
* (at your option) any later version.
*
* SPINdle 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 SPINdle. If not, see <http://www.gnu.org/licenses/>.
*
* @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory
*/
package spindle.engine;
import java.util.Map;
import java.util.TreeMap;
import com.app.utils.TextUtilities;
import com.app.utils.Utilities;
import spindle.core.dom.Theory;
import spindle.core.dom.TheoryType;
import spindle.engine.tdl.TdlConclusionUpdater;
import spindle.sys.AppConst;
import spindle.sys.Conf;
import spindle.sys.message.ErrorMessage;
import spindle.tools.evaluator.LiteralVariablesEvaluator;
/**
* Factory class for theory normalizer and reasoning engine
*
* @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory
* @since version 1.0.0
* @version Last modified 2012.09.18
* @version 2012.07.21
*/
public final class ReasoningEngineFactory {
private static enum ENGINE_TYPE {
AB, AP, AB_WF, AP_WF
};
private static LiteralVariablesEvaluator literalVariableEvaluator = null;
private static TdlConclusionUpdater conclusionUpdater = null;
private static Map<TheoryType, Map<Integer, TheoryNormalizer>> theoryNormalizersStore = new TreeMap<TheoryType, Map<Integer, TheoryNormalizer>>();
private static Map<TheoryType, Map<ENGINE_TYPE, Map<Integer, ReasoningEngine>>> reasoningEnginesStore = new TreeMap<TheoryType, Map<ENGINE_TYPE, Map<Integer, ReasoningEngine>>>();
/**
* Return a copy of literal variables evaluator.
*
* @return Literal variable evaluator.
*/
public static final LiteralVariablesEvaluator getLiteralVariablesEvaluator() {
if (Conf.isMultiThreadMode()) return new LiteralVariablesEvaluator();
if (null == literalVariableEvaluator) literalVariableEvaluator = new LiteralVariablesEvaluator();
return literalVariableEvaluator;
}
/**
* Return a copy of conclusion updater for TDL literals data store according to the configuration information.
*
* @return Conclusion updater.
* @throws ReasoningEngineFactoryException
*/
public static final TdlConclusionUpdater getTdlConclusionUpdater() throws ReasoningEngineFactoryException {
if (null == conclusionUpdater) {
String clazzName = Conf.getTdlConclusionUpdaterClassName();
try {
if (!AppConst.isDeploy) System.out.print("generating TDL conclusion updater class [" + clazzName + "]");
conclusionUpdater = Utilities.getInstance(clazzName, TdlConclusionUpdater.class);
if (!AppConst.isDeploy) System.out.println("..success");
} catch (Exception e) {
if (!AppConst.isDeploy) System.out.println("..failed");
throw new ReasoningEngineFactoryException("exception throw while generating TDL conclusion updater class [" + clazzName
+ "]", e);
}
}
return conclusionUpdater;
}
/**
* Create a new theory normalizer according to the theory type and reasoner version.
*
* @param theoryType theory type.
* @param reasonerVersion reasoner version.
* @return theory normalizer associated with the theory type
* @throws ReasoningEngineFactoryException Indicates when there is no theory normalizer associated with the theory
* type specified or the theory type does not exist.
*/
private static final TheoryNormalizer createTheoryNormalizer(TheoryType theoryType, int reasonerVersion)
throws ReasoningEngineFactoryException {
TheoryNormalizer theoryNormalizer = null;
switch (theoryType) {
case SDL:
switch (reasonerVersion) {
case 1:
theoryNormalizer = new spindle.engine.sdl.SdlTheoryNormalizer();
break;
default:
theoryNormalizer = new spindle.engine.sdl.SdlTheoryNormalizer2();
}
break;
case MDL:
switch (reasonerVersion) {
case 1:
theoryNormalizer = new spindle.engine.mdl.MdlTheoryNormalizer();
break;
default:
theoryNormalizer = new spindle.engine.mdl.MdlTheoryNormalizer2();
}
break;
case TDL:
// only available when the package is not in deploy mode
// - used for testing purpose
if (AppConst.isDeploy)
throw new ReasoningEngineFactoryException(ErrorMessage.THEORY_NORMALIZER_NOT_SUPPORTED, new Object[] { TheoryType.TDL });
try {
theoryNormalizer = new spindle.engine.tdl.TdlTheoryNormalizer2();
} catch (TheoryNormalizerException e) {
throw new ReasoningEngineFactoryException(e);
}
break;
default:
throw new ReasoningEngineFactoryException(ErrorMessage.THEORY_UNRECOGNIZED_THEORY_TYPE, new Object[] { theoryType });
}
return theoryNormalizer;
}
/**
* Return a theory normalizer as specified if the type of theory normalizer is in the theory normalizers store.
* or create a new one otherwise.
*
* @param theoryType theory type.
* @param reasonerVersion reasoner version.
* @return theory normalizer associated with the theory type
* @throws ReasoningEngineFactoryException Indicates when there is no theory normalizer associated with the theory
* type specified or the theory type does not exist.
*/
private static final TheoryNormalizer getTheoryNormalizerFromStore(TheoryType theoryType, int reasonerVersion)
throws ReasoningEngineFactoryException {
Map<Integer, TheoryNormalizer> theoryNormalizers = theoryNormalizersStore.get(theoryType);
if (null == theoryNormalizers) {
theoryNormalizers = new TreeMap<Integer, TheoryNormalizer>();
theoryNormalizersStore.put(theoryType, theoryNormalizers);
}
TheoryNormalizer theoryNormalizer = theoryNormalizers.get(reasonerVersion);
if (null == theoryNormalizer) {
theoryNormalizer = createTheoryNormalizer(theoryType, reasonerVersion);
theoryNormalizers.put(reasonerVersion, theoryNormalizer);
}
return theoryNormalizer;
}
/**
* Return a theory normalizer according to the theory type.
*
* @param theoryType theory type
* @return theory normalizer associated with the theory type
* @throws ReasoningEngineFactoryException Indicates when there is no theory normalizer associated with the theory
* type specified or the theory type does not exist.
*/
public static final TheoryNormalizer getTheoryNormalizer(TheoryType theoryType) throws ReasoningEngineFactoryException {
if (theoryType == null) return null;
if (Conf.isMultiThreadMode()) {
return createTheoryNormalizer(theoryType, Conf.getReasonerVersion());
} else {
return getTheoryNormalizerFromStore(theoryType, Conf.getReasonerVersion());
}
}
/**
* Create a reasoning engine according to the theory type, engine type and reasoner version.
*
* @param theoryType theory type.
* @param engineType engine type (ambiguity blocking, ambiguity propagation, well-founded semantics, or their
* combination).
* @param reasonerVersion reasoner version.
* @return Reasoning engine with appropriate type as specified.
* @throws ReasoningEngineFactoryException
*/
private static final ReasoningEngine createReasoningEngine(TheoryType theoryType, ENGINE_TYPE engineType, int reasonerVersion)
throws ReasoningEngineFactoryException {
ReasoningEngine engine = null;
switch (theoryType) {
case SDL:
switch (reasonerVersion) {
case 1:
switch (engineType) {
case AB:
case AB_WF:
engine = new spindle.engine.sdl.SdlReasoningEngine();
break;
case AP:
case AP_WF:
engine = new spindle.engine.sdl.SdlReasoningEngineAP();
break;
}
break;
default:
switch (engineType) {
case AB:
case AB_WF:
engine = new spindle.engine.sdl.SdlReasoningEngine2();
break;
case AP:
case AP_WF:
engine = new spindle.engine.sdl.SdlReasoningEngineAP2();
break;
}
}
break;
case MDL:
switch (reasonerVersion) {
case 1:
switch (engineType) {
case AB:
case AB_WF:
engine = new spindle.engine.mdl.MdlReasoningEngine();
break;
case AP:
case AP_WF:
engine = new spindle.engine.mdl.MdlReasoningEngineAP();
break;
}
break;
default:
switch (engineType) {
case AB:
case AB_WF:
engine = new spindle.engine.mdl.MdlReasoningEngine2();
break;
case AP:
case AP_WF:
engine = new spindle.engine.mdl.MdlReasoningEngineAP2();
break;
}
}
break;
case TDL: // TDL support only available in version 2 onward
if (!AppConst.isDeploy) {
try {
engine = new spindle.engine.tdl.TdlReasoningEngine2();
} catch (ReasoningEngineException e) {
throw new ReasoningEngineFactoryException(e);
}
}
break;
default:
throw new ReasoningEngineFactoryException(ErrorMessage.THEORY_UNRECOGNIZED_THEORY_TYPE);
}
return engine;
}
/**
* Return a reasoning engine as specified if the type of engine is in the reasoning engines store;
* or create a new one otherwise.
*
* @param theoryType theory type.
* @param engineType engine type (ambiguity blocking, ambiguity propagation, well-founded semantics, or their
* combination).
* @param reasonerVersion reasoner version.
* @return Reasoning engine with appropriate type as specified.
* @throws ReasoningEngineFactoryException
*/
private static final ReasoningEngine getReasoningEngineFromStore(TheoryType theoryType, ENGINE_TYPE engineType, int reasonerVersion)
throws ReasoningEngineFactoryException {
Map<ENGINE_TYPE, Map<Integer, ReasoningEngine>> enginesSetByTheoryType = reasoningEnginesStore.get(theoryType);
if (null == enginesSetByTheoryType) {
enginesSetByTheoryType = new TreeMap<ENGINE_TYPE, Map<Integer, ReasoningEngine>>();
reasoningEnginesStore.put(theoryType, enginesSetByTheoryType);
}
Map<Integer, ReasoningEngine> enginesSet = enginesSetByTheoryType.get(engineType);
if (null == enginesSet) {
enginesSet = new TreeMap<Integer, ReasoningEngine>();
enginesSetByTheoryType.put(engineType, enginesSet);
}
ReasoningEngine engine = enginesSet.get(reasonerVersion);
if (null == engine) {
engine = createReasoningEngine(theoryType, engineType, reasonerVersion);
enginesSet.put(reasonerVersion, engine);
}
engine.clear();
return engine;
}
/**
* Return a reasoning engine according to the theory type, reasoning mode and reasoner version required.
*
* @param theory defeasible theory
* @return reasoning engine associated with the theory type and reasoning mode configured.
* @throws ReasoningEngineFactoryException Indicates when there is no reasoning engine associated with the theory
* type or reasoning mode specified.
*/
public static final ReasoningEngine getReasoningEngine(Theory theory) throws ReasoningEngineFactoryException {
if (theory == null) return null;
TheoryType theoryType = theory.getTheoryType();
if (Conf.isShowProgress() || !AppConst.isDeploy) {
if (theory.getTheoryType() != TheoryType.SDL || Conf.isReasoningWithAmbiguityPropagation()
|| Conf.isReasoningWithWellFoundedSemantics()) {
StringBuilder sb = new StringBuilder();
sb.append("Inferencing with ") //
.append(theoryType).append(" reasoning engine (version ").append(Conf.getReasonerVersion()).append(")");
if (Conf.isReasoningWithAmbiguityPropagation()) sb.append("\n - Ambiguity Propagation");
if (Conf.isReasoningWithWellFoundedSemantics()) sb.append("\n - Well-Founded Semantics");
System.out.println(TextUtilities.generateHighLightedMessage(sb.toString()));
}
}
ENGINE_TYPE engineType = Conf.isReasoningWithAmbiguityPropagation() ? ENGINE_TYPE.AP : ENGINE_TYPE.AB;
if (Conf.isMultiThreadMode()) {
return createReasoningEngine(theoryType, engineType, Conf.getReasonerVersion());
} else {
return getReasoningEngineFromStore(theoryType, engineType, Conf.getReasonerVersion());
}
}
}