allow the library to query the knowledge base

This commit is contained in:
Chris Cromer 2023-02-22 00:42:40 -03:00
parent e665ff044f
commit d84f2a944c
Signed by: cromer
GPG Key ID: FA91071797BEEEC2
11 changed files with 228 additions and 24 deletions

View File

@ -1,6 +1,9 @@
#ifndef OBELISK_INCLUDE_OBELISK_H #ifndef OBELISK_INCLUDE_OBELISK_H
#define OBELISK_INCLUDE_OBELISK_H #define OBELISK_INCLUDE_OBELISK_H
#include "knowledge_base.h"
#include <memory>
#include <string> #include <string>
/** /**
@ -17,12 +20,15 @@ namespace obelisk
*/ */
class Obelisk class Obelisk
{ {
private:
std::unique_ptr<obelisk::KnowledgeBase> kb_;
public: public:
/** /**
* @brief Construct a new Obelisk object. * @brief Construct a new Obelisk object.
* *
*/ */
Obelisk() = default; Obelisk(std::string filename);
/** /**
* @brief Destroy the Obelisk object. * @brief Destroy the Obelisk object.
@ -45,14 +51,14 @@ namespace obelisk
int getLibVersion(); int getLibVersion();
/** /**
* @brief Query the Obelisk KnowledgeBase to see if the Fact is true * @brief Query the obelisk KnowledgeBase to see if a Fact is true
* or not. * or not.
* *
* @param[in] leftEntity The left entity. * @param[in] p_obelisk The obelisk object pointer.
* @param[in] left_entity The left entity.
* @param[in] verb The verb. * @param[in] verb The verb.
* @param[in] rightEntity The right entity. * @param[in] right_entity The right entity.
* @return double Returns a value between 0 and 1 depending on * @return double Returns whether or not the Fact is true.
* whether it is true or false.
*/ */
double query(const std::string& leftEntity, double query(const std::string& leftEntity,
const std::string& verb, const std::string& verb,

View File

@ -15,9 +15,10 @@ extern "C"
/** /**
* @brief Create an obelisk object. * @brief Create an obelisk object.
* *
* @param[in] filename The obelisk KnowledgeBase file to use.
* @return CObelisk* Returns an obelisk object. * @return CObelisk* Returns an obelisk object.
*/ */
extern CObelisk* obelisk_open(); extern CObelisk* obelisk_open(const char* filename);
/** /**
* @brief Delete an obelisk object. * @brief Delete an obelisk object.
@ -35,6 +36,20 @@ extern "C"
*/ */
extern char* obelisk_get_version(CObelisk* obelisk); extern char* obelisk_get_version(CObelisk* obelisk);
/**
* @brief Query the obelisk KnowledgeBase to see if a Fact is true or false.
*
* @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 double Returns whether the Fact is true or false.
*/
extern double obelisk_query(CObelisk* obelisk,
const char* left_entity,
const char* verb,
const char* right_entity);
/** /**
* @brief Get the obelisk library so version. * @brief Get the obelisk library so version.
* *

View File

@ -245,10 +245,10 @@ void obelisk::KnowledgeBase::checkRule(obelisk::Fact& fact)
{ {
auto reason = rule.getReason(); auto reason = rule.getReason();
getFact(reason); getFact(reason);
if (reason.getIsTrue()) if (reason.getIsTrue() > 0)
{ {
auto updateFact = rule.getFact(); auto updateFact = rule.getFact();
updateFact.setIsTrue(true); updateFact.setIsTrue(1.0);
updateFact.updateIsTrue(dbConnection_); updateFact.updateIsTrue(dbConnection_);
} }
} }
@ -259,6 +259,11 @@ void obelisk::KnowledgeBase::updateIsTrue(obelisk::Fact& fact)
fact.updateIsTrue(dbConnection_); fact.updateIsTrue(dbConnection_);
} }
void obelisk::KnowledgeBase::queryFact(obelisk::Fact& fact)
{
fact.selectByName(dbConnection_);
}
void obelisk::KnowledgeBase::getFloat(float& result1, void obelisk::KnowledgeBase::getFloat(float& result1,
float& result2, float& result2,
double var) double var)

View File

@ -200,6 +200,8 @@ namespace obelisk
*/ */
void updateIsTrue(obelisk::Fact& fact); void updateIsTrue(obelisk::Fact& fact);
void queryFact(obelisk::Fact& fact);
/** /**
* @brief Take a float and divide it into 2 floats. * @brief Take a float and divide it into 2 floats.
* *

View File

@ -157,6 +157,125 @@ void obelisk::Fact::selectById(sqlite3* dbConnection)
} }
} }
void obelisk::Fact::selectByName(sqlite3* dbConnection)
{
if (dbConnection == nullptr)
{
throw obelisk::DatabaseException("database isn't open");
}
sqlite3_stmt* ppStmt = nullptr;
auto result = sqlite3_prepare_v2(dbConnection,
"SELECT fact.id, fact.left_entity, fact.right_entity, fact.verb, fact.is_true FROM fact LEFT JOIN entity le ON le.id = fact.left_entity LEFT JOIN entity re ON re.id = fact.right_entity LEFT JOIN verb v ON fact.verb = v.id WHERE (le.name=? AND v.name=? AND re.name=?)",
-1,
&ppStmt,
nullptr);
if (result != SQLITE_OK)
{
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
}
result = sqlite3_bind_text(ppStmt,
1,
getLeftEntity().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_bind_text(ppStmt,
2,
getVerb().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_bind_text(ppStmt,
3,
getRightEntity().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));
getLeftEntity().setId(sqlite3_column_int(ppStmt, 1));
getRightEntity().setId(sqlite3_column_int(ppStmt, 2));
getVerb().setId(sqlite3_column_int(ppStmt, 3));
setIsTrue(sqlite3_column_int(ppStmt, 4));
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) void obelisk::Fact::insert(sqlite3* dbConnection)
{ {
if (dbConnection == nullptr) if (dbConnection == nullptr)
@ -404,12 +523,12 @@ void obelisk::Fact::setVerb(obelisk::Verb verb)
verb_ = verb; verb_ = verb;
} }
bool& obelisk::Fact::getIsTrue() double& obelisk::Fact::getIsTrue()
{ {
return isTrue_; return isTrue_;
} }
void obelisk::Fact::setIsTrue(bool isTrue) void obelisk::Fact::setIsTrue(double isTrue)
{ {
isTrue_ = isTrue; isTrue_ = isTrue;
} }

View File

@ -46,7 +46,7 @@ namespace obelisk
* @brief Whether or not the fact is considered true or not. * @brief Whether or not the fact is considered true or not.
* *
*/ */
bool isTrue_; double isTrue_;
public: public:
/** /**
@ -89,7 +89,7 @@ namespace obelisk
Fact(obelisk::Entity leftEntity, Fact(obelisk::Entity leftEntity,
obelisk::Entity rightEntity, obelisk::Entity rightEntity,
obelisk::Verb verb, obelisk::Verb verb,
bool isTrue = false) : double isTrue = 0) :
id_(0), id_(0),
leftEntity_(leftEntity), leftEntity_(leftEntity),
rightEntity_(rightEntity), rightEntity_(rightEntity),
@ -113,7 +113,7 @@ namespace obelisk
obelisk::Entity leftEntity, obelisk::Entity leftEntity,
obelisk::Entity rightEntity, obelisk::Entity rightEntity,
obelisk::Verb verb, obelisk::Verb verb,
bool isTrue = false) : double isTrue = 0) :
id_(id), id_(id),
leftEntity_(leftEntity), leftEntity_(leftEntity),
rightEntity_(rightEntity), rightEntity_(rightEntity),
@ -191,14 +191,14 @@ namespace obelisk
* @return true If the Fact is considered true. * @return true If the Fact is considered true.
* @return false If the Fact is considered false. * @return false If the Fact is considered false.
*/ */
bool& getIsTrue(); double& getIsTrue();
/** /**
* @brief Set the Fact as true or false. * @brief Set the Fact as true or false.
* *
* @param[in] isTrue Whether or not the Fact is true. * @param[in] isTrue Whether or not the Fact is true.
*/ */
void setIsTrue(bool isTrue); void setIsTrue(double isTrue);
/** /**
* @brief Select the Fact from the KnowledgeBase by IDs of the * @brief Select the Fact from the KnowledgeBase by IDs of the
@ -208,6 +208,14 @@ namespace obelisk
*/ */
void selectById(sqlite3* dbConnection); void selectById(sqlite3* dbConnection);
/**
* @brief Select the Fact from the KnowledgeBase by the name's of
* the entities and verb.
*
* @param[in] dbConnection The database connection to use.
*/
void selectByName(sqlite3* dbConnection);
/** /**
* @brief Insert the Fact into the KnowledgeBase. * @brief Insert the Fact into the KnowledgeBase.
* *

View File

@ -4,9 +4,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
CObelisk* obelisk_open() CObelisk* obelisk_open(const char* filename)
{ {
return create_obelisk(); return create_obelisk(filename);
} }
void obelisk_close(CObelisk* obelisk) void obelisk_close(CObelisk* obelisk)
@ -23,3 +23,11 @@ int obelisk_get_lib_version(CObelisk* obelisk)
{ {
return call_obelisk_getLibVersion(obelisk); return call_obelisk_getLibVersion(obelisk);
} }
double obelisk_query(CObelisk* obelisk,
const char* left_entity,
const char* verb,
const char* right_entity)
{
return call_obelisk_query(obelisk, left_entity, verb, right_entity);
}

View File

@ -1,6 +1,12 @@
#include "include/obelisk.h" #include "include/obelisk.h"
#include "version.h" #include "version.h"
obelisk::Obelisk::Obelisk(std::string filename)
{
kb_ = std::unique_ptr<obelisk::KnowledgeBase> {
new obelisk::KnowledgeBase(filename.c_str())};
}
std::string obelisk::Obelisk::getVersion() std::string obelisk::Obelisk::getVersion()
{ {
return obelisk::version; return obelisk::version;
@ -15,10 +21,18 @@ double obelisk::Obelisk::query(const std::string& leftEntity,
const std::string& verb, const std::string& verb,
const std::string& rightEntity) const std::string& rightEntity)
{ {
obelisk::Fact fact = obelisk::Fact(obelisk::Entity(leftEntity),
obelisk::Entity(rightEntity),
obelisk::Verb(verb));
kb_->queryFact(fact);
return fact.getIsTrue();
} }
std::string obelisk::Obelisk::query_action(const std::string& leftEntity, std::string obelisk::Obelisk::query_action(const std::string& leftEntity,
const std::string& verb, const std::string& verb,
const std::string& rightEntity) const std::string& rightEntity)
{ {
return "yes";
} }

View File

@ -5,9 +5,9 @@
extern "C" extern "C"
{ {
CObelisk* create_obelisk() CObelisk* create_obelisk(const char* filename)
{ {
obelisk::Obelisk* obelisk = new obelisk::Obelisk(); obelisk::Obelisk* obelisk = new obelisk::Obelisk(filename);
return reinterpret_cast<CObelisk*>(obelisk); return reinterpret_cast<CObelisk*>(obelisk);
} }
@ -26,6 +26,18 @@ extern "C"
return obelisk->getLibVersion(); return obelisk->getLibVersion();
} }
double call_obelisk_query(CObelisk* p_obelisk,
const char* left_entity,
const char* verb,
const char* right_entity)
{
obelisk::Obelisk* obelisk
= reinterpret_cast<obelisk::Obelisk*>(p_obelisk);
return obelisk->query(std::string(left_entity),
std::string(verb),
std::string(right_entity));
}
void destroy_obelisk(CObelisk* p_obelisk) void destroy_obelisk(CObelisk* p_obelisk)
{ {
obelisk::Obelisk* obelisk obelisk::Obelisk* obelisk

View File

@ -11,9 +11,10 @@ extern "C"
/** /**
* @brief Create a obelisk object. * @brief Create a obelisk object.
* *
* @param[in] filename The name of the obelisk KnowledgeBase file to use.
* @return CObelisk* Returns the obelisk object. * @return CObelisk* Returns the obelisk object.
*/ */
CObelisk *create_obelisk(); CObelisk *create_obelisk(const char *filename);
/** /**
* @brief Calls the obelisk method getVersion. * @brief Calls the obelisk method getVersion.
@ -32,6 +33,20 @@ extern "C"
*/ */
int call_obelisk_getLibVersion(CObelisk *p_obelisk); int call_obelisk_getLibVersion(CObelisk *p_obelisk);
/**
* @brief Calls the obelisk method query.
*
* @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 double Returns whether or not the Fact is true.
*/
double call_obelisk_query(CObelisk *p_obelisk,
const char *left_entity,
const char *verb,
const char *right_entity);
/** /**
* @brief Delete a obelisk object. * @brief Delete a obelisk object.
* *

View File

@ -806,9 +806,9 @@ void obelisk::Parser::handleRule(std::unique_ptr<obelisk::KnowledgeBase>& kb)
insertFact(kb, rule.getReason()); insertFact(kb, rule.getReason());
// The rule is true, so the fact must be true to. // The rule is true, so the fact must be true to.
if (rule.getReason().getIsTrue()) if (rule.getReason().getIsTrue() > 0)
{ {
rule.getFact().setIsTrue(true); rule.getFact().setIsTrue(1.0);
} }
insertEntity(kb, rule.getFact().getLeftEntity()); insertEntity(kb, rule.getFact().getLeftEntity());
@ -957,7 +957,7 @@ void obelisk::Parser::insertFact(std::unique_ptr<obelisk::KnowledgeBase>& kb,
{ {
if (updateIsTrue) if (updateIsTrue)
{ {
fact.setIsTrue(true); fact.setIsTrue(1.0);
kb->updateIsTrue(fact); kb->updateIsTrue(fact);
} }
} }