Esempio n. 1
0
  /**
   * Creates a new instance of a monotone solver.
   *
   * @param graph Graph that is being worked on.
   * @param lattice Lattice structure that provides the method to merge states.
   * @param startVector Initial state vector.
   * @param transformationProvider Transforms the state vector during each step of the algorithm.
   * @param walker Specifies how to walk through the graph.
   * @param debugger Optional debugger that receives debugging information while the monotone
   *     framework is running.
   */
  public MonotoneSolver(
      final ILatticeGraph<GraphNode> graph,
      final Lattice lattice,
      final IStateVector<GraphNode, LatticeElement> startVector,
      final ITransformationProvider<GraphNode, LatticeElement> transformationProvider,
      final IGraphWalker<GraphNode, ObjectType> walker,
      final IMonotoneDebugger debugger) {
    Preconditions.checkNotNull(graph, "Error: Graph argument can not be null");
    Preconditions.checkNotNull(lattice, "Error: Lattice argument can not be null");
    Preconditions.checkNotNull(startVector, "Error: Start vector argument can not be null");
    Preconditions.checkNotNull(
        transformationProvider, "Error: Transformation list argument can not be null");

    final List<GraphNode> nodes = graph.getNodes();

    Preconditions.checkArgument(
        nodes.size() == startVector.size(),
        String.format(
            "Error: Invalid start vector (%d states for %d nodes)",
            startVector.size(), nodes.size()));

    for (final GraphNode node : nodes) {
      Preconditions.checkArgument(
          startVector.hasState(node),
          "Error: Node " + node + " does not have a state in the initial state vector");
    }

    this.graph = graph;
    this.lattice = lattice;
    this.state = startVector;
    this.transformationList = transformationProvider;
    this.walker = walker;
    this.debugger = debugger;
  }
Esempio n. 2
0
  /**
   * 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);
  }
Esempio n. 3
0
  /**
   * 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;
  }
Esempio n. 4
0
 /**
  * Copies the given state vector into the current state vector.
  *
  * @param newState The state vector to copy.
  */
 private void updateCurrentState(final StateVector<GraphNode, LatticeElement> newState) {
   for (final GraphNode node : newState) {
     state.setState(node, newState.getState(node));
   }
 }