/** * 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.sdl; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.logging.Level; import com.app.utils.Utilities.ProcessStatus; import spindle.core.dom.Conclusion; import spindle.core.dom.ConclusionType; import spindle.core.dom.Literal; import spindle.core.dom.ProvabilityLevel; import spindle.core.dom.Rule; import spindle.core.dom.RuleExt; import spindle.core.dom.RuleType; import spindle.core.dom.Superiority; import spindle.core.dom.TheoryException; import spindle.engine.ReasoningEngineException; import spindle.sys.AppConst; import spindle.sys.Conf; import spindle.sys.message.ErrorMessage; import spindle.tools.explanation.RuleInferenceStatus; /** * SDL Reasoning Engine (version 2). * <p> * This reasoning engine is based on the algorithm presented in: * <ul> * <li>H.-P. Lam and G. Governatori (2011) What are the Necessity Rules in Defeasible Logic, <i> In Proceedings of the * 11th International Conference on Logic Programming and Nonmonotonic Reasoning (LPNMR-2011)</i>, 16-19 May 2011, * Vancouver, BC, Canada</li> * </ul> * </p> * * @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory * @see SdlReasoningEngine * @since version 2.0.0 * @version Last modified: 2012.12.12 on ambiguous conclusions update * <br/> 2012.07.21 */ public class SdlReasoningEngine2 extends spindle.engine.sdl.SdlReasoningEngine { public SdlReasoningEngine2() { super(); } /** * a rule is removed if * <ul> * <li>there exists no rules weaker than it, and</li> * <li>there exists a superior rule with empty body.</li> * </ul> * * @param ruleLabel rule label * @return true if the rule can remove from theory * @throws TheoryException */ protected Set<String> getDefeatedRulesInTheory(String ruleLabel) throws TheoryException { RuleExt rule = (RuleExt) theory.getRule(ruleLabel); Set<String> defeatedRules = new TreeSet<String>(); if (!rule.isEmptyBody()) return defeatedRules; Set<Superiority> superiors = theory.getSuperior(ruleLabel); // remove all inferior rules with no weaker rule if (null != superiors) { for (Superiority superiority : superiors) { RuleExt inferiorRule = (RuleExt) theory.getRule(superiority.getInferior()); if (inferiorRule.getWeakerRulesCount() == 0) { defeatedRules.add(superiority.getInferior()); } } if (defeatedRules.size() > 0) logMessage(Level.FINEST, 3, "getDefeatedRulesInTheory: rule ", ruleLabel, // ", inferiorly defeated rule", defeatedRules); } return defeatedRules; } protected void removeDefeatedRulesInTheory() throws ReasoningEngineException, TheoryException { if (theory.getSuperiorityCount() == 0) return; logMessage(Level.FINE, 1, "removeDefeatedRuleInTheory - start"); Map<String, Set<Superiority>> superiorities = theory.getAllSuperiors(); Set<String> defeatedRules = new TreeSet<String>(); logMessage(Level.FINER, 2, "superiorities=", superiorities); try { do { defeatedRules.clear(); for (String superiorRuleLabel : superiorities.keySet()) { defeatedRules.addAll(getDefeatedRulesInTheory(superiorRuleLabel)); } if (defeatedRules.size() > 0) { removeDefeatedRulesWithInference(defeatedRules, false); } } while (defeatedRules.size() > 0); if (!AppConst.isDeploy) logMessage(Level.INFO, 0, "======\ntheory\n======\n", theory); } catch (TheoryException e) { throw e; } catch (Exception e) { throw new ReasoningEngineException(getClass(), e); } finally { logMessage(Level.FINE, 1, "removeDefeatedRuleInTheory - end"); } } protected void verifyWeakestRuleInTheory(Set<RuleExt> rulesToVerify, Set<String> rulesToRemove) throws ReasoningEngineException { for (RuleExt rule : rulesToVerify) { boolean isBlockedBySccLiteral = false; Set<Superiority> superiorities = theory.getInferior(rule.getLabel()); boolean isAllSuperiorRuleBlockedBySccLiteral = true; for (Superiority sup : superiorities) { RuleExt supRule = (RuleExt) theory.getRule(sup.getSuperior()); isBlockedBySccLiteral = false; for (Literal literal : supRule.getBodyLiterals()) { if (isBlockedBySccLiteral(literal)) isBlockedBySccLiteral = true; } if (!isBlockedBySccLiteral) isAllSuperiorRuleBlockedBySccLiteral = false; } if (isAllSuperiorRuleBlockedBySccLiteral) { rulesToRemove.add(rule.getLabel()); } } } @Override protected ProcessStatus generateInitialPendingConclusions() throws ReasoningEngineException, TheoryException { try { theory.updateRuleSuperiorityRelationCounter(); generatePendingConclusions(false); } catch (TheoryException e) { throw e; } catch (ReasoningEngineException e) { throw e; } catch (Exception e) { throw new ReasoningEngineException(getClass(), e); } return ProcessStatus.SUCCESS; } protected void generatePendingConclusions(boolean isDefeasibleRuleOnly) throws ReasoningEngineException, TheoryException { // System.out.println("SdlReasoningEngine.generatePendingConclusion...start"); logMessage(Level.FINE, 0, "=== SdlReasoningEngine.generatePendingConclusions - start ==="); logMessage(Level.FINE, 1, "isDefeasibleRuleOnly=", isDefeasibleRuleOnly); Set<Literal> unprovedStrictRuleLiterals = new TreeSet<Literal>(theory.getAllLiteralsInRules()); Set<Literal> unprovedDefeasibleRuleLiterals = new TreeSet<Literal>(theory.getAllLiteralsInRules()); logMessage(Level.FINER, 1, "=== +ve set - start ==="); removeDefeatedRulesInTheory(); Set<String> rulesToDelete = new TreeSet<String>(); Map<Conclusion, Set<String>> tempPosDefiniteConclusionSet = new TreeMap<Conclusion, Set<String>>(); Map<Conclusion, Set<String>> tempPosDefeasibleConclusionSet = new TreeMap<Conclusion, Set<String>>(); Set<String> ruleSet = null; for (Rule r : theory.getFactsAndAllRules().values()) { if (r.getHeadLiterals().size() > 1) throw new TheoryException(ErrorMessage.THEORY_NOT_IN_REGULAR_FORM_MULTIPLE_HEADS_RULE, new Object[] { r.getLabel() }); RuleExt rule = (RuleExt) r; Literal literal = rule.getHeadLiterals().get(0); switch (rule.getRuleType()) { case STRICT: if (!isDefeasibleRuleOnly) { if (rule.isEmptyBody()) { Conclusion conclusion = new Conclusion(ConclusionType.DEFINITE_PROVABLE, literal); addRecord(conclusion); ruleSet = tempPosDefiniteConclusionSet.get(conclusion); if (null == ruleSet) { ruleSet = new TreeSet<String>(); tempPosDefiniteConclusionSet.put(conclusion, ruleSet); } ruleSet.add(rule.getOriginalLabel()); rulesToDelete.add(rule.getLabel()); } unprovedStrictRuleLiterals.remove(literal); logMessage(Level.ALL, 2,"unproved literal removed (definite):",literal); } break; case DEFEASIBLE: if (rule.isEmptyBody() && rule.getStrongerRulesCount() == 0 && rule.getWeakerRulesCount() == 0) { Conclusion conclusion = new Conclusion(ConclusionType.DEFEASIBLY_PROVABLE, literal); addRecord(conclusion); ruleSet = tempPosDefeasibleConclusionSet.get(conclusion); if (null == ruleSet) { ruleSet = new TreeSet<String>(); tempPosDefeasibleConclusionSet.put(conclusion, ruleSet); } ruleSet.add(rule.getOriginalLabel()); rulesToDelete.add(rule.getLabel()); } unprovedDefeasibleRuleLiterals.remove(literal); logMessage(Level.ALL, 2,"unproved literal removed (defeasible):",literal); break; default: } } removeRules(rulesToDelete); if (!AppConst.isDeploy) { // logMessage(Level.INFO, 1, "tempPosDefiniteConclusionSet=", tempPosDefiniteConclusionSet); //logMessage(Level.INFO, 1, "tempPosDefeasibleConclusionSet=", tempPosDefeasibleConclusionSet); // logMessage(Level.INFO, 1, "unprovedDefeasibleRuleLiterals=", unprovedDefeasibleRuleLiterals); printPendingConclusionSet(unprovedStrictRuleLiterals, unprovedDefeasibleRuleLiterals, tempPosDefiniteConclusionSet.keySet(),tempPosDefeasibleConclusionSet.keySet()); } TreeSet<Literal> tempPosDefiniteConclusions = extractLiteralsFromConclusions(tempPosDefiniteConclusionSet.keySet()); TreeSet<Literal> tempPosDefeasibleConclusions = extractLiteralsFromConclusions(tempPosDefeasibleConclusionSet.keySet()); if (!isDefeasibleRuleOnly) { for (Entry<Conclusion, Set<String>> entry : tempPosDefiniteConclusionSet.entrySet()) { Conclusion conclusion = entry.getKey(); // ConclusionType conclusionType = conclusion.getConclusionType(); Set<String> ruleLabels = entry.getValue(); boolean ambiguousExist = false, pos = true; Literal literal = conclusion.getLiteral(); Set<Literal> conflictLiterals = getConflictLiterals(literal); // switch (conclusionType) { //case DEFINITE_PROVABLE: //if (!isDefeasibleRuleOnly) { ambiguousExist = isTempConclusionExist(conflictLiterals, tempPosDefiniteConclusions);//, ConclusionType.DEFINITE_PROVABLE); if (!ambiguousExist) ambiguousExist = containsUnprovedRuleInTheory(conflictLiterals, RuleType.STRICT); if (ambiguousExist) { logMessage(Level.FINEST, 1, "==> generatePendingConclusions: ==> add (+D Ambiguous)", literal); addAmbiguousConclusion(conclusion, ruleLabels); } else { if (isRecordExist(conflictLiterals, ConclusionType.DEFINITE_PROVABLE)) pos = false; if (isRecordExist(literal, ConclusionType.DEFINITE_NOT_PROVABLE)) pos = false; logMessage(Level.FINEST, 1, "02, ambiguousExist=", ambiguousExist, ", pos=", pos); if (pos) { if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(ruleLabels, conclusion, RuleInferenceStatus.APPICABLE); newLiteralFind_definiteProvable(literal, false); } else { if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(ruleLabels, conclusion, RuleInferenceStatus.DISCARDED); newLiteralFind_definiteNotProvable(literal, false); } } } // break; } for (Entry<Conclusion, Set<String>> entry : tempPosDefeasibleConclusionSet.entrySet()) { Conclusion conclusion = entry.getKey(); // ConclusionType conclusionType = conclusion.getConclusionType(); Set<String> ruleLabels = entry.getValue(); boolean ambiguousExist = false, pos = true; Literal literal = conclusion.getLiteral(); Set<Literal> conflictLiterals = getConflictLiterals(literal); // case DEFEASIBLY_PROVABLE: if (!pendingConclusions[1].contains(conclusion) // // if (!pendingConclusions[1].contains(new Conclusion(ConclusionType.DEFEASIBLY_PROVABLE, // literal)) // || !isRecordExist(literal, ConclusionType.DEFEASIBLY_PROVABLE)) { ambiguousExist = isTempConclusionExist(conflictLiterals, tempPosDefeasibleConclusions);//, ConclusionType.DEFEASIBLY_PROVABLE); if (!ambiguousExist) ambiguousExist = containsUnprovedRuleInTheory(conflictLiterals, RuleType.DEFEASIBLE); if (ambiguousExist) { logMessage(Level.FINEST, 1, "==> generatePendingConclusions: ==> add (+d Ambiguous)", literal); addAmbiguousConclusion(conclusion, ruleLabels); } else { if (isRecordExist(conflictLiterals, ConclusionType.DEFEASIBLY_PROVABLE)) pos = false; if (isRecordExist(literal, ConclusionType.DEFEASIBLY_NOT_PROVABLE)) pos = false; logMessage(Level.FINEST, 1, "02, ambiguousExist=", ambiguousExist, ", pos=", pos); if (pos) { addPendingConclusion(conclusion); if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(ruleLabels, conclusion, RuleInferenceStatus.APPICABLE); newLiteralFind_defeasiblyProvable(literal, false); } else { Conclusion c = new Conclusion(ConclusionType.DEFEASIBLY_NOT_PROVABLE, literal); addPendingConclusion(c); if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(ruleLabels, conclusion, RuleInferenceStatus.DISCARDED); newLiteralFind_defeasiblyNotProvable(literal, false); } } } // break; //default: //} } logMessage(Level.FINER, 1, "=== +ve set - end ==="); logMessage(Level.FINER, 1, "=== -df set - start ==="); for (Literal literal : unprovedDefeasibleRuleLiterals) { if (!isAmbiguousConclusionExist(literal, ConclusionType.DEFEASIBLY_PROVABLE)) { Conclusion conclusion = new Conclusion(ConclusionType.DEFEASIBLY_NOT_PROVABLE, literal); if (!unresolveableConclusionsSet.contains(conclusion)) { addPendingConclusion(conclusion); addRecord(conclusion); newLiteralFind_defeasiblyNotProvable(literal, false); addInapplicableLiteralsBeforeInference(literal, ConclusionType.DEFEASIBLY_NOT_PROVABLE); } } } logMessage(Level.FINER, 1, "=== -df set - end ==="); // literals that do not exist in strict rule or // literals cannot be resolved using only strict rules are definite not provable if (!isDefeasibleRuleOnly) { logMessage(Level.FINEST, 1, "=== -Df set - start ==="); for (Literal literal : unprovedStrictRuleLiterals) { newLiteralFind_definiteNotProvable(literal, false); addInapplicableLiteralsBeforeInference(literal, ConclusionType.DEFINITE_NOT_PROVABLE); } logMessage(Level.FINEST, 1, "=== -Df set - end ==="); } logMessage(Level.FINE, 0, "=== SdlReasoningEngine.generatePendingConclusions - end ==="); // System.out.println("SdlReasoningEngine.generatePendingConclusion...end"); } @Override protected ProcessStatus generateConclusions_definiteProvable(final Literal literal) throws ReasoningEngineException, TheoryException { // System.out.println("SdlReasoningEngine.generateConclusions_definiteProvable...start"); logMessage(Level.FINE, 0, "=== generate inference: definite provable: ", literal); Set<String> rulesToDelete = new TreeSet<String>(); Set<Rule> rulesModified = theory.removeBodyLiteralFromRules(literal, null); // modified for new algorithm - start provableRulesSuperiorityUpdate(rulesModified); // modified for new algorithm - end if (rulesModified.size() == 0) return ProcessStatus.SUCCESS; for (Rule r : rulesModified) { RuleExt rule = (RuleExt) r; logMessage(Level.FINER, 1, null, literal, ": rule=", rule, ", is empty body=", rule.isEmptyBody()); if (rule.isEmptyBody()) { logMessage(Level.FINER, 2, "remove rule:", rule.getLabel()); Literal headLiteral = rule.getHeadLiterals().get(0); Set<Literal> conflictLiterals = null; switch (rule.getRuleType()) { case STRICT: logMessage(Level.FINEST, 1, "==> (strict) ", literal); rulesToDelete.add(rule.getLabel()); conflictLiterals = getConflictLiterals(headLiteral); if (containsUnprovedRuleInTheory(conflictLiterals, RuleType.STRICT)) { logMessage(Level.FINEST, 2, "==>1.1 generateConclusions_definiteProvable: ==> add ambiguous (+D)", headLiteral); Conclusion conclusion = new Conclusion(ConclusionType.DEFINITE_PROVABLE, headLiteral); addRecord(conclusion); addAmbiguousConclusion(conclusion, rule.getOriginalLabel()); } else { boolean chk1 = isAmbiguousConclusionExist(headLiteral, ConclusionType.DEFINITE_NOT_PROVABLE); boolean chk2 = isAmbiguousConclusionExist(conflictLiterals, ConclusionType.DEFINITE_PROVABLE); if (chk1 || chk2) { logMessage(Level.FINEST, 2, "==>1.2 generateConclusions_definiteProvable: ==> add ambiguous (+D)", headLiteral); Conclusion conclusion = new Conclusion(ConclusionType.DEFINITE_PROVABLE, headLiteral); addRecord(conclusion); addAmbiguousConclusion(conclusion, rule.getOriginalLabel()); } else { boolean hasConflictRecord = false; if (isRecordExist(conflictLiterals, ConclusionType.DEFINITE_PROVABLE)) hasConflictRecord = true; if (isRecordExist(headLiteral, ConclusionType.DEFINITE_NOT_PROVABLE)) hasConflictRecord = true; if (hasConflictRecord) { if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(rule.getOriginalLabel(), RuleType.STRICT, ConclusionType.DEFINITE_NOT_PROVABLE, headLiteral, RuleInferenceStatus.DISCARDED); newLiteralFind_definiteNotProvable(headLiteral, true); } else { if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(rule.getOriginalLabel(), RuleType.STRICT, ConclusionType.DEFINITE_PROVABLE, headLiteral, RuleInferenceStatus.APPICABLE); newLiteralFind_definiteProvable(headLiteral, true); } } } break; case DEFEASIBLE: if (rule.getStrongerRulesCount() == 0 && rule.getWeakerRulesCount() == 0) { logMessage(Level.FINER, 1, "==> (defeasible) ", literal); rulesToDelete.add(rule.getLabel()); // same as 'generateConclusions_defeasiblyProvable(Literal literal)' // duplicated here for efficiency conflictLiterals = getConflictLiterals(headLiteral); if (containsUnprovedRuleInTheory(conflictLiterals, RuleType.DEFEASIBLE)) { logMessage(Level.FINEST, 2, "==>1.5 generateConclusions_definiteProvable: ==> add ambiguous (+d)", headLiteral); Conclusion conclusion = new Conclusion(ConclusionType.DEFEASIBLY_PROVABLE, headLiteral); addAmbiguousConclusion(conclusion, rule.getOriginalLabel()); addRecord(conclusion); } else if (isRecordExist(headLiteral, ConclusionType.DEFEASIBLY_PROVABLE)) { // do nothing } else { boolean chk1 = isAmbiguousConclusionExist(headLiteral, ConclusionType.DEFEASIBLY_NOT_PROVABLE); boolean chk2 = isAmbiguousConclusionExist(conflictLiterals, ConclusionType.DEFEASIBLY_PROVABLE); if (chk1 || chk2) { logMessage(Level.FINEST, 2, "==>1.6 generateConclusions_definiteProvable: ==> add ambiguous (+D)", headLiteral); addAmbiguousConclusion(new Conclusion(ConclusionType.DEFEASIBLY_PROVABLE, headLiteral), rule.getOriginalLabel()); } else { boolean hasConflictRecord = false; if (isRecordExist(conflictLiterals, ConclusionType.DEFEASIBLY_PROVABLE)) hasConflictRecord = true; if (isRecordExist(headLiteral, ConclusionType.DEFEASIBLY_NOT_PROVABLE)) hasConflictRecord = true; if (hasConflictRecord) { if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(rule.getOriginalLabel(), RuleType.DEFEASIBLE, ConclusionType.DEFEASIBLY_NOT_PROVABLE, headLiteral, RuleInferenceStatus.DISCARDED); newLiteralFind_defeasiblyNotProvable(headLiteral, true); } else { if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(rule.getOriginalLabel(), RuleType.DEFEASIBLE, ConclusionType.DEFEASIBLY_PROVABLE, headLiteral, RuleInferenceStatus.APPICABLE); newLiteralFind_defeasiblyProvable(headLiteral, true); } } } } break; default: } } } removeRules(rulesToDelete); // System.out.println("SdlReasoningEngine.generateConclusions_definiteProvable...end"); return ProcessStatus.SUCCESS; } @Override protected ProcessStatus generateConclusions_defeasiblyProvable(final Literal literal) throws ReasoningEngineException, TheoryException { // System.out.println("SdlReasoningEngine.generateConclusions_defeasiblyProvable(" + literal + ")...start"); logMessage(Level.FINE, 1, "generate inference: defeasibly provable: ", literal); Set<String> rulesToRemove = new TreeSet<String>(); Set<Rule> rulesModified = theory.removeBodyLiteralFromRules(literal, RuleType.DEFEASIBLE); // modified for new algorithm - start provableRulesSuperiorityUpdate(rulesModified); // modified for new algorithm - end if (rulesModified.size() == 0) return ProcessStatus.SUCCESS; for (Rule r : rulesModified) { // System.out.println("r=" + r.getLabel()); RuleExt rule = (RuleExt) r; logMessage(Level.FINER, 2, null, literal, ": rule=", rule, ", is empty body=", rule.isEmptyBody()); if (rule.isEmptyBody() && rule.getStrongerRulesCount() == 0 && rule.getWeakerRulesCount() == 0) { Literal headLiteral = rule.getHeadLiterals().get(0); rulesToRemove.add(rule.getLabel()); Set<Literal> conflictLiterals = getConflictLiterals(headLiteral); // System.out.println("generateConclusions_defeasiblyProvable..1"); boolean containsUnprovedRuleInTheory = containsUnprovedRuleInTheory(conflictLiterals, RuleType.DEFEASIBLE); logMessage(Level.FINEST, 2, "==>2.0 conflictLiterals: ", conflictLiterals, ",unproved rule in theory=" + containsUnprovedRuleInTheory); // System.out.println("generateConclusions_defeasiblyProvable..2"); if (containsUnprovedRuleInTheory) { logMessage(Level.FINEST, 2, "==>2.1 generateConclusions_defeasiblyProvable: ==> add ambiguous (+d)", headLiteral); Conclusion conclusion = new Conclusion(ConclusionType.DEFEASIBLY_PROVABLE, headLiteral); addAmbiguousConclusion(conclusion, rule.getOriginalLabel()); addRecord(conclusion); // System.out.println("generateConclusions_defeasiblyProvable..3"); } else if (isRecordExist(headLiteral, ConclusionType.DEFEASIBLY_PROVABLE)) { // System.out.println("generateConclusions_defeasiblyProvable..4"); } else { //System.out.println("generateConclusions_defeasiblyProvable..5"); boolean chk1 = isAmbiguousConclusionExist(headLiteral, ConclusionType.DEFEASIBLY_NOT_PROVABLE); boolean chk2 = isAmbiguousConclusionExist(conflictLiterals, ConclusionType.DEFEASIBLY_PROVABLE); if (chk1 || chk2) { //System.out.println("generateConclusions_defeasiblyProvable..6"); logMessage(Level.FINEST, 2, "==>2.2 generateConclusions_defeasiblyProvable: ==> add ambiguous (+D)", headLiteral); addAmbiguousConclusion(new Conclusion(ConclusionType.DEFEASIBLY_PROVABLE, headLiteral), rule.getOriginalLabel()); } else { // System.out.println("generateConclusions_defeasiblyProvable..7"); boolean hasConflictRecord = false; if (isRecordExist(conflictLiterals, ConclusionType.DEFEASIBLY_PROVABLE)) hasConflictRecord = true; if (isRecordExist(headLiteral, ConclusionType.DEFEASIBLY_NOT_PROVABLE)) hasConflictRecord = true; if (hasConflictRecord) { // System.out.println("generateConclusions_defeasiblyProvable..8"); if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(rule.getOriginalLabel(), RuleType.DEFEASIBLE, ConclusionType.DEFEASIBLY_NOT_PROVABLE, headLiteral, RuleInferenceStatus.DISCARDED); newLiteralFind_defeasiblyNotProvable(headLiteral, true); } else { // System.out.println("generateConclusions_defeasiblyProvable..9"); if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(rule.getOriginalLabel(), RuleType.DEFEASIBLE, ConclusionType.DEFEASIBLY_PROVABLE, headLiteral, RuleInferenceStatus.APPICABLE); newLiteralFind_defeasiblyProvable(headLiteral, true); } } } } } // System.out.println("generateConclusions_defeasiblyProvable..10"); logMessage(Level.FINE, 2, "generateConclusions_defeasiblyProvable.removeRules=", rulesToRemove); removeRules(rulesToRemove); // System.out.println("SdlReasoningEngine.generateConclusions_defeasiblyProvable...end"); return ProcessStatus.SUCCESS; } protected void provableRulesSuperiorityUpdate(Set<Rule> rulesModified) throws ReasoningEngineException, TheoryException { if (rulesModified.size() == 0) return; Set<String> defeatedRulesStr = new TreeSet<String>(); for (Rule rule : rulesModified) { Set<String> inferiorlyDefeatedRulesSet = getDefeatedRulesInTheory(rule.getLabel()); defeatedRulesStr.addAll(inferiorlyDefeatedRulesSet); } if (defeatedRulesStr.size() == 0) return; logMessage(Level.FINE, 2, "defeatedRulesStr=", defeatedRulesStr); for (String ruleLabel : defeatedRulesStr) { Rule rule = theory.getRule(ruleLabel); rulesModified.remove(rule); } removeDefeatedRulesWithInference(defeatedRulesStr, true); } protected void removeDefeatedRulesWithInference(Set<String> defeatedRulesStr, boolean checkInference) throws ReasoningEngineException { try { List<Rule> defeatedRules = new ArrayList<Rule>(); for (String ruleLabel : defeatedRulesStr) { Rule rule = theory.getRule(ruleLabel); defeatedRules.add(rule); if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(rule.getOriginalLabel(), RuleType.DEFEASIBLE, ConclusionType.DEFEASIBLY_NOT_PROVABLE, rule.getHeadLiterals().get(0), RuleInferenceStatus.DEFEATED); } removeRules(defeatedRulesStr); for (Rule rule : defeatedRules) { Literal literal = rule.getHeadLiterals().get(0); if (!containsUnprovedRuleInTheory(literal, RuleType.DEFEASIBLE)) { newLiteralFind_defeasiblyNotProvable(literal, checkInference); } } } catch (Exception e) { throw new ReasoningEngineException(getClass(), e); } } protected boolean containsUnprovedRuleInTheory(final Literal literal, final RuleType ruleType) { return theory.containsUnprovedRule(literal, ruleType, false); } @Override protected boolean containsUnprovedRuleInTheory(final Collection<Literal> literals, final RuleType ruleType) { for (Literal literal : literals) { if (containsUnprovedRuleInTheory(literal, ruleType)) return true; } return false; } @Override protected Conclusion getNextPendingConclusion() throws ReasoningEngineException { // Conclusion pendingConclusion = null; int totalPendingConclusionsCount = 0; for (int i = 0; i < pendingConclusions.length; i++) { // for (int i = 0; i < pendingConclusions.length && null == pendingConclusion; i++) { totalPendingConclusionsCount += pendingConclusions[i].size(); if (totalPendingConclusionsCount == 0) { // flag used to indicate the last update of the scc literals groups int sccLiteralUpdated = -1; // modification start // try generating the conclusion using superiority relations if (i == ProvabilityLevel.DEFEASIBLE.ordinal() && !hasPendingConclusions(i)) { // if (i == 1 && pendingConclusions[i].size() == 0) { if (!Conf.isReasoningWithWellFoundedSemantics() && ! hasAmbiguousConclusions(i)) { logMessage(Level.FINEST, 1, "check for inferiorly defeated rules"); int theorySize = theory.getFactsAndAllRules().size(); do { theorySize = theory.getFactsAndAllRules().size(); Set<RuleExt> weakestRules = new TreeSet<RuleExt>(); for (Superiority sup : theory.getAllSuperiority()) { RuleExt infRule = (RuleExt) theory.getRule(sup.getInferior()); if (infRule.getWeakerRulesCount() == 0 && infRule.getStrongerRulesCount() > 0) weakestRules.add(infRule); } if (weakestRules.size() > 0) { Set<RuleExt> rulesToVerify = new TreeSet<RuleExt>(); Set<String> rulesToRemove = new TreeSet<String>(); for (RuleExt rule : weakestRules) { rulesToVerify.add(rule); } getSccLiteralsGroupInTheory(); sccLiteralUpdated = 1; verifyWeakestRuleInTheory(weakestRules, rulesToRemove); if (rulesToRemove.size() > 0) { if (isLogInferenceProcess) { for (String ruleLabel : rulesToRemove) { Rule rule = theory.getRule(ruleLabel); getInferenceLogger().updateRuleInferenceStatus(rule.getOriginalLabel(), RuleType.DEFEASIBLE, ConclusionType.DEFEASIBLY_NOT_PROVABLE, rule.getHeadLiterals().get(0), RuleInferenceStatus.DEFEATED); } } removeRules(rulesToRemove); } } } while (theorySize > theory.getFactsAndAllRules().size()); } try { generatePendingConclusions(true); } catch (Exception e) { throw new ReasoningEngineException(getClass(), e); } } // modification end if (!hasPendingConclusions(i) && hasAmbiguousConclusions(i)) { // if (pendingConclusions[i].size() == 0 && ambiguousConclusions[i].size() > 0) { // update ambiguous conclusions found if (!AppConst.isDeploy) logMessage(Level.FINEST, 1, "search for ambiguous conclusions, lvl=1, i=", i); if (sccLiteralUpdated != 1) getSccLiteralsGroupInTheory(); sccLiteralUpdated = 2; updateAmbiguousConclusions(i); totalPendingConclusionsCount += pendingConclusions[i].size(); } if (!hasPendingConclusions(i) && hasAmbiguousConclusions(i)) { // if (pendingConclusions[i].size() == 0 && ambiguousConclusions[i].size() > 0) { updateSccAmbiguousConclusions(i, Conf.isReasoningWithWellFoundedSemantics()); } // well-found semantics // - check for strongly connected literals if no new pending conclusions found after ambiguity check if (Conf.isReasoningWithWellFoundedSemantics() // && i == pendingConclusions.length - 1 // && totalPendingConclusionsCount == 0 // && theory.getFactsAndAllRules().size() > 0) { if (!AppConst.isDeploy) logMessage(Level.FINEST, 1, "Analyse theory for strongly connected literals, i=", i); try { if (updateStronglyConnectedComponents(sccLiteralUpdated != 2) > 0) { int jj = 0; while (jj < pendingConclusions.length && pendingConclusions[jj].size() == 0) { jj++; } if (i > jj) i = jj; } } catch (ReasoningEngineException e) { throw e; } catch (Exception e) { throw new ReasoningEngineException(getClass(), "Exception throw while generating strongly connected components", e); } } } if (pendingConclusions[i].size() > 0) { // Conclusion nextConclusion=pendingConclusions[i].get(0);pendingConclusions[i].remove(0);return // nextConclusion; return pendingConclusions[i].removeFirst(); } else { // some loop in the theory may occur } } // return pendingConclusion; return null; } @Override protected void updateAmbiguousConclusions(int i) throws ReasoningEngineException { if (ambiguousConclusions[i].size() == 0) return; if (!AppConst.isDeploy) printEngineStatus("updateAmbiguousConclusions-before"); List<Conclusion> ambiguousConclusionToRemove = new ArrayList<Conclusion>(); List<Conclusion> recordsToRemove = new ArrayList<Conclusion>(); RuleType ruleType=null; ConclusionType negativeConclusionType=null; for (Entry<Conclusion, Set<String>> entry : ambiguousConclusions[i].entrySet()) { Conclusion conclusion = entry.getKey(); Set<String> ruleLabels = entry.getValue(); Literal literal = conclusion.getLiteral(); ConclusionType conclusionType =conclusion.getConclusionType(); switch (conclusionType) { case DEFINITE_PROVABLE: // nothing to change at this moment ruleType=RuleType.STRICT; negativeConclusionType = ConclusionType.DEFINITE_NOT_PROVABLE; break; case DEFEASIBLY_PROVABLE: ruleType = RuleType.DEFEASIBLE; negativeConclusionType = ConclusionType.DEFEASIBLY_NOT_PROVABLE; break; default: } Set<Rule> rulesWithLiteralAsHead = theory.getRulesWithHead(literal); boolean keepLiteralInAmbiguousSet = false; for (Rule r : rulesWithLiteralAsHead) { if (!ruleType.equals(r.getRuleType()))continue; for (Literal bodyLiteral : r.getBodyLiterals()) { if (bodyLiteral.isPlaceHolder()) keepLiteralInAmbiguousSet = true; } } Set<Literal> conflictLiterals = getConflictLiterals(literal); boolean conflictLiteralInSccGroup = false; for (Literal conflictLiteral : conflictLiterals) { if (getSccGroup(conflictLiteral) != null) conflictLiteralInSccGroup = true; } boolean chk = isRecordExist(conflictLiterals, conclusionType); if (keepLiteralInAmbiguousSet) { // defer the removal of literal until all rules generated // by the superiority removal process have been evaluated logMessage(Level.FINER, 2, "keep literal in ambiguous set temporary"); conclusionType=null; } else if (!containsUnprovedRuleInTheory(conflictLiterals, ruleType)) { ambiguousConclusionToRemove.add(conclusion); logMessage(Level.FINER, 0, "*** dchk4=", chk); if (chk) { recordsToRemove.add(conclusion); if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(ruleLabels, ruleType, negativeConclusionType, literal, RuleInferenceStatus.DEFEATED); //newLiteralFind_defeasiblyNotProvable(literal, true); conclusionType=negativeConclusionType; } else { if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(ruleLabels, conclusion, RuleInferenceStatus.APPICABLE); //newLiteralFind_defeasiblyProvable(literal, true); } } else if (conflictLiteralInSccGroup && chk) { ambiguousConclusionToRemove.add(conclusion); recordsToRemove.add(conclusion); if (isLogInferenceProcess) getInferenceLogger().updateRuleInferenceStatus(ruleLabels, conclusion, RuleInferenceStatus.DISCARDED); // newLiteralFind_defeasiblyNotProvable(literal, true); conclusionType=negativeConclusionType; } if (null == conclusionType) continue; // generate new conclusion based on the conclusion type derived above generateConclusionsWithLiteral(conclusionType, literal, true); // ============ commented on 2012.12.12 - start // switch (conclusion.getConclusionType()) { // case DEFINITE_PROVABLE: // logMessage(Level.FINER, 1, "updateAmbiguousConclusion, check literal (definite): ", literal); // for (Rule r : rulesWithLiteralAsHead) { // if (!RuleType.STRICT.equals(r.getRuleType()))continue; // for (Literal bodyLiteral : r.getBodyLiterals()) { // if (bodyLiteral.isPlaceHolder()) keepLiteralInAmbiguousSet = true; // } // } // boolean chk1 = isRecordExist(conflictLiterals, ConclusionType.DEFINITE_PROVABLE); // // if (keepLiteralInAmbiguousSet){ // // defer the removal of literal until all rules generated // // by the superiority removal process have been evaluated // logMessage(Level.FINER, 2, "keep literal in ambiguous set temporary"); // }else if (!containsUnprovedRuleInTheory(conflictLiterals, RuleType.STRICT)) { // ambiguousConclusionToRemove.add(conclusion); // if (chk1) { // recordsToRemove.add(conclusion); // if (isLogInferenceProcess) // getInferenceLogger().updateRuleInferenceStatus(ruleLabels, RuleType.STRICT, // ConclusionType.DEFINITE_NOT_PROVABLE, literal, RuleInferenceStatus.DEFEATED); // newLiteralFind_definiteNotProvable(literal, true); // } else { // if (isLogInferenceProcess) // getInferenceLogger().updateRuleInferenceStatus(ruleLabels, conclusion, RuleInferenceStatus.APPICABLE); // newLiteralFind_definiteProvable(literal, true); // } // } else if (conflictLiteralInSccGroup && chk1) { // ambiguousConclusionToRemove.add(conclusion); // recordsToRemove.add(conclusion); // if (isLogInferenceProcess) // getInferenceLogger().updateRuleInferenceStatus(ruleLabels, conclusion, RuleInferenceStatus.DISCARDED); // newLiteralFind_defeasiblyNotProvable(literal, true); // } // break; // case DEFEASIBLY_PROVABLE: // logMessage(Level.FINER, 1, "updateAmbiguousConclusion, check literal (defeasible): ", literal); // for (Rule r : rulesWithLiteralAsHead) { // if (!RuleType.DEFEASIBLE.equals(r.getRuleType()))continue; // for (Literal bodyLiteral : r.getBodyLiterals()) { // if (bodyLiteral.isPlaceHolder()) keepLiteralInAmbiguousSet = true; // } // } // boolean dchk4 = isRecordExist(conflictLiterals, ConclusionType.DEFEASIBLY_PROVABLE); // if (keepLiteralInAmbiguousSet) { // // defer the removal of literal until all rules generated // // by the superiority removal process have been evaluated // logMessage(Level.FINER, 2, "keep literal in ambiguous set temporary"); // } else if (!containsUnprovedRuleInTheory(conflictLiterals, RuleType.DEFEASIBLE)) { // ambiguousConclusionToRemove.add(conclusion); // logMessage(Level.FINER, 0, "*** dchk4=", dchk4); // if (dchk4) { // recordsToRemove.add(conclusion); // if (isLogInferenceProcess) // getInferenceLogger().updateRuleInferenceStatus(ruleLabels, RuleType.DEFEASIBLE, // ConclusionType.DEFEASIBLY_NOT_PROVABLE, literal, RuleInferenceStatus.DEFEATED); // newLiteralFind_defeasiblyNotProvable(literal, true); // } else { // if (isLogInferenceProcess) // getInferenceLogger().updateRuleInferenceStatus(ruleLabels, conclusion, RuleInferenceStatus.APPICABLE); // newLiteralFind_defeasiblyProvable(literal, true); // } // } else if (conflictLiteralInSccGroup && dchk4) { // ambiguousConclusionToRemove.add(conclusion); // recordsToRemove.add(conclusion); // if (isLogInferenceProcess) // getInferenceLogger().updateRuleInferenceStatus(ruleLabels, conclusion, RuleInferenceStatus.DISCARDED); // newLiteralFind_defeasiblyNotProvable(literal, true); // } // break; // default: // } // ============ commented on 2012.12.12 - start } logMessage(Level.FINER, 1, "ambiguousConclusionToRemove=", ambiguousConclusionToRemove); for (Conclusion conclusion : ambiguousConclusionToRemove) { ambiguousConclusions[i].remove(conclusion); } for (Conclusion record : recordsToRemove) { removeRecord(record); } if (!AppConst.isDeploy) printEngineStatus("updateAmbiguousConclusions-after"); } protected ProcessStatus generateConclusionsWithLiteral(ConclusionType conclusionType, // Literal literal, boolean checkInference) throws ReasoningEngineException { if (null == literal || null == conclusionType) return ProcessStatus.SUCCESS; switch (conclusionType) { case DEFINITE_PROVABLE: return newLiteralFind_definiteProvable(literal, checkInference); case DEFINITE_NOT_PROVABLE: return newLiteralFind_definiteNotProvable(literal, checkInference); case DEFEASIBLY_PROVABLE: return newLiteralFind_defeasiblyProvable(literal, checkInference); case DEFEASIBLY_NOT_PROVABLE: return newLiteralFind_defeasiblyNotProvable(literal, checkInference); default: } return ProcessStatus.SUCCESS; } }