private Collection<List<AbstractState>> callTransferRelation( final CompositeState compositeState, final CompositePrecision compositePrecision, final CFAEdge cfaEdge) throws CPATransferException, InterruptedException { int resultCount = 1; List<AbstractState> componentElements = compositeState.getWrappedStates(); checkArgument( componentElements.size() == size, "State with wrong number of component states given"); List<Collection<? extends AbstractState>> allComponentsSuccessors = new ArrayList<>(size); for (int i = 0; i < size; i++) { TransferRelation lCurrentTransfer = transferRelations.get(i); AbstractState lCurrentElement = componentElements.get(i); Precision lCurrentPrecision = compositePrecision.get(i); Collection<? extends AbstractState> componentSuccessors; componentSuccessors = lCurrentTransfer.getAbstractSuccessorsForEdge( lCurrentElement, lCurrentPrecision, cfaEdge); resultCount *= componentSuccessors.size(); if (resultCount == 0) { // shortcut break; } allComponentsSuccessors.add(componentSuccessors); } // create cartesian product of all elements we got return createCartesianProduct(allComponentsSuccessors, resultCount); }
private Collection<List<AbstractState>> callStrengthen( final List<AbstractState> reachedState, final CompositePrecision compositePrecision, final CFAEdge cfaEdge) throws CPATransferException, InterruptedException { List<Collection<? extends AbstractState>> lStrengthenResults = new ArrayList<>(size); int resultCount = 1; for (int i = 0; i < size; i++) { TransferRelation lCurrentTransfer = transferRelations.get(i); AbstractState lCurrentElement = reachedState.get(i); Precision lCurrentPrecision = compositePrecision.get(i); Collection<? extends AbstractState> lResultsList = lCurrentTransfer.strengthen(lCurrentElement, reachedState, cfaEdge, lCurrentPrecision); if (lResultsList == null) { lStrengthenResults.add(Collections.singleton(lCurrentElement)); } else { resultCount *= lResultsList.size(); if (resultCount == 0) { // shortcut break; } lStrengthenResults.add(lResultsList); } } // special case handling if we have predicate and assumption cpas // TODO remove as soon as we call strengthen in a fixpoint loop if (predicatesIndex >= 0 && assumptionIndex >= 0 && resultCount > 0) { AbstractState predElement = Iterables.getOnlyElement(lStrengthenResults.get(predicatesIndex)); AbstractState assumptionElement = Iterables.getOnlyElement(lStrengthenResults.get(assumptionIndex)); Precision predPrecision = compositePrecision.get(predicatesIndex); TransferRelation predTransfer = transferRelations.get(predicatesIndex); Collection<? extends AbstractState> predResult = predTransfer.strengthen( predElement, Collections.singletonList(assumptionElement), cfaEdge, predPrecision); resultCount *= predResult.size(); lStrengthenResults.set(predicatesIndex, predResult); } // create cartesian product Collection<List<AbstractState>> strengthenedStates = createCartesianProduct(lStrengthenResults, resultCount); // If state was not a target state before but a target state was found during strengthening, // we call strengthen again such that the other CPAs can act on this information. // Note that this terminates because in the inner call the input state // is already a target state and this branch won't be taken. // TODO Generalize this into a full fixpoint algorithm. if (!any(reachedState, IS_TARGET_STATE)) { Collection<List<AbstractState>> newStrengthenedStates = new ArrayList<>(resultCount); for (List<AbstractState> strengthenedState : strengthenedStates) { if (any(strengthenedState, IS_TARGET_STATE)) { newStrengthenedStates.addAll( callStrengthen(strengthenedState, compositePrecision, cfaEdge)); } else { newStrengthenedStates.add(strengthenedState); } } return newStrengthenedStates; } else { return strengthenedStates; } }