add query for suggested actions

This commit is contained in:
Chris Cromer 2023-02-23 01:07:44 -03:00
parent d6532715bd
commit 3a23121743
Signed by: cromer
GPG Key ID: FA91071797BEEEC2
10 changed files with 164 additions and 4 deletions

View File

@ -73,7 +73,7 @@ namespace obelisk
* @param[in] rightEntity The right entity.
* @return std::string Returns the suggested action.
*/
std::string query_action(const std::string& leftEntity,
std::string queryAction(const std::string& leftEntity,
const std::string& verb,
const std::string& rightEntity);
};

View File

@ -50,6 +50,21 @@ extern "C"
const char* verb,
const char* right_entity);
/**
* @brief Query the obelisk KnowledgeBase to get a suggested Action to do.
*
* @param[in] obelisk The obelisk object.
* @param[in] left_entity The left entity.
* @param[in] verb The verb.
* @param[in] right_entity The right entity.
* @return char* Returns the Action to do or an empty string if there is no
* action.
*/
extern char* obelisk_query_action(CObelisk* obelisk,
const char* left_entity,
const char* verb,
const char* right_entity);
/**
* @brief Get the obelisk library so version.
*

View File

@ -264,6 +264,12 @@ void obelisk::KnowledgeBase::queryFact(obelisk::Fact& fact)
fact.selectByName(dbConnection_);
}
void obelisk::KnowledgeBase::querySuggestAction(obelisk::Fact& fact,
obelisk::Action& action)
{
fact.selectActionByFact(dbConnection_, action);
}
void obelisk::KnowledgeBase::getFloat(float& result1,
float& result2,
double var)

View File

@ -200,8 +200,24 @@ namespace obelisk
*/
void updateIsTrue(obelisk::Fact& fact);
/**
* @brief Query the KnowledgeBase to see if a Fact is true or false.
*
* @param[in] fact The Fact to check.
*/
void queryFact(obelisk::Fact& fact);
/**
* @brief Query the KnowledgeBase to get a suggested action based
* on a Fact.
* If a SuggestAction doesn't exist, it will return an empty Action.
*
* @param[in] fact The Fact to search for.
* @param[out] action The Action that is suggested to take.
*/
void querySuggestAction(obelisk::Fact& fact,
obelisk::Action& action);
/**
* @brief Take a float and divide it into 2 floats.
*

View File

@ -276,6 +276,72 @@ void obelisk::Fact::selectByName(sqlite3* dbConnection)
}
}
void obelisk::Fact::selectActionByFact(sqlite3* dbConnection,
obelisk::Action& action)
{
if (dbConnection == nullptr)
{
throw obelisk::DatabaseException("database isn't open");
}
sqlite3_stmt* ppStmt = nullptr;
auto result = sqlite3_prepare_v2(dbConnection,
"SELECT CASE f.is_true WHEN 0 THEN (SELECT name FROM action WHERE id = fa.id) WHEN 1 THEN (SELECT name from action WHERE id = ta.id) END action FROM suggest_action LEFT JOIN action ta ON ta.id = suggest_action.true_action LEFT JOIN action fa ON fa.id = suggest_action.false_action LEFT JOIN fact f ON f.id = suggest_action.fact WHERE (f.id = ?)",
-1,
&ppStmt,
nullptr);
if (result != SQLITE_OK)
{
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
}
result = sqlite3_bind_int(ppStmt, 1, 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 :
action.setName((char*) sqlite3_column_text(ppStmt, 0));
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::Fact::insert(sqlite3* dbConnection)
{
if (dbConnection == nullptr)

View File

@ -1,6 +1,7 @@
#ifndef OBELISK_MODELS_FACT_H
#define OBELISK_MODELS_FACT_H
#include "models/action.h"
#include "models/entity.h"
#include "models/fact.h"
#include "models/verb.h"
@ -216,6 +217,16 @@ namespace obelisk
*/
void selectByName(sqlite3* dbConnection);
/**
* @brief Select an Action from the KnowledgeBase using the provided
* Fact.
*
* @param[in] dbConnection The database connection to use.
* @param[out] action The Action to take based on the provided fact.
*/
void selectActionByFact(sqlite3* dbConnection,
obelisk::Action& action);
/**
* @brief Insert the Fact into the KnowledgeBase.
*

View File

@ -31,3 +31,11 @@ double obelisk_query(CObelisk* obelisk,
{
return call_obelisk_query(obelisk, left_entity, verb, right_entity);
}
char* obelisk_query_action(CObelisk* obelisk,
const char* left_entity,
const char* verb,
const char* right_entity)
{
return call_obelisk_queryAction(obelisk, left_entity, verb, right_entity);
}

View File

@ -30,9 +30,18 @@ double obelisk::Obelisk::query(const std::string& leftEntity,
return fact.getIsTrue();
}
std::string obelisk::Obelisk::query_action(const std::string& leftEntity,
std::string obelisk::Obelisk::queryAction(const std::string& leftEntity,
const std::string& verb,
const std::string& rightEntity)
{
return "yes";
obelisk::Fact fact = obelisk::Fact(obelisk::Entity(leftEntity),
obelisk::Entity(rightEntity),
obelisk::Verb(verb));
kb_->queryFact(fact);
obelisk::Action action;
kb_->querySuggestAction(fact, action);
return action.getName();
}

View File

@ -38,6 +38,20 @@ extern "C"
std::string(right_entity));
}
char* call_obelisk_queryAction(CObelisk* p_obelisk,
const char* left_entity,
const char* verb,
const char* right_entity)
{
obelisk::Obelisk* obelisk
= reinterpret_cast<obelisk::Obelisk*>(p_obelisk);
auto temp = obelisk->queryAction(std::string(left_entity),
std::string(verb),
std::string(right_entity));
auto action = strdup(temp.c_str());
return action;
}
void destroy_obelisk(CObelisk* p_obelisk)
{
obelisk::Obelisk* obelisk

View File

@ -20,7 +20,7 @@ extern "C"
* @brief Calls the obelisk method getVersion.
*
* @param[in] p_obelisk The obelisk object pointer.
* @return const char* Returns the version. This must be freed by the
* @return char* Returns the version. This must be freed by the
* caller.
*/
char *call_obelisk_getVersion(CObelisk *p_obelisk);
@ -47,6 +47,21 @@ extern "C"
const char *verb,
const char *right_entity);
/**
* @brief Calls the obelisk method queryAction.
*
* @param[in] p_obelisk The obelisk object pointer.
* @param[in] left_entity The left entity.
* @param[in] verb The verb.
* @param[in] right_entity The right entity.
* @return char* Returns the sugggested action to take or an empty string if
* no action is found. This must be freed by the caller.
*/
char *call_obelisk_queryAction(CObelisk *p_obelisk,
const char *left_entity,
const char *verb,
const char *right_entity);
/**
* @brief Delete a obelisk object.
*