/** * Transform the current state into the new state. We iterate over all entries in the state vector * that need updating and transform them according to the defined transformation method. * * @param nodesToUpdate Nodes which must be considered in this transformation step. */ private void transformState(final Set<GraphNode> nodesToUpdate) { final StateVector<GraphNode, LatticeElement> newState = new StateVector<GraphNode, LatticeElement>(); final Set<GraphNode> newNodesToUpdate = new LinkedHashSet<GraphNode>(); for (final GraphNode node : nodesToUpdate) { final List<IInfluencingState<LatticeElement, ObjectType>> influencingStates = getStates(walker.getInfluencing(node)); final LatticeElement combinedState = lattice.combine(influencingStates); final LatticeElement transformedState = transformationList.transform(node, state.getState(node), combinedState); newState.setState(node, transformedState); if (debugger != null) { debugger.updatedState(node, influencingStates, transformedState); } // State has changed since the last iteration => We need another iteration with the // nodes that are influenced by this state change. if (!newState.getState(node).equals(state.getState(node))) { newNodesToUpdate.addAll(walker.getInfluenced(node)); } if (newState.getState(node).lessThan(state.getState(node))) { throw new IllegalStateException("Non-monotone transformation detected"); } } updateCurrentState(newState); if (debugger != null) { debugger.updatedState(state); } nodesToUpdate.clear(); nodesToUpdate.addAll(newNodesToUpdate); }
/** * Returns a list of current states associated with a list of given graph nodes. * * @param nodes The graph nodes whose states are determined. * @return The states of the given graph nodes. */ private List<IInfluencingState<LatticeElement, ObjectType>> getStates( final List<? extends IInfluencingNode<GraphNode, ObjectType>> nodes) { final List<IInfluencingState<LatticeElement, ObjectType>> states = new ArrayList<IInfluencingState<LatticeElement, ObjectType>>(); for (final IInfluencingNode<GraphNode, ObjectType> node : nodes) { states.add( new InfluencingState<LatticeElement, ObjectType>( state.getState(node.getNode()), node.getObject())); } return states; }