diff --git a/src/knowledge_base.cpp b/src/knowledge_base.cpp index ce47572..b248b66 100644 --- a/src/knowledge_base.cpp +++ b/src/knowledge_base.cpp @@ -9,11 +9,6 @@ #include #include -obelisk::KnowledgeBase::KnowledgeBase(const char* filename) -{ - KnowledgeBase(filename, DEFAULT_FLAGS); -} - obelisk::KnowledgeBase::KnowledgeBase(const char* filename, int flags) { filename_ = std::move(filename); @@ -66,6 +61,33 @@ void obelisk::KnowledgeBase::createTable(std::function function) } } +int obelisk::KnowledgeBase::addEntities(std::vector& entities) +{ + for (auto& entity : entities) + { + entity.insertEntity(dbConnection_); + } + return 0; +} + +int obelisk::KnowledgeBase::addVerbs(std::vector& verbs) +{ + for (auto& verb : verbs) + { + verb.insertVerb(dbConnection_); + } + return 0; +} + +int obelisk::KnowledgeBase::addFacts(std::vector& facts) +{ + for (auto& fact : facts) + { + fact.insertFact(dbConnection_); + } + return 0; +} + // TODO: log files? void obelisk::KnowledgeBase::logSqliteError(int result) { diff --git a/src/knowledge_base.h b/src/knowledge_base.h index 52e742f..4e79c74 100644 --- a/src/knowledge_base.h +++ b/src/knowledge_base.h @@ -1,10 +1,15 @@ #ifndef OBELISK_KNOWLEDGE_BASE_H #define OBELISK_KNOWLEDGE_BASE_H +#include "models/entity.h" +#include "models/fact.h" +#include "models/verb.h" + #include #include #include +#include #include namespace obelisk @@ -22,16 +27,19 @@ namespace obelisk void createTable(std::function function); public: - KnowledgeBase(const char* filename); KnowledgeBase(const char* filename, int flags); + + KnowledgeBase(const char* filename) : + KnowledgeBase(filename, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) + { + } + ~KnowledgeBase(); - template - int addFacts(std::string verb, T leftEntities, U rightEntities); - // TODO: add parameter for fact - template - int addRules(std::string verb, T leftEntities, U rightEntities); - template int addActions(); + int addEntities(std::vector& entities); + int addVerbs(std::vector& verbs); + int addFacts(std::vector& facts); void getDouble(double& result, float var1, float var2); void getFloat(float& result1, float& result2, double var); diff --git a/src/models/action.cpp b/src/models/action.cpp index 620b6e6..bb6ed06 100644 --- a/src/models/action.cpp +++ b/src/models/action.cpp @@ -11,7 +11,7 @@ const char* obelisk::Action::createTable() )"; } -int obelisk::Action::getId() +int& obelisk::Action::getId() { return id_; } @@ -21,7 +21,7 @@ void obelisk::Action::setId(int id) id_ = id; } -std::string obelisk::Action::getName() +std::string& obelisk::Action::getName() { return name_; } diff --git a/src/models/action.h b/src/models/action.h index d24ba8c..7940f2b 100644 --- a/src/models/action.h +++ b/src/models/action.h @@ -38,10 +38,10 @@ namespace obelisk static const char* createTable(); - int getId(); + int& getId(); void setId(int id); - std::string getName(); + std::string& getName(); void setName(std::string name); }; } // namespace obelisk diff --git a/src/models/entity.cpp b/src/models/entity.cpp index 3345e47..1a4fe78 100644 --- a/src/models/entity.cpp +++ b/src/models/entity.cpp @@ -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_; } @@ -21,7 +130,7 @@ void obelisk::Entity::setId(int id) id_ = id; } -std::string obelisk::Entity::getName() +std::string& obelisk::Entity::getName() { return name_; } diff --git a/src/models/entity.h b/src/models/entity.h index b73f7c9..f83337c 100644 --- a/src/models/entity.h +++ b/src/models/entity.h @@ -1,6 +1,8 @@ #ifndef OBELISK_MODELS_ENTITY_H #define OBELISK_MODELS_ENTITY_H +#include + #include namespace obelisk @@ -38,11 +40,14 @@ namespace obelisk static const char* createTable(); - int getId(); + int& getId(); void setId(int id); - std::string getName(); + std::string& getName(); void setName(std::string name); + + Entity selectEntity(sqlite3* dbConnection, std::string name); + int insertEntity(sqlite3* dbConnection); }; } // namespace obelisk diff --git a/src/models/fact.cpp b/src/models/fact.cpp index 132c80b..6a02b97 100644 --- a/src/models/fact.cpp +++ b/src/models/fact.cpp @@ -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_; } @@ -26,7 +171,7 @@ void obelisk::Fact::setId(int id) id_ = id; } -obelisk::Entity obelisk::Fact::getLeftEntity() +obelisk::Entity& obelisk::Fact::getLeftEntity() { return leftEntity_; } @@ -36,7 +181,7 @@ void obelisk::Fact::setLeftEntity(obelisk::Entity leftEntity) leftEntity_ = leftEntity; } -obelisk::Entity obelisk::Fact::getRightEntity() +obelisk::Entity& obelisk::Fact::getRightEntity() { return rightEntity_; } @@ -46,7 +191,7 @@ void obelisk::Fact::setRightEntity(obelisk::Entity rightEntity) rightEntity_ = rightEntity; } -obelisk::Verb obelisk::Fact::getVerb() +obelisk::Verb& obelisk::Fact::getVerb() { return verb_; } diff --git a/src/models/fact.h b/src/models/fact.h index 6553058..3fc5987 100644 --- a/src/models/fact.h +++ b/src/models/fact.h @@ -2,6 +2,7 @@ #define OBELISK_MODELS_FACT_H #include "models/entity.h" +#include "models/fact.h" #include "models/verb.h" #include @@ -56,17 +57,24 @@ namespace obelisk static const char* createTable(); - int getId(); + int& getId(); void setId(int id); - obelisk::Entity getLeftEntity(); + Entity& getLeftEntity(); void setLeftEntity(obelisk::Entity leftEntity); - obelisk::Entity getRightEntity(); + Entity& getRightEntity(); void setRightEntity(obelisk::Entity leftEntity); - obelisk::Verb getVerb(); + Verb& getVerb(); void setVerb(obelisk::Verb verb); + + Fact selectFact(sqlite3* dbConnection, + int idLeftEntity, + int idRightEntity, + int idVerb); + + int insertFact(sqlite3* dbConnection); }; } // namespace obelisk diff --git a/src/models/rule.cpp b/src/models/rule.cpp index 3282743..e9bde88 100644 --- a/src/models/rule.cpp +++ b/src/models/rule.cpp @@ -14,7 +14,7 @@ const char* obelisk::Rule::createTable() )"; } -int obelisk::Rule::getId() +int& obelisk::Rule::getId() { return id_; } @@ -24,7 +24,7 @@ void obelisk::Rule::setId(int id) id_ = id; } -obelisk::Fact obelisk::Rule::getFact() +obelisk::Fact& obelisk::Rule::getFact() { return fact_; } @@ -34,7 +34,7 @@ void obelisk::Rule::setFact(obelisk::Fact fact) fact_ = fact; } -obelisk::Fact obelisk::Rule::getReason() +obelisk::Fact& obelisk::Rule::getReason() { return reason_; } diff --git a/src/models/rule.h b/src/models/rule.h index f120896..ae75a85 100644 --- a/src/models/rule.h +++ b/src/models/rule.h @@ -45,13 +45,13 @@ namespace obelisk static const char* createTable(); - int getId(); + int& getId(); void setId(int id); - obelisk::Fact getFact(); + obelisk::Fact& getFact(); void setFact(obelisk::Fact fact); - obelisk::Fact getReason(); + obelisk::Fact& getReason(); void setReason(obelisk::Fact reason); }; } // namespace obelisk diff --git a/src/models/suggest_action.cpp b/src/models/suggest_action.cpp index 1b6c6e6..929aa5b 100644 --- a/src/models/suggest_action.cpp +++ b/src/models/suggest_action.cpp @@ -16,7 +16,7 @@ const char* obelisk::SuggestAction::createTable() )"; } -int obelisk::SuggestAction::getId() +int& obelisk::SuggestAction::getId() { return id_; } @@ -26,7 +26,7 @@ void obelisk::SuggestAction::setId(int id) id_ = id; } -obelisk::Fact obelisk::SuggestAction::getFact() +obelisk::Fact& obelisk::SuggestAction::getFact() { return fact_; } @@ -36,7 +36,7 @@ void obelisk::SuggestAction::setFact(obelisk::Fact fact) fact_ = fact; } -obelisk::Action obelisk::SuggestAction::getTrueAction() +obelisk::Action& obelisk::SuggestAction::getTrueAction() { return trueAction_; } @@ -46,7 +46,7 @@ void obelisk::SuggestAction::setTrueAction(obelisk::Action trueAction) trueAction_ = trueAction; } -obelisk::Action obelisk::SuggestAction::getFalseAction() +obelisk::Action& obelisk::SuggestAction::getFalseAction() { return falseAction_; } diff --git a/src/models/suggest_action.h b/src/models/suggest_action.h index 6b33e88..2f680e4 100644 --- a/src/models/suggest_action.h +++ b/src/models/suggest_action.h @@ -56,16 +56,16 @@ namespace obelisk static const char* createTable(); - int getId(); + int& getId(); void setId(int id); - obelisk::Fact getFact(); + obelisk::Fact& getFact(); void setFact(obelisk::Fact fact); - obelisk::Action getTrueAction(); + obelisk::Action& getTrueAction(); void setTrueAction(obelisk::Action trueAction); - obelisk::Action getFalseAction(); + obelisk::Action& getFalseAction(); void setFalseAction(obelisk::Action falseAction); }; } // namespace obelisk diff --git a/src/models/verb.cpp b/src/models/verb.cpp index ac9aeb9..e3820fb 100644 --- a/src/models/verb.cpp +++ b/src/models/verb.cpp @@ -1,5 +1,7 @@ #include "models/verb.h" +#include + const char* obelisk::Verb::createTable() { 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_; } @@ -21,7 +132,7 @@ void obelisk::Verb::setId(int id) id_ = id; } -std::string obelisk::Verb::getName() +std::string& obelisk::Verb::getName() { return name_; } diff --git a/src/models/verb.h b/src/models/verb.h index dfb3a6e..8e8d241 100644 --- a/src/models/verb.h +++ b/src/models/verb.h @@ -1,6 +1,8 @@ #ifndef OBELISK_MODELS_VERB_H #define OBELISK_MODELS_VERB_H +#include + #include namespace obelisk @@ -38,11 +40,14 @@ namespace obelisk static const char* createTable(); - int getId(); + int& getId(); void setId(int id); - std::string getName(); + std::string& getName(); void setName(std::string name); + + Verb selectVerb(sqlite3* dbConnection, std::string name); + int insertVerb(sqlite3* dbConnection); }; } // namespace obelisk diff --git a/src/obelisk.cpp b/src/obelisk.cpp index 47c695a..7586d95 100644 --- a/src/obelisk.cpp +++ b/src/obelisk.cpp @@ -8,9 +8,21 @@ #include #include -static void mainLoop() +static int mainLoop() { auto parser = std::unique_ptr {new obelisk::Parser()}; + std::unique_ptr kb; + + try + { + kb = std::unique_ptr { + new obelisk::KnowledgeBase("cromer.kb")}; + } + catch (obelisk::KnowledgeBaseException& exception) + { + std::cout << exception.what() << std::endl; + return EXIT_FAILURE; + } // Prime the first token. fprintf(stderr, "ready> "); @@ -22,7 +34,7 @@ static void mainLoop() switch (parser->getCurrentToken()) { case obelisk::Lexer::kTokenEof : - return; + return EXIT_SUCCESS; case ';' : // ignore top-level semicolons. std::cout << "Identifier: " << parser->getLexer()->getIdentifier() << std::endl; @@ -31,19 +43,21 @@ static void mainLoop() parser->getNextToken(); break; case obelisk::Lexer::kTokenFact : - // parser->handleFactFunction(); + parser->handleFact(kb); break; case obelisk::Lexer::kTokenRule : - // parser->handleRuleFunction(); + // parser->handleRule(); break; case obelisk::Lexer::kTokenAction : - // parser->handleActionFunction(); + // parser->handleAction(); break; default : parser->getNextToken(); break; } } + + return EXIT_SUCCESS; } int main(int argc, char** argv) @@ -79,28 +93,5 @@ int main(int argc, char** argv) return EXIT_FAILURE; }*/ - try - { - auto kb = std::unique_ptr { - new obelisk::KnowledgeBase("cromer.kb")}; - - /*std::vector leftObjects; - std::vector 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; + return mainLoop(); } diff --git a/src/obelisk.h b/src/obelisk.h index d964df7..47cbdd0 100644 --- a/src/obelisk.h +++ b/src/obelisk.h @@ -1 +1 @@ -static void mainLoop(); +static int mainLoop(); diff --git a/src/parser.cpp b/src/parser.cpp index 9ef3080..339581d 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1,6 +1,9 @@ #include "ast/call_expression_ast.h" #include "ast/number_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 @@ -212,17 +215,19 @@ std::unique_ptr obelisk::Parser::parseExtern() return parsePrototype(); } +//action("martin" is "dangerous" then "avoid" or "ignore"); std::unique_ptr obelisk::Parser::parseAction() { } +//rule("chris" and "martin" is "happy" if "chris" plays "playstation"); std::unique_ptr obelisk::Parser::parseRule() { } // fact("chris cromer" and "martin" and "Isabella" can "program" and "speak english"); // fact("" and "martin") -std::unique_ptr obelisk::Parser::parseFact() +void obelisk::Parser::parseFact(std::vector& facts) { std::stack syntax; @@ -329,18 +334,68 @@ std::unique_ptr 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& kb) { } -void obelisk::Parser::handleRule() +void obelisk::Parser::handleRule(std::unique_ptr& kb) { } -void obelisk::Parser::handleFact() +void obelisk::Parser::handleFact(std::unique_ptr& kb) { - parseFact(); + std::vector facts; + parseFact(facts); + + int verbId = 0; + for (auto& fact : facts) + { + // TODO: doesn't work after first insert + std::vector 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 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 facts {fact}; + kb->addFacts(facts); + fact = facts.front(); + } } + +// fact("chris cromer" and "martin" and "Isabella" can "program" and "speak english"); diff --git a/src/parser.h b/src/parser.h index e020821..a71358e 100644 --- a/src/parser.h +++ b/src/parser.h @@ -4,7 +4,9 @@ #include "ast/expression_ast.h" #include "ast/function_ast.h" #include "ast/prototype_ast.h" +#include "knowledge_base.h" #include "lexer.h" +#include "models/fact.h" #include @@ -34,7 +36,7 @@ namespace obelisk std::unique_ptr parseExtern(); std::unique_ptr parseAction(); std::unique_ptr parseRule(); - std::unique_ptr parseFact(); + void parseFact(std::vector& facts); public: Parser(); @@ -48,9 +50,9 @@ namespace obelisk void handleDefinition(); void handleExtern(); void handleTopLevelExpression(); - void handleAction(); - void handleRule(); - void handleFact(); + void handleAction(std::unique_ptr& kb); + void handleRule(std::unique_ptr& kb); + void handleFact(std::unique_ptr& kb); }; class ParserException : public std::exception