eliza.php
changeset 8 0acb8d9a3194
equal deleted inserted replaced
7:1d6e762433fe 8:0acb8d9a3194
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * Implementation of ELIZA in PHP. Ported from Javascript by Dan Fuhry
       
     5  * Chat Bot by George Dunlop, www.peccavi.com
       
     6  * May be used/modified if credit line is retained
       
     7  * @author George Dunlop <http://www.peccavi.com/>
       
     8  * @author Dan Fuhry <dan@enanocms.org>
       
     9  * @copyright (c) 1997-2008 George Dunlop. All rights reserved, portions copyright (C) 2008 Dan Fuhry.
       
    10  */
       
    11 
       
    12 class Psychotherapist
       
    13 {
       
    14   private $maxKey = 36;
       
    15   private $keyNotFound = 0;
       
    16   private $keyword = array();
       
    17   private $maxresponses = 116;
       
    18   private $response = array();
       
    19   
       
    20   private $maxConj = 19;
       
    21   private $max2ndConj = 7;
       
    22   
       
    23   private $conj1 = Array();
       
    24   private $conj2 = Array();
       
    25   private $conj3 = Array();
       
    26   private $conj4 = Array();
       
    27   
       
    28   private $punct = Array(".", ",", "!", "?", ":", ";", "&", '"', "@", "#", "(", ")" );
       
    29   
       
    30   /**
       
    31    * Constructor.
       
    32    */
       
    33   
       
    34   public function __construct()
       
    35   {
       
    36     $this->keyNotFound = $this->maxKey - 1;
       
    37     $this->keyword = $this->create_array($this->maxKey);
       
    38     $this->response = $this->create_array($this->maxresponses);
       
    39     $this->conj1 = $this->create_array($this->maxConj);
       
    40     $this->conj2 = $this->create_array($this->maxConj);
       
    41     $this->conj3 = $this->create_array($this->max2ndConj);
       
    42     $this->conj4 = $this->create_array($this->max2ndConj);
       
    43     
       
    44     $this->table_setup();
       
    45   }
       
    46   
       
    47   /**
       
    48    * Replacement for str_replace that provides more options.
       
    49    * if type == 0 straight string replacement
       
    50    * if type == 1 assumes padded strings and replaces whole words only
       
    51    * if type == 2 non case sensitive assumes padded strings to compare whole word only
       
    52    * if type == 3 non case sensitive straight string replacement
       
    53    * @param string Haystack
       
    54    * @param string Needle
       
    55    * @param string Replacement
       
    56    * @param int Mode - defaults to 0
       
    57    */
       
    58 
       
    59   private function replaceStr($strng, $substr1, $substr2, $type = 0)
       
    60   {
       
    61     if ( $type == 0 )
       
    62     {  
       
    63       return str_replace($substr1, $substr2, $strng);
       
    64     }
       
    65     else if ( $type == 1 )
       
    66     {
       
    67       return str_replace(" $substr1 ", " $substr2 ", $strng);
       
    68     }
       
    69     else if ( $type == 2 || $type == 3 )
       
    70     {
       
    71       if ( $type == 2 )
       
    72       {
       
    73         $substr1 = " $substr1 ";
       
    74         $substr2 = " $substr2 ";
       
    75       }
       
    76       return preg_replace('/' . preg_quote($substr1) . '/i', $substr2, $strng);
       
    77     }
       
    78     else
       
    79     {
       
    80       throw new Exception("Invalid parameter");
       
    81     }
       
    82   }
       
    83   
       
    84   /**
       
    85    * Function to pad a string. head, tail & punctuation
       
    86    * @param string
       
    87    * @return string
       
    88    */
       
    89   
       
    90   private function padString($strng)
       
    91   {
       
    92     $punct =& $this->punct;
       
    93     
       
    94     $aString = " " . $strng . " ";
       
    95     for ( $i = 0; $i < count($punct); $i++ )
       
    96     {
       
    97       $aString = $this->replaceStr( $aString, $punct[$i], " " . $punct[$i] . " ", 0 );
       
    98     }
       
    99     return $aString;
       
   100   }
       
   101   
       
   102   /**
       
   103    * Function to strip padding
       
   104    */
       
   105   
       
   106   private function unpadString($strng)
       
   107   {
       
   108     $punct =& $this->punct;
       
   109     
       
   110     $aString = $strng;
       
   111     $aString = $this->replaceStr( $aString, "  ", " ", 0 );         // compress spaces
       
   112     
       
   113     $aString = trim($aString, ' ');
       
   114     
       
   115     for ( $i = 0; $i < count($punct); $i++ )
       
   116     {
       
   117       $aString = $this->replaceStr( $aString, " " . $punct[$i], $punct[$i], 0 );
       
   118     }
       
   119     return $aString;
       
   120   }
       
   121   
       
   122   /**
       
   123    * Dress Input formatting i.e leading & trailing spaces and tail punctuation
       
   124    * @param string
       
   125    * @return string
       
   126    */
       
   127 
       
   128   function strTrim($strng)
       
   129   {
       
   130     static $ht = 0;
       
   131     
       
   132     if ( $ht == 0 )
       
   133     {
       
   134       $loc = 0;
       
   135     }                                    // head clip
       
   136     else
       
   137     {
       
   138       $loc = strlen($strng) - 1;
       
   139     }                        // tail clip  ht = 1 
       
   140     if ( substr($strng, $loc, 1) == " " )
       
   141     {
       
   142       $aString = substr($strng, - ( $ht - 1 ), strlen($strng) - $ht);
       
   143       $aString = $this->strTrim($aString);
       
   144     }
       
   145     else
       
   146     {
       
   147       $flg = false;
       
   148       for ( $i = 0; $i <= 5; $i++ )
       
   149       {
       
   150         $flg = $flg || ( substr($strng, $loc, 1) == $this->punct[$i]);
       
   151       }
       
   152       if ( $flg )
       
   153       {    
       
   154         $aString = substr($strng, - ( $ht - 1 ), strlen($strng) - $ht);
       
   155       }
       
   156       else
       
   157       {
       
   158         $aString = $strng;
       
   159       }
       
   160       if ( $aString != $strng )
       
   161       {
       
   162         $aString = $this->strTrim($aString);
       
   163       }
       
   164     }
       
   165     if ( $ht == 0 )
       
   166     {
       
   167       $ht = 1;
       
   168       $aString = $this->strTrim($aString);
       
   169     } 
       
   170     else
       
   171     {
       
   172       $ht = 0;
       
   173     }        
       
   174     return $aString;
       
   175   }
       
   176   
       
   177   /**
       
   178    * adjust pronouns and verbs & such
       
   179    * @param string
       
   180    * @return string
       
   181    */
       
   182   
       
   183   private function conjugate($sStrg)
       
   184   {
       
   185     $sString = $sStrg;
       
   186     for ( $i = 0; $i < $this->maxConj; $i++ )
       
   187     {            // decompose
       
   188       $sString = $this->replaceStr( $sString, $this->conj1[$i], "#@&" . $i, 2 );
       
   189     }
       
   190     for( $i = 0; $i < $this->maxConj; $i++ )
       
   191     {            // recompose
       
   192       $sString = $this->replaceStr( $sString, "#@&" . $i, $this->conj2[$i], 2 );
       
   193     }
       
   194     // post process the resulting string
       
   195     for( $i = 0; $i < $this->max2ndConj; $i++ )
       
   196     {            // decompose
       
   197       $sString = $this->replaceStr( $sString, $this->conj3[$i], "#@&" . $i, 2 );
       
   198     }
       
   199     for( $i = 0; $i < $this->max2ndConj; $i++ )
       
   200     {            // recompose
       
   201       $sString = $this->replaceStr( $sString, "#@&" . $i, $this->conj4[$i], 2 );
       
   202     }
       
   203     return $sString;
       
   204   }
       
   205   
       
   206   /**
       
   207    * Build our response string
       
   208    * get a random choice of response based on the key
       
   209    * Then structure the response
       
   210    * @param string
       
   211    * @param int Key index
       
   212    * @return string
       
   213    */
       
   214   
       
   215   function phrase( $sString, $keyidx )
       
   216   {
       
   217     $idxmin  = $this->keyword[$keyidx]->idx;
       
   218     $idrange = $this->keyword[$keyidx]->end - $idxmin + 1;
       
   219     while ( $pass < 5 )
       
   220     {
       
   221       $choice = $this->keyword[$keyidx]->idx + mt_rand(0, $idrange);
       
   222       if ( $choice == $this->keyword[$keyidx]->last )
       
   223       { 
       
   224         $pass++;
       
   225         continue;
       
   226       }
       
   227       break;
       
   228     }
       
   229     $this->keyword[$keyidx]->last = $choice;
       
   230     $rTemp = $this->response[$choice];
       
   231     $tempt = substr($rTemp, strlen($rTemp) - 1, 1);
       
   232     if ( ( $tempt == "*" ) || ( $tempt == "@" ) )
       
   233     {
       
   234       $sTemp = $this->padString($sString);
       
   235       $wTemp = strtoupper($sTemp);
       
   236       $strpstr = intval(strpos($wTemp, " {$this->keyword[$keyidx]->key} "));
       
   237       
       
   238       $strpstr += strlen($this->keyword[$keyidx]->key) + 1;
       
   239       $thisstr = $this->conjugate( substr($sTemp, $strpstr, strlen($sTemp)) );
       
   240       $thisstr = $this->strTrim( $this->unpadString($thisstr) );
       
   241       if( $tempt == "*" )
       
   242       {
       
   243         $sTemp = $this->replaceStr( $rTemp, "<*", " " . $thisstr . "?", 0 );
       
   244       }
       
   245       else
       
   246       {
       
   247         $sTemp = $this->replaceStr( $rTemp, "<@", " " . $thisstr . ".", 0 );
       
   248       }
       
   249     }
       
   250     else
       
   251     {
       
   252       $sTemp = $rTemp;
       
   253     }
       
   254     return $sTemp;
       
   255   }
       
   256   
       
   257   /**
       
   258    * returns array index of first key found
       
   259    * @param string
       
   260    */
       
   261 
       
   262   private function testkey($wString)
       
   263   {
       
   264     for ( $keyid = 0; $keyid < count($this->keyword); $keyid++ )
       
   265     {
       
   266       if ( strpos($wString, " {$this->keyword[$keyid]->key} ") !== false )
       
   267       { 
       
   268         return $keyid;
       
   269       }
       
   270     }
       
   271     return false;
       
   272   }
       
   273   
       
   274   /**
       
   275    * 
       
   276    */
       
   277   
       
   278   private function findkey($wString)
       
   279   { 
       
   280     $keyid = $this->testkey($wString);
       
   281     if( !$keyid )
       
   282     {
       
   283       $keyid = $this->keyNotFound;
       
   284     }
       
   285     return $keyid;
       
   286   }
       
   287   
       
   288   /**
       
   289    * Process a line from the user.
       
   290    * @param string User input
       
   291    * @return string AI output
       
   292    */
       
   293   
       
   294   function listen($User)
       
   295   {
       
   296     static $wTopic = "";                                            // Last worthy responce
       
   297     static $sTopic = "";                                            // Last worthy responce
       
   298     static $greet = false;
       
   299     static $wPrevious = "";                                    // so we can check for repeats
       
   300     
       
   301     $sInput = $User;
       
   302     $sInput = $this->strTrim($sInput);                            // dress input formating
       
   303     
       
   304     if ( $sInput != "" )
       
   305     { 
       
   306       $wInput = $this->padString(strtoupper($sInput));    // Work copy
       
   307       $foundkey = $this->maxKey;                          // assume it's a repeat input
       
   308       if ( $wInput != $wPrevious )
       
   309       {                       // check if user repeats himself
       
   310         $foundkey = $this->findkey($wInput);               // look for a keyword.
       
   311       }
       
   312       if( $foundkey == $this->keyNotFound )
       
   313       {
       
   314         if( !$greet )
       
   315         {
       
   316           $greet = true;
       
   317           return "Don't you ever say Hello?";
       
   318         }
       
   319         else
       
   320         {
       
   321           $wPrevious = $wInput;                      // save input to check repeats
       
   322           if (( strlen($sInput) < 10 ) && ( $wTopic != "" ) && ( $wTopic != $wPrevious ))
       
   323           {
       
   324             $lTopic = $this->conjugate( $sTopic );
       
   325             $sTopic = "";
       
   326             $wTopic = "";
       
   327             return 'OK... "' + $lTopic + '". Tell me more.';
       
   328           }
       
   329           else
       
   330           {
       
   331             if ( strlen($sInput) < 15 )
       
   332             { 
       
   333               return "Tell me more..."; 
       
   334             }
       
   335             else
       
   336             {
       
   337               return $this->phrase( $sInput, $foundkey );
       
   338             }
       
   339           }
       
   340         }
       
   341       }
       
   342       else
       
   343       { 
       
   344         if ( strlen($sInput) > 12 )
       
   345         {
       
   346           $sTopic = $sInput;
       
   347           $wTopic = $wInput;
       
   348         }
       
   349         $greet = true;
       
   350         $wPrevious = $wInput;              // save input to check repeats
       
   351         return $this->phrase( $sInput, $foundkey );            // Get our response
       
   352       }
       
   353     }
       
   354     else
       
   355     {
       
   356       return "I can't help if you will not chat with me!";
       
   357     }
       
   358   }
       
   359   
       
   360   /**
       
   361    * Creates an array of the specified length, and fills it with null values.
       
   362    * @param int Array size
       
   363    * @return array
       
   364    */
       
   365   
       
   366   function create_array($len)
       
   367   {
       
   368     $ret = array();
       
   369     for ( $i = 0; $i < $len; $i++ )
       
   370     {
       
   371       $ret[] = null;
       
   372     }
       
   373     return $ret;
       
   374   }
       
   375   
       
   376   /**
       
   377    * Sets up the tables of phrases, etc.
       
   378    */
       
   379   
       
   380   private function table_setup()
       
   381   {
       
   382     // build our data base here
       
   383 							 
       
   384     $this->conj1[0]  = "are";           $this->conj2[0]  = "am";
       
   385     $this->conj1[1]  = "am";            $this->conj2[1]  = "are";
       
   386     $this->conj1[2]  = "were";          $this->conj2[2]  = "was";
       
   387     $this->conj1[3]  = "was";           $this->conj2[3]  = "were";
       
   388     $this->conj1[4]  = "I";             $this->conj2[4]  = "you";    
       
   389     $this->conj1[5]  = "me";            $this->conj2[5]  = "you";    
       
   390     $this->conj1[6]  = "you";           $this->conj2[6]  = "me";
       
   391     $this->conj1[7]  = "my";            $this->conj2[7]  = "your";    
       
   392     $this->conj1[8]  = "your";          $this->conj2[8]  = "my";
       
   393     $this->conj1[9]  = "mine";          $this->conj2[9]  = "your's";    
       
   394     $this->conj1[10] = "your's";        $this->conj2[10] = "mine";    
       
   395     $this->conj1[11] = "I'm";           $this->conj2[11] = "you're";
       
   396     $this->conj1[12] = "you're";        $this->conj2[12] = "I'm";    
       
   397     $this->conj1[13] = "I've";          $this->conj2[13] = "you've";
       
   398     $this->conj1[14] = "you've";        $this->conj2[14] = "I've";
       
   399     $this->conj1[15] = "I'll";          $this->conj2[15] = "you'll";
       
   400     $this->conj1[16] = "you'll";        $this->conj2[16] = "I'll";
       
   401     $this->conj1[17] = "myself";        $this->conj2[17] = "yourself";
       
   402     $this->conj1[18] = "yourself";      $this->conj2[18] = "myself";
       
   403     
       
   404     // array to post process correct our tenses of pronouns such as "I/me"
       
   405     
       
   406     $this->conj3[0]  = "me am";         $this->conj4[0]  = "I am";
       
   407     $this->conj3[1]  = "am me";         $this->conj4[1]  = "am I";
       
   408     $this->conj3[2]  = "me can";        $this->conj4[2]  = "I can";
       
   409     $this->conj3[3]  = "can me";        $this->conj4[3]  = "can I";
       
   410     $this->conj3[4]  = "me have";       $this->conj4[4]  = "I have";
       
   411     $this->conj3[5]  = "me will";       $this->conj4[5]  = "I will";
       
   412     $this->conj3[6]  = "will me";       $this->conj4[6]  = "will I";
       
   413     
       
   414     
       
   415     // Keywords
       
   416     
       
   417     $this->keyword[ 0]=new Psychotherapist_Key( "CAN YOU",          1,  3);
       
   418     $this->keyword[ 1]=new Psychotherapist_Key( "CAN I",            4,  5);
       
   419     $this->keyword[ 2]=new Psychotherapist_Key( "YOU ARE",          6,  9);
       
   420     $this->keyword[ 3]=new Psychotherapist_Key( "YOU'RE",           6,  9);
       
   421     $this->keyword[ 4]=new Psychotherapist_Key( "I DON'T",          10, 13);
       
   422     $this->keyword[ 5]=new Psychotherapist_Key( "I FEEL",           14, 16);
       
   423     $this->keyword[ 6]=new Psychotherapist_Key( "WHY DON'T YOU", 17, 19);
       
   424     $this->keyword[ 7]=new Psychotherapist_Key( "WHY CAN'T I",     20, 21);
       
   425     $this->keyword[ 8]=new Psychotherapist_Key( "ARE YOU",          22, 24);
       
   426     $this->keyword[ 9]=new Psychotherapist_Key( "I CAN'T",          25, 27);
       
   427     $this->keyword[10]=new Psychotherapist_Key( "I AM",             28, 31);
       
   428     $this->keyword[11]=new Psychotherapist_Key( "I'M",              28, 31);
       
   429     $this->keyword[12]=new Psychotherapist_Key( "YOU",              32, 34);
       
   430     $this->keyword[13]=new Psychotherapist_Key( "I WANT",           35, 39);
       
   431     $this->keyword[14]=new Psychotherapist_Key( "WHAT",             40, 48);
       
   432     $this->keyword[15]=new Psychotherapist_Key( "HOW",              40, 48);
       
   433     $this->keyword[16]=new Psychotherapist_Key( "WHO",              40, 48);
       
   434     $this->keyword[17]=new Psychotherapist_Key( "WHERE",            40, 48);
       
   435     $this->keyword[18]=new Psychotherapist_Key( "WHEN",             40, 48);
       
   436     $this->keyword[19]=new Psychotherapist_Key( "WHY",              40, 48);
       
   437     $this->keyword[20]=new Psychotherapist_Key( "NAME",             49, 50);
       
   438     $this->keyword[21]=new Psychotherapist_Key( "CAUSE",            51, 54);
       
   439     $this->keyword[22]=new Psychotherapist_Key( "SORRY",            55, 58);
       
   440     $this->keyword[23]=new Psychotherapist_Key( "DREAM",            59, 62);
       
   441     $this->keyword[24]=new Psychotherapist_Key( "HELLO",            63, 63);
       
   442     $this->keyword[25]=new Psychotherapist_Key( "HI",               63, 63);
       
   443     $this->keyword[26]=new Psychotherapist_Key( "MAYBE",            64, 68);
       
   444     $this->keyword[27]=new Psychotherapist_Key( "NO",               69, 73);
       
   445     $this->keyword[28]=new Psychotherapist_Key( "YOUR",             74, 75);
       
   446     $this->keyword[29]=new Psychotherapist_Key( "ALWAYS",           76, 79);
       
   447     $this->keyword[30]=new Psychotherapist_Key( "THINK",            80, 82);
       
   448     $this->keyword[31]=new Psychotherapist_Key( "ALIKE",            83, 89);
       
   449     $this->keyword[32]=new Psychotherapist_Key( "YES",              90, 92);
       
   450     $this->keyword[33]=new Psychotherapist_Key( "FRIEND",           93, 98);
       
   451     $this->keyword[34]=new Psychotherapist_Key( "COMPUTER",         99, 105);
       
   452     $this->keyword[35]=new Psychotherapist_Key( "NO KEY FOUND",     106, 112);
       
   453     $this->keyword[36]=new Psychotherapist_Key( "REPEAT INPUT",     113, 116);
       
   454     
       
   455     
       
   456     $this->response[  0]="ELIZA - PHP version ported from Javascript (George Dunlop) code by Dan Fuhry";
       
   457     $this->response[  1]="Don't you believe that I can<*";
       
   458     $this->response[  2]="Perhaps you would like to be able to<*";
       
   459     $this->response[  3]="You want me to be able to<*";
       
   460     $this->response[  4]="Perhaps you don't want to<*";
       
   461     $this->response[  5]="Do you want to be able to<*";
       
   462     $this->response[  6]="What makes you think I am<*";
       
   463     $this->response[  7]="Does it please you to believe I am<*";
       
   464     $this->response[  8]="Perhaps you would like to be<*";
       
   465     $this->response[  9]="Do you sometimes wish you were<*";
       
   466     $this->response[ 10]="Don't you really<*";
       
   467     $this->response[ 11]="Why don't you<*";
       
   468     $this->response[ 12]="Do you wish to be able to<*";
       
   469     $this->response[ 13]="Does that trouble you?";
       
   470     $this->response[ 14]="Tell me more about such feelings.";
       
   471     $this->response[ 15]="Do you often feel<*";
       
   472     $this->response[ 16]="Do you enjoy feeling<*";
       
   473     $this->response[ 17]="Do you really believe I don't<*";
       
   474     $this->response[ 18]="Perhaps in good time I will<@";
       
   475     $this->response[ 19]="Do you want me to<*";
       
   476     $this->response[ 20]="Do you think you should be able to<*";
       
   477     $this->response[ 21]="Why can't you<*";
       
   478     $this->response[ 22]="Why are you interested in whether or not I am<*";
       
   479     $this->response[ 23]="Would you prefer if I were not<*";
       
   480     $this->response[ 24]="Perhaps in your fantasies I am<*";
       
   481     $this->response[ 25]="How do you know you can't<*";
       
   482     $this->response[ 26]="Have you tried?";
       
   483     $this->response[ 27]="Perhaps you can now<*";
       
   484     $this->response[ 28]="Did you come to me because you are<*";
       
   485     $this->response[ 29]="How long have you been<*";
       
   486     $this->response[ 30]="Do you believe it is normal to be<*";
       
   487     $this->response[ 31]="Do you enjoy being<*";
       
   488     $this->response[ 32]="We were discussing you, not me.";
       
   489     $this->response[ 33]="Oh... <*";
       
   490     $this->response[ 34]="You're not really talking about me, are you?";
       
   491     $this->response[ 35]="What would it mean to you if you got<*";
       
   492     $this->response[ 36]="Why do you want<*";
       
   493     $this->response[ 37]="Suppose you got<*";
       
   494     $this->response[ 38]="What if you never got<*";
       
   495     $this->response[ 39]="I sometimes also want<@";
       
   496     $this->response[ 40]="Why do you ask?";
       
   497     $this->response[ 41]="Does that question interest you?";
       
   498     $this->response[ 42]="What answer would please you the most?";
       
   499     $this->response[ 43]="What do you think?";
       
   500     $this->response[ 44]="Are such questions on your mind often?";
       
   501     $this->response[ 45]="What is it that you really want to know?";
       
   502     $this->response[ 46]="Have you asked anyone else?";
       
   503     $this->response[ 47]="Have you asked such questions before?";
       
   504     $this->response[ 48]="What else comes to mind when you ask that?";
       
   505     $this->response[ 49]="Names don't interest me.";
       
   506     $this->response[ 50]="I don't care about names, please go on.";
       
   507     $this->response[ 51]="Is that the real reason?";
       
   508     $this->response[ 52]="Don't any other reasons come to mind?";
       
   509     $this->response[ 53]="Does that reason explain anything else?";
       
   510     $this->response[ 54]="What other reasons might there be?";
       
   511     $this->response[ 55]="Please don't apologise!";
       
   512     $this->response[ 56]="Apologies are not necessary.";
       
   513     $this->response[ 57]="What feelings do you have when you apologise?";
       
   514     $this->response[ 58]="Don't be so defensive!";
       
   515     $this->response[ 59]="What does that dream suggest to you?";
       
   516     $this->response[ 60]="Do you dream often?";
       
   517     $this->response[ 61]="What persons appear in your dreams?";
       
   518     $this->response[ 62]="Are you disturbed by your dreams?";
       
   519     $this->response[ 63]="How are you today.. What would you like to discuss?";
       
   520     $this->response[ 64]="You don't seem quite certain.";
       
   521     $this->response[ 65]="Why the uncertain tone?";
       
   522     $this->response[ 66]="Can't you be more positive?";
       
   523     $this->response[ 67]="You aren't sure?";
       
   524     $this->response[ 68]="Don't you know?";
       
   525     $this->response[ 69]="Are you saying no just to be negative?";
       
   526     $this->response[ 70]="You are being a bit negative.";
       
   527     $this->response[ 71]="Why not?";
       
   528     $this->response[ 72]="Are you sure?";
       
   529     $this->response[ 73]="Why no?";
       
   530     $this->response[ 74]="Why are you concerned about my<*";
       
   531     $this->response[ 75]="What about your own<*";
       
   532     $this->response[ 76]="Can you think of a specific example?";
       
   533     $this->response[ 77]="When?";
       
   534     $this->response[ 78]="What are you thinking of?";
       
   535     $this->response[ 79]="Really, always?";
       
   536     $this->response[ 80]="Do you really think so?";
       
   537     $this->response[ 81]="But you are not sure you<*";
       
   538     $this->response[ 82]="Do you doubt you<*";
       
   539     $this->response[ 83]="In what way?";
       
   540     $this->response[ 84]="What resemblence do you see?";
       
   541     $this->response[ 85]="What does the similarity suggest to you?";
       
   542     $this->response[ 86]="What other connections do you see?";
       
   543     $this->response[ 87]="Could there really be some connection?";
       
   544     $this->response[ 88]="How?";
       
   545     $this->response[ 89]="You seem quite positive.";
       
   546     $this->response[ 90]="Are you Sure?";
       
   547     $this->response[ 91]="I see.";
       
   548     $this->response[ 92]="I understand.";
       
   549     $this->response[ 93]="Why do you bring up the topic of friends?";
       
   550     $this->response[ 94]="Do your friends worry you?";
       
   551     $this->response[ 95]="Do your friends pick on you?";
       
   552     $this->response[ 96]="Are you sure you have any friends?";
       
   553     $this->response[ 97]="Do you impose on your friends?";
       
   554     $this->response[ 98]="Perhaps your love for friends worries you.";
       
   555     $this->response[ 99]="Do computers worry you?";
       
   556     $this->response[100]="Are you talking about me in particular?";
       
   557     $this->response[101]="Are you frightened by machines?";
       
   558     $this->response[102]="Why do you mention computers?";
       
   559     $this->response[103]="What do you think machines have to do with your problems?";
       
   560     $this->response[104]="Don't you think computers can help people?";
       
   561     $this->response[105]="What is it about machines that worries you?";
       
   562     $this->response[106]="Say, do you have any psychological problems?";
       
   563     $this->response[107]="What does that suggest to you?";
       
   564     $this->response[108]="I see.";
       
   565     $this->response[109]="I'm not sure I understand you fully.";
       
   566     $this->response[110]="Come, come, elucidate your thoughts.";
       
   567     $this->response[111]="Can you elaborate on that?";
       
   568     $this->response[112]="That is quite interesting.";
       
   569     $this->response[113]="Why did you repeat yourself?";
       
   570     $this->response[114]="Do you expect a different answer by repeating yourself?";
       
   571     $this->response[115]="Come, come, elucidate your thoughts.";
       
   572     $this->response[116]="Please don't repeat yourself!";
       
   573   }
       
   574   
       
   575 }
       
   576 
       
   577 /**
       
   578  * Keyword class
       
   579  */
       
   580 
       
   581 class Psychotherapist_Key
       
   582 {
       
   583   /**
       
   584    * Phrase to match
       
   585    * @var string
       
   586    */
       
   587    
       
   588   public $key = '';
       
   589   
       
   590   /**
       
   591    * First response to use
       
   592    * @var int
       
   593    */
       
   594   
       
   595   public $idx = 0;
       
   596   
       
   597   /**
       
   598    * Last response to use
       
   599    * @var int
       
   600    */
       
   601   
       
   602   public $end = 0;
       
   603   
       
   604   /**
       
   605    * Response last used time
       
   606    * @var int
       
   607    */
       
   608   
       
   609   public $last = 0;
       
   610   
       
   611   /**
       
   612    * Constructor.
       
   613    * @param string Key
       
   614    * @param int Index
       
   615    * @param int End
       
   616    */
       
   617   
       
   618   public function __construct($key, $idx, $end)
       
   619   {
       
   620     $this->key = $key;
       
   621     $this->idx = $idx;
       
   622     $this->end = $end;
       
   623   }
       
   624 }
       
   625 
       
   626