@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + formula.hashCode(); result = prime * result + length; result = prime * result + pts.hashCode(); result = prime * result + ssa.hashCode(); return result; }
/** * builds a formula that represents the necessary variable assignments to "merge" the two ssa * maps. That is, for every variable X that has two different ssa indices i and j in the maps, * creates a new formula (X_k = X_i) | (X_k = X_j), where k is a fresh ssa index. Returns the * formula described above, plus a new SSAMap that is the merge of the two. * * @param ssa1 an SSAMap * @param pts1 the PointerTargetSet for ssa1 * @param ssa2 an SSAMap * @param pts2 the PointerTargetSet for ssa1 * @return The new SSAMap and the formulas that need to be added to the path formulas before * disjuncting them. */ MergeResult<SSAMap> mergeSSAMaps( final SSAMap ssa1, final PointerTargetSet pts1, final SSAMap ssa2, final PointerTargetSet pts2) throws InterruptedException { final List<MapsDifference.Entry<String, Integer>> symbolDifferences = new ArrayList<>(); final SSAMap resultSSA = SSAMap.merge(ssa1, ssa2, collectMapsDifferenceTo(symbolDifferences)); BooleanFormula mergeFormula1 = bfmgr.makeTrue(); BooleanFormula mergeFormula2 = bfmgr.makeTrue(); for (final MapsDifference.Entry<String, Integer> symbolDifference : symbolDifferences) { shutdownNotifier.shutdownIfNecessary(); final String symbolName = symbolDifference.getKey(); final CType symbolType = resultSSA.getType(symbolName); final int index1 = symbolDifference.getLeftValue().orElse(1); final int index2 = symbolDifference.getRightValue().orElse(1); assert symbolName != null; if (index1 > index2 && index1 > 1) { // i2:smaller, i1:bigger // => need correction term for i2 BooleanFormula mergeFormula = makeSsaMerger(symbolName, symbolType, index2, index1, pts2); mergeFormula2 = bfmgr.and(mergeFormula2, mergeFormula); } else if (index2 > 1) { assert index1 < index2; // i1:smaller, i2:bigger // => need correction term for i1 BooleanFormula mergeFormula = makeSsaMerger(symbolName, symbolType, index1, index2, pts1); mergeFormula1 = bfmgr.and(mergeFormula1, mergeFormula); } } return new MergeResult<>(resultSSA, mergeFormula1, mergeFormula2, bfmgr.makeTrue()); }
BooleanFormula addMergeAssumptions( final BooleanFormula pFormula, final SSAMap ssa1, final PointerTargetSet pts1, final SSAMap ssa2) throws InterruptedException { final List<MapsDifference.Entry<String, Integer>> symbolDifferences = new ArrayList<>(); final SSAMap resultSSA = SSAMap.merge(ssa1, ssa2, collectMapsDifferenceTo(symbolDifferences)); List<BooleanFormula> mergeFormula = new ArrayList<>(); mergeFormula.add(pFormula); for (final MapsDifference.Entry<String, Integer> symbolDifference : symbolDifferences) { shutdownNotifier.shutdownIfNecessary(); final String symbolName = symbolDifference.getKey(); final CType symbolType = resultSSA.getType(symbolName); final int index1 = symbolDifference.getLeftValue().orElse(1); final int index2 = symbolDifference.getRightValue().orElse(1); assert symbolName != null; if (index1 > index2 && index1 > 1) { // assumption violated // ssa2 is not the merge result of ssa1 and further ssa maps // simplify following PCC coverage check which will likely fail anyway // and return coarsest overapproximation return bfmgr.makeTrue(); } else if (index2 > 1) { assert index1 < index2; // i1:smaller, i2:bigger // => need correction term for i1 for (int i = index1; i < index2; i++) { mergeFormula.add(makeSsaMerger(symbolName, symbolType, i, i + 1, pts1)); } } } return bfmgr.and(mergeFormula); }
@Override public boolean equals(@Nullable Object obj) { if (this == obj) { return true; } if (!(obj instanceof PathFormula)) { return false; } PathFormula other = (PathFormula) obj; return (length == other.length) && formula.equals(other.formula) && ssa.equals(other.ssa) && pts.equals(other.pts); }