/**
* 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.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.logging.Level;
import com.app.utils.Utilities.ProcessStatus;
import spindle.core.MessageType;
import spindle.core.dom.Conclusion;
import spindle.core.dom.ConclusionType;
import spindle.core.dom.Literal;
import spindle.core.dom.Rule;
import spindle.core.dom.RuleExt;
import spindle.core.dom.RuleType;
import spindle.core.dom.Superiority;
import spindle.core.dom.Theory;
import spindle.core.dom.TheoryException;
import spindle.sys.AppConst;
import spindle.sys.AppModuleBase;
import spindle.sys.AppModuleListener;
import spindle.sys.Conf;
import spindle.sys.Messages;
import spindle.sys.message.ErrorMessage;
import spindle.sys.message.SystemMessage;
import spindle.tools.analyser.TheoryAnalyser;
import spindle.tools.explanation.InferenceLogger;
/**
* Base class for reasoning engines.
*
* @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory
* @since version 1.0.0
* @version Last modified 2012.07.21
*/
public abstract class ReasoningEngineBase extends AppModuleBase implements ReasoningEngine {
public static final String STRICT_TO_DEFEASIBLE_POSTFIX = "_s2d";
private static ReasoningEngineUtilities reasoningEngineUtilities = null;
protected Theory theory = null;
private TheoryAnalyser _theoryAnalyser = null;
protected Map<String, Rule> strictRules = null;
protected Map<String, Rule> defeasibleRules = null;
protected Map<Literal, Map<ConclusionType, Conclusion>> _conclusions = null;
private Map<Literal, Set<ConclusionType>> records = null;
private Timer timer = null;
protected boolean isUpdateInapplicableLiteralsBeforeInference = true;
protected Map<ConclusionType, Set<Literal>> inapplicableLiteralsBeforeInference = null;
protected boolean isLogInferenceProcess = false;
private InferenceLogger inferenceLogger = null;
public ReasoningEngineBase() {
super();
inapplicableLiteralsBeforeInference = new TreeMap<ConclusionType, Set<Literal>>();
}
@Override
public Map<Literal, Map<ConclusionType, Conclusion>> getConclusions(final Theory theory) throws ReasoningEngineException {
clear();
if (theory == null) throw new ReasoningEngineException(getClass(), ErrorMessage.THEORY_NULL_THEORY);
if (theory.isEmpty()) throw new ReasoningEngineException(getClass(), ErrorMessage.THEORY_EMPTY_THEORY);
// this.theory = (Conf.isCloneTheoryInReasoner()) ? theory.clone() : theory;
this.theory = theory;
// if (this.theory.getLiteralVariableCount() > 0)
if (this.theory.getLiteralVariablesInRulesCount() > 0)
throw new ReasoningEngineException(getClass(), ErrorMessage.REASONING_ENGINE_LITERAL_VARIABLES_NOT_YET_EVALUATED);
if (this.theory.getLiteralBooleanFunctionCount() > 0)
throw new ReasoningEngineException(getClass(), ErrorMessage.REASONING_ENGINE_LITERAL_BOOLEAN_FUNCTION_NOT_YET_EVALUATED);
if (this.theory.getFactsCount() > 0)
throw new ReasoningEngineException(getClass(), ErrorMessage.THEORY_NOT_IN_REGULAR_FORM_CONTAINS_FACT);
if (this.theory.getDefeatersCount() > 0)
throw new ReasoningEngineException(getClass(), ErrorMessage.THEORY_NOT_IN_REGULAR_FORM_CONTAINS_DFEATER);
switch (Conf.getReasonerVersion()) {
case 1:
if (this.theory.getSuperiorityCount() > 0)
throw new ReasoningEngineException(getClass(), ErrorMessage.THEORY_NOT_IN_REGULAR_FORM_CONTAINS_SUPERIORITY_RELATION);
break;
default:
}
// assume the theory is normalized,
// i.e., no facts, defeaters and superiority is needed to be considered
strictRules = this.theory.getRules(RuleType.STRICT);
defeasibleRules = this.theory.getRules(RuleType.DEFEASIBLE);
//records = new TreeMap<Literal, Map<ConclusionType, Conclusion>>();
records=new TreeMap<Literal,Set<ConclusionType>>();
if (Conf.isShowProgress()) getReasoningEngineUtilities().printTheorySummary(this.theory);
try {
isLogInferenceProcess = Conf.isLogInferenceProcess();
_initialize();
fireSetInapplicableLiteralsBeforeInference();
isUpdateInapplicableLiteralsBeforeInference = false;
if (Conf.isReasonerGarbageCollection()) {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.gc();
}
}, Conf.getGarbageCollectionTimeInterval() + 20, Conf.getGarbageCollectionTimeInterval());
}
if (Conf.isShowProgress()) {
if (null == timer) timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
fireOnReasoningEngineMessage(MessageType.INFO, getProgressMessage());
}
}, Conf.getShowProgressTimeInterval() + 10, Conf.getShowProgressTimeInterval());
}
_generateConclusions();
if (Conf.isShowProgress())
System.out.println(Messages.getSystemMessage(SystemMessage.REASONING_ENGINE_ALL_PENDING_CONCLUSIONS_ARE_EVALUATED));
if (isLogInferenceProcess) fireSetInferenceLogger();
_terminate();
return _conclusions;
} catch (ReasoningEngineException e) {
throw e;
} finally {
if (timer != null) {
timer.cancel();
timer = null;
}
}
}
protected void removeRules(Set<String> ruleLabels) throws ReasoningEngineException {
logMessage(Level.FINE, 0, "removeRules:", ruleLabels);
try {
for (String ruleLabel : ruleLabels) {
removeRule(ruleLabel);
}
} catch (ReasoningEngineException e) {
throw e;
} catch (Exception e) {
throw new ReasoningEngineException(getClass(), e);
}
}
protected void removeRule(String ruleLabel) throws ReasoningEngineException {
try {
Rule rule = theory.getRule(ruleLabel);
Rule ruleRemoved = null;
switch (rule.getRuleType()) {
case STRICT:
ruleRemoved = strictRules.remove(ruleLabel);
if (null == ruleRemoved)
throw new ReasoningEngineException(getClass(), "removeRule: strict rule NOT found! ruleLabel=" + ruleLabel);
try {
theory.removeRule(ruleLabel);
logMessage(Level.FINE, 0, "removeRule: strict rule", ruleLabel, " - removed");
} catch (TheoryException e) {
throw new ReasoningEngineException(getClass(), e);
}
break;
case DEFEASIBLE:
ruleRemoved = defeasibleRules.get(ruleLabel);
if (null == ruleRemoved)
throw new ReasoningEngineException(getClass(), "removeRule: defeasible rule NOT found! ruleLabel=" + ruleLabel);
try {
switch (Conf.getReasonerVersion()) {
case 2:
// update superiority rules counter
Set<Superiority> superiorities = theory.getSuperior(ruleLabel);
if (null != superiorities) {
List<Superiority> s2 = new Vector<Superiority>(superiorities);
for (int i = s2.size() - 1; i >= 0; i--) {
Superiority sup = s2.get(i);
((RuleExt) theory.getRule(sup.getInferior())).strongerRulesCountDecrement();
theory.remove(sup);
}
}
superiorities = theory.getInferior(ruleLabel);
if (null != superiorities) {
List<Superiority> s2 = new Vector<Superiority>(superiorities);
for (int i = s2.size() - 1; i >= 0; i--) {
Superiority sup = s2.get(i);
((RuleExt) theory.getRule(sup.getSuperior())).weakerRulesCountDecrement();
theory.remove(sup);
}
}
break;
default:
}
theory.removeRule(ruleLabel);
logMessage(Level.FINE, 0, "removeRule: defeasiblerule", ruleLabel, " - removed");
} catch (TheoryException e) {
throw new ReasoningEngineException(getClass(), e);
}
break;
default:
}
} catch (ReasoningEngineException e) {
throw e;
} catch (Exception e) {
throw new ReasoningEngineException(getClass(), "removeRule" + ruleLabel + "\n======" + theory, e);
}
}
protected Set<Literal> getConflictLiterals(final Literal literal) {
Set<Literal> conflictLiterals = theory.getConflictLiterals(literal);
//logMessage(Level.FINEST, 2, "*** ", literal, "conflict literals=", conflictLiterals);
return conflictLiterals;
}
private ProcessStatus _generateConclusions() throws ReasoningEngineException {
logMessage(Level.INFO, 0, Messages.getSystemMessage(SystemMessage.REASONING_ENGINE_CONCLUSIONS_GENERATION_START));
generateConclusions();
logMessage(Level.INFO, 0, Messages.getSystemMessage(SystemMessage.REASONING_ENGINE_CONCLUSIONS_GENERATION_END));
return ProcessStatus.SUCCESS;
}
private ProcessStatus _initialize() throws ReasoningEngineException {
logMessage(Level.INFO, 0, Messages.getSystemMessage(SystemMessage.REASONING_ENGINE_INITIALIZE_START));
initialize();
logMessage(Level.INFO, 0, Messages.getSystemMessage(SystemMessage.REASONING_ENGINE_INITIALIZE_END));
return ProcessStatus.SUCCESS;
}
private ProcessStatus _terminate() throws ReasoningEngineException {
logMessage(Level.INFO, 0, Messages.getSystemMessage(SystemMessage.REASONING_ENGINE_TERMINATE_START));
terminate();
logMessage(Level.INFO, 0, Messages.getSystemMessage(SystemMessage.REASONING_ENGINE_TERMINATE_END));
return ProcessStatus.SUCCESS;
}
protected ProcessStatus setConclusion(Map<Literal, Map<ConclusionType, Conclusion>> conclusions) {
// protected ProcessStatus setConclusion(Map<Literal, Map<ConclusionType, Conclusion>> conclusions) {
this._conclusions = conclusions;
return ProcessStatus.SUCCESS;
}
/**
* verify conclusions - remove conflicting conclusions from the conclusion list
*
* @return list of consolidated conclusions
*/
protected synchronized Map<Literal, Map<ConclusionType, Conclusion>> verifyConclusions(
Map<Literal, Map<ConclusionType, Conclusion>> pendingConclusionSet) {
Map<Literal, Map<ConclusionType, Conclusion>> verifiedConclusions = new TreeMap<Literal, Map<ConclusionType, Conclusion>>(
pendingConclusionSet);
Set<Conclusion> conclusionsToRemove = new TreeSet<Conclusion>();
if (AppConst.isDeploy) {
// if in deploy mode, execute the loop without appending the string builder.
for (Entry<Literal,Map<ConclusionType,Conclusion>>literalEntry:pendingConclusionSet.entrySet()){
Literal literal=literalEntry.getKey();
Map<ConclusionType,Conclusion> conclusionsSet=literalEntry.getValue();
// for (Literal literal : pendingConclusionSet.keySet()) {
// Map<ConclusionType, Conclusion> conclusionsSet = pendingConclusionSet.get(literal);
Map<ConclusionType, Conclusion> complementConclusionsSet = pendingConclusionSet.get(literal.getComplementClone());
for (Conclusion conclusion : conclusionsSet.values()) {
if (conclusion.isConflictWith(conclusionsSet.values())) {
conclusionsToRemove.add(conclusion);
}
if (complementConclusionsSet != null) {
if (conclusion.isConflictWith(complementConclusionsSet.values())) {
conclusionsToRemove.add(conclusion);
}
}
}
}
} else {
// otherwise, execute the loop with string appending.
// ** code duplicated here due to efficiency purpose.
StringBuilder sb = new StringBuilder();
for (Entry<Literal,Map<ConclusionType,Conclusion>>literalEntry:pendingConclusionSet.entrySet()){
Literal literal=literalEntry.getKey();
Map<ConclusionType,Conclusion> conclusionsSet=literalEntry.getValue();
// for (Literal literal : pendingConclusionSet.keySet()) {
sb.append(LINE_SEPARATOR).append("for literal: ").append(literal.toString());
// Map<ConclusionType, Conclusion> conclusionsSet = pendingConclusionSet.get(literal);
Map<ConclusionType, Conclusion> complementConclusionsSet = pendingConclusionSet.get(literal.getComplementClone());
for (Conclusion conclusion : conclusionsSet.values()) {
ConclusionType conclusionType = conclusion.getConclusionType();
sb.append(LINE_SEPARATOR).append(AppConst.IDENTATOR).append("Check conclusion: ").append(conclusion.toString());
if (conclusion.isConflictWith(conclusionsSet.values())) {
conclusionsToRemove.add(conclusion);
sb.append(LINE_SEPARATOR).append(AppConst.IDENTATOR)
.append("conclusion contains conflict, remove conclusion type: ").append(conclusionType.toString());
}
if (complementConclusionsSet != null) {
if (conclusion.isConflictWith(complementConclusionsSet.values())) {
conclusionsToRemove.add(conclusion);
sb.append(LINE_SEPARATOR).append(AppConst.IDENTATOR)
.append("conclusion contains conflict, remove conclusion type: ").append(conclusionType.toString());
}
}
}
}
logMessage(Level.INFO, 0, sb.toString());
}
if (conclusionsToRemove.size() > 0) {
for (Conclusion conclusionToRemove : conclusionsToRemove) {
Map<ConclusionType, Conclusion> conclusionsList = verifiedConclusions.get(conclusionToRemove.getLiteral());
ConclusionType conclusionType = conclusionToRemove.getConclusionType();
conclusionsList.remove(conclusionType);
if (conclusionsList.size() == 0) verifiedConclusions.remove(conclusionToRemove.getLiteral());
}
}
return verifiedConclusions;
}
protected void addInapplicableLiteralsBeforeInference(Literal literal, ConclusionType conclusionType) {
if (!isUpdateInapplicableLiteralsBeforeInference) return;
Set<Literal> literalsSet = inapplicableLiteralsBeforeInference.get(conclusionType);
if (null == literalsSet) {
literalsSet = new TreeSet<Literal>();
inapplicableLiteralsBeforeInference.put(conclusionType, literalsSet);
}
literalsSet.add(literal);
}
public Set<Literal> getInapplicableLiteralsBeforeInference(ConclusionType conclusionType) {
return inapplicableLiteralsBeforeInference.get(conclusionType);
}
protected ProcessStatus duplicateStrictRulesToDefeasibleRules() throws ReasoningEngineException {
List<Rule> newDefeasibleRules = theory
.duplicateRulesToType(strictRules.values(), RuleType.DEFEASIBLE, STRICT_TO_DEFEASIBLE_POSTFIX);
for (Rule rule : newDefeasibleRules) {
try {
theory.addRule(rule);
} catch (TheoryException e) {
throw new ReasoningEngineException(getClass(), "Exception throw while duplicating strict rules, rule=" + rule.toString(), e);
}
}
return ProcessStatus.SUCCESS;
}
protected boolean containsUnprovedRuleInTheory(final Collection<Literal> literals, final RuleType ruleType) {
// if (null==literals||literals.size()==0)return true;
for (Literal literal : literals) {
if (theory.containsUnprovedRule(literal, ruleType, true)) return true;
}
return false;
}
protected TreeSet<Literal> extractLiteralsFromConclusions(Collection<Conclusion> conclusions) {
TreeSet<Literal> literals = new TreeSet<Literal>();
for (Conclusion conclusion : conclusions) {
literals.add(conclusion.getLiteral());
}
return literals;
}
/**
* clear the engine data
*
* @return Process status
*/
@Override
public ProcessStatus clear() {
theory = null;
strictRules = null;
defeasibleRules = null;
records = null;
_conclusions = null;
_theoryAnalyser = null;
isUpdateInapplicableLiteralsBeforeInference = true;
return ProcessStatus.SUCCESS;
}
protected TheoryAnalyser getTheoryAnalyser() throws ReasoningEngineException {
try {
if (null == _theoryAnalyser) {
_theoryAnalyser = new TheoryAnalyser();
_theoryAnalyser.setAppLogger(logger);
}
_theoryAnalyser.setTheory(theory);
return _theoryAnalyser;
} catch (Exception e) {
throw new ReasoningEngineException(getClass(), e);
}
}
protected ReasoningEngineUtilities getReasoningEngineUtilities() {
if (null == reasoningEngineUtilities) reasoningEngineUtilities = new ReasoningEngineUtilities();
return reasoningEngineUtilities;
}
protected InferenceLogger getInferenceLogger() {
if (null == inferenceLogger) inferenceLogger = new InferenceLogger();
return inferenceLogger;
}
// protected Map<Literal, Map<ConclusionType, Conclusion>> getRecords() {
// return records;
// }
protected Map<Literal,Set<ConclusionType>>getRecords(){
return records;
}
protected ProcessStatus addRecord(ConclusionType conclusionType,Literal literal){
logMessage(Level.FINE, 3, "record added: ", conclusionType.getSymbol(),literal);
Set<ConclusionType> recordList=records.get(literal);
if (null==recordList){
recordList=new TreeSet<ConclusionType>();
records.put(literal, recordList);
}
recordList.add(conclusionType);
return ProcessStatus.SUCCESS;
}
protected ProcessStatus addRecord(Conclusion conclusion) {
return addRecord(conclusion.getConclusionType(),conclusion.getLiteral());
// logMessage(Level.FINE, 3, "record added: ", conclusion);
//
// Literal literal = conclusion.getLiteral();
// Set<ConclusionType> recordList=records.get(literal);
// if (null==recordList){
// recordList=new TreeSet<ConclusionType>();
// records.put(literal, recordList);
// }
// recordList.add(conclusion.getConclusionType());
// return ProcessStatus.SUCCESS;
}
protected ProcessStatus removeRecord(Conclusion conclusion) {
Literal literal = conclusion.getLiteral();
Set<ConclusionType>recordList=records.get(literal);
if (null!=recordList){
recordList.remove(conclusion.getConclusionType());
if (recordList.size()==0)records.remove(literal);
}
// Map<ConclusionType, Conclusion> recordList = records.get(literal);
// if (null != recordList) {
// recordList.remove(conclusion.getConclusionType());
// if (recordList.size() == 0) records.remove(literal);
// }
return ProcessStatus.SUCCESS;
}
protected boolean isRecordExist(Literal literal, ConclusionType conclusionType) {
if (records == null) return false;
// if (!records.containsKey(literal))return false;
Set<ConclusionType> recordList = records.get(literal);
logMessage(Level.FINEST,3,"isRecordExist(",literal,conclusionType,")=",recordList,"::",null==recordList?"null":recordList,"::",null==recordList?"":recordList.contains(conclusionType));
if (null == recordList) return false;
return recordList.contains(conclusionType);
// Map<ConclusionType, Conclusion> recordList = records.get(literal);
// if (null == recordList) return false;
// return recordList.containsKey(conclusionType);
}
protected boolean isRecordExist(Collection<Literal> literals, ConclusionType conclusionType) {
for (Literal literal : literals) {
if (isRecordExist(literal, conclusionType)) return true;
}
return false;
}
protected ProcessStatus newLiteralFind_definiteProvable(final Literal literal, final boolean isCheckInference) {
logMessage(Level.FINE, 1, "newLiteralFind_definiteProvable", literal);
Conclusion conclusion1 = new Conclusion(ConclusionType.DEFINITE_PROVABLE, literal);
Conclusion conclusion2 = new Conclusion(ConclusionType.DEFEASIBLY_PROVABLE, literal);
Conclusion conclusion3 = new Conclusion(ConclusionType.TENTATIVELY_PROVABLE, literal);
addPendingConclusion(conclusion1);
addRecord(conclusion1);
addRecord(conclusion2);
addRecord(conclusion3);
if (isCheckInference) {
checkInference(conclusion1);
}
return ProcessStatus.SUCCESS;
}
protected ProcessStatus newLiteralFind_definiteNotProvable(final Literal literal, final boolean isCheckInference) {
logMessage(Level.FINE, 1, "newLiteralFind_definiteNotProvable", literal);
Conclusion conclusion = new Conclusion(ConclusionType.DEFINITE_NOT_PROVABLE, literal);
addPendingConclusion(conclusion);
addRecord(conclusion);
if (isCheckInference) {
checkInference(conclusion);
}
return ProcessStatus.SUCCESS;
}
protected ProcessStatus newLiteralFind_defeasiblyProvable(final Literal literal, final boolean isCheckInference) {
logMessage(Level.FINE, 1, "newLiteralFind_defeasiblyProvable", literal);
Conclusion conclusion = new Conclusion(ConclusionType.TENTATIVELY_PROVABLE, literal);
addRecord(conclusion);
if (isCheckInference) {
checkInference(conclusion);
}
return ProcessStatus.SUCCESS;
}
protected ProcessStatus newLiteralFind_defeasiblyNotProvable(final Literal literal, final boolean isCheckInference) {
logMessage(Level.FINE, 1, "newLiteralFind_defeasiblyNotProvable", literal);
Conclusion conclusion = new Conclusion(ConclusionType.TENTATIVELY_NOT_PROVABLE, literal);
addRecord(conclusion);
if (isCheckInference) {
checkInference(conclusion);
}
return ProcessStatus.SUCCESS;
}
/**
* check inference for a literal q,
* <p>
* for defeasible provable, check
*
* <pre>
* +D q OR
* +tt q AND -D ˜q AND -tt ˜q
* </pre>
*
* </p>
* <p>
* for not defeasible provable, check
*
* <pre>
* -D q AND
* -tt q OR +D ˜q OR +tt ˜q
* </pre>
*
* where +tt and -tt are tentatively provable and not tentatively provable respectively
*
* @param conclusion
* @return Process status - ProcessStatus.SUCCESS, if process completed
* successfully, exception throw otherwise
*/
// @Override
protected ProcessStatus checkInference(Conclusion conclusion) {
if (conclusion == null) return ProcessStatus.SUCCESS;
//logMessage(Level.FINEST,0,"----------------------------------\ncheckInference("+conclusion+")");
//logMessage(Level.FINEST,1,getReasoningEngineUtilities().generateEngineInferenceStatusMessage(getClass().getName(), null, null, null, null, null, records));
Literal literal = conclusion.getLiteral();
Set<Literal> conflictLiteralList = getConflictLiterals(literal);
Iterator<Literal> conflictLiteralsIterator = conflictLiteralList.iterator();
boolean hasDefPosConflict = false;
boolean hasDefNegConflict = false;
logMessage(Level.FINER, 1, "checkInference: literal=", literal);
for (int i = 0; i < conflictLiteralList.size() && !(hasDefPosConflict && hasDefNegConflict); i++) {
Literal conflictLiteral = conflictLiteralsIterator.next();// conflictLiteralList.get(i);
logMessage(Level.FINER, 2, "checkInference: literal=", literal, "conflictLiteral=", conflictLiteral);
boolean hasLiteralComplement = theory.contains(conflictLiteral);
// for defeasibly provable
boolean isDefiniteProvable = isRecordExist(literal, ConclusionType.DEFINITE_PROVABLE);
boolean isTentativeProvable = isRecordExist(literal, ConclusionType.TENTATIVELY_PROVABLE);
boolean isComplementDefiniteNotProvable = isRecordExist(conflictLiteral, ConclusionType.DEFINITE_NOT_PROVABLE);
boolean isComplementNotTentativeProvable = isRecordExist(conflictLiteral, ConclusionType.TENTATIVELY_NOT_PROVABLE);
// for NOT defeasibly provable
boolean isDefiniteNotProvable = isRecordExist(literal, ConclusionType.DEFINITE_NOT_PROVABLE);
boolean isTentativeNotProvable = isRecordExist(literal, ConclusionType.TENTATIVELY_NOT_PROVABLE);
boolean isComplementDefiniteProvable = isRecordExist(conflictLiteral, ConclusionType.DEFINITE_PROVABLE);
boolean isComplementTentativeProvable = isRecordExist(conflictLiteral, ConclusionType.TENTATIVELY_PROVABLE);
logMessage(Level.FINEST, 3, "check inference for literal=", conclusion);
logMessage(Level.FINEST, 4, "complement literal check=", conflictLiteral);
logMessage(Level.FINEST, 5, "hasLiteralComplement=" + hasLiteralComplement);
logMessage(Level.FINEST, 5, "[" + isDefiniteProvable + "]", "[" + isTentativeProvable, isComplementDefiniteNotProvable,
isComplementNotTentativeProvable + "]");
logMessage(Level.FINEST, 5, "[" + isDefiniteNotProvable + "]", "[" + isTentativeNotProvable, isComplementDefiniteProvable,
isComplementTentativeProvable + "]");
// for defeasibly provable
boolean defeasibleProvableCase1 = isDefiniteProvable;
boolean defeasibleProvableCase2 = isTentativeProvable
&& (!hasLiteralComplement || (isComplementDefiniteNotProvable && isComplementNotTentativeProvable));
if (defeasibleProvableCase1 || defeasibleProvableCase2) {
} else {
hasDefPosConflict = true;
logMessage(Level.FINEST, 4, "==> hasDefPosConflict=" + hasDefPosConflict);
}
// for defeasibly NOT provable
// check inference if the literal complement exist
// i.e. for the literal ~q
// defeasible provable, check
// +D ~q OR
// +tt ~q AND -D q AND -tt q
// not defeasible provable, check
// -D ~q AND
// -tt ~q OR +D q OR +tt q
boolean defeasibleNotProvableCase1 = isDefiniteNotProvable;
boolean defeasibleNotProvableCase2 = isTentativeNotProvable || isComplementDefiniteProvable || isComplementTentativeProvable;
logMessage(Level.FINEST, 5, "[" + defeasibleNotProvableCase1 + "]", "[" + defeasibleNotProvableCase1+"]");
logMessage(Level.FINEST, 5, "[" + defeasibleNotProvableCase2 + "]", "[" + isTentativeNotProvable, isComplementDefiniteProvable,
isComplementTentativeProvable + "]");
if (defeasibleNotProvableCase1 && defeasibleNotProvableCase2) {
} else {
hasDefNegConflict = true;
logMessage(Level.FINEST, 4, "==> hasDefNegConflict=" + hasDefNegConflict);
}
}
if (!hasDefPosConflict) {
logMessage(Level.FINER, 3, "==> add new defeasibly provable literal", literal);
Conclusion defeasibleConclusion = new Conclusion(ConclusionType.DEFEASIBLY_PROVABLE, literal);
addPendingConclusion(defeasibleConclusion);
addRecord(defeasibleConclusion);
addRecord(new Conclusion(ConclusionType.TENTATIVELY_PROVABLE, literal));
}
if (!hasDefNegConflict) {
logMessage(Level.FINER, 3, "==> add new defeasibly NOT provable literal", literal);
Conclusion defeasibleNotConclusion = new Conclusion(ConclusionType.DEFEASIBLY_NOT_PROVABLE, literal);
addPendingConclusion(defeasibleNotConclusion);
addRecord(defeasibleNotConclusion);
addRecord(new Conclusion(ConclusionType.TENTATIVELY_NOT_PROVABLE, literal));
}
// // check inference if the literal complement exist
// // i.e. for the literal ~q
// // defeasible provable, check
// // +D ~q OR
// // +tt ~q AND -D q AND -tt q
// // not defeasible provable, check
// // -D ~q AND
// // -tt ~q OR +D q OR +tt q
// if (hasLiteralComplement) {
// boolean complementDefeasibleCase1 = isComplementDefiniteProvable;
// boolean complementDefeasibleCase2 = isComplementTentativeProvable &&
// isDefiniteNotProvable &&
// isTentativeNotProvable;
// if (complementDefeasibleCase1 || complementDefeasibleCase2) {
// if (logger != null)
// logger.onLogMessage("\t\t\t\t===> add new defeasibly provable literal:"
// +
// conflictLiteral);
// Conclusion complmementDefeasibleConclusion = new
// Conclusion(ConclusionType.DEFEASIBLY_PROVABLE,
// conflictLiteral);
// addPendingConclusion(complmementDefeasibleConclusion);
// addRecord(complmementDefeasibleConclusion);
// addRecord(new Conclusion(ConclusionType.TENTATIVELY_PROVABLE,
// conflictLiteral));
// isDone = true;
// }
//
// boolean complementDefeasibleNotProvableCase1 =
// isComplementDefiniteNotProvable;
// boolean complementDefeasibleNotProvableCase2 =
// isComplementNotTentativeProvable || isDefiniteProvable
// ||
// isTentativeProvable;
// if (complementDefeasibleNotProvableCase1 &&
// complementDefeasibleNotProvableCase2) {
// if (logger != null)
// logger.onLogMessage("\t\t\t\t===> add new defeasibly NOT provable literal:"
// +
// conflictLiteral);
// Conclusion complementDefeasibleNotConclusion = new
// Conclusion(ConclusionType.DEFEASIBLY_NOT_PROVABLE,
// conflictLiteral);
// addPendingConclusion(complementDefeasibleNotConclusion);
// addRecord(complementDefeasibleNotConclusion);
// addRecord(new Conclusion(ConclusionType.TENTATIVELY_NOT_PROVABLE,
// conflictLiteral));
// isDone = true;
// }
// }
return ProcessStatus.SUCCESS;
}
// =================================
// Reasoning Engine Listener - start
// =================================
@Override
public void addReasoningEngineListener(ReasoningEngineListener listener) {
addAppModuleListener(listener);
}
@Override
public void removeReasoningEngineListener(ReasoningEngineListener listener) {
removeAppModuleListener(listener);
}
protected void fireOnReasoningEngineMessage(MessageType messageType, String message) {
for (AppModuleListener listener : getAppModuleListeners()) {
if (listener instanceof ReasoningEngineListener) {
((ReasoningEngineListener) listener).onReasoningEngineMessage(messageType, message);
}
}
}
private void fireSetInapplicableLiteralsBeforeInference() {
for (AppModuleListener listener : getAppModuleListeners()) {
if (listener instanceof ReasoningEngineListener) {
((ReasoningEngineListener) listener).setInapplicableLiteralsBeforeInference((new TreeMap<ConclusionType, Set<Literal>>(
inapplicableLiteralsBeforeInference)));
}
}
}
private void fireSetInferenceLogger() {
for (AppModuleListener listener : getAppModuleListeners()) {
if (listener instanceof ReasoningEngineListener) {
((ReasoningEngineListener) listener).setInferenceLogger(inferenceLogger);
}
}
}
// ===============================
// Reasoning Engine Listener - end
// ===============================
// ======================================
// Abstract functions declaration - start
// ======================================
protected abstract void initialize() throws ReasoningEngineException;
protected abstract void generateConclusions() throws ReasoningEngineException;
protected abstract ProcessStatus addPendingConclusion(Conclusion conclusion);
protected abstract String getProgressMessage();
protected abstract void terminate() throws ReasoningEngineException;
// ====================================
// Abstract functions declaration - end
// ====================================
}