feature/kb #14
@ -1,11 +1,5 @@
|
||||
#include "knowledge_base.h"
|
||||
#include "models/action.h"
|
||||
#include "models/entity.h"
|
||||
#include "models/error.h"
|
||||
#include "models/fact.h"
|
||||
#include "models/rule.h"
|
||||
#include "models/suggest_action.h"
|
||||
#include "models/verb.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
@ -119,6 +113,25 @@ void obelisk::KnowledgeBase::addVerbs(std::vector<obelisk::Verb>& verbs)
|
||||
}
|
||||
}
|
||||
|
||||
void obelisk::KnowledgeBase::addActions(std::vector<obelisk::Action>& actions)
|
||||
{
|
||||
for (auto& action : actions)
|
||||
{
|
||||
try
|
||||
{
|
||||
action.insert(dbConnection_);
|
||||
}
|
||||
catch (obelisk::DatabaseConstraintException& exception)
|
||||
{
|
||||
// ignore unique constraint error
|
||||
if (std::strcmp(exception.what(), "UNIQUE constraint failed: action.name") != 0)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void obelisk::KnowledgeBase::addFacts(std::vector<obelisk::Fact>& facts)
|
||||
{
|
||||
for (auto& fact : facts)
|
||||
@ -150,9 +163,14 @@ void obelisk::KnowledgeBase::getVerb(obelisk::Verb& verb)
|
||||
verb.selectByName(dbConnection_);
|
||||
}
|
||||
|
||||
void obelisk::KnowledgeBase::getAction(obelisk::Action& action)
|
||||
{
|
||||
action.selectByName(dbConnection_);
|
||||
}
|
||||
|
||||
void obelisk::KnowledgeBase::getFact(obelisk::Fact& fact)
|
||||
{
|
||||
fact.selectByName(dbConnection_);
|
||||
fact.selectById(dbConnection_);
|
||||
}
|
||||
|
||||
void obelisk::KnowledgeBase::getFloat(float& result1, float& result2, double var)
|
@ -1,8 +1,11 @@
|
||||
#ifndef OBELISK_KNOWLEDGE_BASE_H
|
||||
#define OBELISK_KNOWLEDGE_BASE_H
|
||||
|
||||
#include "models/action.h"
|
||||
#include "models/entity.h"
|
||||
#include "models/fact.h"
|
||||
#include "models/rule.h"
|
||||
#include "models/suggest_action.h"
|
||||
#include "models/verb.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
@ -23,7 +26,7 @@ namespace obelisk
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* @brief The filename of the opened knowledge base.
|
||||
* @brief The filename of the opened KnowledgeBase.
|
||||
*
|
||||
*/
|
||||
const char* filename_;
|
||||
@ -61,7 +64,7 @@ namespace obelisk
|
||||
*
|
||||
* @param[in] filename The name of the file to save the knowledge
|
||||
* base as.
|
||||
* @param[in] flags The flags to open the knowledge base with.
|
||||
* @param[in] flags The flags to open the KnowledgeBase with.
|
||||
*/
|
||||
KnowledgeBase(const char* filename, int flags);
|
||||
|
||||
@ -79,12 +82,12 @@ namespace obelisk
|
||||
/**
|
||||
* @brief Destroy the KnowledgeBase object.
|
||||
*
|
||||
* This will close the opened knowledge base before destroying it.
|
||||
* This will close the opened KnowledgeBase before destroying it.
|
||||
*/
|
||||
~KnowledgeBase();
|
||||
|
||||
/**
|
||||
* @brief Add entities to the knowledge base.
|
||||
* @brief Add entities to the KnowledgeBase.
|
||||
*
|
||||
* @param[in,out] entities The entities to add. If the insert is
|
||||
* successful it will have a row ID, if not the ID will be 0.
|
||||
@ -92,13 +95,21 @@ namespace obelisk
|
||||
void addEntities(std::vector<obelisk::Entity>& entities);
|
||||
|
||||
/**
|
||||
* @brief Add verbs to the knowledge base.
|
||||
* @brief Add verbs to the KnowledgeBase.
|
||||
*
|
||||
* @param[in,out] verbs The verbs to add. If the insert is
|
||||
* successful it will have a row ID, if not the ID will be 0.
|
||||
*/
|
||||
void addVerbs(std::vector<obelisk::Verb>& verbs);
|
||||
|
||||
/**
|
||||
* @brief Add actions to the KnowledgeBase.
|
||||
*
|
||||
* @param[in,out] actions The actions to add. If the insert is
|
||||
* successful it will have a row ID, if nto the ID will be 0.
|
||||
*/
|
||||
void addActions(std::vector<obelisk::Action>& actions);
|
||||
|
||||
/**
|
||||
* @brief Add facts to the database.
|
||||
*
|
||||
@ -123,6 +134,14 @@ namespace obelisk
|
||||
*/
|
||||
void getVerb(obelisk::Verb& verb);
|
||||
|
||||
/**
|
||||
* @brief Get an action based on the ID it contains.
|
||||
*
|
||||
* @param[in] action The Action object should contain just the ID
|
||||
* and the rest will be filled in.
|
||||
*/
|
||||
void getAction(obelisk::Action& action);
|
||||
|
||||
/**
|
||||
* @brief Get a fact object based on the ID it contains.
|
||||
*
|
@ -9,7 +9,8 @@ configure_file(input : 'version.h.in',
|
||||
subdir('models')
|
||||
|
||||
obelisk_lib_sources = files(
|
||||
'obelisk.cpp'
|
||||
'obelisk.cpp',
|
||||
'knowledge_base.cpp'
|
||||
)
|
||||
|
||||
obelisk_lib_sources += obelisk_model_sources
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "models/action.h"
|
||||
#include "models/error.h"
|
||||
|
||||
const char* obelisk::Action::createTable()
|
||||
{
|
||||
@ -11,6 +12,131 @@ const char* obelisk::Action::createTable()
|
||||
)";
|
||||
}
|
||||
|
||||
void obelisk::Action::selectByName(sqlite3* dbConnection)
|
||||
{
|
||||
if (dbConnection == nullptr)
|
||||
{
|
||||
throw obelisk::DatabaseException("database isn't open");
|
||||
}
|
||||
|
||||
sqlite3_stmt* ppStmt = nullptr;
|
||||
|
||||
auto result = sqlite3_prepare_v2(dbConnection, "SELECT id, name FROM action WHERE name=?", -1, &ppStmt, nullptr);
|
||||
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
}
|
||||
|
||||
result = sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_STATIC);
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_OK :
|
||||
break;
|
||||
case SQLITE_TOOBIG :
|
||||
throw obelisk::DatabaseSizeException();
|
||||
break;
|
||||
case SQLITE_RANGE :
|
||||
throw obelisk::DatabaseRangeException();
|
||||
break;
|
||||
case SQLITE_NOMEM :
|
||||
throw obelisk::DatabaseMemoryException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_step(ppStmt);
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_DONE :
|
||||
// no rows in the database
|
||||
break;
|
||||
case SQLITE_ROW :
|
||||
setId(sqlite3_column_int(ppStmt, 0));
|
||||
setName((char*) sqlite3_column_text(ppStmt, 1));
|
||||
break;
|
||||
case SQLITE_BUSY :
|
||||
throw obelisk::DatabaseBusyException();
|
||||
break;
|
||||
case SQLITE_MISUSE :
|
||||
throw obelisk::DatabaseMisuseException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_finalize(ppStmt);
|
||||
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
}
|
||||
}
|
||||
|
||||
void obelisk::Action::insert(sqlite3* dbConnection)
|
||||
{
|
||||
if (dbConnection == nullptr)
|
||||
{
|
||||
throw obelisk::DatabaseException("database isn't open");
|
||||
}
|
||||
|
||||
sqlite3_stmt* ppStmt = nullptr;
|
||||
|
||||
auto result = sqlite3_prepare_v2(dbConnection, "INSERT INTO action (name) VALUES (?)", -1, &ppStmt, nullptr);
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
}
|
||||
|
||||
result = sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_OK :
|
||||
break;
|
||||
case SQLITE_TOOBIG :
|
||||
throw obelisk::DatabaseSizeException();
|
||||
break;
|
||||
case SQLITE_RANGE :
|
||||
throw obelisk::DatabaseRangeException();
|
||||
break;
|
||||
case SQLITE_NOMEM :
|
||||
throw obelisk::DatabaseMemoryException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_step(ppStmt);
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_DONE :
|
||||
setId((int) sqlite3_last_insert_rowid(dbConnection));
|
||||
sqlite3_set_last_insert_rowid(dbConnection, 0);
|
||||
break;
|
||||
case SQLITE_CONSTRAINT :
|
||||
throw obelisk::DatabaseConstraintException(sqlite3_errmsg(dbConnection));
|
||||
case SQLITE_BUSY :
|
||||
throw obelisk::DatabaseBusyException();
|
||||
break;
|
||||
case SQLITE_MISUSE :
|
||||
throw obelisk::DatabaseMisuseException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_finalize(ppStmt);
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
}
|
||||
}
|
||||
|
||||
int& obelisk::Action::getId()
|
||||
{
|
||||
return id_;
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef OBELISK_MODELS_ACTION_H
|
||||
#define OBELISK_MODELS_ACTION_H
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace obelisk
|
||||
@ -14,7 +16,7 @@ namespace obelisk
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* @brief The ID of the Action in the knowledge base.
|
||||
* @brief The ID of the Action in the KnowledgeBase.
|
||||
*
|
||||
*/
|
||||
int id_;
|
||||
@ -71,7 +73,7 @@ namespace obelisk
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create the Action table in the knowledge base.
|
||||
* @brief Create the Action table in the KnowledgeBase.
|
||||
*
|
||||
* @return const char* Returns the query used to create the table.
|
||||
*/
|
||||
@ -104,6 +106,22 @@ namespace obelisk
|
||||
* @param[in] name The name of the Action.
|
||||
*/
|
||||
void setName(std::string name);
|
||||
|
||||
/**
|
||||
* @brief Select an Action from the datbase based on the object
|
||||
* name.
|
||||
*
|
||||
* @param[in] dbConnection The database connection to use.
|
||||
*/
|
||||
void selectByName(sqlite3* dbConnection);
|
||||
|
||||
/**
|
||||
* @brief Insert an Action into the KnowledgeBase based on the
|
||||
* object's fields.
|
||||
*
|
||||
* @param[in] dbConnection The database connection to use.
|
||||
*/
|
||||
void insert(sqlite3* dbConnection);
|
||||
};
|
||||
} // namespace obelisk
|
||||
|
||||
|
@ -16,10 +16,11 @@ namespace obelisk
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* @brief The ID of the Entity.
|
||||
* @brief The ID of the Entity in the KnowledgeBase.
|
||||
*
|
||||
*/
|
||||
int id_;
|
||||
|
||||
/**
|
||||
* @brief The name of the Entity.
|
||||
*
|
||||
@ -72,7 +73,7 @@ namespace obelisk
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create the table in the knowledge base.
|
||||
* @brief Create the table in the KnowledgeBase.
|
||||
*
|
||||
* @return const char* Returns the query used to create the table.
|
||||
*/
|
||||
@ -107,7 +108,7 @@ namespace obelisk
|
||||
void setName(std::string name);
|
||||
|
||||
/**
|
||||
* @brief Select an Entity from the database based on the object's
|
||||
* @brief Select an Entity from the KnowledgeBase based on the object's
|
||||
* name.
|
||||
*
|
||||
* @param[in] dbConnection The database connection to use.
|
||||
@ -115,7 +116,7 @@ namespace obelisk
|
||||
void selectByName(sqlite3* dbConnection);
|
||||
|
||||
/**
|
||||
* @brief Insert an Entity into the database based on the object's
|
||||
* @brief Insert an Entity into the KnowledgeBase based on the object's
|
||||
* fields.
|
||||
*
|
||||
* @param[in] dbConnection The database connection to use.
|
||||
|
@ -6,77 +6,152 @@
|
||||
|
||||
namespace obelisk
|
||||
{
|
||||
/**
|
||||
* @brief Exception thrown by database models.
|
||||
*
|
||||
*/
|
||||
class DatabaseException : public std::exception
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* @brief The error message describing the exception.
|
||||
*
|
||||
*/
|
||||
std::string errorMessage_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new DatabaseException object.
|
||||
*
|
||||
*/
|
||||
DatabaseException() :
|
||||
errorMessage_("an unknown error ocurred")
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new DatabaseException object.
|
||||
*
|
||||
* @param[in] errorCode The error code that came from sqlite.
|
||||
*/
|
||||
DatabaseException(const int errorCode) :
|
||||
errorMessage_("database error " + std::to_string(errorCode) + " ocurred")
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new DatabaseException object.
|
||||
*
|
||||
* @param[in] errorMessage The error message to describe the
|
||||
* exception.
|
||||
*/
|
||||
DatabaseException(const std::string& errorMessage) :
|
||||
errorMessage_(errorMessage)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retreive the exception message as a C type string.
|
||||
*
|
||||
* @return const char* The error message.
|
||||
*/
|
||||
virtual const char* what() const noexcept
|
||||
{
|
||||
return errorMessage_.c_str();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the error message.
|
||||
*
|
||||
* @param[in] errorMessage The error message.
|
||||
*/
|
||||
virtual void setErrorMessage(const std::string errorMessage)
|
||||
{
|
||||
errorMessage_ = errorMessage;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Exception thrown if the string or blob size exceeds sqlite's
|
||||
* limits.
|
||||
*
|
||||
*/
|
||||
class DatabaseSizeException : public obelisk::DatabaseException
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new DatabaseSizeException object.
|
||||
*
|
||||
*/
|
||||
DatabaseSizeException()
|
||||
{
|
||||
setErrorMessage("size of string or blob exceeds limits");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Exception thrown if the index used it out of range.
|
||||
*
|
||||
*/
|
||||
class DatabaseRangeException : public obelisk::DatabaseException
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new DatabaseRangeException object.
|
||||
*
|
||||
*/
|
||||
DatabaseRangeException()
|
||||
{
|
||||
setErrorMessage("parameter index is out of range");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Exception thrown if there is not enough memory to perform the
|
||||
* operation.
|
||||
*
|
||||
*/
|
||||
class DatabaseMemoryException : public obelisk::DatabaseException
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new DatabaseMemoryException object.
|
||||
*
|
||||
*/
|
||||
DatabaseMemoryException()
|
||||
{
|
||||
setErrorMessage("not enough memory for operation");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Exception thrown if the database was busy.
|
||||
*
|
||||
*/
|
||||
class DatabaseBusyException : public obelisk::DatabaseException
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new DatabaseBusyException object.
|
||||
*
|
||||
*/
|
||||
DatabaseBusyException()
|
||||
{
|
||||
setErrorMessage("database was busy and operation was not performed");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Exception thrown if there is a misuse of the databse.
|
||||
*
|
||||
*/
|
||||
class DatabaseMisuseException : public obelisk::DatabaseException
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new DatabaseMisuseException object.
|
||||
*
|
||||
*/
|
||||
DatabaseMisuseException()
|
||||
|
||||
{
|
||||
@ -84,14 +159,28 @@ namespace obelisk
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Exception thrown if a constraint was violated.
|
||||
*
|
||||
*/
|
||||
class DatabaseConstraintException : public obelisk::DatabaseException
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new DatabaseConstraintException object.
|
||||
*
|
||||
*/
|
||||
DatabaseConstraintException()
|
||||
{
|
||||
setErrorMessage("a constraint exception occurred");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new DatabaseConstraintException object.
|
||||
*
|
||||
* @param[in] errorMessage The error message to send when the
|
||||
* constraint is violated.
|
||||
*/
|
||||
DatabaseConstraintException(const std::string& errorMessage)
|
||||
{
|
||||
setErrorMessage(errorMessage);
|
||||
|
@ -19,7 +19,7 @@ const char* obelisk::Fact::createTable()
|
||||
)";
|
||||
}
|
||||
|
||||
void obelisk::Fact::selectByName(sqlite3* dbConnection)
|
||||
void obelisk::Fact::selectById(sqlite3* dbConnection)
|
||||
{
|
||||
if (dbConnection == nullptr)
|
||||
{
|
||||
|
@ -9,16 +9,50 @@
|
||||
|
||||
namespace obelisk
|
||||
{
|
||||
/**
|
||||
* @brief The Fact model represents truth in the releationship between two
|
||||
* entities separated by a verb.
|
||||
*
|
||||
*/
|
||||
class Fact
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* @brief The ID of the Fact in the KnowledgeBase.
|
||||
*
|
||||
*/
|
||||
int id_;
|
||||
|
||||
/**
|
||||
* @brief The Entity from the left side of the expression.
|
||||
*
|
||||
*/
|
||||
obelisk::Entity leftEntity_;
|
||||
|
||||
/**
|
||||
* @brief The Entity from the right side of the expression.
|
||||
*
|
||||
*/
|
||||
obelisk::Entity rightEntity_;
|
||||
|
||||
/**
|
||||
* @brief The Verb that represents the relationship in the
|
||||
* expression.
|
||||
*
|
||||
*/
|
||||
obelisk::Verb verb_;
|
||||
|
||||
/**
|
||||
* @brief Whether or not the fact is considered true or not.
|
||||
*
|
||||
*/
|
||||
bool isTrue_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Fact object.
|
||||
*
|
||||
*/
|
||||
Fact() :
|
||||
id_(0),
|
||||
leftEntity_(),
|
||||
@ -28,6 +62,11 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Fact object.
|
||||
*
|
||||
* @param[in] id The ID of the Fact in the KnowledgeBase.
|
||||
*/
|
||||
Fact(int id) :
|
||||
id_(id),
|
||||
leftEntity_(),
|
||||
@ -37,6 +76,16 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Fact object.
|
||||
*
|
||||
* @param[in] leftEntity The Entity on the left side of the
|
||||
* expression.
|
||||
* @param[in] rightEntity The Entity on the right side of the
|
||||
* expression.
|
||||
* @param[in] verb The Verb separating the entities.
|
||||
* @param[in] isTrue Whether or not the fact is true.
|
||||
*/
|
||||
Fact(obelisk::Entity leftEntity, obelisk::Entity rightEntity, obelisk::Verb verb, bool isTrue = false) :
|
||||
id_(0),
|
||||
leftEntity_(leftEntity),
|
||||
@ -46,6 +95,17 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Fact object.
|
||||
*
|
||||
* @param[in] id The ID of the Fact in the KnowledgeBase.
|
||||
* @param[in] leftEntity The Entity on the left side of the
|
||||
* expression.
|
||||
* @param[in] rightEntity The Entity on the right side of the
|
||||
* expression.
|
||||
* @param[in] verb The Verb separating the entities.
|
||||
* @param[in] isTrue Whether or not the fact is true.
|
||||
*/
|
||||
Fact(int id,
|
||||
obelisk::Entity leftEntity,
|
||||
obelisk::Entity rightEntity,
|
||||
@ -59,24 +119,97 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create the Fact table in the KnowledgeBase.
|
||||
*
|
||||
* @return const char* Returns the query used to create the table.
|
||||
*/
|
||||
static const char* createTable();
|
||||
|
||||
/**
|
||||
* @brief Get the ID of the Fact
|
||||
*
|
||||
* @return int& Returns the ID.
|
||||
*/
|
||||
int& getId();
|
||||
|
||||
/**
|
||||
* @brief Set the ID of the Fact.
|
||||
*
|
||||
* @param[in] id Set the ID of the Fact.
|
||||
*/
|
||||
void setId(int id);
|
||||
|
||||
/**
|
||||
* @brief Get the left Entity object.
|
||||
*
|
||||
* @return Entity& The left Entity.
|
||||
*/
|
||||
Entity& getLeftEntity();
|
||||
|
||||
/**
|
||||
* @brief Set the left Entity object.
|
||||
*
|
||||
* @param[in] leftEntity The left Entity to set.
|
||||
*/
|
||||
void setLeftEntity(obelisk::Entity leftEntity);
|
||||
|
||||
/**
|
||||
* @brief Get the right Entity object.
|
||||
*
|
||||
* @return Entity& The right Entity.
|
||||
*/
|
||||
Entity& getRightEntity();
|
||||
void setRightEntity(obelisk::Entity leftEntity);
|
||||
|
||||
/**
|
||||
* @brief Set the right Entity object.
|
||||
*
|
||||
* @param[in] rightEntity The right Entity to set.
|
||||
*/
|
||||
void setRightEntity(obelisk::Entity rightEntity);
|
||||
|
||||
/**
|
||||
* @brief Get the Verb object.
|
||||
*
|
||||
* @return Verb& The Verb.
|
||||
*/
|
||||
Verb& getVerb();
|
||||
|
||||
/**
|
||||
* @brief Set the Verb object.
|
||||
*
|
||||
* @param[in] verb The Verb.
|
||||
*/
|
||||
void setVerb(obelisk::Verb verb);
|
||||
|
||||
/**
|
||||
* @brief Gets the isTrue value.
|
||||
*
|
||||
* @return true If the Fact is considered true.
|
||||
* @return false If the Fact is considered false.
|
||||
*/
|
||||
bool& getIsTrue();
|
||||
|
||||
/**
|
||||
* @brief Set the Fact as true or false.
|
||||
*
|
||||
* @param[in] isTrue Whether or not the Fact is true.
|
||||
*/
|
||||
void setIsTrue(bool isTrue);
|
||||
|
||||
void selectByName(sqlite3* dbConnection);
|
||||
/**
|
||||
* @brief Select the Fact from the KnowledgeBase by IDs of the
|
||||
* sub-objects.
|
||||
*
|
||||
* @param[in] dbConnection The database connection to use.
|
||||
*/
|
||||
void selectById(sqlite3* dbConnection);
|
||||
|
||||
/**
|
||||
* @brief Insert the Fact into the KnowledgeBase.
|
||||
*
|
||||
* @param[in] dbConnection The database connection to use.
|
||||
*/
|
||||
void insert(sqlite3* dbConnection);
|
||||
};
|
||||
} // namespace obelisk
|
||||
|
@ -7,14 +7,36 @@
|
||||
|
||||
namespace obelisk
|
||||
{
|
||||
/**
|
||||
* @brief The Rule model represents a truth relation between 2 Facts.
|
||||
*
|
||||
*/
|
||||
class Rule
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* @brief The ID of the Rule in the KnowledgeBase.
|
||||
*
|
||||
*/
|
||||
int id_;
|
||||
|
||||
/**
|
||||
* @brief The Fact that depends on the Fact reason being true.
|
||||
*
|
||||
*/
|
||||
obelisk::Fact fact_;
|
||||
|
||||
/**
|
||||
* @brief The Fact that makes the other Fact true or false.
|
||||
*
|
||||
*/
|
||||
obelisk::Fact reason_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Rule object.
|
||||
*
|
||||
*/
|
||||
Rule() :
|
||||
id_(0),
|
||||
fact_(),
|
||||
@ -22,6 +44,11 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Rule object.
|
||||
*
|
||||
* @param[in] id The ID of the Rule in the KnowledgeBase.
|
||||
*/
|
||||
Rule(int id) :
|
||||
id_(id),
|
||||
fact_(),
|
||||
@ -29,6 +56,12 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Rule object.
|
||||
*
|
||||
* @param[in] fact The Fact.
|
||||
* @param[in] reason The reason Fact.
|
||||
*/
|
||||
Rule(obelisk::Fact fact, obelisk::Fact reason) :
|
||||
id_(0),
|
||||
fact_(fact),
|
||||
@ -36,6 +69,13 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Rule object.
|
||||
*
|
||||
* @param[in] id The ID of the Rule.
|
||||
* @param[in] fact The Fact.
|
||||
* @param[in] reason The reason Fact.
|
||||
*/
|
||||
Rule(int id, obelisk::Fact fact, obelisk::Fact reason) :
|
||||
id_(id),
|
||||
fact_(fact),
|
||||
@ -43,15 +83,53 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create the Rule table in the KnowledgeBase.
|
||||
*
|
||||
* @return const char* Returns the query used to create the table.
|
||||
*/
|
||||
static const char* createTable();
|
||||
|
||||
/**
|
||||
* @brief Get the ID of the Rule.
|
||||
*
|
||||
* @return int& The ID.
|
||||
*/
|
||||
int& getId();
|
||||
|
||||
/**
|
||||
* @brief Set the ID of the Rule.
|
||||
*
|
||||
* @param[in] id The ID.
|
||||
*/
|
||||
void setId(int id);
|
||||
|
||||
/**
|
||||
* @brief Get the Fact object.
|
||||
*
|
||||
* @return obelisk::Fact& The Fact.
|
||||
*/
|
||||
obelisk::Fact& getFact();
|
||||
|
||||
/**
|
||||
* @brief Set the Fact object.
|
||||
*
|
||||
* @param[in] fact The Fact.
|
||||
*/
|
||||
void setFact(obelisk::Fact fact);
|
||||
|
||||
/**
|
||||
* @brief Get the reason Fact object.
|
||||
*
|
||||
* @return obelisk::Fact& The reason Fact.
|
||||
*/
|
||||
obelisk::Fact& getReason();
|
||||
|
||||
/**
|
||||
* @brief Set the reason Fact object.
|
||||
*
|
||||
* @param[in] reason The reason Fact.
|
||||
*/
|
||||
void setReason(obelisk::Fact reason);
|
||||
};
|
||||
} // namespace obelisk
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "models/error.h"
|
||||
#include "models/suggest_action.h"
|
||||
|
||||
const char* obelisk::SuggestAction::createTable()
|
||||
@ -17,6 +18,215 @@ const char* obelisk::SuggestAction::createTable()
|
||||
)";
|
||||
}
|
||||
|
||||
void obelisk::SuggestAction::selectById(sqlite3* dbConnection)
|
||||
{
|
||||
if (dbConnection == nullptr)
|
||||
{
|
||||
throw obelisk::DatabaseException("database isn't open");
|
||||
}
|
||||
|
||||
sqlite3_stmt* ppStmt = nullptr;
|
||||
|
||||
auto result = sqlite3_prepare_v2(dbConnection,
|
||||
"SELECT id, fact, true_action, false_action FROM suggest_action WHERE (fact=? AND true_action=? AND false_action=?)",
|
||||
-1,
|
||||
&ppStmt,
|
||||
nullptr);
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
}
|
||||
|
||||
result = sqlite3_bind_int(ppStmt, 1, getFact().getId());
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_OK :
|
||||
break;
|
||||
case SQLITE_TOOBIG :
|
||||
throw obelisk::DatabaseSizeException();
|
||||
break;
|
||||
case SQLITE_RANGE :
|
||||
throw obelisk::DatabaseRangeException();
|
||||
break;
|
||||
case SQLITE_NOMEM :
|
||||
throw obelisk::DatabaseMemoryException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_bind_int(ppStmt, 2, getTrueAction().getId());
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_OK :
|
||||
break;
|
||||
case SQLITE_TOOBIG :
|
||||
throw obelisk::DatabaseSizeException();
|
||||
break;
|
||||
case SQLITE_RANGE :
|
||||
throw obelisk::DatabaseRangeException();
|
||||
break;
|
||||
case SQLITE_NOMEM :
|
||||
throw obelisk::DatabaseMemoryException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_bind_int(ppStmt, 3, getFalseAction().getId());
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_OK :
|
||||
break;
|
||||
case SQLITE_TOOBIG :
|
||||
throw obelisk::DatabaseSizeException();
|
||||
break;
|
||||
case SQLITE_RANGE :
|
||||
throw obelisk::DatabaseRangeException();
|
||||
break;
|
||||
case SQLITE_NOMEM :
|
||||
throw obelisk::DatabaseMemoryException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_step(ppStmt);
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_DONE :
|
||||
// no rows in the database
|
||||
break;
|
||||
case SQLITE_ROW :
|
||||
setId(sqlite3_column_int(ppStmt, 0));
|
||||
getFact().setId(sqlite3_column_int(ppStmt, 1));
|
||||
getTrueAction().setId(sqlite3_column_int(ppStmt, 2));
|
||||
getFalseAction().setId(sqlite3_column_int(ppStmt, 3));
|
||||
break;
|
||||
case SQLITE_BUSY :
|
||||
throw obelisk::DatabaseBusyException();
|
||||
break;
|
||||
case SQLITE_MISUSE :
|
||||
throw obelisk::DatabaseMisuseException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_finalize(ppStmt);
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
}
|
||||
}
|
||||
|
||||
void obelisk::SuggestAction::insert(sqlite3* dbConnection)
|
||||
{
|
||||
if (dbConnection == nullptr)
|
||||
{
|
||||
throw obelisk::DatabaseException("database isn't open");
|
||||
}
|
||||
|
||||
sqlite3_stmt* ppStmt = nullptr;
|
||||
|
||||
auto result = sqlite3_prepare_v2(dbConnection,
|
||||
"INSERT INTO suggest_action (fact, true_action, false_action) VALUES (?, ?, ?)",
|
||||
-1,
|
||||
&ppStmt,
|
||||
nullptr);
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
}
|
||||
|
||||
result = sqlite3_bind_int(ppStmt, 1, getFact().getId());
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_OK :
|
||||
break;
|
||||
case SQLITE_TOOBIG :
|
||||
throw obelisk::DatabaseSizeException();
|
||||
break;
|
||||
case SQLITE_RANGE :
|
||||
throw obelisk::DatabaseRangeException();
|
||||
break;
|
||||
case SQLITE_NOMEM :
|
||||
throw obelisk::DatabaseMemoryException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_bind_int(ppStmt, 2, getTrueAction().getId());
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_OK :
|
||||
break;
|
||||
case SQLITE_TOOBIG :
|
||||
throw obelisk::DatabaseSizeException();
|
||||
break;
|
||||
case SQLITE_RANGE :
|
||||
throw obelisk::DatabaseRangeException();
|
||||
break;
|
||||
case SQLITE_NOMEM :
|
||||
throw obelisk::DatabaseMemoryException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_bind_int(ppStmt, 3, getFalseAction().getId());
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_OK :
|
||||
break;
|
||||
case SQLITE_TOOBIG :
|
||||
throw obelisk::DatabaseSizeException();
|
||||
break;
|
||||
case SQLITE_RANGE :
|
||||
throw obelisk::DatabaseRangeException();
|
||||
break;
|
||||
case SQLITE_NOMEM :
|
||||
throw obelisk::DatabaseMemoryException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_step(ppStmt);
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_DONE :
|
||||
setId((int) sqlite3_last_insert_rowid(dbConnection));
|
||||
sqlite3_set_last_insert_rowid(dbConnection, 0);
|
||||
break;
|
||||
case SQLITE_CONSTRAINT :
|
||||
throw obelisk::DatabaseConstraintException(sqlite3_errmsg(dbConnection));
|
||||
case SQLITE_BUSY :
|
||||
throw obelisk::DatabaseBusyException();
|
||||
break;
|
||||
case SQLITE_MISUSE :
|
||||
throw obelisk::DatabaseMisuseException();
|
||||
break;
|
||||
default :
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
break;
|
||||
}
|
||||
|
||||
result = sqlite3_finalize(ppStmt);
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
}
|
||||
}
|
||||
|
||||
int& obelisk::SuggestAction::getId()
|
||||
{
|
||||
return id_;
|
||||
|
@ -8,15 +8,43 @@
|
||||
|
||||
namespace obelisk
|
||||
{
|
||||
/**
|
||||
* @brief The SuggestAction model representas the actions to take depending
|
||||
* on if the Fact is true or false.
|
||||
*
|
||||
*/
|
||||
class SuggestAction
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* @brief The ID of the SuggestAction.
|
||||
*
|
||||
*/
|
||||
int id_;
|
||||
|
||||
/**
|
||||
* @brief The Fact to check the truth of.
|
||||
*
|
||||
*/
|
||||
obelisk::Fact fact_;
|
||||
|
||||
/**
|
||||
* @brief The Action to take if the Fact is true.
|
||||
*
|
||||
*/
|
||||
obelisk::Action trueAction_;
|
||||
|
||||
/**
|
||||
* @brief The Action to take if the Fact is false.
|
||||
*
|
||||
*/
|
||||
obelisk::Action falseAction_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new SuggestAction object.
|
||||
*
|
||||
*/
|
||||
SuggestAction() :
|
||||
id_(0),
|
||||
fact_(),
|
||||
@ -25,6 +53,11 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new SuggestAction object.
|
||||
*
|
||||
* @param[in] id The ID of the SuggestAction in the KnowledgeBase.
|
||||
*/
|
||||
SuggestAction(int id) :
|
||||
id_(id),
|
||||
fact_(),
|
||||
@ -33,6 +66,13 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new SuggestAction object.
|
||||
*
|
||||
* @param[in] fact The Fact.
|
||||
* @param[in] trueAction The true Action.
|
||||
* @param[in] falseAction The false Action.
|
||||
*/
|
||||
SuggestAction(obelisk::Fact fact, obelisk::Action trueAction, obelisk::Action falseAction) :
|
||||
id_(0),
|
||||
fact_(fact),
|
||||
@ -41,6 +81,14 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new SuggestAction object.
|
||||
*
|
||||
* @param[in] id The ID of the SuggestAction in the KnowledgeBase.
|
||||
* @param[in] fact The Fact.
|
||||
* @param[in] trueAction The true Action.
|
||||
* @param[in] falseAction The false Action.
|
||||
*/
|
||||
SuggestAction(int id, obelisk::Fact fact, obelisk::Action trueAction, obelisk::Action falseAction) :
|
||||
id_(id),
|
||||
fact_(fact),
|
||||
@ -49,19 +97,83 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create the SuggestAction table in the database.
|
||||
*
|
||||
* @return const char* Returns the query used to create the table.
|
||||
*/
|
||||
static const char* createTable();
|
||||
|
||||
/**
|
||||
* @brief Get the ID of the SuggestAction.
|
||||
*
|
||||
* @return int& Returns the ID.
|
||||
*/
|
||||
int& getId();
|
||||
|
||||
/**
|
||||
* @brief Set the ID of the SuggestAction.
|
||||
*
|
||||
* @param[in] id The new ID.
|
||||
*/
|
||||
void setId(int id);
|
||||
|
||||
/**
|
||||
* @brief Get the Fact object.
|
||||
*
|
||||
* @return obelisk::Fact& Returns the Fact.
|
||||
*/
|
||||
obelisk::Fact& getFact();
|
||||
|
||||
/**
|
||||
* @brief Set the Fact object.
|
||||
*
|
||||
* @param[in] fact The new Fact.
|
||||
*/
|
||||
void setFact(obelisk::Fact fact);
|
||||
|
||||
/**
|
||||
* @brief Get the true Action object.
|
||||
*
|
||||
* @return obelisk::Action& Returns the true Action.
|
||||
*/
|
||||
obelisk::Action& getTrueAction();
|
||||
|
||||
/**
|
||||
* @brief Set the true Action object.
|
||||
*
|
||||
* @param[in] trueAction The new true Action.
|
||||
*/
|
||||
void setTrueAction(obelisk::Action trueAction);
|
||||
|
||||
/**
|
||||
* @brief Get the false Action object.
|
||||
*
|
||||
* @return obelisk::Action& Returns the false Action.
|
||||
*/
|
||||
obelisk::Action& getFalseAction();
|
||||
|
||||
/**
|
||||
* @brief Set the false Action object.
|
||||
*
|
||||
* @param[in] falseAction The new false Action.
|
||||
*/
|
||||
void setFalseAction(obelisk::Action falseAction);
|
||||
|
||||
/**
|
||||
* @brief Select the SuggestAction from the KnowledgeBase by IDs of the
|
||||
* sub-objects.
|
||||
*
|
||||
* @param[in] dbConnection The database connection to use.
|
||||
*/
|
||||
void selectById(sqlite3* dbConnection);
|
||||
|
||||
/**
|
||||
* @brief Insert the SuggestAction into the KnowledgeBase.
|
||||
*
|
||||
* @param[in] dbConnection The database connection to use.
|
||||
*/
|
||||
void insert(sqlite3* dbConnection);
|
||||
};
|
||||
} // namespace obelisk
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace obelisk
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* @brief The ID of the Verb in the knowledge base.
|
||||
* @brief The ID of the Verb in the KnowledgeBase.
|
||||
*
|
||||
*/
|
||||
int id_;
|
||||
|
@ -1,8 +1,6 @@
|
||||
#include "include/obelisk.h"
|
||||
#include "version.h"
|
||||
|
||||
// TODO: Move the models to the library then link the compiler to the library
|
||||
|
||||
std::string obelisk::Obelisk::getVersion()
|
||||
{
|
||||
return obelisk::version;
|
||||
|
@ -3,8 +3,7 @@ subdir('lib')
|
||||
obelisk_sources = files(
|
||||
'main.cpp',
|
||||
'lexer.cpp',
|
||||
'parser.cpp',
|
||||
'knowledge_base.cpp'
|
||||
'parser.cpp'
|
||||
)
|
||||
|
||||
sqlite3 = dependency('sqlite3')
|
||||
|
@ -389,7 +389,7 @@ void obelisk::Parser::parseAction(obelisk::SuggestAction& suggestAction)
|
||||
break;
|
||||
}
|
||||
|
||||
if (getLexer()->getIdentifier() == "or")
|
||||
if (getLexer()->getIdentifier() == "else")
|
||||
{
|
||||
getNextToken();
|
||||
getAction = true;
|
||||
@ -406,7 +406,7 @@ void obelisk::Parser::parseAction(obelisk::SuggestAction& suggestAction)
|
||||
suggestAction.setFact(
|
||||
obelisk::Fact(obelisk::Entity(leftEntity), obelisk::Entity(rightEntity), obelisk::Verb(verb)));
|
||||
suggestAction.setTrueAction(obelisk::Action(trueAction));
|
||||
suggestAction.setTrueAction(obelisk::Action(falseAction));
|
||||
suggestAction.setFalseAction(obelisk::Action(falseAction));
|
||||
}
|
||||
|
||||
void obelisk::Parser::parseRule(std::vector<obelisk::Rule>& rules)
|
||||
@ -547,6 +547,8 @@ void obelisk::Parser::handleAction(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
||||
insertEntity(kb, suggestAction.getFact().getRightEntity());
|
||||
insertVerb(kb, suggestAction.getFact().getVerb());
|
||||
insertFact(kb, suggestAction.getFact());
|
||||
insertAction(kb, suggestAction.getTrueAction());
|
||||
insertAction(kb, suggestAction.getFalseAction());
|
||||
|
||||
// TODO: insert the actions, then insert the suggested action
|
||||
}
|
||||
@ -647,6 +649,23 @@ void obelisk::Parser::insertVerb(std::unique_ptr<obelisk::KnowledgeBase>& kb, ob
|
||||
}
|
||||
}
|
||||
|
||||
void obelisk::Parser::insertAction(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Action& action)
|
||||
{
|
||||
std::vector<obelisk::Action> actions {action};
|
||||
kb->addActions(actions);
|
||||
action = std::move(actions.front());
|
||||
|
||||
// the id was not inserted, so check if it exists in the database
|
||||
if (action.getId() == 0)
|
||||
{
|
||||
kb->getAction(action);
|
||||
if (action.getId() == 0)
|
||||
{
|
||||
throw obelisk::ParserException("action could not be inserted into the database");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void obelisk::Parser::insertFact(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Fact& fact)
|
||||
{
|
||||
std::vector<obelisk::Fact> facts {fact};
|
||||
|
@ -63,6 +63,7 @@ namespace obelisk
|
||||
|
||||
void insertEntity(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Entity& entity);
|
||||
void insertVerb(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Verb& verb);
|
||||
void insertAction(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Action& action);
|
||||
void insertFact(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Fact& fact);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user