/** * Translate a single linear path to code. * * @param pPath the path to translate * @param callback A callback that receives each <code>ARGState</code> along with their edges and * can then determine what code to generate from it. The default behavior of a <code> * ProcessEdgeFunction</code> is to call {@link #processEdge(ARGState, CFAEdge, Stack)} */ protected void translateSinglePath0(ARGPath pPath, EdgeVisitor callback) { assert pPath.size() >= 1; PathIterator pathIt = pPath.fullPathIterator(); ARGState firstElement = pathIt.getAbstractState(); Stack<FunctionBody> functionStack = new Stack<>(); // create the first function and put in into the stack startFunction(firstElement, functionStack, extractFunctionCallLocation(firstElement)); while (pathIt.hasNext()) { pathIt.advance(); CFAEdge currentCFAEdge = pathIt.getIncomingEdge(); ARGState childElement; if (pathIt.isPositionWithState()) { childElement = pathIt.getAbstractState(); } else { childElement = pathIt.getPreviousAbstractState(); } callback.visit(childElement, currentCFAEdge, functionStack); } }
/** * 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; } } } }