@Override public AbstractState join(AbstractState successor, AbstractState reached) { Pair<OctagonState, OctagonState> shrinkedStates = getShrinkedStates((OctagonState) successor, (OctagonState) reached); Octagon newOctagon = shrinkedStates .getFirst() .getOctagon() .getManager() .union(shrinkedStates.getFirst().getOctagon(), shrinkedStates.getSecond().getOctagon()); // TODO this should not be necessary however it occurs that a widened state is bottom if (shrinkedStates.getFirst().getOctagon().getManager().isEmpty(newOctagon)) { throw new AssertionError("bottom state occured where it should not be"); } OctagonState newState = new OctagonState( newOctagon, shrinkedStates.getFirst().getVariableToIndexMap(), shrinkedStates.getFirst().getVariableToTypeMap(), logger); if (((OctagonState) reached).isLoopHead()) { newState = newState.asLoopHead(); } if (newState.equals(reached)) { return reached; } else if (newState.equals(successor)) { return successor; } else { return newState; } }
public AbstractState widening(OctagonState successorOct, OctagonState reachedOct) { Pair<OctagonState, OctagonState> shrinkedStates = getShrinkedStates(successorOct, reachedOct); successorOct = shrinkedStates.getFirst(); reachedOct = shrinkedStates.getSecond(); Octagon newOctagon = reachedOct .getOctagon() .getManager() .widening(reachedOct.getOctagon(), successorOct.getOctagon()); // TODO this should not be necessary however it occurs that a widened state is bottom if (reachedOct.getOctagon().getManager().isEmpty(newOctagon)) { newOctagon = reachedOct .getOctagon() .getManager() .union(reachedOct.getOctagon(), successorOct.getOctagon()); logger.log( Level.WARNING, "bottom state occured where it should not be, using union instead of widening as a fallback"); if (reachedOct.getOctagon().getManager().isEmpty(newOctagon)) { throw new AssertionError("bottom state occured where it should not be"); } } OctagonState newState = new OctagonState( newOctagon, successorOct.getVariableToIndexMap(), successorOct.getVariableToTypeMap(), logger); if (reachedOct.isLoopHead()) { newState = newState.asLoopHead(); } if (newState.equals(successorOct)) { return successorOct; } else if (newState.equals(reachedOct)) { return reachedOct; } else { return newState; } }