/** * Author: Georg Hofferek <georg.hofferek@iaik.tugraz.at> */ package at.iaik.suraq.proof; import java.util.HashMap; import java.util.Map; import java.util.Set; import at.iaik.suraq.smtlib.formula.Formula; /** * @author Georg Hofferek <georg.hofferek@iaik.tugraz.at> * */ public final class AnnotatedProofNodes { /** * */ //private static final long serialVersionUID = 1L; private Map<Formula, Map<Set<Formula>, AnnotatedProofNode>> map = new HashMap<Formula, Map<Set<Formula>, AnnotatedProofNode>>(); /** * Constructs a new <code>AnnotatedProofNodes</code> set. */ public AnnotatedProofNodes() { super(); } /** * Returns a node that has the given consequent. Uses the * <code>equals</code> method of formulas to determine equality. * * @param consequent * the consequent to look for * @param hypotheses * the set of hypotheses the searched node should have * @param obsoleteLiterals * a call-by-reference parameter, via which the new obsolete * literals (if any) will be returned. Must be an empty set at * call time! * @return a node with the given consequent or <code>null</code> if such a * node does not exist. */ public AnnotatedProofNode getNodeWithConsequent(Formula consequent, Set<Formula> hypotheses, Set<Formula> obsoleteLiterals) { assert (obsoleteLiterals.isEmpty()); Map<Set<Formula>, AnnotatedProofNode> currentMap = map.get(consequent .transformToConsequentsForm()); if (currentMap == null) return null; // TODO Instead of returning a node with matching hypotheses, or // a matching subset, one could search for the smallest subset here. // This would decrease overall proof size. AnnotatedProofNode result = currentMap.get(hypotheses); if (result == null) { for (AnnotatedProofNode potentialResult : currentMap.values()) { if (hypotheses.containsAll(potentialResult.getHypotheses())) { obsoleteLiterals.addAll(hypotheses); obsoleteLiterals.removeAll(potentialResult.getHypotheses()); return potentialResult; } } } return result; } /** * Returns an annotated node with a consequent that has the given id. If no * such node exists, <code>null</code> is returned. This method iterated * through the internal map(s) and is thus very inefficient! * * @param id * @return an annotated node whose consequent has the given <code>id</code>, * or <code>null</code> if no such node exists. */ public AnnotatedProofNode getNodeWithId(int id) { for (Map<Set<Formula>, AnnotatedProofNode> currentMap : map.values()) { for (AnnotatedProofNode node : currentMap.values()) if (node.getConsequent().getID() == id) return node; } return null; } public void add(AnnotatedProofNode node) { assert (node != null); assert (node.getConsequent() != null); assert (node.getConsequent().getConsequent() != null); Formula formula = node.getConsequent().getConsequent() .transformToConsequentsForm(); Map<Set<Formula>, AnnotatedProofNode> currentMap = map.get(formula); if (currentMap == null) { currentMap = new HashMap<Set<Formula>, AnnotatedProofNode>(); map.put(formula, currentMap); } currentMap.put(node.getHypotheses(), node); } }