/** * 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; }
/** * 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.'); } 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); }); foreach ($states as $state) { $stack->push($state->getId()); if ($this->traverse($sigma, 0, $state, $stack)) { return true; } $stack->pop(); } $stack->clear(); return false; }