6  * Segment of a query string.
 
   8  * The parts of a query strings are usually separated by commas.
 
  14     // Complete phrase as a string.
 
  16     // Element type for structured searches.
 
  18     // Space-separated words of the phrase.
 
  20     // Possible segmentations of the phrase.
 
  24     public function __construct($sPhrase, $sPhraseType)
 
  26         $this->sPhrase = trim($sPhrase);
 
  27         $this->sPhraseType = $sPhraseType;
 
  28         $this->aWords = explode(' ', $this->sPhrase);
 
  29         $this->aWordSets = $this->createWordSets($this->aWords, 0);
 
  33      * Return the element type of the phrase.
 
  35      * @return string Pharse type if the phrase comes from a structured query
 
  36      *                or empty string otherwise.
 
  38     public function getPhraseType()
 
  40         return $this->sPhraseType;
 
  44      * Return the array of possible segmentations of the phrase.
 
  46      * @return string[][] Array of segmentations, each consisting of an
 
  49     public function getWordSets()
 
  51         return $this->aWordSets;
 
  55      * Add the tokens from this phrase to the given list of tokens.
 
  57      * @param string[] $aTokens List of tokens to append.
 
  61     public function addTokens(&$aTokens)
 
  63         foreach ($this->aWordSets as $aSet) {
 
  64             foreach ($aSet as $sWord) {
 
  65                 $aTokens[' '.$sWord] = ' '.$sWord;
 
  66                 $aTokens[$sWord] = $sWord;
 
  72      * Invert the set of possible segmentations.
 
  76     public function invertWordSets()
 
  78         $this->aWordSets = $this->createInverseWordSets($this->aWords, 0);
 
  81     private function createWordSets($aWords, $iDepth)
 
  83         $aResult = array(array(join(' ', $aWords)));
 
  85         if ($iDepth < Phrase::MAX_DEPTH) {
 
  86             while (count($aWords) > 1) {
 
  87                 $sWord = array_shift($aWords);
 
  88                 $sFirstToken .= ($sFirstToken?' ':'').$sWord;
 
  89                 $aRest = $this->createWordSets($aWords, $iDepth + 1);
 
  90                 foreach ($aRest as $aSet) {
 
  91                     $aResult[] = array_merge(array($sFirstToken), $aSet);
 
  99     private function createInverseWordSets($aWords, $iDepth)
 
 101         $aResult = array(array(join(' ', $aWords)));
 
 103         if ($iDepth < Phrase::MAX_DEPTH) {
 
 104             while (count($aWords) > 1) {
 
 105                 $sWord = array_pop($aWords);
 
 106                 $sFirstToken = $sWord.($sFirstToken?' ':'').$sFirstToken;
 
 107                 $aRest = $this->createInverseWordSets($aWords, $iDepth + 1);
 
 108                 foreach ($aRest as $aSet) {
 
 109                     $aResult[] = array_merge(array($sFirstToken), $aSet);
 
 117     public function debugInfo()
 
 120                 'Type' => $this->sPhraseType,
 
 121                 'Phrase' => $this->sPhrase,
 
 122                 'Words' => $this->aWords,
 
 123                 'WordSets' => $this->aWordSets