presage 0.9.1
presage.cpp
Go to the documentation of this file.
1
2/******************************************************
3 * Presage, an extensible predictive text entry system
4 * ---------------------------------------------------
5 *
6 * Copyright (C) 2008 Matteo Vescovi <matteo.vescovi@yahoo.co.uk>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 **********(*)*/
23
24
25#include "presage.h"
26
27#include "core/profileManager.h"
30#include "core/selector.h"
32
42
52
54{
55 delete selector;
56 delete predictorActivator;
57 delete contextTracker;
58 delete predictorRegistry;
59 delete profileManager;
60}
61
62std::vector<std::string> Presage::predict ()
63{
64 std::vector<std::string> result;
65
66 unsigned int multiplier = 1;
67 Prediction prediction = predictorActivator->predict(multiplier++, 0);
68 result = selector->select(prediction);
69
70 Prediction previous_prediction = prediction;
71 while ((result.size() < (selector->get_suggestions()))
72 && (prediction = predictorActivator->predict(multiplier++, 0)).size() > previous_prediction.size()) {
73 // while the number of predicted tokens is lower than desired,
74 // search harder (i.e. higher multiplier) for a prediction of
75 // sufficient size (i.e. that satisfies selector), as long as
76 // the result of current prediction is greater than the
77 // previous prediction (i.e. we are finding new tokens).
78 result = selector->select(prediction);
79 previous_prediction = prediction;
80 }
81
83
84 return result;
85}
86
87std::multimap<double, std::string> Presage::predict (std::vector<std::string> filter)
88{
89 std::multimap<double, std::string> result;
90
91 std::vector<std::string> selection;
92 const char** internal_filter = 0;
93 if(filter.size()>0)
94 {
95 // convert filter to internal representation - currently a null
96 // terminated const char**
97 internal_filter = new const char*[filter.size() + 1];
98 for (std::vector<std::string>::size_type i = 0; i < filter.size(); i++) {
99 internal_filter[i] = filter[i].c_str();
100 }
101 internal_filter[filter.size()] = 0;
102 }
103
104 unsigned int multiplier = 1;
105 Prediction prediction = predictorActivator->predict(multiplier++, internal_filter);
106 selection = selector->select(prediction);
107
108 Prediction previous_prediction = prediction;
109 while ((selection.size() < (selector->get_suggestions()))
110 && (prediction = predictorActivator->predict(multiplier++, internal_filter)).size() > previous_prediction.size()) {
111 // while the number of predicted tokens is lower than desired,
112 // search harder (i.e. higher multiplier) for a prediction of
113 // sufficient size (i.e. that satisfies selector), as long as
114 // the selection of current prediction is greater than the
115 // previous prediction (i.e. we are finding new tokens).
116 selection = selector->select(prediction);
117 previous_prediction = prediction;
118 }
119
120 delete[] internal_filter;
121
122 for (std::vector<std::string>::const_iterator it = selection.begin();
123 it != selection.end();
124 it++) {
125 std::pair<const double, std::string> p(prediction.getSuggestion(*it).getProbability(),
126 (*it));
127 result.insert(p);
128 }
129
131
132 return result;
133}
134
135void Presage::learn(const std::string text)
136{
137 contextTracker->learn(text); // TODO: can pass additional param to
138 // learn to specify offline learning
139}
140
145
146std::string Presage::completion (const std::string str)
147{
148 // There are two types of completions: normal and erasing.
149 // normal_completion = prefix + remainder
150 // erasing_completion = eraser + prefix + remainder
151 //
152 // or, given that token = prefix + remainder
153 // normal_completion = token
154 // erasing_completion = eraser + token
155 //
156 // where eraser = ^H+ (one or more backspace characters)
157 //
158 // offset to first non ^H character in completion (^H are inserted
159 // by abbreviation expansion predictor to erase abbreviation from
160 // stream)
161 //
162 std::string result;
163
164 std::string::size_type offset = str.find_first_not_of('\b');
165 if (offset == 0) {
166 // normal completion,
167 // ensure that current prefix is a substring of completion
168 // token and set result
169 //
171 std::string prefix = contextTracker->getPrefix();
172 result = str.substr(prefix.size());
173 } else {
174 std::string message = "[Presage] Error: token '";
175 message += str;
176 message += "' does not match prefix: ";
177 message += contextTracker->getPrefix();
179 }
180 } else {
181 // erasing completion,
182 // pass it to tracker in its entirety
183 //
184 result = str;
185 }
186
187 // if (append_trailing_space_is_on()) // TODO: make this configurable
188 result += ' ';
189
190 return result;
191}
192
193std::string Presage::context ()
194{
196}
197
199{
201}
202
203std::string Presage::prefix ()
204{
205 return contextTracker->getPrefix();
206}
207
208std::string Presage::config (const std::string variable)
209{
210 return configuration->find (variable)->get_value ();
211}
212
213void Presage::config (const std::string variable, const std::string value)
214{
215 configuration->insert (variable, value);
216}
217
222
223
224
229
259
260#define presage_exception_handler(CODE) \
261 try \
262 { \
263 CODE; \
264 } \
265 catch (PresageException& ex) \
266 { \
267 return ex.code (); \
268 } \
269 return PRESAGE_OK;
270
271#define presage_exception_handler_with_result(CODE) \
272 try \
273 { \
274 CODE; \
275 } \
276 catch (PresageException& ex) \
277 { \
278 (*result) = 0; \
279 return ex.code (); \
280 } \
281 return PRESAGE_OK;
282
283static char* alloc_c_str (const std::string& str)
284{
285 char* result_c_str = (char*) malloc (str.size() + 1);
286 if (result_c_str)
287 strcpy (result_c_str, str.c_str());
288 return result_c_str;
289}
290
292 void* past_stream_cb_arg,
294 void* future_stream_cb_arg,
295 presage_t* result)
296{
298 (
299 (*result) = (presage_t) malloc (sizeof (_presage));
300 if (*result != NULL)
301 {
302 (*result)->presage_callback_object = new CPresageCallback (past_stream_cb,
303 past_stream_cb_arg,
304 future_stream_cb,
305 future_stream_cb_arg);
306 (*result)->presage_object = new Presage ((*result)->presage_callback_object);
307 }
308
309 );
310}
311
313 void* past_stream_cb_arg,
315 void* future_stream_cb_arg,
316 const char* config,
317 presage_t* result)
318{
320 (
321 (*result) = (presage_t) malloc (sizeof (_presage));
322 if (*result != NULL)
323 {
324
325 (*result)->presage_callback_object = new CPresageCallback (past_stream_cb,
326 past_stream_cb_arg,
327 future_stream_cb,
328 future_stream_cb_arg);
329 (*result)->presage_object = new Presage ((*result)->presage_callback_object, config);
330 }
331 );
332}
333
335{
336 if (prsg)
337 {
338 delete prsg->presage_object;
339 delete prsg->presage_callback_object;
340
341 free (prsg);
342 }
343}
344
345void presage_free_string (char* str)
346{
347 free (str);
348}
349
351{
352 if (strs) {
353 for (size_t t = 0; strs[t] != 0; t++) {
354 free (strs[t]);
355 }
356 free (strs);
357 }
358}
359
361{
363 (
364 std::vector<std::string> prediction = prsg->presage_object->predict();
365
366 size_t prediction_c_str_size = prediction.size() + 1;
367 char** prediction_c_str = (char**) malloc (prediction_c_str_size * sizeof(char*));
368 if (prediction_c_str != NULL)
369 {
370 memset (prediction_c_str, 0, prediction_c_str_size * sizeof(char*));
371
372 size_t i = 0;
373 while (i < prediction_c_str_size - 1) {
374 prediction_c_str[i] = (char*) malloc (prediction[i].size() + 1);
375 if (prediction_c_str[i] != NULL)
376 strcpy (prediction_c_str[i], prediction[i].c_str());
377 i++;
378 }
379 prediction_c_str[i] = 0;
380 }
381
382 *result = prediction_c_str;
383 );
384}
385
387{
389 (
390 prsg->presage_object->learn (text);
391 );
392}
393
394presage_error_code_t presage_completion (presage_t prsg, const char* token, char** result)
395{
397 (
398 *result = alloc_c_str (prsg->presage_object->completion (token));
399 );
400}
401
403{
405 (
406 *result = alloc_c_str (prsg->presage_object->context ());
407 );
408}
409
417
419{
421 (
422 *result = alloc_c_str (prsg->presage_object->prefix ());
423 );
424}
425
426presage_error_code_t presage_config (presage_t prsg, const char* variable, char** result)
427{
429 (
430 *result = alloc_c_str (prsg->presage_object->config (variable));
431 );
432}
433
434presage_error_code_t presage_config_set (presage_t prsg, const char* variable, const char* value)
435{
437 (
438 prsg->presage_object->config (variable, value)
439 );
440}
441
virtual ~CPresageCallback()
Definition presage.cpp:243
CPresageCallback(_presage_callback_get_past_stream past, void *past_arg, _presage_callback_get_future_stream future, void *future_arg)
Definition presage.cpp:233
void * m_get_past_stream_cb_arg
Definition presage.cpp:255
void * m_get_future_stream_cb_arg
Definition presage.cpp:257
_presage_callback_get_past_stream m_get_past_stream_cb
Definition presage.cpp:254
_presage_callback_get_future_stream m_get_future_stream_cb
Definition presage.cpp:256
std::string get_past_stream() const
Definition presage.cpp:245
std::string get_future_stream() const
Definition presage.cpp:249
void insert(const std::string &variable, const std::string &value)
Variable * find(const std::string &variable) const
Tracks user interaction and context.
std::string getPastStream() const
bool isCompletionValid(const std::string &) const
const PresageCallback * callback(const PresageCallback *callback)
std::string getPrefix() const
void learn(const std::string &text) const
Learn from text.
Suggestion getSuggestion(int=0) const
size_t size() const
Prediction predict(unsigned int multiplier, const char **filter)
Presage, the intelligent predictive text entry platform.
Definition presage.h:107
bool context_change()
Returns true if a context change occured.
Definition presage.cpp:198
Configuration * configuration
Definition presage.h:247
std::string completion(std::string str)
Request presage to return the completion string for the given predicted token.
Definition presage.cpp:146
std::string config(const std::string variable)
Gets the value of specified configuration variable.
Definition presage.cpp:208
std::vector< std::string > predict()
Obtain a prediction.
Definition presage.cpp:62
PresageCallback * callback(PresageCallback *callback)
Callback getter/setter.
Definition presage.cpp:141
void learn(const std::string text)
Learn from text offline.
Definition presage.cpp:135
Selector * selector
Definition presage.h:251
ContextTracker * contextTracker
Definition presage.h:249
~Presage()
Definition presage.cpp:53
PredictorRegistry * predictorRegistry
Definition presage.h:248
void save_config()
Save current configuration to file.
Definition presage.cpp:218
Presage(PresageCallback *callback)
Definition presage.cpp:33
std::string context()
Returns the text entered so far.
Definition presage.cpp:193
ProfileManager * profileManager
Definition presage.h:246
std::string prefix()
Returns the current prefix.
Definition presage.cpp:203
PredictorActivator * predictorActivator
Definition presage.h:250
void save_profile() const
Configuration * get_configuration()
std::vector< std::string > select(Prediction)
Definition selector.cpp:55
size_t get_suggestions() const
Definition selector.cpp:246
double getProbability() const
std::string get_value() const
Definition variable.cpp:62
const char *(* _presage_callback_get_past_stream)(void *)
const char *(* _presage_callback_get_future_stream)(void *)
std::string config
presage_error_code_t
@ PRESAGE_TOKEN_PREFIX_MISMATCH_ERROR
presage_error_code_t presage_prefix(presage_t prsg, char **result)
Definition presage.cpp:418
void presage_free_string_array(char **strs)
Definition presage.cpp:350
presage_error_code_t presage_context(presage_t prsg, char **result)
Definition presage.cpp:402
presage_error_code_t presage_completion(presage_t prsg, const char *token, char **result)
Definition presage.cpp:394
presage_error_code_t presage_new_with_config(_presage_callback_get_past_stream past_stream_cb, void *past_stream_cb_arg, _presage_callback_get_future_stream future_stream_cb, void *future_stream_cb_arg, const char *config, presage_t *result)
Definition presage.cpp:312
presage_error_code_t presage_predict(presage_t prsg, char ***result)
Definition presage.cpp:360
presage_error_code_t presage_learn(presage_t prsg, const char *text)
Definition presage.cpp:386
presage_error_code_t presage_new(_presage_callback_get_past_stream past_stream_cb, void *past_stream_cb_arg, _presage_callback_get_future_stream future_stream_cb, void *future_stream_cb_arg, presage_t *result)
Definition presage.cpp:291
#define presage_exception_handler(CODE)
Definition presage.cpp:260
presage_error_code_t presage_config_set(presage_t prsg, const char *variable, const char *value)
Definition presage.cpp:434
presage_error_code_t presage_context_change(presage_t prsg, int *result)
Definition presage.cpp:410
#define presage_exception_handler_with_result(CODE)
Definition presage.cpp:271
static char * alloc_c_str(const std::string &str)
Definition presage.cpp:283
presage_error_code_t presage_config(presage_t prsg, const char *variable, char **result)
Definition presage.cpp:426
void presage_free(presage_t prsg)
Definition presage.cpp:334
void presage_free_string(char *str)
Definition presage.cpp:345
presage_error_code_t presage_save_config(presage_t prsg)
Definition presage.cpp:442
PresageCallback * presage_callback_object
Definition presage.cpp:226
Presage * presage_object
Definition presage.cpp:227