Example #1
0
 /**
  * This constructor initializes the class using the specified options.
  *
  * @access public
  * @param string $id                                        the id given to the state
  * @param \Unicity\Automaton\StateType $type                the type of state
  * @param mixed $value                                      the value associated with the state
  * @param mixed $constraint                                 a constraint on the state
  * @param double $priority                                  the priority given to the state
  */
 public function __construct($id, Automaton\StateType $type, $value = null, $constraint = null, $priority = 0.0)
 {
     $this->constraint = $constraint;
     $this->id = $id;
     $this->priority = $priority;
     $this->transitions = new Common\Mutable\HashSet();
     $this->type = $type !== null ? $type : Automaton\StateType::normal();
     $this->value = $value;
 }
Example #2
0
 /**
  * This method recursively traverses the machine.
  *
  * @access protected
  * @param \Unicity\Common\IList $sigma                      the sigma to be processed
  * @param integer $i                                        the index to the input symbol
  * @param \Unicity\Automaton\IState $state                  the current a set of target states
  * @param \Unicity\Common\Mutable\Stack $stack              the path through which the pattern
  *                                                          was found
  * @return boolean                                          whether the machine finished in
  *                                                          a goal state
  *                                                          a goal state
  * @throws \Unicity\Throwable\Parse\Exception               indicates that the machine failed
  *                                                          to parse
  */
 protected function traverse(Common\IList $sigma, $i, Automaton\IState $state, Common\Mutable\Stack $stack)
 {
     if ($i >= $sigma->count()) {
         return Automaton\StateType::goal()->__equals($state->getType());
     }
     $transitions = $this->transitions->getValues($state->getTransitions());
     usort($transitions, function (Core\IComparable $c0, Core\IComparable $c1) {
         return $c0->compareTo($c1);
     });
     $hasTransitioned = false;
     foreach ($transitions as $transition) {
         if ($transition->isTraversable($sigma, $i)) {
             $targets = $this->states->getValues($transition->getTargets());
             usort($targets, function (Core\IComparable $c0, Core\IComparable $c1) {
                 return $c0->compareTo($c1);
             });
             foreach ($targets as $target) {
                 $stack->push($target->getId());
                 if ($this->traverse($sigma, $i + 1, $target, $stack)) {
                     return true;
                 }
                 $stack->pop();
             }
             $hasTransitioned = true;
             break;
         }
     }
     if (!$hasTransitioned) {
         throw new Throwable\Parse\Exception('Machine failed. Unable to transition between states.');
     }
     return false;
 }
Example #3
0
 /**
  * This method runs the machine using the specified sigma (i.e. the input alphabet/sequence).
  *
  * @access public
  * @param \Unicity\Common\IList $sigma                      the sigma to be processed
  * @param \Unicity\Common\Mutable\IList $path               the path through which the pattern
  *                                                          was found
  * @return boolean                                          whether the machine finished in
  *                                                          a goal state
  * @throws \Unicity\Throwable\InvalidArgument\Exception     indicates that no sigma has been
  *                                                          specified
  * @throws \Unicity\Throwable\Parse\Exception               indicates that the machine failed
  *                                                          to parse
  */
 public function run(Common\IList $sigma, Common\Mutable\IList $path = null)
 {
     if ($sigma === null || $sigma->isEmpty()) {
         throw new Throwable\InvalidArgument\Exception('No sigma has been defined.');
     }
     $count = $sigma->count();
     if ($this->initials === null || $this->initials->isEmpty()) {
         throw new Throwable\Parse\Exception('Machine failed. No initial state has been defined.');
     }
     $stack = new Common\Mutable\Stack($path);
     $states = $this->states->getValues($this->initials);
     usort($states, function (Core\IComparable $c0, Core\IComparable $c1) {
         return $c0->compareTo($c1);
     });
     $state = $states[0];
     $stack->push($state->getId());
     $this->onStart($this, $state);
     for ($i = 0; $i < $count; $i++) {
         $transitions = $this->transitions->getValues($state->getTransitions());
         usort($transitions, function (Core\IComparable $c0, Core\IComparable $c1) {
             return $c0->compareTo($c1);
         });
         $hasTransitioned = false;
         foreach ($transitions as $transition) {
             if ($transition->isTraversable($sigma, $i)) {
                 $this->onExit($this, $state);
                 $this->onTransition($this, $transition);
                 $targets = $this->states->getValues($transition->getTargets());
                 usort($targets, function (Core\IComparable $c0, Core\IComparable $c1) {
                     return $c0->compareTo($c1);
                 });
                 $state = $targets[0];
                 $stack->push($state->getId());
                 $this->onEntry($this, $state);
                 $hasTransitioned = true;
                 break;
             }
         }
         if (!$hasTransitioned) {
             $stack->clear();
             throw new Throwable\Parse\Exception('Machine failed. Unable to transition between states.');
         }
     }
     $this->onCompletion($this, $state);
     if (Automaton\StateType::goal()->__equals($state->getType())) {
         return true;
     }
     $stack->clear();
     return false;
 }