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;
 }