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

View File

@ -15,9 +15,10 @@ extern "C"
/**
* @brief Create an obelisk object.
*
* @param[in] filename The obelisk KnowledgeBase file to use.
* @return CObelisk* Returns an obelisk object.
*/
extern CObelisk* obelisk_open();
extern CObelisk* obelisk_open(const char* filename);
/**
* @brief Delete an obelisk object.
@ -35,6 +36,20 @@ extern "C"
*/
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.
*

View File

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

View File

@ -200,6 +200,8 @@ namespace obelisk
*/
void updateIsTrue(obelisk::Fact& fact);
void queryFact(obelisk::Fact& fact);
/**
* @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)
{
if (dbConnection == nullptr)
@ -404,12 +523,12 @@ void obelisk::Fact::setVerb(obelisk::Verb verb)
verb_ = verb;
}
bool& obelisk::Fact::getIsTrue()
double& obelisk::Fact::getIsTrue()
{
return isTrue_;
}
void obelisk::Fact::setIsTrue(bool isTrue)
void obelisk::Fact::setIsTrue(double isTrue)
{
isTrue_ = isTrue;
}

View File

@ -46,7 +46,7 @@ namespace obelisk
* @brief Whether or not the fact is considered true or not.
*
*/
bool isTrue_;
double isTrue_;
public:
/**
@ -89,7 +89,7 @@ namespace obelisk
Fact(obelisk::Entity leftEntity,
obelisk::Entity rightEntity,
obelisk::Verb verb,
bool isTrue = false) :
double isTrue = 0) :
id_(0),
leftEntity_(leftEntity),
rightEntity_(rightEntity),
@ -113,7 +113,7 @@ namespace obelisk
obelisk::Entity leftEntity,
obelisk::Entity rightEntity,
obelisk::Verb verb,
bool isTrue = false) :
double isTrue = 0) :
id_(id),
leftEntity_(leftEntity),
rightEntity_(rightEntity),
@ -191,14 +191,14 @@ namespace obelisk
* @return true If the Fact is considered true.
* @return false If the Fact is considered false.
*/
bool& getIsTrue();
double& getIsTrue();
/**
* @brief Set the Fact as true or false.
*
* @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
@ -208,6 +208,14 @@ namespace obelisk
*/
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.
*

View File

@ -4,9 +4,9 @@
#include <stdlib.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)
@ -23,3 +23,11 @@ int obelisk_get_lib_version(CObelisk* 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 "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()
{
return obelisk::version;
@ -15,10 +21,18 @@ double obelisk::Obelisk::query(const std::string& leftEntity,
const std::string& verb,
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,
const std::string& verb,
const std::string& rightEntity)
{
return "yes";
}

View File

@ -5,9 +5,9 @@
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);
}
@ -26,6 +26,18 @@ extern "C"
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)
{
obelisk::Obelisk* obelisk

View File

@ -11,9 +11,10 @@ extern "C"
/**
* @brief Create a obelisk object.
*
* @param[in] filename The name of the obelisk KnowledgeBase file to use.
* @return CObelisk* Returns the obelisk object.
*/
CObelisk *create_obelisk();
CObelisk *create_obelisk(const char *filename);
/**
* @brief Calls the obelisk method getVersion.
@ -32,6 +33,20 @@ extern "C"
*/
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.
*

View File

@ -806,9 +806,9 @@ void obelisk::Parser::handleRule(std::unique_ptr<obelisk::KnowledgeBase>& kb)
insertFact(kb, rule.getReason());
// 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());
@ -957,7 +957,7 @@ void obelisk::Parser::insertFact(std::unique_ptr<obelisk::KnowledgeBase>& kb,
{
if (updateIsTrue)
{
fact.setIsTrue(true);
fact.setIsTrue(1.0);
kb->updateIsTrue(fact);
}
}