private boolean noConcreteSuccessorExist( final ARGState pPredecessor, final CFAEdge pSuccEdge, HistoryForwardingReachedSet pForwaredReachedSet) { // check if analysis stopped exploration due e.g. time limit for (ReachedSet reached : pForwaredReachedSet.getAllReachedSetsUsedAsDelegates()) { if (reached.getWaitlist().contains(pPredecessor)) { return false; } } // check if analysis stopped exploration due to true state in automaton --> concrete successors // may exist for (AbstractState state : AbstractStates.asIterable(pPredecessor)) { if (state instanceof AutomatonState && ((AutomatonState) state).getOwningAutomatonName().equals("AssumptionAutomaton")) { if (AutomatonStateARGCombiningHelper.endsInAssumptionTrueState( (AutomatonState) state, pSuccEdge)) { return false; } } } return true; }
@Override public AlgorithmStatus run(ReachedSet pReachedSet) throws CPAException, InterruptedException, CPAEnabledAnalysisPropertyViolationException { checkArgument( pReachedSet instanceof ForwardingReachedSet, "PartialARGsCombiner needs ForwardingReachedSet"); HistoryForwardingReachedSet reached = new HistoryForwardingReachedSet(pReachedSet); logger.log(Level.INFO, "Start inner algorithm to analyze program(s)"); AlgorithmStatus status = AlgorithmStatus.UNSOUND_AND_PRECISE; stats.analysisTime.start(); try { status = restartAlgorithm.run(reached); } finally { stats.analysisTime.stop(); } if (status.isSound()) { shutdown.shutdownIfNecessary(); logger.log(Level.INFO, "Program(s) soundly analyzed, start combining ARGs."); stats.argCombineTime.start(); try { Collection<ReachedSet> usedReachedSets = reached.getAllReachedSetsUsedAsDelegates(); if (usedReachedSets.size() <= 1) { logger.log(Level.INFO, "Only a single ARG is considered. Do not need to combine ARGs"); if (usedReachedSets.size() == 1) { ((ForwardingReachedSet) pReachedSet).setDelegate(reached.getDelegate()); } return status; } if (from(reached.getDelegate()).anyMatch((IS_TARGET_STATE))) { logger.log(Level.INFO, "Error found, do not combine ARGs."); ((ForwardingReachedSet) pReachedSet).setDelegate(reached.getDelegate()); return status; } logger.log(Level.FINE, "Extract root nodes of ARGs"); List<ARGState> rootNodes = new ArrayList<>(usedReachedSets.size()); for (ReachedSet usedReached : usedReachedSets) { checkArgument( usedReached.getFirstState() instanceof ARGState, "Require that all restart configurations use ARGCPA as top level CPA."); checkArgument( AbstractStates.extractLocation(usedReached.getFirstState()) != null, "Require that all restart configurations consider a location aware state"); for (AbstractState errorState : from(usedReached).filter((IS_TARGET_STATE))) { logger.log( Level.INFO, "Error state found in reached set ", usedReached, "but not by last configuration. Error state must be infeasible."); logger.log(Level.FINE, "Remove infeasible error state", errorState); ((ARGState) errorState).removeFromARG(); } rootNodes.add((ARGState) usedReached.getFirstState()); } shutdown.shutdownIfNecessary(); if (!combineARGs(rootNodes, (ForwardingReachedSet) pReachedSet, reached)) { logger.log(Level.SEVERE, "Combination of ARGs failed."); return status.withSound(false); } } finally { stats.argCombineTime.stop(); } logger.log(Level.INFO, "Finished combination of ARGS"); } else { logger.log( Level.INFO, "Program analysis is already unsound.", "Do not continue with combination of unsound results"); // set reached set to last used by restart algorithm if (reached.getDelegate() != pReachedSet) { ((ForwardingReachedSet) pReachedSet).setDelegate(reached.getDelegate()); } return status.withSound(false); } return status.withSound(true); }