feature/fact_knowledge_base #7

Merged
cromer merged 7 commits from feature/fact_knowledge_base into develop 2022-11-29 00:07:51 -03:00
18 changed files with 547 additions and 86 deletions
Showing only changes of commit 3bc6ebe4d8 - Show all commits

View File

@ -9,11 +9,6 @@
#include <filesystem> #include <filesystem>
#include <iostream> #include <iostream>
obelisk::KnowledgeBase::KnowledgeBase(const char* filename)
{
KnowledgeBase(filename, DEFAULT_FLAGS);
}
obelisk::KnowledgeBase::KnowledgeBase(const char* filename, int flags) obelisk::KnowledgeBase::KnowledgeBase(const char* filename, int flags)
{ {
filename_ = std::move(filename); filename_ = std::move(filename);
@ -66,6 +61,33 @@ void obelisk::KnowledgeBase::createTable(std::function<const char*()> function)
} }
} }
int obelisk::KnowledgeBase::addEntities(std::vector<obelisk::Entity>& entities)
{
for (auto& entity : entities)
{
entity.insertEntity(dbConnection_);
}
return 0;
}
int obelisk::KnowledgeBase::addVerbs(std::vector<obelisk::Verb>& verbs)
{
for (auto& verb : verbs)
{
verb.insertVerb(dbConnection_);
}
return 0;
}
int obelisk::KnowledgeBase::addFacts(std::vector<obelisk::Fact>& facts)
{
for (auto& fact : facts)
{
fact.insertFact(dbConnection_);
}
return 0;
}
// TODO: log files? // TODO: log files?
void obelisk::KnowledgeBase::logSqliteError(int result) void obelisk::KnowledgeBase::logSqliteError(int result)
{ {

View File

@ -1,10 +1,15 @@
#ifndef OBELISK_KNOWLEDGE_BASE_H #ifndef OBELISK_KNOWLEDGE_BASE_H
#define OBELISK_KNOWLEDGE_BASE_H #define OBELISK_KNOWLEDGE_BASE_H
#include "models/entity.h"
#include "models/fact.h"
#include "models/verb.h"
#include <sqlite3.h> #include <sqlite3.h>
#include <functional> #include <functional>
#include <iostream> #include <iostream>
#include <memory>
#include <string> #include <string>
namespace obelisk namespace obelisk
@ -22,16 +27,19 @@ namespace obelisk
void createTable(std::function<const char*()> function); void createTable(std::function<const char*()> function);
public: public:
KnowledgeBase(const char* filename);
KnowledgeBase(const char* filename, int flags); KnowledgeBase(const char* filename, int flags);
KnowledgeBase(const char* filename) :
KnowledgeBase(filename,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)
{
}
~KnowledgeBase(); ~KnowledgeBase();
template<typename T, typename U> int addEntities(std::vector<obelisk::Entity>& entities);
int addFacts(std::string verb, T leftEntities, U rightEntities); int addVerbs(std::vector<obelisk::Verb>& verbs);
// TODO: add parameter for fact int addFacts(std::vector<obelisk::Fact>& facts);
template<typename T, typename U>
int addRules(std::string verb, T leftEntities, U rightEntities);
template<typename T, typename U> int addActions();
void getDouble(double& result, float var1, float var2); void getDouble(double& result, float var1, float var2);
void getFloat(float& result1, float& result2, double var); void getFloat(float& result1, float& result2, double var);

View File

@ -11,7 +11,7 @@ const char* obelisk::Action::createTable()
)"; )";
} }
int obelisk::Action::getId() int& obelisk::Action::getId()
{ {
return id_; return id_;
} }
@ -21,7 +21,7 @@ void obelisk::Action::setId(int id)
id_ = id; id_ = id;
} }
std::string obelisk::Action::getName() std::string& obelisk::Action::getName()
{ {
return name_; return name_;
} }

View File

@ -38,10 +38,10 @@ namespace obelisk
static const char* createTable(); static const char* createTable();
int getId(); int& getId();
void setId(int id); void setId(int id);
std::string getName(); std::string& getName();
void setName(std::string name); void setName(std::string name);
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -11,7 +11,116 @@ const char* obelisk::Entity::createTable()
)"; )";
} }
int obelisk::Entity::getId() obelisk::Entity obelisk::Entity::selectEntity(sqlite3* dbConnection,
std::string name)
{
// TODO: check if database is open
sqlite3_stmt* ppStmt = nullptr;
const char* pzTail = nullptr;
auto result = sqlite3_prepare_v2(dbConnection,
"SELECT id, name FROM entity WHERE name=?;",
-1,
&ppStmt,
&pzTail);
if (result != SQLITE_OK)
{
// TODO: something went wrong throw an error
}
if (pzTail != nullptr)
{
// TODO: Something was not used... throw an error
}
result = sqlite3_bind_text(ppStmt, 1, name.c_str(), -1, SQLITE_TRANSIENT);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
result = sqlite3_step(ppStmt);
if (result != SQLITE_DONE)
{
// TODO: Something is wrong... throw an error
}
if (result == SQLITE_ROW)
{
auto id = sqlite3_column_int(ppStmt, 0);
std::string name((char*) sqlite3_column_text(ppStmt, 1));
result = sqlite3_finalize(ppStmt);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
return Entity(id, name);
}
else
{
result = sqlite3_finalize(ppStmt);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
return Entity();
}
}
int obelisk::Entity::insertEntity(sqlite3* dbConnection)
{
// TODO: check if database is open
if (selectEntity(dbConnection, getName()).getId() != 0)
{
// TODO: already exists in database, throw an error? Or skip past it?
return -1;
}
sqlite3_stmt* ppStmt = nullptr;
const char* pzTail = nullptr;
auto result = sqlite3_prepare_v2(dbConnection,
"INSERT INTO entity (name) VALUES (?);",
-1,
&ppStmt,
&pzTail);
if (result != SQLITE_OK)
{
// TODO: something went wrong throw an error
}
if (pzTail != nullptr)
{
// TODO: Something was not used... throw an error
}
result
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
result = sqlite3_step(ppStmt);
if (result != SQLITE_DONE)
{
// TODO: Something is wrong... throw an error
}
setId((int) sqlite3_last_insert_rowid(dbConnection));
result = sqlite3_finalize(ppStmt);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
return 0;
}
int& obelisk::Entity::getId()
{ {
return id_; return id_;
} }
@ -21,7 +130,7 @@ void obelisk::Entity::setId(int id)
id_ = id; id_ = id;
} }
std::string obelisk::Entity::getName() std::string& obelisk::Entity::getName()
{ {
return name_; return name_;
} }

View File

@ -1,6 +1,8 @@
#ifndef OBELISK_MODELS_ENTITY_H #ifndef OBELISK_MODELS_ENTITY_H
#define OBELISK_MODELS_ENTITY_H #define OBELISK_MODELS_ENTITY_H
#include <sqlite3.h>
#include <string> #include <string>
namespace obelisk namespace obelisk
@ -38,11 +40,14 @@ namespace obelisk
static const char* createTable(); static const char* createTable();
int getId(); int& getId();
void setId(int id); void setId(int id);
std::string getName(); std::string& getName();
void setName(std::string name); void setName(std::string name);
Entity selectEntity(sqlite3* dbConnection, std::string name);
int insertEntity(sqlite3* dbConnection);
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -16,7 +16,152 @@ const char* obelisk::Fact::createTable()
)"; )";
} }
int obelisk::Fact::getId() obelisk::Fact obelisk::Fact::selectFact(sqlite3* dbConnection,
int idLeftEntity,
int idRightEntity,
int idVerb)
{
// TODO: check if database is open
sqlite3_stmt* ppStmt = nullptr;
const char* pzTail = nullptr;
auto result = sqlite3_prepare_v2(dbConnection,
"SELECT id, left_entity, right_entity, verb FROM fact WHERE (left_entity=? AND right_entity=? AND verb=?);",
-1,
&ppStmt,
&pzTail);
if (result != SQLITE_OK)
{
// TODO: something went wrong throw an error
}
if (pzTail != nullptr)
{
// TODO: Something was not used... throw an error
}
result = sqlite3_bind_int(ppStmt, 1, getLeftEntity().getId());
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
result = sqlite3_bind_int(ppStmt, 2, getRightEntity().getId());
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
result = sqlite3_bind_int(ppStmt, 3, getVerb().getId());
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
result = sqlite3_step(ppStmt);
if (result != SQLITE_DONE)
{
// TODO: Something is wrong... throw an error
}
if (result == SQLITE_ROW)
{
auto id = sqlite3_column_int(ppStmt, 0);
auto leftEntity = sqlite3_column_int(ppStmt, 1);
auto rightEntity = sqlite3_column_int(ppStmt, 2);
auto verb = sqlite3_column_int(ppStmt, 3);
result = sqlite3_finalize(ppStmt);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
return Fact(id, leftEntity, rightEntity, verb);
}
else
{
result = sqlite3_finalize(ppStmt);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
return Fact();
}
}
int obelisk::Fact::insertFact(sqlite3* dbConnection)
{
// TODO: make sure database is open
// check if the fact id exists, based on the ids of the entities and verb
if (selectFact(dbConnection,
getLeftEntity().getId(),
getRightEntity().getId(),
getVerb().getId())
.getId()
!= 0)
{
// TODO: Verb is already in database, throw an error? Or just skip it?
return -1;
}
// TODO: verify that verbId, leftEntityId, and rightEntityId are not 0
sqlite3_stmt* ppStmt = nullptr;
const char* pzTail = nullptr;
auto result = sqlite3_prepare_v2(dbConnection,
"INSERT INTO fact (left_entity, right_entity, verb) VALUES (?, ?, ?);",
-1,
&ppStmt,
&pzTail);
if (result != SQLITE_OK)
{
// TODO: something went wrong throw an error
}
if (pzTail != nullptr)
{
// TODO: Something was not used... throw an error
}
result = sqlite3_bind_int(ppStmt, 1, getLeftEntity().getId());
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
result = sqlite3_bind_int(ppStmt, 2, getRightEntity().getId());
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
result = sqlite3_bind_int(ppStmt, 3, getVerb().getId());
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
result = sqlite3_step(ppStmt);
if (result != SQLITE_DONE)
{
// TODO: Something is wrong... throw an error
}
setId((int) sqlite3_last_insert_rowid(dbConnection));
result = sqlite3_finalize(ppStmt);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
return 0;
}
int& obelisk::Fact::getId()
{ {
return id_; return id_;
} }
@ -26,7 +171,7 @@ void obelisk::Fact::setId(int id)
id_ = id; id_ = id;
} }
obelisk::Entity obelisk::Fact::getLeftEntity() obelisk::Entity& obelisk::Fact::getLeftEntity()
{ {
return leftEntity_; return leftEntity_;
} }
@ -36,7 +181,7 @@ void obelisk::Fact::setLeftEntity(obelisk::Entity leftEntity)
leftEntity_ = leftEntity; leftEntity_ = leftEntity;
} }
obelisk::Entity obelisk::Fact::getRightEntity() obelisk::Entity& obelisk::Fact::getRightEntity()
{ {
return rightEntity_; return rightEntity_;
} }
@ -46,7 +191,7 @@ void obelisk::Fact::setRightEntity(obelisk::Entity rightEntity)
rightEntity_ = rightEntity; rightEntity_ = rightEntity;
} }
obelisk::Verb obelisk::Fact::getVerb() obelisk::Verb& obelisk::Fact::getVerb()
{ {
return verb_; return verb_;
} }

View File

@ -2,6 +2,7 @@
#define OBELISK_MODELS_FACT_H #define OBELISK_MODELS_FACT_H
#include "models/entity.h" #include "models/entity.h"
#include "models/fact.h"
#include "models/verb.h" #include "models/verb.h"
#include <string> #include <string>
@ -56,17 +57,24 @@ namespace obelisk
static const char* createTable(); static const char* createTable();
int getId(); int& getId();
void setId(int id); void setId(int id);
obelisk::Entity getLeftEntity(); Entity& getLeftEntity();
void setLeftEntity(obelisk::Entity leftEntity); void setLeftEntity(obelisk::Entity leftEntity);
obelisk::Entity getRightEntity(); Entity& getRightEntity();
void setRightEntity(obelisk::Entity leftEntity); void setRightEntity(obelisk::Entity leftEntity);
obelisk::Verb getVerb(); Verb& getVerb();
void setVerb(obelisk::Verb verb); void setVerb(obelisk::Verb verb);
Fact selectFact(sqlite3* dbConnection,
int idLeftEntity,
int idRightEntity,
int idVerb);
int insertFact(sqlite3* dbConnection);
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -14,7 +14,7 @@ const char* obelisk::Rule::createTable()
)"; )";
} }
int obelisk::Rule::getId() int& obelisk::Rule::getId()
{ {
return id_; return id_;
} }
@ -24,7 +24,7 @@ void obelisk::Rule::setId(int id)
id_ = id; id_ = id;
} }
obelisk::Fact obelisk::Rule::getFact() obelisk::Fact& obelisk::Rule::getFact()
{ {
return fact_; return fact_;
} }
@ -34,7 +34,7 @@ void obelisk::Rule::setFact(obelisk::Fact fact)
fact_ = fact; fact_ = fact;
} }
obelisk::Fact obelisk::Rule::getReason() obelisk::Fact& obelisk::Rule::getReason()
{ {
return reason_; return reason_;
} }

View File

@ -45,13 +45,13 @@ namespace obelisk
static const char* createTable(); static const char* createTable();
int getId(); int& getId();
void setId(int id); void setId(int id);
obelisk::Fact getFact(); obelisk::Fact& getFact();
void setFact(obelisk::Fact fact); void setFact(obelisk::Fact fact);
obelisk::Fact getReason(); obelisk::Fact& getReason();
void setReason(obelisk::Fact reason); void setReason(obelisk::Fact reason);
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -16,7 +16,7 @@ const char* obelisk::SuggestAction::createTable()
)"; )";
} }
int obelisk::SuggestAction::getId() int& obelisk::SuggestAction::getId()
{ {
return id_; return id_;
} }
@ -26,7 +26,7 @@ void obelisk::SuggestAction::setId(int id)
id_ = id; id_ = id;
} }
obelisk::Fact obelisk::SuggestAction::getFact() obelisk::Fact& obelisk::SuggestAction::getFact()
{ {
return fact_; return fact_;
} }
@ -36,7 +36,7 @@ void obelisk::SuggestAction::setFact(obelisk::Fact fact)
fact_ = fact; fact_ = fact;
} }
obelisk::Action obelisk::SuggestAction::getTrueAction() obelisk::Action& obelisk::SuggestAction::getTrueAction()
{ {
return trueAction_; return trueAction_;
} }
@ -46,7 +46,7 @@ void obelisk::SuggestAction::setTrueAction(obelisk::Action trueAction)
trueAction_ = trueAction; trueAction_ = trueAction;
} }
obelisk::Action obelisk::SuggestAction::getFalseAction() obelisk::Action& obelisk::SuggestAction::getFalseAction()
{ {
return falseAction_; return falseAction_;
} }

View File

@ -56,16 +56,16 @@ namespace obelisk
static const char* createTable(); static const char* createTable();
int getId(); int& getId();
void setId(int id); void setId(int id);
obelisk::Fact getFact(); obelisk::Fact& getFact();
void setFact(obelisk::Fact fact); void setFact(obelisk::Fact fact);
obelisk::Action getTrueAction(); obelisk::Action& getTrueAction();
void setTrueAction(obelisk::Action trueAction); void setTrueAction(obelisk::Action trueAction);
obelisk::Action getFalseAction(); obelisk::Action& getFalseAction();
void setFalseAction(obelisk::Action falseAction); void setFalseAction(obelisk::Action falseAction);
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -1,5 +1,7 @@
#include "models/verb.h" #include "models/verb.h"
#include <iostream>
const char* obelisk::Verb::createTable() const char* obelisk::Verb::createTable()
{ {
return R"( return R"(
@ -11,7 +13,116 @@ const char* obelisk::Verb::createTable()
)"; )";
} }
int obelisk::Verb::getId() obelisk::Verb obelisk::Verb::selectVerb(sqlite3* dbConnection, std::string name)
{
// TODO: check if database is open
sqlite3_stmt* ppStmt = nullptr;
const char* pzTail = nullptr;
auto result = sqlite3_prepare_v2(dbConnection,
"SELECT id, name FROM verb WHERE name=?;",
-1,
&ppStmt,
&pzTail);
if (result != SQLITE_OK)
{
// TODO: something went wrong throw an error
}
if (pzTail != nullptr)
{
// TODO: Something was not used... throw an error
}
result = sqlite3_bind_text(ppStmt, 1, name.c_str(), -1, SQLITE_TRANSIENT);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
result = sqlite3_step(ppStmt);
if (result != SQLITE_DONE)
{
// TODO: Something is wrong... throw an error
}
if (result == SQLITE_ROW)
{
auto id = sqlite3_column_int(ppStmt, 0);
std::string name((char*) sqlite3_column_text(ppStmt, 1));
result = sqlite3_finalize(ppStmt);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
return Verb(id, name);
}
else
{
result = sqlite3_finalize(ppStmt);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
return Verb();
}
}
int obelisk::Verb::insertVerb(sqlite3* dbConnection)
{
// TODO: make sure database is open
if (selectVerb(dbConnection, getName()).getId() != 0)
{
// TODO: Verb is already in database, throw an error? Or just skip it?
return -1;
}
sqlite3_stmt* ppStmt = nullptr;
const char* pzTail = nullptr;
auto result = sqlite3_prepare_v2(dbConnection,
"INSERT INTO verb (name) VALUES (?);",
-1,
&ppStmt,
&pzTail);
if (result != SQLITE_OK)
{
// TODO: something went wrong throw an error
}
if (pzTail != nullptr)
{
// TODO: Something was not used... throw an error
}
result
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
result = sqlite3_step(ppStmt);
if (result != SQLITE_DONE)
{
// TODO: Something is wrong... throw an error
}
setId((int) sqlite3_last_insert_rowid(dbConnection));
result = sqlite3_finalize(ppStmt);
if (result != SQLITE_OK)
{
// TODO: Something is wrong... throw an error
}
return 0;
}
int& obelisk::Verb::getId()
{ {
return id_; return id_;
} }
@ -21,7 +132,7 @@ void obelisk::Verb::setId(int id)
id_ = id; id_ = id;
} }
std::string obelisk::Verb::getName() std::string& obelisk::Verb::getName()
{ {
return name_; return name_;
} }

View File

@ -1,6 +1,8 @@
#ifndef OBELISK_MODELS_VERB_H #ifndef OBELISK_MODELS_VERB_H
#define OBELISK_MODELS_VERB_H #define OBELISK_MODELS_VERB_H
#include <sqlite3.h>
#include <string> #include <string>
namespace obelisk namespace obelisk
@ -38,11 +40,14 @@ namespace obelisk
static const char* createTable(); static const char* createTable();
int getId(); int& getId();
void setId(int id); void setId(int id);
std::string getName(); std::string& getName();
void setName(std::string name); void setName(std::string name);
Verb selectVerb(sqlite3* dbConnection, std::string name);
int insertVerb(sqlite3* dbConnection);
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -8,9 +8,21 @@
#include <limits> #include <limits>
#include <memory> #include <memory>
static void mainLoop() static int mainLoop()
{ {
auto parser = std::unique_ptr<obelisk::Parser> {new obelisk::Parser()}; auto parser = std::unique_ptr<obelisk::Parser> {new obelisk::Parser()};
std::unique_ptr<obelisk::KnowledgeBase> kb;
try
{
kb = std::unique_ptr<obelisk::KnowledgeBase> {
new obelisk::KnowledgeBase("cromer.kb")};
}
catch (obelisk::KnowledgeBaseException& exception)
{
std::cout << exception.what() << std::endl;
return EXIT_FAILURE;
}
// Prime the first token. // Prime the first token.
fprintf(stderr, "ready> "); fprintf(stderr, "ready> ");
@ -22,7 +34,7 @@ static void mainLoop()
switch (parser->getCurrentToken()) switch (parser->getCurrentToken())
{ {
case obelisk::Lexer::kTokenEof : case obelisk::Lexer::kTokenEof :
return; return EXIT_SUCCESS;
case ';' : // ignore top-level semicolons. case ';' : // ignore top-level semicolons.
std::cout << "Identifier: " std::cout << "Identifier: "
<< parser->getLexer()->getIdentifier() << std::endl; << parser->getLexer()->getIdentifier() << std::endl;
@ -31,19 +43,21 @@ static void mainLoop()
parser->getNextToken(); parser->getNextToken();
break; break;
case obelisk::Lexer::kTokenFact : case obelisk::Lexer::kTokenFact :
// parser->handleFactFunction(); parser->handleFact(kb);
break; break;
case obelisk::Lexer::kTokenRule : case obelisk::Lexer::kTokenRule :
// parser->handleRuleFunction(); // parser->handleRule();
break; break;
case obelisk::Lexer::kTokenAction : case obelisk::Lexer::kTokenAction :
// parser->handleActionFunction(); // parser->handleAction();
break; break;
default : default :
parser->getNextToken(); parser->getNextToken();
break; break;
} }
} }
return EXIT_SUCCESS;
} }
int main(int argc, char** argv) int main(int argc, char** argv)
@ -79,28 +93,5 @@ int main(int argc, char** argv)
return EXIT_FAILURE; return EXIT_FAILURE;
}*/ }*/
try return mainLoop();
{
auto kb = std::unique_ptr<obelisk::KnowledgeBase> {
new obelisk::KnowledgeBase("cromer.kb")};
/*std::vector<std::string> leftObjects;
std::vector<std::string> rightObjects;
leftObjects.push_back("chris");
leftObjects.push_back("martin");
rightObjects.push_back("happy");
rightObjects.push_back("smart");
kb->addFacts("is", leftObjects, rightObjects);*/
}
catch (obelisk::KnowledgeBaseException& exception)
{
std::cout << exception.what() << std::endl;
return EXIT_FAILURE;
}
mainLoop();
return EXIT_SUCCESS;
} }

View File

@ -1 +1 @@
static void mainLoop(); static int mainLoop();

View File

@ -1,6 +1,9 @@
#include "ast/call_expression_ast.h" #include "ast/call_expression_ast.h"
#include "ast/number_expression_ast.h" #include "ast/number_expression_ast.h"
#include "ast/variable_expression_ast.h" #include "ast/variable_expression_ast.h"
#include "models/entity.h"
#include "models/fact.h"
#include "models/verb.h"
#include "parser.h" #include "parser.h"
#include <memory> #include <memory>
@ -212,17 +215,19 @@ std::unique_ptr<obelisk::PrototypeAST> obelisk::Parser::parseExtern()
return parsePrototype(); return parsePrototype();
} }
//action("martin" is "dangerous" then "avoid" or "ignore");
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseAction() std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseAction()
{ {
} }
//rule("chris" and "martin" is "happy" if "chris" plays "playstation");
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseRule() std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseRule()
{ {
} }
// fact("chris cromer" and "martin" and "Isabella" can "program" and "speak english"); // fact("chris cromer" and "martin" and "Isabella" can "program" and "speak english");
// fact("" and "martin") // fact("" and "martin")
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseFact() void obelisk::Parser::parseFact(std::vector<obelisk::Fact>& facts)
{ {
std::stack<char> syntax; std::stack<char> syntax;
@ -329,18 +334,68 @@ std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseFact()
} }
} }
return nullptr; for (auto& leftEntity : leftEntities)
{
for (auto& rightEntity : rightEntities)
{
facts.push_back(obelisk::Fact(obelisk::Entity(leftEntity),
obelisk::Entity(rightEntity),
obelisk::Verb(verb)));
}
}
} }
void obelisk::Parser::handleAction() void obelisk::Parser::handleAction(std::unique_ptr<obelisk::KnowledgeBase>& kb)
{ {
} }
void obelisk::Parser::handleRule() void obelisk::Parser::handleRule(std::unique_ptr<obelisk::KnowledgeBase>& kb)
{ {
} }
void obelisk::Parser::handleFact() void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
{ {
parseFact(); std::vector<obelisk::Fact> facts;
parseFact(facts);
int verbId = 0;
for (auto& fact : facts)
{
// TODO: doesn't work after first insert
std::vector<obelisk::Entity> entities {fact.getLeftEntity()};
kb->addEntities(entities);
fact.setLeftEntity(entities.front());
entities = {fact.getRightEntity()};
kb->addEntities(entities);
fact.setRightEntity(entities.front());
if (verbId == 0)
{
std::vector<obelisk::Verb> verbs = {fact.getVerb()};
kb->addVerbs(verbs);
if (verbs.front().getId() != 0)
{
// The verb was inserted
fact.setVerb(verbs.front());
verbId = fact.getVerb().getId();
} }
else
{
// The verb is already already in the knowledge base
// TODO: SELECT the verb and save it into verbId
}
}
else
{
fact.getVerb().setId(verbId);
}
// INSERT INTO fact
std::vector<obelisk::Fact> facts {fact};
kb->addFacts(facts);
fact = facts.front();
}
}
// fact("chris cromer" and "martin" and "Isabella" can "program" and "speak english");

View File

@ -4,7 +4,9 @@
#include "ast/expression_ast.h" #include "ast/expression_ast.h"
#include "ast/function_ast.h" #include "ast/function_ast.h"
#include "ast/prototype_ast.h" #include "ast/prototype_ast.h"
#include "knowledge_base.h"
#include "lexer.h" #include "lexer.h"
#include "models/fact.h"
#include <memory> #include <memory>
@ -34,7 +36,7 @@ namespace obelisk
std::unique_ptr<obelisk::PrototypeAST> parseExtern(); std::unique_ptr<obelisk::PrototypeAST> parseExtern();
std::unique_ptr<obelisk::ExpressionAST> parseAction(); std::unique_ptr<obelisk::ExpressionAST> parseAction();
std::unique_ptr<obelisk::ExpressionAST> parseRule(); std::unique_ptr<obelisk::ExpressionAST> parseRule();
std::unique_ptr<obelisk::ExpressionAST> parseFact(); void parseFact(std::vector<obelisk::Fact>& facts);
public: public:
Parser(); Parser();
@ -48,9 +50,9 @@ namespace obelisk
void handleDefinition(); void handleDefinition();
void handleExtern(); void handleExtern();
void handleTopLevelExpression(); void handleTopLevelExpression();
void handleAction(); void handleAction(std::unique_ptr<obelisk::KnowledgeBase>& kb);
void handleRule(); void handleRule(std::unique_ptr<obelisk::KnowledgeBase>& kb);
void handleFact(); void handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb);
}; };
class ParserException : public std::exception class ParserException : public std::exception