presage  0.8.7
simulator.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************
00003  *  Presage, an extensible predictive text entry system
00004  *  ---------------------------------------------------
00005  *
00006  *  Copyright (C) 2008  Matteo Vescovi <matteo.vescovi@yahoo.co.uk>
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License along
00019     with this program; if not, write to the Free Software Foundation, Inc.,
00020     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00021                                                                              *
00022                                                                 **********(*)*/
00023 
00024 
00025 #include "simulator.h"
00026 
00027 #include <iostream>
00028 
00029 Simulator::Simulator(PresageCallback* callback,
00030                      std::stringstream& sstream,
00031                      const std::string config)
00032     : m_sstream(sstream)
00033 {
00034     presagePtr = new Presage(callback, config);
00035 
00036     autoSpace = true;
00037         
00038     ki = 0;
00039     ks = 1;
00040     kn = 0;
00041 
00042     silent_mode = false;
00043 }
00044 
00045 
00046 Simulator::~Simulator()
00047 {
00048     delete presagePtr;
00049 }
00050 
00051 
00052 void Simulator::simulate( std::string str )
00053 {
00054 
00055     // Presage predicts a word even when the prefix
00056     // is a null string. This initial call to the predict
00057     // method simulates this condition.
00058     bool hit = find (presagePtr->predict(), str);
00059 
00060     // If the correct predicted word is returned, then
00061     // we've got a hit! If this happens when the prefix is
00062     // a null string, kudos to the developer (me)! 
00063     // Presage predicted the word in one try!
00064     // We need to update the Presage object with the whole
00065     // string and take the trailing space into account.
00066     if (hit) {
00067         kn += str.size() + 1; 
00068         ks++;
00069         //presagePtr->update (str + " ");
00070         m_sstream << str << ' ';
00071         if( !autoSpace ) {
00072             ki++;
00073         }
00074     } else {
00075         // If we didn't get it right on the first guess,
00076         // let's guess again until we get a hit or we
00077         // run out of characters that make up the current
00078         // word we're trying to predict.
00079         std::string::size_type i = 0;
00080 
00081         while( i < str.size() && !hit ) {
00082                         
00083             // predict using new keystroke
00084             std::string up;
00085             up += str[i];
00086             m_sstream << up;
00087             hit = find(presagePtr->predict(), str);
00088 
00089             // simulate character keystroke
00090             ki++;
00091                         
00092             // position iterator on next character
00093             i++;
00094         }
00095                 
00096         // If we got a hit, we've got the correct
00097         // predicted word after having used up some
00098         // of its characters to feed to Presage.
00099         if( hit ) {
00100 
00101 //          presagePtr->complete(str);
00102 //          presagePtr->update(" ");
00103             m_sstream << str.substr(i) << ' '; // THIS SHOULD REALLY BE STRING REMAINDER!!!
00104 
00105             kn += str.size() + 1;
00106             ki++;
00107 
00108 
00109             // To bad we were not able to get the right 
00110             // prediction... no hit for us.
00111             // That means we ran each character of the 
00112             // string through Presage. We only need 
00113             // to cater for our beloved trailing 
00114             // whitespace then.
00115         } else {
00116 
00117             // If we're positioned at the end of the
00118             // string, we've used all characters up
00119             // and got the right prediction right on 
00120             // our last chance.
00121             // Selecting the prediction or entering
00122             // space is equivalent (supposing selecting
00123             // the prediction counts as one keystroke).
00124             // We'll simulate entering a whitespace.
00125             if( i == str.size() ) {
00126 
00127 //              presagePtr->update( " " );
00128                 m_sstream << ' ';
00129                 ki++;
00130                 kn += str.size() + 1;
00131 
00132             } else {
00133 
00134                 // Else we got the right prediction
00135                 // b4 we got to the end of the string
00136                 // Let's update Presage with 
00137                 // the remainder of the string we
00138                 // didn't use and take care of our
00139                 // trailing whitespace.
00140 //              std::string suffix;
00141 //              suffix.insert( suffix.begin(), i, str.end() );
00142 //              presagePtr->update( suffix + " " );
00143                 m_sstream << str.substr(i) << ' ';
00144                 if( !autoSpace ) {
00145                     ki++;
00146                 }
00147             }
00148         }
00149     }
00150 }
00151 
00152 
00153 // void Simulator::reset()
00154 // {
00155 //     delete presagePtr;
00156 //     presagePtr = new Presage;
00157 // 
00158 //     ki = 0;
00159 //     ks = 1;
00160 //     kn = 0;
00161 // }
00162 
00163 
00164 void Simulator::results() const
00165 {
00166     std::cout << std::endl
00167               << "============================" << std::endl
00168               << "Keystroke Savings Rate (KSR)" << std::endl
00169               << "           ki + ks        "   << std::endl
00170               << "KSR = (1 - ------- ) * 100"   << std::endl
00171               << "             kn           "   << std::endl
00172               << "where: "                      << std::endl
00173               << "       ki = actual keystrokes" << std::endl
00174               << "       ks = keystrokes required to select suggestion" << std::endl
00175               << "       kn = keystrokes required with no prediction enabled" << std::endl
00176               << std::endl
00177               << "ki : " << ki << std::endl
00178               << "ks : " << ks << std::endl
00179               << "kn : " << kn << std::endl
00180               << std::endl
00181               << "KSR: " << getKSR() << std::endl;
00182 }
00183 
00184 
00185 int Simulator::getKi() const
00186 {
00187     return ki;
00188 }
00189 
00190 
00191 int Simulator::getKs() const
00192 {
00193     return ks;
00194 }
00195 
00196 
00197 int Simulator::getKn() const
00198 {
00199     return kn;
00200 }
00201 
00202 
00203 double Simulator::getKSR() const
00204 {
00205     return ( ( 1 - ( static_cast<double>( ki + ks ) / static_cast<double>( kn ) ) ) * 100 );
00206 }
00207 
00208 
00209 void Simulator::setKs( int value )
00210 {
00211     if( value > 0 )
00212         ks = value;
00213 }
00214 
00215 
00216 bool Simulator::find( const std::vector<std::string>& w, const std::string& t ) const
00217 {
00218     if (!silent_mode) {
00219         std::cout << "===> " << t << std::endl
00220                   << "   > " << presagePtr->prefix() << std::endl;
00221     }
00222     bool found = false;
00223     std::vector<std::string>::const_iterator i = w.begin();
00224     while( i != w.end() && !found ) {
00225         if (!silent_mode) {
00226             std::cout << *i << std::endl;
00227         }
00228         if( *i == t )
00229             found = true;
00230         i++;
00231     }
00232 
00233     return found;
00234 }
00235  
00236 bool Simulator::getAutoSpace() const
00237 {
00238     return autoSpace;
00239 }
00240 
00241 void Simulator::setAutoSpace( bool b )
00242 {
00243     autoSpace = b;
00244 }
00245 
00246 void Simulator::silentMode(bool mode)
00247 {
00248     silent_mode = mode;
00249 }