All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.exigen.ie.constrainer.impl.GoalStack Maven / Gradle / Ivy

package com.exigen.ie.constrainer.impl;
import java.io.Serializable;

import com.exigen.ie.constrainer.ChoicePointLabel;
import com.exigen.ie.constrainer.Goal;
import com.exigen.ie.tools.FastStack;

/**
 * An implementation of the goal stack.
 */
public final class GoalStack implements Serializable
{
  private FastStack           _exeStack;
  private FastStack           _choicePointStack;
  private int                 _undoStackSize;
  private UndoStack           _undoStack;

 /**
  * Constructor with given undo stack.
  */
  public GoalStack(UndoStack undoStack)
  {
    init(new FastStack(), undoStack);
  }

 /**
  * Constructor with given main goal and undo stack.
  */
  public GoalStack(Goal mainGoal, UndoStack undoStack)
  {
    FastStack initialGoals = new FastStack();
    initialGoals.push(mainGoal);
    init(initialGoals, undoStack);
  }

 /**
  * Constructor with given initial goals and undo stack.
  */
  public GoalStack(FastStack initialGoals, UndoStack undoStack)
  {
    init((FastStack)initialGoals.clone(), undoStack);
  }

 /**
  * Initialize this goal stack.
  */
  final void init(FastStack initialGoals, UndoStack undoStack)
  {
    _exeStack = initialGoals;
    _choicePointStack = new FastStack();
    _undoStack = undoStack;
    _undoStackSize = undoStack.size();
  }

  /**
   * Pushes the goal onto the execution stack.
   */
  final public void pushGoal(Goal goal)
  {
    _exeStack.push(goal);
  }

  /**
   * Pops the goal from the execution stack and returns it.
   */
  final public Goal popGoal()
  {
    return (Goal)_exeStack.pop();
  }

  /**
   * Returns true if the execution stack is empty.
   */
  final public boolean empty()
  {
    return _exeStack.empty();
  }

  /**
   * Sets a labeled choice point between two goals.
   */
  final public void setChoicePoint(Goal g1, Goal g2, ChoicePointLabel label)
  {
    ChoicePoint cp = new ChoicePoint(g2, label, _exeStack, _undoStack.size());
    _choicePointStack.push(cp);
    pushGoal(g1);
  }

  /**
   * Backtracks the state of this goal stack to the latest labeled choice point.
   *
   * If the required choice point is found:
   *  - it restores the state of the execution stack
   *  - the required choice point is returned
   * If the required choice point is not found:
   *  - the goal stack is empty
   *  - null is returned
   */
  final public ChoicePoint backtrackStack(ChoicePointLabel label)
  {
    while(!_choicePointStack.empty())
    {
      ChoicePoint cp = (ChoicePoint)_choicePointStack.pop();
      // the condition "the required label found"
      if(label == null || label.equals(cp.label()))
      {
        _exeStack = cp.exeStack();
        return cp;
      }
    }

    // no choice point found -> clear the state of the goal stack
    _exeStack.clear();

    return null;
  }

  /**
   * Backtracks this goal stack and the undo stack
   * to the most recent labeled choice point.
   *
   * If the required choice point was found:
   *  - goal stack is restored to the state when the choice point was created
   *  - undo stack is restored to the state when the choice point was created
   *  - choice point goal is pushed onto goal stack
   *  - true is returned
   *
   * If the required choice point was not found:
   *  - goal stack will be empty
   *  - undo stack is restored to the state when the goal stack was created
   *  - false is returned
   */
  final public boolean backtrack(ChoicePointLabel label)
  {
    ChoicePoint cp = backtrackStack(label);
    if(cp != null)
    {
      _undoStack.backtrack( cp.undoStackSize() );
      pushGoal( cp.goal() );
      return true;
    }
    else
    {
      _undoStack.backtrack( undoStackSize() );
      return false;
    }
  }

  /**
   * Returns the current choice point.
   */
  final public ChoicePoint currentChoicePoint()
  {
    if(_choicePointStack.empty())
      throw new RuntimeException("No current choice point");

    return (ChoicePoint)_choicePointStack.peek();
  }

  /**
   * A placeholder for the information about the choice point.
   */
  static public class ChoicePoint implements java.io.Serializable
  {
    Goal              _goal;
    ChoicePointLabel  _label;
    FastStack         _exeStack;
    int               _undoStackSize;

    public ChoicePoint(Goal goal, ChoicePointLabel label, FastStack exeStack, int undoStackSize)
    {
      _goal = goal;
      _label = label;
      _exeStack = (FastStack)exeStack.clone();
      _undoStackSize = undoStackSize;
    }

    final public Goal goal()
    {
      return _goal;
    }

    final public ChoicePointLabel label()
    {
      return _label;
    }

    final public FastStack exeStack()
    {
      return _exeStack;
    }

    final public int undoStackSize()
    {
      return _undoStackSize;
    }

  } // ~ChoicePoint

  final public int undoStackSize()
  {
    return _undoStackSize;
  }

  public String toString()
  {
    return "GoalStack: "
           +"\n\tExecutionStack: " + _exeStack
           +"\n\tChoicePointStack: " + _choicePointStack
           ;
  }

} // ~GoalStack




© 2015 - 2024 Weber Informatics LLC | Privacy Policy