/** * 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; } } } }
/** * This method chooses a new refinement root, in a bottom-up fashion along the error path. It * either picks the next state on the path sharing the same CFA location, or the (only) child of * the ARG root, what ever comes first. * * @param currentRoot the current refinement root * @return the relocated refinement root */ private ARGState relocateRepeatedRefinementRoot(final ARGState currentRoot) { repeatedRefinements.inc(); int currentRootNumber = AbstractStates.extractLocation(currentRoot).getNodeNumber(); ARGPath path = ARGUtils.getOnePathTo(currentRoot); for (ARGState currentState : path.asStatesList().reverse()) { // skip identity, because a new root has to be found if (currentState == currentRoot) { continue; } if (currentRootNumber == AbstractStates.extractLocation(currentState).getNodeNumber()) { return currentState; } } return Iterables.getOnlyElement(path.getFirstState().getChildren()); }