/**
* 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.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
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.Vector;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicLong;
import com.app.utils.Utilities.ProcessStatus;
import spindle.sys.Conf;
import spindle.sys.message.ErrorMessage;
/**
* DOM for representing a defeasible theory.
*
* @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory
* @since version 1.0.0
* @version Last modified 2012.08.08
*/
public class Theory extends TheoryCore implements Cloneable {
private static final long serialVersionUID = 1L;
private static final LiteralComparator PLAIN_LITERAL_COMPARATOR = new LiteralComparator(false);
public static final String DEFAULT_RULE_LABEL_PREFIX = "Rule_";
public static final NumberFormat formatter = new DecimalFormat("00000");
private Map<String, AtomicLong> ruleLabelCounters;
private final Map<String, Set<String>> strongerModeSet = new TreeMap<String, Set<String>>();
private final Map<String, Set<String>> allModeConflictRulesResolved = new TreeMap<String, Set<String>>();
protected Map<Literal, TreeSet<Literal>> sameConflictLiteralsStore;
protected Map<Literal, TreeSet<Literal>> conflictLiteralsStore;
private Map<String, Set<String>> ruleLabelMapping;
public Theory() {
this(null);
}
public Theory(Theory theory) {
super(theory);
ruleLabelCounters = new HashMap<String, AtomicLong>();
sameConflictLiteralsStore = new TreeMap<Literal, TreeSet<Literal>>(PLAIN_LITERAL_COMPARATOR);
conflictLiteralsStore = new TreeMap<Literal, TreeSet<Literal>>(PLAIN_LITERAL_COMPARATOR);
}
/**
* Return a duplicated copy of the theory.
*
* @return cloned theory.
*/
public Theory clone() {
return new Theory(this);
}
/**
* Return an unique new rule label.
*
* @return An unique rule label.
* @see #getUniqueRuleLabel(String)
*/
public String getUniqueRuleLabel() {
return getUniqueRuleLabel(DEFAULT_RULE_LABEL_PREFIX);
}
/**
* Return an unique new rule label with the specified prefix.
*
* @return An unique rule label with the specified prefix.
* @see #getUniqueRuleLabel()
*/
public String getUniqueRuleLabel(final String prefix) {
AtomicLong ruleLabelCounter = ruleLabelCounters.get(prefix);
if (null == ruleLabelCounter) {
ruleLabelCounter = new AtomicLong();
ruleLabelCounters.put(prefix, ruleLabelCounter);
}
String id;
do {
id = prefix + formatter.format(ruleLabelCounter.getAndIncrement());
} while (factsAndAllRules.containsKey(id));
return id;
}
public void updateRuleLabelMapping(Map<String, List<Rule>> ruleLabelMapping) {
if (null == ruleLabelMapping || ruleLabelMapping.size() == 0) return;
if (this.ruleLabelMapping == null) this.ruleLabelMapping = new TreeMap<String, Set<String>>();
for (Entry<String, List<Rule>> entry : ruleLabelMapping.entrySet()) {
Set<String> ruleLabels = new TreeSet<String>();
for (Rule rule : entry.getValue()) {
ruleLabels.add(rule.getLabel());
}
this.ruleLabelMapping.put(entry.getKey(), ruleLabels);
}
}
/**
* Update the theory by adding new rules, removing old rules, and updating the superiority relations with the
* old-new rule mapping.
*
* @param rulesToAdd New rules to be added to the theory.
* @param rulesToDelete Old rules to be removed from the theory
* @throws TheoryException
*/
public void updateTheory(final List<Rule> rulesToAdd, //
final Set<String> rulesToDelete, //
Map<String, List<Rule>> oldNewRuleMapping) throws TheoryException {
if (null != rulesToDelete) {
for (String ruleLabel : rulesToDelete) {
removeRule(ruleLabel);
}
}
if (null != rulesToAdd) {
for (Rule rule : rulesToAdd) {
addRule(rule);
}
}
if (null != oldNewRuleMapping && oldNewRuleMapping.size() > 0) {
// System.out.println(oldNewRuleMapping.toString());
try {
updateSuperiorityMapping(oldNewRuleMapping);
} catch (TheoryException e) {
throw new TheoryException("Old-New rule mapping exception appeared while updating the theory!", e);
}
}
}
/**
* Update the superior rules and inference rules counters of each rules.
*
* @throws TheoryException
*/
public void updateRuleSuperiorityRelationCounter() throws TheoryException {
if (superiors.size() == 0) return;
switch (Conf.getReasonerVersion()) {
case 2:
for (Entry<String, Set<Superiority>> entry : superiors.entrySet()) {
RuleExt superiorRule = (RuleExt) factsAndAllRules.get(entry.getKey());
if (null == superiorRule)
throw new RuleException(ErrorMessage.SUPERIORITY_SUPERIOR_RULE_NOT_DEFINED, new Object[] { entry.getKey() });
superiorRule.resetRuleSuperiorityRelationCounter();
for (Superiority sup : entry.getValue()) {
RuleExt inferiorRule = (RuleExt) factsAndAllRules.get(sup.getInferior());
if (null == inferiorRule)
throw new RuleException(ErrorMessage.SUPERIORITY_INFERIOR_RULE_NOT_DEFINED, new Object[] { sup.getInferior() });
inferiorRule.resetRuleSuperiorityRelationCounter();
}
}
for (Entry<String, Set<Superiority>> superiorityEntry : superiors.entrySet()) {
RuleExt superiorRule = (RuleExt) factsAndAllRules.get(superiorityEntry.getKey());
superiorRule.setWeakerRulesCount(superiorityEntry.getValue().size());
for (Superiority superiority : superiorityEntry.getValue()) {
RuleExt inferiorRule = (RuleExt) factsAndAllRules.get(superiority.getInferior());
inferiorRule.strongerRulesCountIncrement();
}
}
break;
default:
}
}
/**
* Update rule mapping using the normalized new rule labels
*
* @param oldNewRuleMapping Mapping between the old and new rules.
* @return
*/
private ProcessStatus updateSuperiorityMapping( //
Map<String, List<Rule>> oldNewRuleMapping) throws TheoryException {
List<Superiority> originalSuperiorityList = null;
for (String originalLabel : oldNewRuleMapping.keySet()) {
originalSuperiorityList = new ArrayList<Superiority>();
if (superiors.containsKey(originalLabel)) originalSuperiorityList.addAll(superiors.get(originalLabel));
if (inferiors.containsKey(originalLabel)) originalSuperiorityList.addAll(inferiors.get(originalLabel));
if (originalSuperiorityList.size() > 0) {
superiors.remove(originalLabel);
inferiors.remove(originalLabel);
List<Superiority> supToAdd = new ArrayList<Superiority>();
List<Superiority> supToDelete = new ArrayList<Superiority>();
for (Superiority origSuperiority : originalSuperiorityList) {
String supLabel = origSuperiority.getSuperior();
String infLabel = origSuperiority.getInferior();
List<Rule> supRules = oldNewRuleMapping.get(supLabel);
if (null == supRules) {
supRules = new ArrayList<Rule>();
Rule r = factsAndAllRules.get(supLabel);
if (null == r)
throw new TheoryException(ErrorMessage.SUPERIORITY_SUPERIOR_RULE_NOT_DEFINED, new Object[] { supLabel });
supRules.add(r);
} else {
if (!supToDelete.contains(origSuperiority)) supToDelete.add(origSuperiority);
}
List<Rule> infRules = oldNewRuleMapping.get(infLabel);
if (null == infRules) {
infRules = new ArrayList<Rule>();
Rule r = factsAndAllRules.get(infLabel);
if (null == r)
throw new TheoryException(ErrorMessage.SUPERIORITY_INFERIOR_RULE_NOT_DEFINED, new Object[] { infLabel });
infRules.add(r);
} else {
if (!supToDelete.contains(origSuperiority)) supToDelete.add(origSuperiority);
}
for (Rule newSupRule : supRules) {
for (Rule inferiorRule : infRules) {
if (newSupRule.isConflictRule(inferiorRule)) {
supToAdd.add(new Superiority(newSupRule.getLabel(), inferiorRule.getLabel()));
}
}
}
}
for (Superiority s : supToDelete)
remove(s);
for (Superiority s : supToAdd)
add(s);
}
}
return ProcessStatus.SUCCESS;
}
/**
* Return the set of rules contain the set of literals specified.
* Note that the literals specified may appear in the body or head of the rules returned.
*
* @param literals literals to be contained in rules.
* @return A set of rule labels for the set of rules contain the set of literals specified.
* @see #getRulesWithHead(Literal)
* @see #getRulesWithBody(Set)
* @see #getRulesWithBody(Set, int)
*/
public Set<String> getRules(Set<Literal> literals) {
Set<String> rules = new TreeSet<String>();
if (null == literals || literals.size() == 0) return rules;
for (Literal literal : literals) {
rules.addAll(getRules(literal).keySet());
}
return rules;
}
/**
* Return the set of rules with the specified literals appear in the body and retrieve its set of dependency rules
* that appear in the theory.
*
* @param literals Literals that appeared in the body of rules.
* @return A set of rules with the specified literals appeared in the body.
* @see #getRules(Literal)
* @see #getRulesWithHead(Literal)
* @see #getRulesWithBody(Set, int)
*/
public Set<String> getRulesWithBody(Set<Literal> literals) {
return getRulesWithBody(literals, -1);
}
/**
* Return the set of rules with the specified literals appear in the body and retrieve its set of dependency rules
* that appear in the theory with the depth specified.
*
* @param literals Literals that appeared in the body of rules.
* @param maxDepth Depth of inference to be traversed. If maxDepth is negative, then the rules will be traversed
* until it is exhausted.
* @return A set of rules with the specified literals appeared in the body.
* @see #getRules(Literal)
* @see #getRulesWithHead(Literal)
* @see #getRulesWithBody(Set)
*/
public Set<String> getRulesWithBody(Set<Literal> literals, int maxDepth) {
Set<String> rulesExtracted = new TreeSet<String>();
if (null == literals || literals.size() == 0) return rulesExtracted;
Set<Literal> literalsToCheck = new TreeSet<Literal>();
Set<Literal> literalsChecked = new TreeSet<Literal>();
Set<Literal> literalsToAdd = new TreeSet<Literal>();
for (Literal literal : getLiteralsToCheck(literals)) {
Map<String, Rule> rules = getRules(literal);
for (Rule rule : rules.values()) {
if (rule.isBodyLiteral(literal)) {
rulesExtracted.add(rule.getLabel());
literalsToCheck.addAll(getLiteralsToCheck(rule.getHeadLiterals()));
}
}
}
if (0 == maxDepth) return rulesExtracted;
int currDepth = 0;
do {
literalsToCheck.addAll(literalsToAdd);
literalsChecked.addAll(literalsToAdd);
literalsToAdd.clear();
for (Literal literal : literalsToCheck) {
Map<String, Rule> rules = getRules(literal);
for (Rule rule : rules.values()) {
if (!rulesExtracted.contains(rule.getLabel())) {
if (rule.isHeadLiteral(literal)) {
rulesExtracted.add(rule.getLabel());
} else {
for (Literal hl : rule.getHeadLiterals()) {
if (!literalsChecked.contains(hl)) {
literalsToAdd.addAll(getLiteralsToCheck(hl));
}
}
}
}
}
}
} while ((maxDepth < 0 || ++currDepth < maxDepth) && literalsToAdd.size() > 0);
return rulesExtracted;
}
/**
* Return the set of rules with the specified literals appear in the head.
*
* @param literal Literal that appeared in the head of rules.
* @return A set of rules with the specified literals appeared in the head.
* @see #getRules(Literal)
* @see #getRulesWithBody(Set)
* @see #getRulesWithBody(Set, int)
*/
public Set<Rule> getRulesWithHead(Literal literal) {
Set<Rule> rules = new HashSet<Rule>();
for (Rule rule : getRules(literal).values()) {
if (rule.isHeadLiteral(literal)) rules.add(rule);
}
return rules;
}
public boolean containsInRuleHead(final Literal literal, final RuleType ruleType) {
return containsUnprovedRule(literal, ruleType, false);
// Collection<Rule> rules = getRules(literal).values();
// if (rules == null || rules.size() == 0) return false; // literal does not appear in theory
//
// if (null == ruleType) {
// for (Rule rule : rules) {
// if (rule.isHeadLiteral(literal)) return true;
// }
// } else {
// for (Rule rule : rules) {
// if (ruleType == rule.getRuleType() && rule.isHeadLiteral(literal)) return true;
// }
// }
// return false;
}
public boolean containsInRuleBody(final Literal literal, final RuleType ruleType) {
Map<String, Rule> rules = getRules(literal);
if (null == ruleType) {
for (Rule rule : rules.values()) {
if (rule.isBodyLiteral(literal)) return true;
}
} else {
for (Rule rule : rules.values()) {
if (ruleType == rule.getRuleType() && rule.isBodyLiteral(literal)) return true;
}
}
return false;
}
public boolean containsUnprovedRule(final Literal literal, final RuleType ruleType, boolean checkEmptyBody) {
Map<String, Rule> rules = getRules(literal);
if (null == rules || rules.size() == 0) return false; // literal does not appear in theory
if (null == ruleType) {
if (checkEmptyBody) {
for (Rule rule : rules.values()) {
if (!rule.isEmptyBody() && rule.isHeadLiteral(literal)) return true;
}
} else {
for (Rule rule : rules.values()) {
if (rule.isHeadLiteral(literal)) return true;
}
}
} else {
if (checkEmptyBody) {
for (Rule rule : rules.values()) {
if (ruleType == rule.getRuleType() && rule.isEmptyBody() && rule.isHeadLiteral(literal)) return true;
}
} else {
for (Rule rule : rules.values()) {
if (ruleType == rule.getRuleType() && rule.isHeadLiteral(literal)) return true;
}
}
}
return false;
}
public List<Rule> duplicateRulesToType(Collection<Rule> rules, RuleType ruleType, final String rulePostfix) {
List<Rule> newRules = new ArrayList<Rule>();
for (Rule rule : rules) {
Rule newRule = rule.clone();
newRule.setLabel(rule.getLabel() + rulePostfix);
newRule.setOriginalLabel(rule.getOriginalLabel());
newRule.setRuleType(ruleType);
newRules.add(newRule);
}
return newRules;
}
/**
* Return the set of conflict literals but with no temporal information.
*
* @param origLiteral Original literal.
* @return The set of plain literals that are conflict with the prescribed literal, i.e., set of conflicting
* literals without temporal information.
*/
public TreeSet<Literal> getConflictLiterals(Literal origLiteral) {
if (isConflictRulesModified() || isConversionRulesModified()) {
updateModeConversionConflictRules();
}
TreeSet<Literal> conflictLiterals = conflictLiteralsStore.get(origLiteral);
if (null != conflictLiterals) return conflictLiterals;
conflictLiterals = new TreeSet<Literal>(PLAIN_LITERAL_COMPARATOR);
Literal literal = origLiteral.cloneWithNoTemporal();
Literal literalComplement = literal.getComplementClone();
conflictLiterals.add(literalComplement);
Mode literalMode = literal.getMode();
if (!"".equals(literalMode.getName())) {
Set<String> modeList = allModeConflictRulesResolved.get(literalMode.getName());
if (null != modeList) {
boolean modeNeg=literalMode.isNegation();
boolean negatedModeNeg=!modeNeg;
for (String modeStr : modeList) {
Literal conflictLiteral1 = literalComplement.clone();
conflictLiteral1.setMode(new Mode(modeStr, modeNeg));
conflictLiterals.add(conflictLiteral1);
Literal conflictLiteral2 = literal.clone();
conflictLiteral2.setMode(new Mode(modeStr, negatedModeNeg));
conflictLiterals.add(conflictLiteral2);
}
}
Literal conflictLiteral = literal.clone();
conflictLiteral.setMode(literalMode.getComplementClone());
conflictLiterals.add(conflictLiteral);
}
conflictLiteralsStore.put(literal, conflictLiterals);
return conflictLiterals;
}
/**
* Return the set of literals that are having the same conflicting literals.
*
* @param origLiteral Literal to be examined.
* @return The set of literals that are having the same conflicting literals.
*/
public TreeSet<Literal> getLiteralsWithSameConflictLiterals(Literal origLiteral) {
if (isConflictRulesModified() || isConversionRulesModified()) {
updateModeConversionConflictRules();
}
TreeSet<Literal> sameConflictLiterals = sameConflictLiteralsStore.get(origLiteral);
if (null != sameConflictLiterals) return sameConflictLiterals;
Literal literal = origLiteral.cloneWithNoTemporal();
sameConflictLiterals = new TreeSet<Literal>();
sameConflictLiterals.add(literal);
Mode literalMode = literal.getMode();
if (!"".equals(literalMode.getName())) {
Set<String> modeList = allModeConflictRulesResolved.get(literalMode.getName());
if (null != modeList) {
boolean modeNeg=literalMode.isNegation();
boolean negatedModeNeg=!modeNeg;
for (String modeStr : modeList) {
Literal l1 = literal.clone();
l1.setMode(new Mode(modeStr, modeNeg));
sameConflictLiterals.add(l1);
Literal l2 = literal.getComplementClone();
l2.setMode(new Mode(modeStr, negatedModeNeg));
sameConflictLiterals.add(l2);
}
}
Literal l = literal.getComplementClone();
l.setMode(literalMode.getComplementClone());
sameConflictLiterals.add(l);
}
sameConflictLiteralsStore.put(literal, sameConflictLiterals);
return sameConflictLiterals;
}
public Set<Literal> getSameStartLiterals(Literal literal, ProvabilityLevel provability) {
Set<Literal> relatedLiterals = getRelatedLiterals(literal, provability);
if (null == relatedLiterals) return null;
Set<Literal> sameStartLiterals = new TreeSet<Literal>();
Temporal literalTemporal = literal.getTemporal();
for (Literal l : relatedLiterals) {
Temporal t = l.getTemporal();
if (null == t) {
if (null == literalTemporal || Long.MIN_VALUE == literalTemporal.getStartTime()) sameStartLiterals.add(l);
} else {
if (null == literalTemporal) {
if (Long.MIN_VALUE == t.getStartTime()) sameStartLiterals.add(l);
} else {
if (t.sameStart(literalTemporal)) sameStartLiterals.add(l);
}
}
}
return sameStartLiterals.size() == 0 ? null : sameStartLiterals;
}
public Set<Literal> getOverlappedLiterals(Literal literal, ProvabilityLevel provability) {
Set<Literal> relatedLiterals = getRelatedLiterals(literal, provability);
if (null == relatedLiterals) return null;
Set<Literal> extractedLiterals = new TreeSet<Literal>();
Temporal literalTemporal = literal.getTemporal();
for (Literal l : relatedLiterals) {
Temporal lt = l.getTemporal();
if (null == literalTemporal || null == lt) {
extractedLiterals.add(l);
} else {
if (literalTemporal.overlap(lt)) extractedLiterals.add(l);
}
}
return extractedLiterals;
}
public Map<String, Set<String>> getStrongModeSet() {
if (isConflictRulesModified() || isConversionRulesModified()) {
updateModeConversionConflictRules();
}
return strongerModeSet;
}
private void updateModeConversionConflictRules() {
synchronized (this) {
generateStrongModeSet();
updateConflictModeRules();
resetConversionRulesModified();
resetConflictRulesModified();
resetExclusionRulesModified();
sameConflictLiteralsStore.clear();
conflictLiteralsStore.clear();
}
}
private void generateStrongModeSet() {
strongerModeSet.clear();
strongerModeSet.putAll(getAllModeConflictRules());
boolean isModified = false;
List<String> modeToAdd = null;
do {
isModified = false;
for (Entry<String, Set<String>> entry : strongerModeSet.entrySet()) {
Set<String> mList = entry.getValue();
modeToAdd = new Vector<String>();
for (String weakerMode : mList) {
if (strongerModeSet.containsKey(weakerMode)) {
Set<String> weakerModeList = strongerModeSet.get(weakerMode);
for (String m : weakerModeList) {
if (!mList.contains(m)) modeToAdd.add(m);
}
}
}
if (modeToAdd.size() > 0) {
mList.addAll(modeToAdd);
isModified = true;
}
}
} while (isModified);
}
private void updateConflictModeRules() {
allModeConflictRulesResolved.clear();
Map<String, Set<String>> modeConflictRules = strongerModeSet;
for (Entry<String, Set<String>> entry : modeConflictRules.entrySet()) {
String mode = entry.getKey();
for (String conflictMode : entry.getValue()) {
addResolvedConflictRule(mode, conflictMode);
addResolvedConflictRule(conflictMode, mode);
}
}
}
private void addResolvedConflictRule(final String mode, final String conflictMode) {
Set<String> conflictModeList = allModeConflictRulesResolved.get(mode);
if (null == conflictModeList) {
conflictModeList = new TreeSet<String>();
allModeConflictRulesResolved.put(mode, conflictModeList);
}
if (!conflictModeList.contains(conflictMode)) conflictModeList.add(conflictMode);
}
private Set<Literal> getLiteralsToCheck(Collection<Literal> literals) {
Set<Literal> literalsToCheck = new TreeSet<Literal>();
for (Literal literal : literals) {
literalsToCheck.addAll(getLiteralsToCheck(literal));
}
return literalsToCheck;
}
private Set<Literal> getLiteralsToCheck(Literal literal) {
String literalModeName = literal.getMode().getName();
Set<Literal> literalsToCheck = new TreeSet<Literal>();
literalsToCheck.add(literal.clone());
if ("".equals(literalModeName)) {
literalsToCheck.add(literal.getComplementClone());
} else {
Set<String> conversionRules = getModeConversionRules(literalModeName);
if (null == conversionRules) {
literalsToCheck.addAll(getConflictLiterals(literal));
} else {
for (String modeName : conversionRules) {
Literal nl = literal.clone();
Mode mode = nl.getMode().clone();
mode.setName(modeName);
nl.setMode(mode);
literalsToCheck.add(nl);
literalsToCheck.addAll(getConflictLiterals(nl));
}
}
}
return literalsToCheck;
}
/**
* Return the set of rules that are used to derive the literals specified.
*
* @param literals literals to check
* @return A set of rule labels that indicating the set of rules that are required to derive the set of literals
* specified.
*/
public Set<String> getRulesToDerive(Set<Literal> literals) {
Set<Literal> literalsChecked = new TreeSet<Literal>();
Set<Literal> literalsToCheck = new TreeSet<Literal>();
Set<Literal> literalsToAdd = new TreeSet<Literal>();
Set<String> rulesExtracted = new TreeSet<String>();
literalsToAdd.addAll(getLiteralsToCheck(literals));
do {
literalsChecked.addAll(literalsToAdd);
literalsToCheck.addAll(literalsToAdd);
literalsToAdd.clear();
for (Literal literalToCheck : literalsToCheck) {
for (Rule rule : getRulesWithHead(literalToCheck)) {
if (!rulesExtracted.contains(rule.getLabel())) {
rulesExtracted.add(rule.getLabel());
for (Literal bodyLiteral : rule.getBodyLiterals()) {
if (!literalsToAdd.contains(bodyLiteral)) {
literalsToAdd.addAll(getLiteralsToCheck(bodyLiteral));
}
}
}
}
}
} while (literalsToAdd.size() > 0);
return rulesExtracted;
}
/**
* Return the set of rules after excluding the rule set specified from the theory.
*
* @param excludedRules The set of rules to be excluded.
* @return A set of rule labels after excluding the rules specified.
*/
public Set<String> getRulesExclude(Set<String> excludedRules) {
Set<String> ruleLabels = new TreeSet<String>(factsAndAllRules.keySet());
ruleLabels.removeAll(excludedRules);
return ruleLabels;
}
/**
* Create a new theory using the rule specified.
*
* @param rules The set of rules to be used.
* @return A new theory that contains the set of rules (including facts, all types of rules, superiorities, etc)
* that are specified.
* @see #getRulesToDerive(Set literals)
*/
public Theory createNewTheoryWithRules(Set<String> rules) throws TheoryException {
Theory newTheory = new Theory();
// add rules to theory
for (String ruleLabel : rules) {
Rule rule = getRule(ruleLabel);
newTheory.addRule(rule.clone());
Set<Superiority> superiorities = getSuperior(ruleLabel);
if (null != superiorities) {
for (Superiority sup : superiorities) {
if (rules.contains(sup.getInferior())) newTheory.add(sup.clone());
}
}
Set<Superiority> inferiorities = getInferior(ruleLabel);
if (null != inferiorities) {
for (Superiority sup : inferiorities) {
if (rules.contains(sup.getSuperior())) newTheory.add(sup.clone());
}
}
}
// add all literal variables to theory
for (Entry<LiteralVariable, LiteralVariable> entry : literalVariables.entrySet()) {
newTheory.addLiteralVariable(entry.getKey().clone(), entry.getValue().clone());
}
// add all literal boolean functions to theory
for (Entry<LiteralVariable, LiteralVariable> entry : literalBooleanFunctions.entrySet()) {
newTheory.addLiteralVariable(entry.getKey().clone(), entry.getValue().clone());
}
// add mode conversion rules to theory
for (Entry<String, Set<String>> entry : modeConversionRules.entrySet()) {
String[] modeRules = new String[entry.getValue().size()];
entry.getValue().toArray(modeRules);
newTheory.addModeConversionRules(entry.getKey(), modeRules);
}
// add mode conflict rules to theory
for (Entry<String, Set<String>> entry : modeConflictRules.entrySet()) {
String[] modeRules = new String[entry.getValue().size()];
entry.getValue().toArray(modeRules);
newTheory.addModeConflictRules(entry.getKey(), modeRules);
}
return newTheory;
}
}