- Timestamp:
- 03/04/10 12:21:26 (14 years ago)
- Location:
- vtcross/trunk/src
- Files:
-
- 3 modified
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
vtcross/trunk/src/cognitive_engines/CBR.cpp
r518 r544 15 15 */ 16 16 17 /*! This header contains the declaration and a full implementation of 18 * the CBR class - the default CROSS case-based reasoner, which can be used as a 19 * backend for cognitive engines. 20 */ 21 22 23 24 #ifndef CBR_H 25 #define CBR_H 26 27 #include <cstdlib> 28 #include <cstring> 29 #include <cstdio> 30 #include <stdint.h> 31 #include <string> 32 33 #include <sqlite3.h> 34 35 #include "vtcross/common.h" 36 #include "vtcross/debug.h" 37 #include "vtcross/error.h" 17 /*! This file contains the default implementation of the CBR class, defined in 18 * the cbr.h include file. This implementation is compiled into a static 19 * library which can be used as as backend for any cognitive engine. */ 20 21 22 #include "vtcross/cbr.h" 23 38 24 39 25 using namespace std; 40 41 42 #define DATABASENAME "cross_cbr"43 26 44 27 … … 55 38 return 0; 56 39 } 57 58 59 /*! \brief Case-Based Reasoner class declaration.60 *61 * The CBR class is designed to used as either as-is, or as a parent class. All62 * functions are declared virtual, and internal members are 'protected' rather63 * than private. If you require functionality in a CBR not specifically provided64 * by this class, include this header in your source file, create a new class65 * that derives from CBR, and implement your desired functionality over the66 * original virtual functions as necessary.67 */68 class CBR69 {70 public:71 /*! \brief Constructors for the CBR class.72 *73 * Note that the default constructor74 * must be defined inline here so that super-calls from child classes75 * don't fail (i.e. we cannot rely on the compiler-provided constructor. */76 CBR(){};77 CBR(string _filename, string _tablename, string _cols[], uint32_t _len);78 CBR(string _filename, string _tablename, string _cols[], \79 string _primcols[], uint32_t _len, uint32_t _primlen);80 81 /*! \brief Destructors for the CBR class.82 *83 * Destructor for the CBR class. Note that this destructor will be84 * called automatically by any derived classes, and so child classes85 * should not repeat the freeing actions performed in this function. */86 virtual ~CBR();87 88 /*! \brief Open/Create a sqlite database for the CBR.89 *90 * This function opens the CROSS database, or if it has not been91 * created yet, creates it. */92 virtual int32_t OpenDatabase();93 94 /*! \brief Execute a sqlite command.95 *96 * Construct and execute a sqlite3 command and pass the return code back. */97 virtual int32_t ExecuteCommand();98 99 /*! \brief Search the sqlite3 database.100 *101 * Execute a sqlite3 search command and store the results in the passed102 * retvals argument. */103 virtual int32_t ExecuteSearchCommand(float *_retvals);104 105 /*! \brief Print the CROSS sqlite database. */106 virtual void Print();107 108 /*! \brief Search the CBR database.109 *110 * Search the CROSS database for specific fields and store the results111 * in the passed retvals argument. */112 virtual int32_t Search(string _names[], int32_t *_ops, float *_vals, \113 uint32_t _n, float *_retvals);114 virtual int32_t SearchSum(string _name, float *_retvals);115 virtual int32_t SearchRand(string _names[], int32_t *_ops, float *_vals, uint32_t _n, \116 float *_retvals);117 118 /*! \brief Update an entry in the CBR database. */119 virtual int32_t Update(string _where[], string _set[], float *_wherevals, \120 float *_setvals, uint32_t _wherelen, uint32_t _setlen);121 122 /*! \brief Add a row to the CROSS sqlite3 database. */123 virtual int32_t AddRow(string _cols[], float *_vals, uint32_t _len);124 125 protected:126 string filename;127 string tablename;128 string command;129 130 sqlite3 *db;131 uint32_t numColumns;132 };133 40 134 41 … … 411 318 } 412 319 413 #endif -
vtcross/trunk/src/cognitive_engines/CognitiveEngine.cpp
r532 r544 309 309 310 310 SendMessage(commandSocketFD, "receive_config_ack"); 311 312 BuildCognitiveEngine();313 311 } 314 312 -
vtcross/trunk/src/cognitive_engines/Makefile.am
r534 r544 19 19 AM_CXXFLAGS = -Wall -g 20 20 21 noinst_LIBRARIES = libce.a 21 noinst_LIBRARIES = libce.a libcbr.a 22 22 libce_a_SOURCES = CognitiveEngine.cpp 23 libcbr_a_SOURCES = CBR.cpp 23 24 24 25 SUBDIRS = . CBR_CE DSA_CE OSSIE_DEMO_CE -
vtcross/trunk/src/include/vtcross/cbr.h
r518 r544 21 21 22 22 23 24 23 #ifndef CBR_H 25 24 #define CBR_H … … 37 36 #include "vtcross/error.h" 38 37 39 using namespace std;40 41 38 42 39 #define DATABASENAME "cross_cbr" 43 44 45 /* This is an internal debugging function used by some sqlite3 function calls.46 * It is not used otherwise in the CROSS codebase. */47 int32_t48 callback(void *notUsed, int32_t argc, char **argv, char **azColName)49 {50 for(size_t i = 0; i < argc; i++) {51 LOG("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");52 }53 LOG("\n");54 55 return 0;56 }57 40 58 41 … … 75 58 * don't fail (i.e. we cannot rely on the compiler-provided constructor. */ 76 59 CBR(){}; 77 CBR(st ring _filename, string _tablename,string _cols[], uint32_t _len);78 CBR(st ring _filename, string _tablename,string _cols[], \79 st ring _primcols[], uint32_t _len, uint32_t _primlen);60 CBR(std::string _filename, std::string _tablename, std::string _cols[], uint32_t _len); 61 CBR(std::string _filename, std::string _tablename, std::string _cols[], \ 62 std::string _primcols[], uint32_t _len, uint32_t _primlen); 80 63 81 64 /*! \brief Destructors for the CBR class. … … 110 93 * Search the CROSS database for specific fields and store the results 111 94 * in the passed retvals argument. */ 112 virtual int32_t Search(st ring _names[], int32_t *_ops, float *_vals, \95 virtual int32_t Search(std::string _names[], int32_t *_ops, float *_vals, \ 113 96 uint32_t _n, float *_retvals); 114 virtual int32_t SearchSum(st ring _name, float *_retvals);115 virtual int32_t SearchRand(st ring _names[], int32_t *_ops, float *_vals, uint32_t _n, \97 virtual int32_t SearchSum(std::string _name, float *_retvals); 98 virtual int32_t SearchRand(std::string _names[], int32_t *_ops, float *_vals, uint32_t _n, \ 116 99 float *_retvals); 117 100 118 101 /*! \brief Update an entry in the CBR database. */ 119 virtual int32_t Update(st ring _where[],string _set[], float *_wherevals, \102 virtual int32_t Update(std::string _where[], std::string _set[], float *_wherevals, \ 120 103 float *_setvals, uint32_t _wherelen, uint32_t _setlen); 121 104 105 122 106 /*! \brief Add a row to the CROSS sqlite3 database. */ 123 virtual int32_t AddRow(st ring _cols[], float *_vals, uint32_t _len);107 virtual int32_t AddRow(std::string _cols[], float *_vals, uint32_t _len); 124 108 125 109 protected: 126 st ring filename;127 st ring tablename;128 st ring command;110 std::string filename; 111 std::string tablename; 112 std::string command; 129 113 130 114 sqlite3 *db; … … 132 116 }; 133 117 134 135 CBR::CBR(string _filename, string _tablename, string _cols[], uint32_t _len)136 {137 /* Store database properties. */138 filename = _filename;139 tablename = _tablename;140 numColumns = _len;141 142 /* Create the database (or open it if it already exists). */143 OpenDatabase();144 145 /* Generate the command that will create the initial table within the146 * CROSS database. */147 command = "CREATE TABLE " + tablename + "(";148 for(size_t i = 0; i < numColumns; i++) {149 command += _cols[i] + " FLOAT";150 151 /* If this column is not the last entry, add a comma to the command in152 * preperation for the next entry. */153 if(i != numColumns - 1)154 command += ", ";155 }156 command += ");";157 158 /* Execute the generated command. At this point, the database is ready for159 * use. */160 ExecuteCommand();161 }162 163 164 CBR::CBR(string _filename, string _tablename, string _cols[], \165 string _primcols[], uint32_t _len, uint32_t _primlen)166 {167 /* Store database properties. */168 filename = _filename;169 tablename = _tablename;170 numColumns = _len;171 172 /* Create the database (or open it if it already exists). */173 OpenDatabase();174 175 /* Generate the command that will create the initial table within the176 * CROSS database with primary keys. */177 command = "CREATE TABLE " + tablename + "(";178 for(size_t i = 0; i < numColumns; i++) {179 command += _cols[i] + " FLOAT, ";180 }181 182 command += "PRIMARY KEY (";183 for(size_t j = 0; j < _primlen; j++) {184 command += _primcols[j];185 186 /* If this column is not the last entry, add a comma to the command in187 * preperation for the next entry. */188 if(j != _primlen - 1)189 command += ", ";190 }191 command += "));";192 193 /* Execute the generated command. At this point, the database is ready for194 * use. */195 ExecuteCommand();196 }197 198 199 CBR::~CBR()200 {201 /* Generate the sqlite command to delete a table and all of its contents,202 * and then execute it. */203 command = "drop table " + tablename;204 ExecuteCommand();205 206 /* Tell sqlite to clean up the database. */207 command = "vacuum";208 ExecuteCommand();209 }210 211 212 int32_t213 CBR::OpenDatabase()214 {215 int32_t rc = sqlite3_open(filename.c_str(), &db);216 if(rc) {217 WARNING("Can't open database: %s\n", sqlite3_errmsg(db));218 sqlite3_close(db);219 exit(1);220 }221 222 return rc;223 }224 225 226 int32_t227 CBR::ExecuteCommand()228 {229 char *zErrMsg = 0;230 231 int32_t rc = sqlite3_exec(db, command.c_str(), callback, 0, &zErrMsg);232 if(rc != SQLITE_OK) {233 WARNING("SQL error: %s: %s\n", zErrMsg, command.c_str());234 sqlite3_free(zErrMsg);235 }236 237 return rc;238 }239 240 241 int32_t242 CBR::ExecuteSearchCommand(float *_retvals)243 {244 sqlite3_stmt *pStatement;245 246 int32_t rc = sqlite3_prepare_v2(db, command.c_str(), -1, &pStatement, NULL);247 if(rc == SQLITE_OK) {248 if(sqlite3_step(pStatement) == SQLITE_ROW) {249 for(size_t i = 0; i < numColumns; ++i) {250 _retvals[i] = sqlite3_column_double(pStatement, i);251 }252 } else {253 LOG("CBR:: No matched results returning default.\n");254 rc = 31337;255 }256 } else {257 WARNING("CBR:: Error executing SQL statement. rc = %i\n%s\n", rc, command.c_str());258 }259 260 sqlite3_finalize(pStatement);261 262 return rc;263 }264 265 266 void267 CBR::Print()268 {269 /* Generate the sqlite command to print the database, which is effectively a270 * 'select all elements' command, and then execute it. */271 command = "select " + tablename + ".* from " + tablename + ";";272 273 ExecuteCommand();274 LOG("database %s, table %s:\n", filename.c_str(), tablename.c_str());275 }276 277 278 int32_t279 CBR::Search(string _names[], int32_t *_ops, float *_vals, uint32_t _n, \280 float *_retvals)281 {282 char str_buffer[64];283 const string ops_str[] = {"==", "!=", ">", ">=", "<", "<="};284 285 command = "select " + tablename + ".* from " + tablename + " where ";286 287 for(size_t i = 0; i < _n; i++) {288 /* Make sure that the passed ops value is valid. */289 if((_ops[i] < 0) || (_ops[i] > 5)) {290 ERROR(1, "Error: cbr_search(), invalid ops id : %d\n", _ops[i]);291 }292 293 command += _names[i] + ops_str[_ops[i]];294 295 296 sprintf(str_buffer, "%E", _vals[i]);297 command += string(str_buffer);298 299 if(i < _n - 1)300 command += " AND ";301 else302 command += " order by utility desc;";303 304 }305 //LOG("CBR::Search - command: %s\n", command.c_str());306 307 return ExecuteSearchCommand(_retvals);308 }309 310 311 int32_t312 CBR::SearchSum(string _name, float *_retvals)313 {314 command = "select SUM(" + tablename + "." + _name + ") from " + tablename + ";";315 316 return ExecuteSearchCommand(_retvals);317 }318 319 320 int32_t321 CBR::SearchRand(string _names[], int32_t *_ops, float *_vals, uint32_t _n, \322 float *_retvals)323 {324 char str_buffer[64];325 const char *ops_str[] = {"==", "!=", ">", ">=", "<", "<="};326 327 command = "select " + tablename + ".* from " + tablename + " where ";328 329 for(size_t i = 0; i < _n; i++) {330 /* Make sure that the passed ops value is valid. */331 if((_ops[i] < 0) || (_ops[i] > 5)) {332 ERROR(1, "Error: cbr_search(), invalid ops id : %d\n", _ops[i]);333 }334 335 command += _names[i] + ops_str[_ops[i]];336 337 sprintf(str_buffer, "%E", _vals[i]);338 command += str_buffer;339 340 if(i < _n - 1)341 command += " AND ";342 else343 command += " order by RAND();";344 }345 346 return ExecuteSearchCommand(_retvals);347 }348 349 350 int32_t351 CBR::Update(string _where[], string _set[], float *_wherevals, float *_setvals,352 uint32_t _wherelen, uint32_t _setlen)353 {354 char str_buffer[64];355 356 /* Generate the command to update the table. */357 command = "UPDATE " + tablename + " SET ";358 359 for(size_t i = 0; i < _setlen; i++) {360 command += _set[i] + " = ";361 sprintf(str_buffer, "%f", _setvals[i]);362 command += string(str_buffer) + " ";363 364 if(i != _setlen - 1)365 command += ", ";366 }367 command += " WHERE ";368 369 for(size_t j = 0; j < _wherelen; j++) {370 command += _where[j] + " = ";371 sprintf(str_buffer, "%f", _wherevals[j]);372 command += string(str_buffer) + " ";373 374 if(j != _wherelen - 1)375 command += "AND ";376 }377 command += ";";378 379 return ExecuteCommand();380 }381 382 383 int32_t384 CBR::AddRow(string _cols[], float *_vals, uint32_t _len)385 {386 char str_buffer[64];387 388 command = "insert into " + tablename + " (";389 390 for(size_t i = 0; i < _len; i++) {391 command += _cols[i];392 393 if(i != numColumns - 1)394 command += ", ";395 }396 command += ") values(";397 398 for(size_t j = 0; j < _len; j++) {399 // TODO I have no idea what the below question is about.400 // ???? how to fill the values if numColumns != _len401 // assume = in the following402 sprintf(str_buffer, "%f", _vals[j]);403 command += str_buffer;404 405 if(j != numColumns - 1)406 command += ", ";407 }408 command += ");";409 410 return ExecuteCommand();411 }412 413 118 #endif