protected void updateARG(PredicatePrecision pNewPrecision, ARGState pRefinementRoot) throws InterruptedException { argUpdate.start(); List<Precision> precisions = new ArrayList<>(2); List<Predicate<? super Precision>> precisionTypes = new ArrayList<>(2); precisions.add(pNewPrecision); precisionTypes.add(Predicates.instanceOf(PredicatePrecision.class)); UnmodifiableReachedSet unmodifiableReached = reached.asReachedSet(); if (isValuePrecisionAvailable(pRefinementRoot)) { precisions.add(mergeAllValuePrecisionsFromSubgraph(pRefinementRoot, unmodifiableReached)); precisionTypes.add(VariableTrackingPrecision.isMatchingCPAClass(ValueAnalysisCPA.class)); } reached.removeSubtree(pRefinementRoot, precisions, precisionTypes); if (sharePredicates) { reached.updatePrecisionGlobally( pNewPrecision, Predicates.instanceOf(PredicatePrecision.class)); } argUpdate.stop(); }
/** * After a path was strengthened, we need to take care of the coverage relation. We also remove * the infeasible part from the ARG, and re-establish the coverage invariant (i.e., that states on * the path are either covered or cannot be covered). */ @Override protected void finishRefinementOfPath( ARGState infeasiblePartOfART, List<ARGState> changedElements, ARGReachedSet pReached, boolean pRepeatedCounterexample) throws CPAException, InterruptedException { checkState(lastAbstraction != null); lastAbstraction = null; stats.argUpdate.start(); for (ARGState w : changedElements) { pReached.removeCoverageOf(w); } pReached.removeInfeasiblePartofARG(infeasiblePartOfART); stats.argUpdate.stop(); // optimization: instead of closing all ancestors of v, // close only those that were strengthened during refine stats.coverTime.start(); try { for (ARGState w : changedElements) { if (pReached.tryToCover(w)) { break; // all further elements are covered anyway } } } finally { stats.coverTime.stop(); } }
private boolean isValuePrecisionAvailable(ARGState root) { if (!reached.asReachedSet().contains(root)) { return false; } return Precisions.extractPrecisionByType( reached.asReachedSet().getPrecision(root), VariableTrackingPrecision.class) != null; }
private void refineRelevantPredicatesComputer(List<ARGState> pPath, ARGReachedSet pReached) { UnmodifiableReachedSet reached = pReached.asReachedSet(); Precision oldPrecision = reached.getPrecision(reached.getLastState()); PredicatePrecision oldPredicatePrecision = Precisions.extractPrecisionByType(oldPrecision, PredicatePrecision.class); BlockPartitioning partitioning = predicateCpa.getPartitioning(); Deque<Block> openBlocks = new ArrayDeque<>(); openBlocks.push(partitioning.getMainBlock()); for (ARGState pathElement : pPath) { CFANode currentNode = AbstractStates.extractLocation(pathElement); Integer currentNodeInstance = getPredicateState(pathElement).getAbstractionLocationsOnPath().get(currentNode); if (partitioning.isCallNode(currentNode)) { openBlocks.push(partitioning.getBlockForCallNode(currentNode)); } Collection<AbstractionPredicate> localPreds = oldPredicatePrecision.getPredicates(currentNode, currentNodeInstance); for (Block block : openBlocks) { for (AbstractionPredicate pred : localPreds) { relevantPredicatesComputer.considerPredicateAsRelevant(block, pred); } } while (openBlocks.peek().isReturnNode(currentNode)) { openBlocks.pop(); } } }
protected final PredicatePrecision extractPredicatePrecision( final ARGReachedSet pReached, ARGState state) { return (PredicatePrecision) Precisions.asIterable(pReached.asReachedSet().getPrecision(state)) .filter(Predicates.instanceOf(PredicatePrecision.class)) .get(0); }
private VariableTrackingPrecision extractValuePrecision( final ARGReachedSet pReached, ARGState state) { return (VariableTrackingPrecision) Precisions.asIterable(pReached.asReachedSet().getPrecision(state)) .filter(VariableTrackingPrecision.isMatchingCPAClass(ValueAnalysisCPA.class)) .get(0); }
private final PredicatePrecision computeNewPrecision() { // get previous precision UnmodifiableReachedSet unmodifiableReached = reached.asReachedSet(); logger.log(Level.FINEST, "Removing everything below", refinementRoot, "from ARG."); // now create new precision precisionUpdate.start(); PredicatePrecision basePrecision = findAllPredicatesFromSubgraph(refinementRoot, unmodifiableReached); logger.log(Level.ALL, "Old predicate map is", basePrecision); logger.log(Level.ALL, "New predicates are", newPredicates); PredicatePrecision newPrecision = basePrecision.addLocalPredicates(newPredicates.entries()); logger.log(Level.ALL, "Predicate map now is", newPrecision); assert basePrecision.calculateDifferenceTo(newPrecision) == 0 : "We forgot predicates during refinement!"; precisionUpdate.stop(); return newPrecision; }
/** * Merge all predicate precisions in the subgraph below the refinement root into a new predicate * precision * * @return a new predicate precision containing all predicate precision from the subgraph below * the refinement root. */ private PredicatePrecision mergePredicatePrecisionsForSubgraph( final ARGState pRefinementRoot, final ARGReachedSet pReached) { UnmodifiableReachedSet reached = pReached.asReachedSet(); return PredicatePrecision.unionOf( from(pRefinementRoot.getSubgraph()) .filter(not(ARGState::isCovered)) .transform(reached::getPrecision)); }
@Override protected void refineUsingInterpolants( final ARGReachedSet pReached, final InterpolationTree<ValueAnalysisState, ValueAnalysisInterpolant> pInterpolationTree) throws InterruptedException { final boolean predicatePrecisionIsAvailable = isPredicatePrecisionAvailable(pReached); Map<ARGState, List<Precision>> refinementInformation = new HashMap<>(); Collection<ARGState> refinementRoots = pInterpolationTree.obtainRefinementRoots(restartStrategy); for (ARGState root : refinementRoots) { shutdownNotifier.shutdownIfNecessary(); root = relocateRefinementRoot(root, predicatePrecisionIsAvailable); if (refinementRoots.size() == 1 && isSimilarRepeatedRefinement( pInterpolationTree.extractPrecisionIncrement(root).values())) { root = relocateRepeatedRefinementRoot(root); } List<Precision> precisions = new ArrayList<>(2); // merge the value precisions of the subtree, and refine it precisions.add( mergeValuePrecisionsForSubgraph(root, pReached) .withIncrement(pInterpolationTree.extractPrecisionIncrement(root))); // merge the predicate precisions of the subtree, if available if (predicatePrecisionIsAvailable) { precisions.add(mergePredicatePrecisionsForSubgraph(root, pReached)); } refinementInformation.put(root, precisions); } for (Entry<ARGState, List<Precision>> info : refinementInformation.entrySet()) { shutdownNotifier.shutdownIfNecessary(); List<Predicate<? super Precision>> precisionTypes = new ArrayList<>(2); precisionTypes.add(VariableTrackingPrecision.isMatchingCPAClass(ValueAnalysisCPA.class)); if (predicatePrecisionIsAvailable) { precisionTypes.add(Predicates.instanceOf(PredicatePrecision.class)); } pReached.removeSubtree(info.getKey(), info.getValue(), precisionTypes); } }
/** * After a path was strengthened, we need to take care of the coverage relation. We also remove * the infeasible part from the ARG, and re-establish the coverage invariant (i.e., that states on * the path are either covered or cannot be covered). */ @Override protected void finishRefinementOfPath( ARGState infeasiblePartOfART, List<ARGState> changedElements, ARGReachedSet pReached, boolean pRepeatedCounterexample) throws CPAException, InterruptedException { // only thing to do here is adding the false predicate for unreacheable states newPredicates.put(extractLocation(infeasiblePartOfART), predAbsMgr.makeFalsePredicate()); changedElements.add(infeasiblePartOfART); if (restartAfterRefinement) { refinementRoot = (ARGState) reached.asReachedSet().getFirstState(); } else if (refinementRoot == null) { refinementRoot = changedElements.get(0); // search parent of both refinement roots and use this as the new // refinement root } else { PathIterator firstPath = ARGUtils.getOnePathTo(refinementRoot).pathIterator(); PathIterator secondPath = ARGUtils.getOnePathTo(changedElements.get(0)).pathIterator(); // TODO should they be equal or identical? while (firstPath.getAbstractState().equals(secondPath.getAbstractState())) { refinementRoot = firstPath.getAbstractState(); if (firstPath.hasNext() && secondPath.hasNext()) { firstPath.advance(); secondPath.advance(); } else { break; } } } }
private boolean isPredicatePrecisionAvailable(final ARGReachedSet pReached) { return Precisions.extractPrecisionByType( pReached.asReachedSet().getPrecision(pReached.asReachedSet().getFirstState()), PredicatePrecision.class) != null; }