/** * 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.core.dom; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.Map.Entry; import com.app.utils.FileManager; import com.app.utils.Utilities; import spindle.sys.AppConst; import spindle.sys.Messages; import spindle.sys.message.ErrorMessage; import spindle.sys.message.SystemMessage; /** * Base class for defeasible theory (data getter/setter functions). * * @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory * @since version 1.0.0 */ public abstract class TheoryCore implements Serializable { private static final long serialVersionUID = 1L; private static String LINE_SEPARATOR = FileManager.LINE_SEPARATOR; // ===== // basic theory data protected String description = ""; // - literal variables protected Map<LiteralVariable, LiteralVariable> literalVariables = null; protected Map<LiteralVariable, LiteralVariable> literalBooleanFunctions = null; protected Set<LiteralVariable> literalVariablesInRules = null; protected Set<LiteralVariable> literalBooleanFunctionsInRules = null; // - rules, superiority relations and their association list protected Map<String, Rule> factsAndAllRules = null; protected Map<String, Set<Superiority>> superiors = null; protected Map<String, Set<Superiority>> inferiors = null; protected int superiorityCount = 0; protected TheoryType theoryType = TheoryType.SDL; protected Map<Literal, Map<String, Rule>> literalRuleAssoList = null; protected Map<RuleType, Map<String, Rule>> ruleTypeAssoList = null; protected Map<Literal, TreeSet<Literal>> mixedLiteralsSets[] = null; // - mode conversation and mode conflict rules protected Map<String, Set<String>> modeConversionRules = null; protected Map<String, Set<String>> modeConflictRules = null; protected Map<String, Set<String>> modeExclusionRules = null; private boolean conversionRulesModified = false; private boolean conflictRulesModified = false; private boolean exclusionRulesModified = false; @SuppressWarnings("unchecked") public TheoryCore() { description = ""; literalVariables = new TreeMap<LiteralVariable, LiteralVariable>(); literalBooleanFunctions = new TreeMap<LiteralVariable, LiteralVariable>(); literalVariablesInRules = new TreeSet<LiteralVariable>(); literalBooleanFunctionsInRules = new TreeSet<LiteralVariable>(); factsAndAllRules = new TreeMap<String, Rule>(); superiors = new TreeMap<String, Set<Superiority>>(); inferiors = new TreeMap<String, Set<Superiority>>(); superiorityCount = 0; literalRuleAssoList = new TreeMap<Literal, Map<String, Rule>>(); ruleTypeAssoList = new TreeMap<RuleType, Map<String, Rule>>(); mixedLiteralsSets = new TreeMap[2]; for (int i = 0; i < 2; i++) { mixedLiteralsSets[i] = new TreeMap<Literal, TreeSet<Literal>>(new LiteralComparator(false)); } // mixedLiteralsSets = new TreeMap<Literal, TreeSet<Literal>>(new LiteralComparator(false)); modeConversionRules = new TreeMap<String, Set<String>>(); modeConflictRules = new TreeMap<String, Set<String>>(); modeExclusionRules = new TreeMap<String, Set<String>>(); resetConversionRulesModified(); resetConflictRulesModified(); resetExclusionRulesModified(); } public TheoryCore(TheoryCore theory) { this(); if (null == theory) return; setDescription(theory.getDescription()); try { for (Entry<LiteralVariable, LiteralVariable> entry : theory.literalVariables.entrySet()) { addLiteralVariable(entry.getKey(), entry.getValue()); } for (Entry<LiteralVariable, LiteralVariable> entry : theory.literalBooleanFunctions.entrySet()) { addLiteralVariable(entry.getKey(), entry.getValue()); } for (Rule rule : theory.factsAndAllRules.values()) { addRule(rule.clone()); } for (Superiority superiority : theory.getAllSuperiority()) { add(superiority.clone()); } for (Entry<String, Set<String>> entry : theory.modeConversionRules.entrySet()) { Set<String> convertModesSet = entry.getValue(); String[] convertModes = convertModesSet.toArray(new String[convertModesSet.size()]); addModeConversionRules(entry.getKey(), convertModes); } for (Entry<String, Set<String>> entry : theory.modeConflictRules.entrySet()) { Set<String> conflictModesSet = entry.getValue(); String[] conflictModes = conflictModesSet.toArray(new String[conflictModesSet.size()]); addModeConflictRules(entry.getKey(), conflictModes); } for (Entry<String, Set<String>> entry : theory.modeExclusionRules.entrySet()) { Set<String> excludedModesSet = entry.getValue(); String[] excludedModes = excludedModesSet.toArray(new String[excludedModesSet.size()]); addModeExclusionRules(entry.getKey(), excludedModes); } } catch (TheoryException e) { e.printStackTrace(); } } public void setDescription(String description) { this.description = null == description ? "" : description.trim(); } public String getDescription() { return description; } public void addLiteralVariable(final LiteralVariable varName, final LiteralVariable value) throws TheoryException { if (varName.getName().charAt(0) != DomConst.Literal.LITERAL_VARIABLE_PREFIX) throw new TheoryException(ErrorMessage.LITERAL_VARIABLE_PREFIX_ERROR, new String[] { varName.toString() }); if (literalVariables.containsKey(varName)) { throw new TheoryException(ErrorMessage.LITERAL_VARIABLE_EXISTS, new Object[] { varName.getName() }); } else if (literalBooleanFunctions.containsKey(varName)) { throw new TheoryException(ErrorMessage.LITERAL_BOOLEAN_FUNCTION_EXISTS, new Object[] { varName.getName() }); } if (value.getName().charAt(0) == DomConst.Literal.LITERAL_VARIABLE_PREFIX) { literalVariables.put(varName.clone(), value.clone()); } else if (value.getName().charAt(0) == DomConst.Literal.LITERAL_BOOLEAN_FUNCTION_PREFIX) { literalBooleanFunctions.put(varName.clone(), value.clone()); } else { throw new TheoryException(ErrorMessage.LITERAL_VARIABLE_PREFIX_ERROR); } } public void removeLiteralVariable(final LiteralVariable varName) throws TheoryException { if (varName.getName().charAt(0) == DomConst.Literal.LITERAL_VARIABLE_PREFIX) { literalVariables.remove(varName); } else if (varName.getName().charAt(0) == DomConst.Literal.LITERAL_BOOLEAN_FUNCTION_PREFIX) { literalBooleanFunctions.remove(varName); } else { throw new TheoryException(ErrorMessage.LITERAL_VARIABLE_PREFIX_ERROR); } } public Map<LiteralVariable, LiteralVariable> getLiteralVariables() { return literalVariables; } public int getLiteralVariableCount() { return literalVariables.size(); } public void clearLiteralVariables() { // for (LiteralVariable lv:literalVariables.keySet()){ // literalRuleAssoList.remove(lv); // for (int i=0;i<mixedLiteralsSets.length;i++){ // mixedLiteralsSets[i].remove(lv); // } // } literalVariables.clear(); } public Map<LiteralVariable, LiteralVariable> getLiteralBooleanFunctions() { return literalBooleanFunctions; } public int getLiteralBooleanFunctionCount() { return literalBooleanFunctions.size(); } public void clearLiteralBooleanFunctions() { literalBooleanFunctions.clear(); } public Set<LiteralVariable> getLiteralVariablesInRules() { return literalVariablesInRules; } /** * Update the literal variable with a literal. * This can be used to replace a literal variable with a regular literal after the literal variable evaluation * process. * See {@link spindle.tools.evaluator.LiteralVariablesEvaluator#addBooleanConclusionGenerated} for details. * * @param literalVariable Literal variable to be replaced. * @param literal Literal used to substitute the literal variable. * @throws TheoryException */ public void updateLiteralVariableInRule(LiteralVariable literalVariable, Literal literal) throws TheoryException { Map<String, Rule> lvRules = getRules(literalVariable); if (null == literal) { for (Entry<String, Rule> entry : lvRules.entrySet()) { String ruleLabel = entry.getKey(); Rule r = entry.getValue(); removeRule(ruleLabel); r.removeBodyLiteral(literalVariable); addRule(r); } } else { for (Entry<String, Rule> entry : lvRules.entrySet()) { String ruleLabel = entry.getKey(); Rule r = entry.getValue(); removeRule(ruleLabel); r.removeBodyLiteral(literalVariable); r.addBodyLiteral(literal); addRule(r); } } literalVariablesInRules.remove(literalVariable); } public int getLiteralVariablesInRulesCount() { for (LiteralVariable lv : literalVariablesInRules) { System.out.println("literalVariablesInRules=" + lv); } return literalVariablesInRules.size(); } public Set<LiteralVariable> getLiteralBooleanFunctionsInRules() { return literalBooleanFunctionsInRules; } public int getLiteralBooleanFunctionsInRulesCount() { return literalBooleanFunctionsInRules.size(); } public void addModeExclusionRules(final String modeName, final String[] excludedModes) { if (null == excludedModes || excludedModes.length == 0) return; if (addModeToSet(modeName, modeExclusionRules, excludedModes)) exclusionRulesModified = true; // String o = modeName.trim().toUpperCase(); // Set<String> modeList = modeExclusionRules.get(o); // if (null == modeList) { // modeList = new TreeSet<String>(); // modeExclusionRules.put(o, modeList); // } // for (String excludedMode : excludedModes) { // String mode = excludedMode.trim().toUpperCase(); // if (!"".equals(mode)) { // if (modeList.add(mode)) exclusionRulesModified = true; // } // } // if (modeList.size() == 0) modeExclusionRules.remove(o); } public void removeModeExclusionRule(final String modeName, String excludedMode) { if (removeModeFromSet(modeName, modeExclusionRules, excludedMode)) exclusionRulesModified = true; // String modeNameUpper = modeName.trim().toUpperCase(); // String excludedModeUpper = excludedMode.trim().toUpperCase(); // Set<String> modeList = modeExclusionRules.get(modeNameUpper); // if (null == modeList) return; // if (modeList.remove(excludedModeUpper)) { // if (modeList.size() == 0) modeExclusionRules.remove(modeNameUpper); // exclusionRulesModified = true; // } } private boolean removeModeFromSet(final String modeName, Map<String, Set<String>> modeSets, String modeToRemove) { if (null == modeName || "".equals(modeName.trim())) return false; boolean isModified = false; String o = modeName.trim().toUpperCase(); Set<String> modeSet = modeSets.get(o); if (null == modeSet) return isModified; String n = modeToRemove.trim().toUpperCase(); if (!"".equals(n) && modeSet.remove(n)) { isModified = true; if (modeSet.size() == 0) modeSets.remove(o); } return isModified; } private boolean addModeToSet(final String modeName, Map<String, Set<String>> modeSets, String[] modeToAdd) { if (null == modeName || "".equals(modeName.trim())) return false; boolean isModified = false; String o = modeName.trim().toUpperCase(); Set<String> modeSet = modeSets.get(o); if (null == modeSet) { modeSet = new TreeSet<String>(); modeSets.put(o, modeSet); } for (String newMode : modeToAdd) { String n = newMode.trim().toUpperCase(); if ("".equals(n)) continue; if (modeSet.add(n)) isModified = true; } if (modeSet.size() == 0) modeSets.remove(o); return isModified; } /** * check if there exist any mode conversion rules * * @return true if there exist any mode conversion rules in theory */ public boolean isExclusionRulesModified() { return exclusionRulesModified; } /** * add mode conversions rule to theory * * @param modeName Name of modal operator. * @param convertModes List of converting modalities. */ public void addModeConversionRules(final String modeName, final String[] convertModes) { if (null == convertModes || convertModes.length == 0) return; if (addModeToSet(modeName, modeConversionRules, convertModes)) conversionRulesModified = true; // String o = modeName.trim().toUpperCase(); // Set<String> modeList = modeConversionRules.get(o); // if (null == modeList) { // modeList = new TreeSet<String>(); // modeConversionRules.put(o, modeList); // } // for (String convertMode : convertModes) { // String mode = convertMode.trim().toUpperCase(); // if (!"".equals(mode)) { // if (modeList.add(mode)) conversionRulesModified = true; // } // } // if (modeList.size() == 0) modeConversionRules.remove(o); } /** * remove mode conversion rule from theory * * @param modeName * @param convertMode */ public void removeModeConversionRule(final String modeName, final String convertMode) { if (removeModeFromSet(modeName, modeConversionRules, convertMode)) conversionRulesModified = true; // String modeNameUpper = modeName.trim().toUpperCase(); // String covertModeUpper = convertMode.trim().toUpperCase(); // Set<String> modeList = modeConversionRules.get(modeNameUpper); // if (null == modeList) return; // if (modeList.remove(covertModeUpper)) { // if (modeList.size() == 0) modeConversionRules.remove(modeNameUpper); // conversionRulesModified = true; // } } public Set<String> getModeConversionRules(final String mode) { return modeConversionRules.get(mode.trim().toUpperCase()); } public Map<String, Set<String>> getAllModeConversionRules() { return modeConversionRules; } public Set<String> getModeExclusionRules(final String mode) { return modeExclusionRules.get(mode.trim().toUpperCase()); } public int getModeExclusionRulesCount(){ return modeExclusionRules.size(); } public Map<String, Set<String>> getAllModeExclusionRules() { return modeExclusionRules; } /** * check if there exist any mode conversion rules * * @return true if there exist any mode conversion rules in theory */ public boolean isConversionRulesModified() { return conversionRulesModified; } /** * reset all mode conversion rules */ public void resetConversionRulesModified() { conversionRulesModified = false; } /** * add mode conflict rule to theory * * @param modeName Name of modal operator. * @param conflictModes List of conflicting modalities. */ public void addModeConflictRules(final String modeName, final String[] conflictModes) { if (null == conflictModes || conflictModes.length == 0) return; if (addModeToSet(modeName, modeConflictRules, conflictModes)) conflictRulesModified = true; // String o = modeName.trim().toUpperCase(); // Set<String> modeList = modeConflictRules.get(o); // if (null == modeList) { // modeList = new TreeSet<String>(); // modeConflictRules.put(o, modeList); // } // for (String conflictMode : conflictModes) { // String mode = conflictMode.trim().toUpperCase(); // if (!"".equals(mode)) { // if (modeList.add(mode)) conflictRulesModified = true; // } // } // if (modeList.size() == 0) modeConversionRules.remove(o); } /** * remove a mode conflict rule from theory * * @param modeName * @param conflictMode */ public void removeModeConflictRule(final String modeName, final String conflictMode) { if (removeModeFromSet(modeName, modeConflictRules, conflictMode)) conflictRulesModified = true; // String modeNameUpper = modeName.trim().toUpperCase(); // String conflictModeUpper = conflictMode.trim().toUpperCase(); // Set<String> modeList = modeConflictRules.get(modeNameUpper); // if (null == modeList) return; // if (modeList.remove(conflictModeUpper)) { // if (modeList.size() == 0) modeConflictRules.remove(modeNameUpper); // conflictRulesModified = true; // } } /** * return the set of mode conversion rules with the original mode specified * * @param mode * @return set of mode conversion rules */ public Set<String> getModeConflictRules(final String mode) { return modeConflictRules.get(mode.trim().toUpperCase()); } /** * get all mode conflict rules * * @return all mode conflict rules */ public Map<String, Set<String>> getAllModeConflictRules() { return modeConflictRules; } /** * check if there exist any mode conflict rules in theory * * @return true if theory contains any mode conflict rules */ public boolean isConflictRulesModified() { return conflictRulesModified; } /** * reset all mode conflict rules */ public void resetConflictRulesModified() { conflictRulesModified = false; } /** * reset all mode exclusion rules */ public void resetExclusionRulesModified() { exclusionRulesModified = false; } /** * add new fact to theory * * @param fact * @throws TheoryException */ public void addFact(Rule fact) throws TheoryException { addRule(fact); } /** * update the rule with new content * * @param rule * @throws TheoryException */ public synchronized void updateRule(Rule rule) throws TheoryException { if (factsAndAllRules.containsKey(rule.getLabel())) removeRule(rule.getLabel()); addRule(rule); } /** * add new rule to theory * * @param newRule * @throws TheoryException */ public synchronized void addRule(Rule newRule) throws TheoryException { if (newRule == null) throw new TheoryException(ErrorMessage.RULE_NULL_RULE); // throw exception if rule contains no head literals if (newRule.getHeadLiterals().size() == 0) throw new RuleException(ErrorMessage.RULE_NO_HEAD_LITERAL, new Object[] { newRule.getLabel() }); // add rule to the theory if it does not already exist if (factsAndAllRules.containsKey(newRule.getLabel())) throw new TheoryException(ErrorMessage.RULE_ALREADY_EXISTS, new Object[] { newRule.getLabel() }); switch (newRule.getRuleType()) { case FACT: factsAndAllRules.put(newRule.getLabel(), newRule); break; case STRICT: factsAndAllRules.put(newRule.getLabel(), newRule); break; case DEFEASIBLE: factsAndAllRules.put(newRule.getLabel(), newRule); break; case DEFEATER: factsAndAllRules.put(newRule.getLabel(), newRule); break; default: throw new TheoryException(ErrorMessage.RULE_UNRECOGNIZED_RULE_TYPE, new Object[] { newRule.getRuleType() }); } // update literal-rule type association list updateRuleTypeAssociationList_addRule(newRule); // update literal-rule association list updateLiteralRuleAssociationList_addRule(newRule); // update mixed literals sets updateMixedLiteralsSets_add(newRule); } /** * remove the rule from the rule set and update the literal-rule association * list * * @param ruleLabel * label of the rule to be removed * @throws TheoryException */ public void removeRule(final String ruleLabel) throws TheoryException { if (!factsAndAllRules.containsKey(ruleLabel)) throw new TheoryException(ErrorMessage.RULE_UNRECOGNIZED_RULE_ID, new Object[] { ruleLabel }); Rule rule = factsAndAllRules.get(ruleLabel); if (rule == null) throw new TheoryException(ErrorMessage.RULE_NULL_RULE); updateRuleTypeAssociationList_removeRule(rule); // update literal-rule association list updateLiteralRuleAssociationList_removeRule(rule); // updated mixed literals sets updateMixedLiteralsSets_remove(rule); // delete the rule from the rule set factsAndAllRules.remove(ruleLabel); } /** * remove the literal from rule body * * @param literal * literal to be removed from body * @return list of rules removed from the literal association list * @throws TheoryException */ public Set<Rule> removeBodyLiteralFromRules(final Literal literal, final RuleType ruleType) throws TheoryException { try { Set<Rule> rulesModified = new HashSet<Rule>(); Map<String, Rule> ruleList = literalRuleAssoList.get(literal); if (null == ruleList || ruleList.size() == 0) return rulesModified; if (ruleList != null) { for (Rule rule : ruleList.values()) { if (ruleType == null) { if (rule.isBodyLiteral(literal)) { rule.removeBodyLiteral(literal); rulesModified.add(rule); } } else { if (rule.getRuleType() == ruleType && rule.isBodyLiteral(literal)) { rule.removeBodyLiteral(literal); rulesModified.add(rule); } } } for (Rule rule : rulesModified) { if (!rule.isHeadLiteral(literal)) ruleList.remove(rule.getLabel()); } if (ruleList.size() == 0) literalRuleAssoList.remove(literal); if (rulesModified.size() > 0) updateMixedLiteralsSets_remove(literal, ruleType); } return rulesModified; } catch (Exception e) { throw new TheoryException("exception throw, litreal=" + literal + ", ruleType=" + ruleType, e); } } /** * add a superiority relation to theory * * @param sup */ public void add(final Superiority sup) { Set<Superiority> list = superiors.get(sup.getSuperior()); if (null == list) { list = new TreeSet<Superiority>(); superiors.put(sup.getSuperior(), list); } if (!list.contains(sup)) { list.add(sup); superiorityCount++; } list = inferiors.get(sup.getInferior()); if (null == list) { list = new TreeSet<Superiority>(); inferiors.put(sup.getInferior(), list); } if (!list.contains(sup)) list.add(sup); } /** * remove the superiority relation specified * * @param sup */ public void remove(final Superiority sup) { Set<Superiority> list = superiors.get(sup.getSuperior()); if (null != list) { if (list.remove(sup)) superiorityCount--; if (list.size() == 0) superiors.remove(sup.getSuperior()); } list = inferiors.get(sup.getInferior()); if (null != list) { list.remove(sup); if (list.size() == 0) inferiors.remove(sup.getInferior()); } } /** * add all rules and superiority relations of other theory to this theory * * @param theoryPrefix * @param theory * @throws TheoryException */ public void add(String theoryPrefix, TheoryCore theory) throws TheoryException { Collection<Rule> newRules = theory.factsAndAllRules.values(); Map<String, Set<Superiority>> newSuperiority = theory.superiors; if (null == theoryPrefix) theoryPrefix = Utilities.getRandomString(5); if (!"".equals(theoryPrefix) && !theoryPrefix.endsWith("_")) theoryPrefix += "_"; Set<String> rulesAdded = new HashSet<String>(); try { for (Entry<LiteralVariable, LiteralVariable> entry : theory.literalVariables.entrySet()) { addLiteralVariable(entry.getKey(), entry.getValue()); } for (Entry<LiteralVariable, LiteralVariable> entry : theory.literalBooleanFunctions.entrySet()) { addLiteralVariable(entry.getKey(), entry.getValue()); } if ("".equals(theoryPrefix)) { for (Rule rule : newRules) { Rule newRule = rule.clone(); addRule(newRule); rulesAdded.add(newRule.getLabel()); } for (Entry<String, Set<Superiority>> entry : newSuperiority.entrySet()) { for (Superiority s : entry.getValue()) { add(new Superiority(s.getSuperior(), s.getInferior())); } } } else { for (Rule rule : newRules) { Rule newRule = rule.clone(); String newRuleLabel = theoryPrefix + rule.getLabel(); newRule.setLabel(newRuleLabel); addRule(newRule); rulesAdded.add(newRule.getLabel()); } for (Entry<String, Set<Superiority>> entry : newSuperiority.entrySet()) { for (Superiority s : entry.getValue()) { add(new Superiority(theoryPrefix + s.getSuperior(), theoryPrefix + s.getInferior())); } } } } catch (Exception e) { System.err.println(e.getMessage()); System.err.print("restore theory..."); for (String ruleAdded : rulesAdded) { this.removeRule(ruleAdded); } System.err.println(Messages.getSystemMessage(SystemMessage.APPLICATION_OPERATION_SUCCESS)); throw new TheoryException(e); } } private void updateLiteralRuleAssociationList_addRule(final Rule newRule) throws TheoryException { // Set<Literal> literalList = newRule.getLiteralList(); Map<String, Rule> ruleList = null; // theory type checking if (newRule.hasTemporalInfo()) theoryType = TheoryType.TDL; else if (newRule.hasModalInfo() && theoryType.compareTo(TheoryType.SDL) <= 0) theoryType = TheoryType.MDL; // else if (!"".equals(newRule.getMode().getName()) && theoryType == TheoryType.SDL) theoryType = // TheoryType.MDL; for (Literal literal : newRule.getLiteralList()) { // for (Literal l : newRule.getLiteralList()) { // Literal literal=l instanceof LiteralVariable ? DomUtilities.getLiteral(l):l; // for (Literal literal : literalList) { // if (literal.containsTemporalInfo()) theoryType = TheoryType.TDL; // else if (!"".equals(literal.getMode().getName()) && theoryType == TheoryType.SDL) theoryType = // TheoryType.MDL; ruleList = literalRuleAssoList.get(literal); if (null == ruleList) { ruleList = new TreeMap<String, Rule>(); // if (literal instanceof LiteralVariable){ // Literal l=DomUtilities.getLiteral(literal); // Map<String,Rule>ruleList2=literalRuleAssoList.get(l); // if (null!=ruleList2){ // ruleList.putAll(ruleList2); // literalRuleAssoList.remove(l); // } // } literalRuleAssoList.put(literal, ruleList); } if (!ruleList.containsKey(newRule.getLabel())) ruleList.put(newRule.getLabel(), newRule); // literal variable and boolean operation handling if (literal instanceof LiteralVariable) { LiteralVariable lv = (LiteralVariable) literal; if (lv.isLiteralVariable()) literalVariablesInRules.add(lv); else if (lv.isLiteralBooleanFunction()) literalBooleanFunctionsInRules.add(lv); } } } private void updateLiteralRuleAssociationList_removeRule(final Rule rule) throws TheoryException { try { for (Literal literal : rule.getLiteralList()) { // for (Literal l : rule.getLiteralList()) { // Literal literal=l instanceof LiteralVariable ? DomUtilities.getLiteral(l):l; Map<String, Rule> ruleList = literalRuleAssoList.get(literal); if (null == ruleList) { System.out.println("e1, literal=" + literal + "\n" + toString()); throw new TheoryException("updateLiteralRuleAssociationList_removeRule1: literal [" + literal + "] contains in no rules!!"); } Rule retn = ruleList.remove(rule.getLabel()); if (null == retn) { System.out.println("e2, literal=" + literal + ": ruleLabel=" + rule.getLabel() + "\nruleList=" + ruleList + "\n" + toString()); throw new TheoryException(ErrorMessage.RULE_UNRECOGNIZED_RULE_ID, "updateLiteralRuleAssociationList_removeRule2:" + rule.toString(), new Object[] { rule.getLabel() }); } if (ruleList.size() == 0) { literalRuleAssoList.remove(literal); // literal variable and boolean operation handling if (literal instanceof LiteralVariable) { LiteralVariable lv = (LiteralVariable) literal; if (lv.isLiteralVariable()) literalVariablesInRules.remove(lv); else if (lv.isLiteralBooleanFunction()) literalBooleanFunctionsInRules.remove(lv); } } } } catch (Exception e) { System.err.println(rule); throw new TheoryException("exception throw while updating literal-rule association list:" + rule.toString(), e); } } private void updateRuleTypeAssociationList_addRule(final Rule newRule) throws TheoryException { Map<String, Rule> ruleSet = ruleTypeAssoList.get(newRule.getRuleType()); if (ruleSet == null) { ruleSet = new TreeMap<String, Rule>(); ruleTypeAssoList.put(newRule.getRuleType(), ruleSet); } ruleSet.put(newRule.getLabel(), newRule); } private void updateRuleTypeAssociationList_removeRule(final Rule rule) throws TheoryException { try { Map<String, Rule> ruleSet = ruleTypeAssoList.get(rule.getRuleType()); if (null == ruleSet) throw new TheoryException("Rule type not exist in the theory"); Rule retn = ruleSet.remove(rule.getLabel()); if (null == retn) throw new TheoryException(ErrorMessage.RULE_UNRECOGNIZED_RULE_ID_IN_TYPE, new Object[] { rule.getLabel(), rule.getRuleType() }); if (ruleSet.size() == 0) ruleTypeAssoList.remove(rule.getRuleType()); } catch (Exception e) { throw new TheoryException("exception throw while updating literal-rule association list ", e); } } private void updateMixedLiteralsSets_add(final Rule rule) throws TheoryException { int ind = RuleType.STRICT.equals(rule.getRuleType()) ? 0 : 1; for (Literal literal : rule.getLiteralList()) { // for (Literal l : rule.getLiteralList()) { // Literal literal=l instanceof LiteralVariable ? DomUtilities.getLiteral(l):l; TreeSet<Literal> literalSet = mixedLiteralsSets[ind].get(literal); if (null == literalSet) { literalSet = new TreeSet<Literal>(); mixedLiteralsSets[ind].put(literal.cloneWithNoTemporal(), literalSet); // mixedLiteralsSets.put(DomUtilities.getPlainLiteral(literal), literalSet); } literalSet.add(literal); } } private void updateMixedLiteralsSets_remove(final Rule rule) throws TheoryException { for (Literal literal : rule.getLiteralList()) { updateMixedLiteralsSets_remove(literal, rule.getRuleType()); // System.out.println("updateMixedLiteralsSets_removeRule("+rule.getLabel()+"):"+literal); // TreeSet<Literal>literalSet=mixedLiteralsSets.get(literal); // if (null==literalSet) throw new TheoryException ("Literal ["+literal+"] not exist in theory"); // // System.out.println("updateMixedLiteralsSets_removeRule("+rule.getLabel()+"):"+literal+", literalRuleAssoList.containsKey="+(literalRuleAssoList.containsKey(literal))); // if (literalRuleAssoList.containsKey(literal)){ // System.out.println(" "+(literalRuleAssoList.get(literal))); // } // if (literalRuleAssoList.containsKey(literal)) continue; // literalSet.remove(literal); // System.out.println(" literalSet="+(literalSet)+","+literalSet.size()); // if (literalSet.size()==0) { // mixedLiteralsSets.remove(literal); // System.out.println(" mixedLiteralsSets="+(mixedLiteralsSets.containsKey(literal))); // System.out.println(" mixedLiteralsSets="+(mixedLiteralsSets.keySet())); // } } } private void updateMixedLiteralsSets_remove(final Literal literal, RuleType ruleType) throws TheoryException { // if (!AppConst.isDeploy) System.out.println("updateMixedLiteralsSets_removeLiteral:" + literal); if (literalRuleAssoList.containsKey(literal)) { // if (!AppConst.isDeploy) System.out.println(" " + (literalRuleAssoList.get(literal))); return; } int ind = RuleType.STRICT.equals(ruleType) ? 0 : 1; TreeSet<Literal> literalSet = mixedLiteralsSets[ind].get(literal); if (null == literalSet) throw new TheoryException(ErrorMessage.LITERAL_LITERAL_NOT_EXIST_IN_THEORY, new Object[] { literal }); // if (!AppConst.isDeploy) // System.out.println("updateMixedLiteralsSets_removeLiteral:" + literal + ", literalRuleAssoList.containsKey=" // + (literalRuleAssoList.containsKey(literal))); literalSet.remove(literal); if (literalSet.size() == 0) mixedLiteralsSets[ind].remove(literal); } public Map<String, Rule> getFactsAndAllRules() { return factsAndAllRules; } public Map<String, Rule> getFacts() { return getRules(RuleType.FACT); } /** * return the set of rules with specified rule type * * @param ruleType * @return list of rules with specified rule type */ public Map<String, Rule> getRules(final RuleType ruleType) { Map<String, Rule> ruleSet = new TreeMap<String, Rule>(); Map<String, Rule> rules = ruleTypeAssoList.get(ruleType); if (null != rules) ruleSet.putAll(rules); return ruleSet; } /** * Retrieve rule with the rule label specified. * * @param ruleLabel Rule label. * @return Rule with specified rule label; or null otherwise. */ public Rule getRule(String ruleLabel) { return factsAndAllRules.get(ruleLabel); } /** * Retrieve the set of rules containing the literal specified. * * @param literal * @return list of rules contain the specified literal */ public Map<String, Rule> getRules(Literal literal) { Map<String, Rule> ruleSet = new TreeMap<String, Rule>(); Map<String, Rule> rules = literalRuleAssoList.get(literal); if (null != rules) ruleSet.putAll(rules); return ruleSet; } /** * Return the set of literals that appear in the theory. * * @return The set of literals that appear in the theory. */ public Set<Literal> getAllLiteralsInRules() { return literalRuleAssoList.keySet(); } /** * Return the set of literals containing the same set of content but with different temporal intervals. * * @param literal Literal to be extracted. * @return The set of literals with same content but with different temporal intervals. */ public Set<Literal> getRelatedLiterals(Literal literal, ProvabilityLevel provability) { return mixedLiteralsSets[provability.ordinal()].get(literal); } /** * get the number of mode conversion rules * * @return no. of mode conversion rules */ public int getModeConversionRulesCount() { int c = 0; for (Collection<String> modeLst : modeConversionRules.values()) { c += modeLst.size(); } return c; } /** * get the number of mode conflict rules * * @return no. of mode conflict rules */ public int getModeConflictRulesCount() { int c = 0; for (Collection<String> modeLst : modeConflictRules.values()) { c += modeLst.size(); } return c; } /** * get the number of facts * * @return number of facts */ public int getFactsCount() { Map<String, Rule> ruleSet = ruleTypeAssoList.get(RuleType.FACT); return (ruleSet == null) ? 0 : ruleSet.size(); } /** * get the number of strict rules * * @return number of strict rules */ public int getStrictRulesCount() { Map<String, Rule> ruleSet = ruleTypeAssoList.get(RuleType.STRICT); return (ruleSet == null) ? 0 : ruleSet.size(); } /** * get the number of defeaters * * @return no. of defeaters */ public int getDefeasibleRulesCount() { Map<String, Rule> ruleSet = ruleTypeAssoList.get(RuleType.DEFEASIBLE); return (ruleSet == null) ? 0 : ruleSet.size(); } /** * get the number of superiority relation * * @return no. of superiority relations */ public int getSuperiorityCount() { return superiors.size(); } /** * get the number of defeaters * * @return number of defeaters */ public int getDefeatersCount() { Map<String, Rule> ruleSet = ruleTypeAssoList.get(RuleType.DEFEATER); return (ruleSet == null) ? 0 : ruleSet.size(); } /** * check if the theory contains any rules * * @return true if there is no rule in the theory */ public boolean isEmpty() { // if (!AppConst.isDeploy) { // System.out.println("mixedLiteralsSets.size()=" + mixedLiteralsSets.size()); // if (mixedLiteralsSets.size() > 0) { // StringBuilder sb = new StringBuilder(TextUtilities.generateHighLightedMessage("mixedLiteralsSet")); // for (Entry<Literal, TreeSet<Literal>> entry : mixedLiteralsSets.entrySet()) { // String v = entry.getValue().toString(); // sb.append("\n").append(entry.getKey()).append(" ::: ").append(v.substring(1, v.length() - 1)); // } // System.out.println(sb.toString()); // } // } if (literalVariables.size() > 0) return false; if (literalBooleanFunctions.size() > 0) return false; if (factsAndAllRules.size() > 0) return false; return true; } /** * check whether a literal appear in theory * * @param literal * @return true if the theory contains the literal specified */ public boolean contains(final Literal literal) { return literalRuleAssoList.containsKey(literal); } public boolean containsRuleLabel(final String ruleLabel) throws RuleException { if (ruleLabel == null || "".equals(ruleLabel.trim())) throw new RuleException(ErrorMessage.RULE_NULL_RULE); // if (ruleLabel == null || "".equals(ruleLabel.trim())) throw new RuleException("rule label is null"); return factsAndAllRules.containsKey(ruleLabel.trim()); } public boolean contains(final Superiority sup) { if (sup == null) return false; Set<Superiority> superioritiesSet = superiors.get(sup.getSuperior()); if (null != superioritiesSet) return superioritiesSet.contains(sup); return false; } public boolean containsRuleModeConversionRules() { return modeConversionRules.size() > 0; } public boolean containsRuleModeConflictRules() { return modeConflictRules.size() > 0; } /** * get all superiority relations in theory * * @return all superiority relations in theory */ public List<Superiority> getAllSuperiority() { List<Superiority> supList = new ArrayList<Superiority>(); for (String s : superiors.keySet()) { supList.addAll(superiors.get(s)); } return supList; } /** * clear all superiority relations */ public void clearSuperiority() { superiors.clear(); inferiors.clear(); } public Map<String, Set<Superiority>> getAllSuperiors() { return superiors; } public Set<Superiority> getSuperior(final String ruleLabel) { return superiors.get(ruleLabel); } public Map<String, Set<Superiority>> getAllInferiors() { return inferiors; } public Set<Superiority> getInferior(final String ruleLabel) { return inferiors.get(ruleLabel); } /** * get the theory type * * @return theory type * @see TheoryType */ public TheoryType getTheoryType() { return theoryType; } public void clearAllRules() { factsAndAllRules.clear(); literalRuleAssoList.clear(); ruleTypeAssoList.clear(); for (int i = 0; i < mixedLiteralsSets.length; i++) { mixedLiteralsSets[i].clear(); } superiors.clear(); inferiors.clear(); superiorityCount = 0; } /** * clear the theory */ public void clear() { description = ""; clearAllRules(); clearModeConversionRules(); clearModeConflictRules(); } public void clearModeConversionRules() { modeConversionRules.clear(); } public void clearModeConflictRules() { modeConflictRules.clear(); } public void clearModeExclusionRules() { modeExclusionRules.clear(); } public String toString() { if (isEmpty()) return "** Theory is EMPTY **"; StringBuilder sb = new StringBuilder(); int v = literalVariables.size() + literalBooleanFunctions.size(); String NEW_LINE = LINE_SEPARATOR + DomConst.IDENTATOR; if (!"".equals(description)) sb.append(LINE_SEPARATOR).append("Description:").append(NEW_LINE).append(description); if (v > 0) { sb.append(LINE_SEPARATOR).append(RuleType.LITERAL_VARIABLE_SET.getLabel()).append(" (").append(v).append("):"); for (Entry<LiteralVariable, LiteralVariable> entry : literalVariables.entrySet()) { sb.append(NEW_LINE).append(RuleType.LITERAL_VARIABLE_SET.getSymbol()).append(" ").append(entry.getKey()) .append(DomConst.Literal.THEORY_EQUAL_SIGN).append(entry.getValue()); } for (Entry<LiteralVariable, LiteralVariable> entry : literalBooleanFunctions.entrySet()) { sb.append(NEW_LINE).append(RuleType.LITERAL_VARIABLE_SET.getSymbol()).append(" ").append(entry.getKey()) .append(DomConst.Literal.THEORY_EQUAL_SIGN).append(entry.getValue()); } } if (modeConversionRules.size() > 0) { sb.append(LINE_SEPARATOR).append(RuleType.MODE_CONVERSION.getLabel()).append(" (").append(modeConversionRules.size()) .append("):"); for (Entry<String, Set<String>> entry : modeConversionRules.entrySet()) { sb.append(NEW_LINE).append(entry.getKey()).append(": "); sb.append(entry.getValue()); } } if (modeConflictRules.size() > 0) { sb.append(LINE_SEPARATOR).append(RuleType.MODE_CONFLICT.getLabel()).append(" (").append(modeConflictRules.size()).append("):"); for (Entry<String, Set<String>> entry : modeConflictRules.entrySet()) { sb.append(NEW_LINE).append(entry.getKey()).append(": "); sb.append(entry.getValue()); } } if (modeExclusionRules.size()>0){ sb.append(LINE_SEPARATOR).append(RuleType.MODE_EXCLUSION.getLabel()).append(" (").append(modeExclusionRules.size()).append("):"); for (Entry<String, Set<String>> entry : modeExclusionRules.entrySet()) { sb.append(NEW_LINE).append(entry.getKey()).append(": "); sb.append(entry.getValue()); } } Map<String, Rule> ruleSet = null; for (RuleType ruleType : RuleType.values()) { ruleSet = getRules(ruleType); if (ruleSet.size() > 0) { sb.append(LINE_SEPARATOR).append(ruleType.getLabel()).append(" (").append(ruleSet.size()).append("):"); for (Rule rule : ruleSet.values()) { sb.append(NEW_LINE).append(rule.toString()); } } } if (superiors.size() > 0) { if (sb.length() > 0) sb.append(LINE_SEPARATOR); sb.append(RuleType.SUPERIORITY.getLabel()).append(" (").append(superiors.size()).append("):"); for (Entry<String, Set<Superiority>> entry : superiors.entrySet()) { sb.append(LINE_SEPARATOR + " ").append(entry.getKey()); for (Superiority sup : entry.getValue()) { sb.append(NEW_LINE).append(sup.toString()); } } } if (!AppConst.isDeploy) { if (literalVariablesInRules.size() > 0) { sb.append(LINE_SEPARATOR).append("literalVariablesInRules"); for (LiteralVariable lv : literalVariablesInRules) { sb.append(NEW_LINE).append(lv); } } } // if (!AppConst.isDeploy){ // sb.append("\n").append(TextUtilities.generateHighLightedMessage("Literal rule association list")); // for( Entry<Literal, Map<String, Rule>> entry:literalRuleAssoList.entrySet()){ // sb.append(LINE_SEPARATOR).append(entry.getKey()).append(":").append(entry.getKey().getClass().getName()); // for (String ruleLabel:entry.getValue().keySet()){ // sb.append(NEW_LINE).append(ruleLabel); // } // } // } // if (!AppConst.isDeploy) { // for (int i = 0; i < mixedLiteralsSets.length; i++) { // if (mixedLiteralsSets[i].size() > 0) { // sb.append(LINE_SEPARATOR).append(TextUtilities.generateHighLightedMessage("Mixed literals sets")); // for (Entry<Literal, TreeSet<Literal>> entry : mixedLiteralsSets[i].entrySet()) { // sb.append(LINE_SEPARATOR).append(entry.getKey()); // for (Literal literal : entry.getValue()) { // sb.append(NEW_LINE).append(literal); // } // } // } // } // } return sb.toString().substring(LINE_SEPARATOR.length()); } }