Source of file FSM.php
Size: 14,019 Bytes - Last Modified: 2021-12-23T10:29:30+00:00
/var/www/docs.ssmods.com/process/src/thirdparty/Zend/Search/Lucene/FSM.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 | <?php /** * Zend Framework * * LICENSE * * This source file is subject to the new BSD license that is bundled * with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://framework.zend.com/license/new-bsd * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@zend.com so we can send you a copy immediately. * * @category Zend * @package Zend_Search_Lucene * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @version $Id: FSM.php 20096 2010-01-06 02:05:09Z bkarwin $ */ /** * Zend_Search_Lucene_FSMAction */ require_once 'Zend/Search/Lucene/FSMAction.php'; /** * Abstract Finite State Machine * * Take a look on Wikipedia state machine description: http://en.wikipedia.org/wiki/Finite_state_machine * * Any type of Transducers (Moore machine or Mealy machine) also may be implemented by using this abstract FSM. * process() methods invokes a specified actions which may construct FSM output. * Actions may be also used to signal, that we have reached Accept State * * @category Zend * @package Zend_Search_Lucene * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ abstract class Zend_Search_Lucene_FSM { /** * Machine States alphabet * * @var array */ private $_states = array(); /** * Current state * * @var integer|string */ private $_currentState = null; /** * Input alphabet * * @var array */ private $_inputAphabet = array(); /** * State transition table * * [sourceState][input] => targetState * * @var array */ private $_rules = array(); /** * List of entry actions * Each action executes when entering the state * * [state] => action * * @var array */ private $_entryActions = array(); /** * List of exit actions * Each action executes when exiting the state * * [state] => action * * @var array */ private $_exitActions = array(); /** * List of input actions * Each action executes when entering the state * * [state][input] => action * * @var array */ private $_inputActions = array(); /** * List of input actions * Each action executes when entering the state * * [state1][state2] => action * * @var array */ private $_transitionActions = array(); /** * Finite State machine constructor * * $states is an array of integers or strings with a list of possible machine states * constructor treats fist list element as a sturt state (assignes it to $_current state). * It may be reassigned by setState() call. * States list may be empty and can be extended later by addState() or addStates() calls. * * $inputAphabet is the same as $states, but represents input alphabet * it also may be extended later by addInputSymbols() or addInputSymbol() calls. * * $rules parameter describes FSM transitions and has a structure: * array( array(sourseState, input, targetState[, inputAction]), * array(sourseState, input, targetState[, inputAction]), * array(sourseState, input, targetState[, inputAction]), * ... * ) * Rules also can be added later by addRules() and addRule() calls. * * FSM actions are very flexible and may be defined by addEntryAction(), addExitAction(), * addInputAction() and addTransitionAction() calls. * * @param array $states * @param array $inputAphabet * @param array $rules */ public function __construct($states = array(), $inputAphabet = array(), $rules = array()) { $this->addStates($states); $this->addInputSymbols($inputAphabet); $this->addRules($rules); } /** * Add states to the state machine * * @param array $states */ public function addStates($states) { foreach ($states as $state) { $this->addState($state); } } /** * Add state to the state machine * * @param integer|string $state */ public function addState($state) { $this->_states[$state] = $state; if ($this->_currentState === null) { $this->_currentState = $state; } } /** * Set FSM state. * No any action is invoked * * @param integer|string $state * @throws Zend_Search_Exception */ public function setState($state) { if (!isset($this->_states[$state])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('State \'' . $state . '\' is not on of the possible FSM states.'); } $this->_currentState = $state; } /** * Get FSM state. * * @return integer|string $state|null */ public function getState() { return $this->_currentState; } /** * Add symbols to the input alphabet * * @param array $inputAphabet */ public function addInputSymbols($inputAphabet) { foreach ($inputAphabet as $inputSymbol) { $this->addInputSymbol($inputSymbol); } } /** * Add symbol to the input alphabet * * @param integer|string $inputSymbol */ public function addInputSymbol($inputSymbol) { $this->_inputAphabet[$inputSymbol] = $inputSymbol; } /** * Add transition rules * * array structure: * array( array(sourseState, input, targetState[, inputAction]), * array(sourseState, input, targetState[, inputAction]), * array(sourseState, input, targetState[, inputAction]), * ... * ) * * @param array $rules */ public function addRules($rules) { foreach ($rules as $rule) { $this->addrule($rule[0], $rule[1], $rule[2], isset($rule[3])?$rule[3]:null); } } /** * Add symbol to the input alphabet * * @param integer|string $sourceState * @param integer|string $input * @param integer|string $targetState * @param Zend_Search_Lucene_FSMAction|null $inputAction * @throws Zend_Search_Exception */ public function addRule($sourceState, $input, $targetState, $inputAction = null) { if (!isset($this->_states[$sourceState])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('Undefined source state (' . $sourceState . ').'); } if (!isset($this->_states[$targetState])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('Undefined target state (' . $targetState . ').'); } if (!isset($this->_inputAphabet[$input])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('Undefined input symbol (' . $input . ').'); } if (!isset($this->_rules[$sourceState])) { $this->_rules[$sourceState] = array(); } if (isset($this->_rules[$sourceState][$input])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('Rule for {state,input} pair (' . $sourceState . ', '. $input . ') is already defined.'); } $this->_rules[$sourceState][$input] = $targetState; if ($inputAction !== null) { $this->addInputAction($sourceState, $input, $inputAction); } } /** * Add state entry action. * Several entry actions are allowed. * Action execution order is defined by addEntryAction() calls * * @param integer|string $state * @param Zend_Search_Lucene_FSMAction $action */ public function addEntryAction($state, Zend_Search_Lucene_FSMAction $action) { if (!isset($this->_states[$state])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('Undefined state (' . $state. ').'); } if (!isset($this->_entryActions[$state])) { $this->_entryActions[$state] = array(); } $this->_entryActions[$state][] = $action; } /** * Add state exit action. * Several exit actions are allowed. * Action execution order is defined by addEntryAction() calls * * @param integer|string $state * @param Zend_Search_Lucene_FSMAction $action */ public function addExitAction($state, Zend_Search_Lucene_FSMAction $action) { if (!isset($this->_states[$state])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('Undefined state (' . $state. ').'); } if (!isset($this->_exitActions[$state])) { $this->_exitActions[$state] = array(); } $this->_exitActions[$state][] = $action; } /** * Add input action (defined by {state, input} pair). * Several input actions are allowed. * Action execution order is defined by addInputAction() calls * * @param integer|string $state * @param integer|string $input * @param Zend_Search_Lucene_FSMAction $action */ public function addInputAction($state, $inputSymbol, Zend_Search_Lucene_FSMAction $action) { if (!isset($this->_states[$state])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('Undefined state (' . $state. ').'); } if (!isset($this->_inputAphabet[$inputSymbol])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('Undefined input symbol (' . $inputSymbol. ').'); } if (!isset($this->_inputActions[$state])) { $this->_inputActions[$state] = array(); } if (!isset($this->_inputActions[$state][$inputSymbol])) { $this->_inputActions[$state][$inputSymbol] = array(); } $this->_inputActions[$state][$inputSymbol][] = $action; } /** * Add transition action (defined by {state, input} pair). * Several transition actions are allowed. * Action execution order is defined by addTransitionAction() calls * * @param integer|string $sourceState * @param integer|string $targetState * @param Zend_Search_Lucene_FSMAction $action */ public function addTransitionAction($sourceState, $targetState, Zend_Search_Lucene_FSMAction $action) { if (!isset($this->_states[$sourceState])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('Undefined source state (' . $sourceState. ').'); } if (!isset($this->_states[$targetState])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('Undefined source state (' . $targetState. ').'); } if (!isset($this->_transitionActions[$sourceState])) { $this->_transitionActions[$sourceState] = array(); } if (!isset($this->_transitionActions[$sourceState][$targetState])) { $this->_transitionActions[$sourceState][$targetState] = array(); } $this->_transitionActions[$sourceState][$targetState][] = $action; } /** * Process an input * * @param mixed $input * @throws Zend_Search_Exception */ public function process($input) { if (!isset($this->_rules[$this->_currentState])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('There is no any rule for current state (' . $this->_currentState . ').'); } if (!isset($this->_rules[$this->_currentState][$input])) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('There is no any rule for {current state, input} pair (' . $this->_currentState . ', ' . $input . ').'); } $sourceState = $this->_currentState; $targetState = $this->_rules[$this->_currentState][$input]; if ($sourceState != $targetState && isset($this->_exitActions[$sourceState])) { foreach ($this->_exitActions[$sourceState] as $action) { $action->doAction(); } } if (isset($this->_inputActions[$sourceState]) && isset($this->_inputActions[$sourceState][$input]) ) { foreach ($this->_inputActions[$sourceState][$input] as $action) { $action->doAction(); } } $this->_currentState = $targetState; if (isset($this->_transitionActions[$sourceState]) && isset($this->_transitionActions[$sourceState][$targetState]) ) { foreach ($this->_transitionActions[$sourceState][$targetState] as $action) { $action->doAction(); } } if ($sourceState != $targetState && isset($this->_entryActions[$targetState])) { foreach ($this->_entryActions[$targetState] as $action) { $action->doAction(); } } } public function reset() { if (count($this->_states) == 0) { include_once 'Zend/Search/Exception.php'; throw new Zend_Search_Exception('There is no any state defined for FSM.'); } $this->_currentState = $this->_states[0]; } } |