From dc210ee6eba3b1d173808bd858113f6abd90bff1 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Wed, 16 Mar 2016 21:35:35 -0400 Subject: Added word derivational relationships (kind of eh at the moment) and moved verbly into its own directory --- CMakeLists.txt | 9 + LICENSE | 3 + adjective.cpp | 586 ---------------- adjective.h | 133 ---- adverb.cpp | 364 ---------- adverb.h | 82 --- c++14.h | 35 - data.cpp | 50 -- data.h | 49 -- generator/CMakeLists.txt | 12 + generator/generator.cpp | 1663 ++++++++++++++++++++++++++++++++++++++++++++++ generator/progress.h | 50 ++ generator/schema.sql | 252 +++++++ lib/adjective.cpp | 690 +++++++++++++++++++ lib/adjective.h | 143 ++++ lib/adverb.cpp | 468 +++++++++++++ lib/adverb.h | 95 +++ lib/c++14.h | 35 + lib/data.cpp | 50 ++ lib/data.h | 49 ++ lib/noun.cpp | 1032 ++++++++++++++++++++++++++++ lib/noun.h | 183 +++++ lib/token.cpp | 53 ++ lib/token.h | 313 +++++++++ lib/util.h | 53 ++ lib/verb.cpp | 193 ++++++ lib/verb.h | 73 ++ lib/verbly.h | 14 + lib/word.cpp | 32 + lib/word.h | 35 + noun.cpp | 916 ------------------------- noun.h | 171 ----- token.cpp | 53 -- token.h | 313 --------- util.h | 53 -- verb.cpp | 193 ------ verb.h | 73 -- verbly.h | 14 - word.cpp | 32 - word.h | 35 - 40 files changed, 5500 insertions(+), 3152 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 LICENSE delete mode 100644 adjective.cpp delete mode 100644 adjective.h delete mode 100644 adverb.cpp delete mode 100644 adverb.h delete mode 100644 c++14.h delete mode 100644 data.cpp delete mode 100644 data.h create mode 100644 generator/CMakeLists.txt create mode 100644 generator/generator.cpp create mode 100644 generator/progress.h create mode 100644 generator/schema.sql create mode 100644 lib/adjective.cpp create mode 100644 lib/adjective.h create mode 100644 lib/adverb.cpp create mode 100644 lib/adverb.h create mode 100644 lib/c++14.h create mode 100644 lib/data.cpp create mode 100644 lib/data.h create mode 100644 lib/noun.cpp create mode 100644 lib/noun.h create mode 100644 lib/token.cpp create mode 100644 lib/token.h create mode 100644 lib/util.h create mode 100644 lib/verb.cpp create mode 100644 lib/verb.h create mode 100644 lib/verbly.h create mode 100644 lib/word.cpp create mode 100644 lib/word.h delete mode 100644 noun.cpp delete mode 100644 noun.h delete mode 100644 token.cpp delete mode 100644 token.h delete mode 100644 util.h delete mode 100644 verb.cpp delete mode 100644 verb.h delete mode 100644 verbly.h delete mode 100644 word.cpp delete mode 100644 word.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5a3e526 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required (VERSION 2.6) +project (verbly) + +find_package(PkgConfig) +pkg_check_modules(sqlite3 sqlite3 REQUIRED) + +add_library(verbly lib/data.cpp lib/adjective.cpp lib/noun.cpp lib/verb.cpp lib/adverb.cpp lib/token.cpp lib/word.cpp) +set_property(TARGET verbly PROPERTY CXX_STANDARD 11) +set_property(TARGET verbly PROPERTY CXX_STANDARD_REQUIRED ON) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4c4b690 --- /dev/null +++ b/LICENSE @@ -0,0 +1,3 @@ +WordNet Release 3.0 + +This software and database is being provided to you, the LICENSEE, by Princeton University under the following license. By obtaining, using and/or copying this software and database, you agree that you have read, understood, and will comply with these terms and conditions.: Permission to use, copy, modify and distribute this software and database and its documentation for any purpose and without fee or royalty is hereby granted, provided that you agree to comply with the following copyright notice and statements, including the disclaimer, and that the same appear on ALL copies of the software, database and documentation, including modifications that you make for internal use or for distribution. WordNet 3.0 Copyright 2006 by Princeton University. All rights reserved. THIS SOFTWARE AND DATABASE IS PROVIDED "AS IS" AND PRINCETON UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PRINCETON UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANT- ABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE, DATABASE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. The name of Princeton University or Princeton may not be used in advertising or publicity pertaining to distribution of the software and/or database. Title to copyright in this software, database and any associated documentation shall at all times remain with Princeton University and LICENSEE agrees to preserve same. \ No newline at end of file diff --git a/adjective.cpp b/adjective.cpp deleted file mode 100644 index 0f4087f..0000000 --- a/adjective.cpp +++ /dev/null @@ -1,586 +0,0 @@ -#include "verbly.h" - -namespace verbly { - - adjective::adjective(const data& _data, int _id) : word(_data, _id) - { - - } - - std::string adjective::base_form() const - { - return _base_form; - } - - std::string adjective::comparative_form() const - { - return _comparative_form; - } - - std::string adjective::superlative_form() const - { - return _superlative_form; - } - - adjective::positioning adjective::position() const - { - return _position; - } - - bool adjective::has_comparative_form() const - { - return !_comparative_form.empty(); - } - - bool adjective::has_superlative_form() const - { - return !_superlative_form.empty(); - } - - bool adjective::has_position() const - { - return _position != adjective::positioning::undefined; - } - - adjective_query adjective::antonyms() const - { - return _data.adjectives().antonym_of(*this); - } - - adjective_query adjective::synonyms() const - { - return _data.adjectives().synonym_of(*this); - } - - adjective_query adjective::generalizations() const - { - return _data.adjectives().generalization_of(*this); - } - - adjective_query adjective::specifications() const - { - return _data.adjectives().specification_of(*this); - } - - noun_query adjective::anti_pertainyms() const - { - return _data.nouns().anti_pertainym_of(*this); - } - - adverb_query adjective::mannernyms() const - { - return _data.adverbs().mannernym_of(*this); - } - - noun_query adjective::attributes() const - { - return _data.nouns().attribute_of(*this); - } - - adjective_query::adjective_query(const data& _data) : _data(_data) - { - - } - - adjective_query& adjective_query::limit(int _limit) - { - if ((_limit > 0) || (_limit == unlimited)) - { - this->_limit = _limit; - } - - return *this; - } - - adjective_query& adjective_query::random(bool _random) - { - this->_random = _random; - - return *this; - } - - adjective_query& adjective_query::except(const adjective& _word) - { - _except.push_back(_word); - - return *this; - } - - adjective_query& adjective_query::rhymes_with(const word& _word) - { - for (auto rhyme : _word.rhyme_phonemes()) - { - _rhymes.push_back(rhyme); - } - - if (dynamic_cast(&_word) != nullptr) - { - _except.push_back(dynamic_cast(_word)); - } - - return *this; - } - - adjective_query& adjective_query::has_pronunciation(bool _has_prn) - { - this->_has_prn = _has_prn; - - return *this; - } - - adjective_query& adjective_query::is_variant(bool _is_variant) - { - this->_is_variant = _is_variant; - - return *this; - } - - adjective_query& adjective_query::variant_of(const noun& _noun) - { - _variant_of.push_back(_noun); - - return *this; - } - - adjective_query& adjective_query::not_variant_of(const noun& _noun) - { - _not_variant_of.push_back(_noun); - - return *this; - } - - adjective_query& adjective_query::has_antonyms(bool _is_antonymic) - { - this->_is_antonymic = _is_antonymic; - - return *this; - } - - adjective_query& adjective_query::antonym_of(const adjective& _adj) - { - _antonym_of.push_back(_adj); - - return *this; - } - - adjective_query& adjective_query::not_antonym_of(const adjective& _adj) - { - _not_antonym_of.push_back(_adj); - - return *this; - } - - adjective_query& adjective_query::has_synonyms(bool _is_synonymic) - { - this->_is_synonymic = _is_synonymic; - - return *this; - } - - adjective_query& adjective_query::synonym_of(const adjective& _adj) - { - _synonym_of.push_back(_adj); - - return *this; - } - - adjective_query& adjective_query::not_synonym_of(const adjective& _adj) - { - _not_synonym_of.push_back(_adj); - - return *this; - } - - adjective_query& adjective_query::is_generalization(bool _is_generalization) - { - this->_is_generalization = _is_generalization; - - return *this; - } - - adjective_query& adjective_query::generalization_of(const adjective& _adj) - { - _generalization_of.push_back(_adj); - - return *this; - } - - adjective_query& adjective_query::not_generalization_of(const adjective& _adj) - { - _not_generalization_of.push_back(_adj); - - return *this; - } - - adjective_query& adjective_query::is_specification(bool _is_specification) - { - this->_is_specification = _is_specification; - - return *this; - } - - adjective_query& adjective_query::specification_of(const adjective& _adj) - { - _specification_of.push_back(_adj); - - return *this; - } - - adjective_query& adjective_query::not_specification_of(const adjective& _adj) - { - _not_specification_of.push_back(_adj); - - return *this; - } - - adjective_query& adjective_query::is_pertainymic(bool _is_pertainymic) - { - this->_is_pertainymic = _is_pertainymic; - - return *this; - } - - adjective_query& adjective_query::pertainym_of(const noun& _noun) - { - _pertainym_of.push_back(_noun); - - return *this; - } - - adjective_query& adjective_query::is_mannernymic(bool _is_mannernymic) - { - this->_is_mannernymic = _is_mannernymic; - - return *this; - } - - adjective_query& adjective_query::anti_mannernym_of(const adverb& _adv) - { - _anti_mannernym_of.push_back(_adv); - - return *this; - } - - std::list adjective_query::run() const - { - std::stringstream construct; - construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives"; - std::list conditions; - - if (_has_prn) - { - conditions.push_back("adjective_id IN (SELECT adjective_id FROM adjective_pronunciations)"); - } - - if (!_rhymes.empty()) - { - std::list clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); - std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - for (auto except : _except) - { - conditions.push_back("adjective_id != @EXCID"); - } - - if (_requires_comparative_form) - { - conditions.push_back("comparative IS NOT NULL"); - } - - if (_requires_superlative_form) - { - conditions.push_back("superlative IS NOT NULL"); - } - - if (_position != adjective::positioning::undefined) - { - switch (_position) - { - case adjective::positioning::predicate: conditions.push_back("position = 'p'"); break; - case adjective::positioning::attributive: conditions.push_back("position = 'a'"); break; - case adjective::positioning::postnominal: conditions.push_back("position = 'i'"); break; - } - } - - if (_is_variant) - { - conditions.push_back("adjective_id IN (SELECT adjective_id FROM variation)"); - } - - if (!_variant_of.empty()) - { - std::list clauses(_variant_of.size(), "noun_id = @ATTRID"); - std::string cond = "adjective_id IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_variant_of.empty()) - { - std::list clauses(_not_variant_of.size(), "noun_id = @NATTRID"); - std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_antonymic) - { - conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy)"); - } - - if (!_antonym_of.empty()) - { - std::list clauses(_antonym_of.size(), "adjective_1_id = @ANTID"); - std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_antonym_of.empty()) - { - std::list clauses(_not_antonym_of.size(), "adjective_1_id = @NANTID"); - std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_synonymic) - { - conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy)"); - } - - if (!_synonym_of.empty()) - { - std::list clauses(_synonym_of.size(), "adjective_1_id = @SYNID"); - std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_synonym_of.empty()) - { - std::list clauses(_not_synonym_of.size(), "adjective_1_id = @NSYNID"); - std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_generalization) - { - conditions.push_back("adjective_id IN (SELECT general_id FROM specification)"); - } - - if (!_generalization_of.empty()) - { - std::list clauses(_generalization_of.size(), "specific_id = @SPECID"); - std::string cond = "adjective_id IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_generalization_of.empty()) - { - std::list clauses(_not_generalization_of.size(), "specific_id = @NSPECID"); - std::string cond = "adjective_id NOT IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_specification) - { - conditions.push_back("adjective_id IN (SELECT specific_id FROM specification)"); - } - - if (!_specification_of.empty()) - { - std::list clauses(_specification_of.size(), "general_id = @GENID"); - std::string cond = "adjective_id IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_specification_of.empty()) - { - std::list clauses(_not_specification_of.size(), "general_id = @NGENID"); - std::string cond = "adjective_id NOT IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_pertainymic) - { - conditions.push_back("adjective_id IN (SELECT pertainym_id FROM pertainymy)"); - } - - if (!_pertainym_of.empty()) - { - std::list clauses(_pertainym_of.size(), "noun_id = @APERID"); - std::string cond = "adjective_id IN (SELECT pertainym_id FROM pertainymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_mannernymic) - { - conditions.push_back("adjective_id IN (SELECT adjective_id FROM mannernymy)"); - } - - if (!_anti_mannernym_of.empty()) - { - std::list clauses(_anti_mannernym_of.size(), "mannernym_id = @MANID"); - std::string cond = "adjective_id IN (SELECT adjective_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!conditions.empty()) - { - construct << " WHERE "; - construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); - } - - if (_random) - { - construct << " ORDER BY RANDOM()"; - } - - if (_limit != unlimited) - { - construct << " LIMIT " << _limit; - } - - sqlite3_stmt* ppstmt; - std::string query = construct.str(); - if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) - { - throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); - } - - if (!_rhymes.empty()) - { - int i = 0; - for (auto rhyme : _rhymes) - { - std::string rhymer = "%" + rhyme; - sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); - - i++; - } - } - - for (auto except : _except) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); - } - - for (auto attribute : _variant_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id); - } - - for (auto attribute : _not_variant_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NATTRID"), attribute._id); - } - - for (auto antonym : _antonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); - } - - for (auto antonym : _not_antonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); - } - - for (auto synonym : _synonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); - } - - for (auto synonym : _not_synonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); - } - - for (auto specific : _generalization_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SPECID"), specific._id); - } - - for (auto specific : _not_generalization_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSPECID"), specific._id); - } - - for (auto general : _specification_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GENID"), general._id); - } - - for (auto general : _not_specification_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NGENID"), general._id); - } - - for (auto n : _pertainym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@APERID"), n._id); - } - - for (auto mannernym : _anti_mannernym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MANID"), mannernym._id); - } - - std::list output; - while (sqlite3_step(ppstmt) == SQLITE_ROW) - { - adjective tnc {_data, sqlite3_column_int(ppstmt, 0)}; - tnc._base_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 1))); - - if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) - { - tnc._comparative_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 2))); - } - - if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) - { - tnc._superlative_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 3))); - } - - if (sqlite3_column_type(ppstmt, 4) != SQLITE_NULL) - { - std::string adjpos(reinterpret_cast(sqlite3_column_text(ppstmt, 4))); - if (adjpos == "p") - { - tnc._position = adjective::positioning::predicate; - } else if (adjpos == "a") - { - tnc._position = adjective::positioning::attributive; - } else if (adjpos == "i") - { - tnc._position = adjective::positioning::postnominal; - } - } - - output.push_back(tnc); - } - - sqlite3_finalize(ppstmt); - - for (auto& adjective : output) - { - query = "SELECT pronunciation FROM adjective_pronunciations WHERE adjective_id = ?"; - if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) - { - throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); - } - - sqlite3_bind_int(ppstmt, 1, adjective._id); - - while (sqlite3_step(ppstmt) == SQLITE_ROW) - { - std::string pronunciation(reinterpret_cast(sqlite3_column_text(ppstmt, 0))); - auto phonemes = verbly::split>(pronunciation, " "); - - adjective.pronunciations.push_back(phonemes); - } - - sqlite3_finalize(ppstmt); - } - - return output; - } - -}; diff --git a/adjective.h b/adjective.h deleted file mode 100644 index 4927d59..0000000 --- a/adjective.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef ADJECTIVE_H_87B3FB75 -#define ADJECTIVE_H_87B3FB75 - -namespace verbly { - - class adjective_query; - class adverb_query; - class noun_query; - - class adjective : public word { - public: - enum class positioning { - undefined, - predicate, - attributive, - postnominal - }; - - private: - std::string _base_form; - std::string _comparative_form; - std::string _superlative_form; - positioning _position = positioning::undefined; - - friend class adjective_query; - - public: - adjective(const data& _data, int _id); - - std::string base_form() const; - std::string comparative_form() const; - std::string superlative_form() const; - positioning position() const; - - bool has_comparative_form() const; - bool has_superlative_form() const; - bool has_position() const; - - adjective_query antonyms() const; - adjective_query synonyms() const; - adjective_query generalizations() const; - adjective_query specifications() const; - noun_query anti_pertainyms() const; - adverb_query mannernyms() const; - noun_query attributes() const; - }; - - class adjective_query { - public: - adjective_query(const data& _data); - - adjective_query& limit(int _limit); - adjective_query& random(bool _random); - adjective_query& except(const adjective& _word); - adjective_query& rhymes_with(const word& _word); - adjective_query& has_pronunciation(bool _has_prn); - - adjective_query& requires_comparative_form(bool req); - adjective_query& requires_superlative_form(bool req); - adjective_query& position(adjective::positioning pos); - - adjective_query& is_variant(bool _is_variant); - adjective_query& variant_of(const noun& _noun); - adjective_query& not_variant_of(const noun& _noun); - - adjective_query& has_antonyms(bool _is_antonymic); - adjective_query& antonym_of(const adjective& _adj); - adjective_query& not_antonym_of(const adjective& _adj); - - adjective_query& has_synonyms(bool _is_synonymic); - adjective_query& synonym_of(const adjective& _adj); - adjective_query& not_synonym_of(const adjective& _adj); - - adjective_query& is_generalization(bool _is_generalization); - adjective_query& generalization_of(const adjective& _adj); - adjective_query& not_generalization_of(const adjective& _adj); - - adjective_query& is_specification(bool _is_specification); - adjective_query& specification_of(const adjective& _adj); - adjective_query& not_specification_of(const adjective& _adj); - - adjective_query& is_pertainymic(bool _is_pertainymic); - adjective_query& pertainym_of(const noun& _noun); - - adjective_query& is_mannernymic(bool _is_mannernymic); - adjective_query& anti_mannernym_of(const adverb& _adv); - - std::list run() const; - - const static int unlimited = -1; - - protected: - const data& _data; - int _limit = unlimited; - bool _random = false; - std::list _rhymes; - std::list _except; - bool _has_prn = false; - - bool _requires_comparative_form = false; - bool _requires_superlative_form = false; - adjective::positioning _position = adjective::positioning::undefined; - - bool _is_variant = false; - std::list _variant_of; - std::list _not_variant_of; - - bool _is_antonymic = false; - std::list _antonym_of; - std::list _not_antonym_of; - - bool _is_synonymic = false; - std::list _synonym_of; - std::list _not_synonym_of; - - bool _is_generalization = false; - std::list _generalization_of; - std::list _not_generalization_of; - - bool _is_specification = false; - std::list _specification_of; - std::list _not_specification_of; - - bool _is_pertainymic = false; - std::list _pertainym_of; - - bool _is_mannernymic = false; - std::list _anti_mannernym_of; - }; - -}; - -#endif /* end of include guard: ADJECTIVE_H_87B3FB75 */ diff --git a/adverb.cpp b/adverb.cpp deleted file mode 100644 index 9bb5a0d..0000000 --- a/adverb.cpp +++ /dev/null @@ -1,364 +0,0 @@ -#include "verbly.h" - -namespace verbly { - - adverb::adverb(const data& _data, int _id) : word(_data, _id) - { - - } - - std::string adverb::base_form() const - { - return _base_form; - } - - std::string adverb::comparative_form() const - { - return _comparative_form; - } - - std::string adverb::superlative_form() const - { - return _superlative_form; - } - - bool adverb::has_comparative_form() const - { - return !_comparative_form.empty(); - } - - bool adverb::has_superlative_form() const - { - return !_superlative_form.empty(); - } - - adverb_query adverb::antonyms() const - { - return _data.adverbs().antonym_of(*this); - } - - adverb_query adverb::synonyms() const - { - return _data.adverbs().synonym_of(*this); - } - - adjective_query adverb::anti_mannernyms() const - { - return _data.adjectives().anti_mannernym_of(*this); - } - - adverb_query::adverb_query(const data& _data) : _data(_data) - { - - } - - adverb_query& adverb_query::limit(int _limit) - { - if ((_limit > 0) || (_limit == unlimited)) - { - this->_limit = _limit; - } - - return *this; - } - - adverb_query& adverb_query::random(bool _random) - { - this->_random = _random; - - return *this; - } - - adverb_query& adverb_query::except(const adverb& _word) - { - _except.push_back(_word); - - return *this; - } - - adverb_query& adverb_query::rhymes_with(const word& _word) - { - for (auto rhyme : _word.rhyme_phonemes()) - { - _rhymes.push_back(rhyme); - } - - if (dynamic_cast(&_word) != nullptr) - { - _except.push_back(dynamic_cast(_word)); - } - - return *this; - } - - adverb_query& adverb_query::has_pronunciation(bool _has_prn) - { - this->_has_prn = _has_prn; - - return *this; - } - - adverb_query& adverb_query::requires_comparative_form(bool _arg) - { - _requires_comparative_form = _arg; - - return *this; - } - - adverb_query& adverb_query::requires_superlative_form(bool _arg) - { - _requires_superlative_form = _arg; - - return *this; - } - - adverb_query& adverb_query::has_antonyms(bool _arg) - { - _has_antonyms = _arg; - - return *this; - } - - adverb_query& adverb_query::antonym_of(const adverb& _adv) - { - _antonym_of.push_back(_adv); - - return *this; - } - - adverb_query& adverb_query::not_antonym_of(const adverb& _adv) - { - _not_antonym_of.push_back(_adv); - - return *this; - } - - adverb_query& adverb_query::has_synonyms(bool _arg) - { - _has_synonyms = _arg; - - return *this; - } - - adverb_query& adverb_query::synonym_of(const adverb& _adv) - { - _synonym_of.push_back(_adv); - - return *this; - } - - adverb_query& adverb_query::not_synonym_of(const adverb& _adv) - { - _not_synonym_of.push_back(_adv); - - return *this; - } - - adverb_query& adverb_query::is_mannernymic(bool _arg) - { - _is_mannernymic = _arg; - - return *this; - } - - adverb_query& adverb_query::mannernym_of(const adjective& _adj) - { - _mannernym_of.push_back(_adj); - - return *this; - } - - std::list adverb_query::run() const - { - std::stringstream construct; - construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs"; - std::list conditions; - - if (_has_prn) - { - conditions.push_back("adverb_id IN (SELECT adverb_id FROM adverb_pronunciations)"); - } - - if (!_rhymes.empty()) - { - std::list clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); - std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - for (auto except : _except) - { - conditions.push_back("adverb_id != @EXCID"); - } - - if (_requires_comparative_form) - { - conditions.push_back("comparative IS NOT NULL"); - } - - if (_requires_superlative_form) - { - conditions.push_back("superlative IS NOT NULL"); - } - - if (_has_antonyms) - { - conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)"); - } - - if (!_antonym_of.empty()) - { - std::list clauses(_antonym_of.size(), "adverb_1_id = @ANTID"); - std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_antonym_of.empty()) - { - std::list clauses(_not_antonym_of.size(), "adverb_1_id = @NANTID"); - std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_has_synonyms) - { - conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy)"); - } - - if (!_synonym_of.empty()) - { - std::list clauses(_synonym_of.size(), "adverb_1_id = @SYNID"); - std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_synonym_of.empty()) - { - std::list clauses(_not_synonym_of.size(), "adverb_1_id = @NSYNID"); - std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_mannernymic) - { - conditions.push_back("adverb_id IN (SELECT mannernym_id FROM mannernymy)"); - } - - if (!_mannernym_of.empty()) - { - std::list clauses(_mannernym_of.size(), "adjective_id = @AMANID"); - std::string cond = "adverb_id IN (SELECT mannernym_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!conditions.empty()) - { - construct << " WHERE "; - construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); - } - - if (_random) - { - construct << " ORDER BY RANDOM()"; - } - - if (_limit != unlimited) - { - construct << " LIMIT " << _limit; - } - - sqlite3_stmt* ppstmt; - std::string query = construct.str(); - if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) - { - throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); - } - - if (!_rhymes.empty()) - { - int i = 0; - for (auto rhyme : _rhymes) - { - std::string rhymer = "%" + rhyme; - sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); - - i++; - } - } - - for (auto except : _except) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); - } - - for (auto antonym : _antonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); - } - - for (auto antonym : _not_antonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); - } - - for (auto synonym : _synonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); - } - - for (auto synonym : _not_synonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); - } - - for (auto adj : _mannernym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id); - } - - std::list output; - while (sqlite3_step(ppstmt) == SQLITE_ROW) - { - adverb tnc {_data, sqlite3_column_int(ppstmt, 0)}; - tnc._base_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 1))); - - if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) - { - tnc._comparative_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 2))); - } - - if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) - { - tnc._superlative_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 3))); - } - - output.push_back(tnc); - } - - sqlite3_finalize(ppstmt); - - for (auto& adverb : output) - { - query = "SELECT pronunciation FROM adverb_pronunciations WHERE adverb_id = ?"; - if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) - { - throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); - } - - sqlite3_bind_int(ppstmt, 1, adverb._id); - - while (sqlite3_step(ppstmt) == SQLITE_ROW) - { - std::string pronunciation(reinterpret_cast(sqlite3_column_text(ppstmt, 0))); - auto phonemes = verbly::split>(pronunciation, " "); - - adverb.pronunciations.push_back(phonemes); - } - - sqlite3_finalize(ppstmt); - } - - return output; - } - -}; diff --git a/adverb.h b/adverb.h deleted file mode 100644 index 42c3492..0000000 --- a/adverb.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef ADVERB_H_86F8302F -#define ADVERB_H_86F8302F - -namespace verbly { - - class adverb : public word { - private: - std::string _base_form; - std::string _comparative_form; - std::string _superlative_form; - - friend class adverb_query; - - public: - adverb(const data& _data, int _id); - - std::string base_form() const; - std::string comparative_form() const; - std::string superlative_form() const; - - bool has_comparative_form() const; - bool has_superlative_form() const; - - adverb_query antonyms() const; - adverb_query synonyms() const; - adjective_query anti_mannernyms() const; - }; - - class adverb_query { - public: - adverb_query(const data& _data); - - adverb_query& limit(int _limit); - adverb_query& random(bool _random); - adverb_query& except(const adverb& _word); - adverb_query& rhymes_with(const word& _word); - adverb_query& has_pronunciation(bool _has_prn); - - adverb_query& requires_comparative_form(bool _arg); - adverb_query& requires_superlative_form(bool _arg); - - adverb_query& has_antonyms(bool _arg); - adverb_query& antonym_of(const adverb& _adv); - adverb_query& not_antonym_of(const adverb& _adv); - - adverb_query& has_synonyms(bool _arg); - adverb_query& synonym_of(const adverb& _adv); - adverb_query& not_synonym_of(const adverb& _adv); - - adverb_query& is_mannernymic(bool _arg); - adverb_query& mannernym_of(const adjective& _adj); - - std::list run() const; - - const static int unlimited = -1; - - private: - const data& _data; - int _limit = unlimited; - bool _random = false; - std::list _rhymes; - std::list _except; - bool _has_prn = false; - - bool _requires_comparative_form = false; - bool _requires_superlative_form = false; - - bool _has_antonyms = false; - std::list _antonym_of; - std::list _not_antonym_of; - - bool _has_synonyms = false; - std::list _synonym_of; - std::list _not_synonym_of; - - bool _is_mannernymic = false; - std::list _mannernym_of; - }; - -}; - -#endif /* end of include guard: ADVERB_H_86F8302F */ diff --git a/c++14.h b/c++14.h deleted file mode 100644 index b3efbe2..0000000 --- a/c++14.h +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include -#include - -namespace std { - template struct _Unique_if { - typedef unique_ptr _Single_object; - }; - - template struct _Unique_if { - typedef unique_ptr _Unknown_bound; - }; - - template struct _Unique_if { - typedef void _Known_bound; - }; - - template - typename _Unique_if::_Single_object - make_unique(Args&&... args) { - return unique_ptr(new T(std::forward(args)...)); - } - - template - typename _Unique_if::_Unknown_bound - make_unique(size_t n) { - typedef typename remove_extent::type U; - return unique_ptr(new U[n]()); - } - - template - typename _Unique_if::_Known_bound - make_unique(Args&&...) = delete; -} diff --git a/data.cpp b/data.cpp deleted file mode 100644 index 57a8850..0000000 --- a/data.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "verbly.h" - -namespace verbly { - - data::data(std::string datafile) - { - if (sqlite3_open_v2(datafile.c_str(), &ppdb, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) - { - throw std::invalid_argument(sqlite3_errmsg(ppdb)); - } - } - - data::data(data&& other) - { - ppdb = other.ppdb; - } - - data& data::operator=(data&& other) - { - ppdb = other.ppdb; - - return *this; - } - - data::~data() - { - sqlite3_close_v2(ppdb); - } - - verb_query data::verbs() const - { - return verb_query(*this); - } - - adjective_query data::adjectives() const - { - return adjective_query(*this); - } - - adverb_query data::adverbs() const - { - return adverb_query(*this); - } - - noun_query data::nouns() const - { - return noun_query(*this); - } - -}; diff --git a/data.h b/data.h deleted file mode 100644 index 37092d7..0000000 --- a/data.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef DATA_H_C4AEC3DD -#define DATA_H_C4AEC3DD - -#include -#include - -namespace verbly { - - class data; - class word; - class adjective; - class noun; - class verb; - class adverb; - class adjective_query; - class adverb_query; - class noun_query; - class verb_query; - - class data { - private: - sqlite3* ppdb; - - friend class adjective_query; - friend class noun_query; - friend class verb_query; - friend class adverb_query; - - public: - data(std::string datafile); - - data(const data& other) = delete; - data& operator=(const data& other) = delete; - - data(data&& other); - data& operator=(data&& other); - - ~data(); - - verb_query verbs() const; - adjective_query adjectives() const; - adverb_query adverbs() const; - noun_query nouns() const; - - }; - -}; - -#endif /* end of include guard: DATA_H_C4AEC3DD */ diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt new file mode 100644 index 0000000..bbc3c4f --- /dev/null +++ b/generator/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required (VERSION 2.6) +project (generator) + +find_package(PkgConfig) +pkg_check_modules(sqlite3 sqlite3 REQUIRED) +find_package(libxml2 REQUIRED) + +include_directories(${sqlite3_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR}) +add_executable(generator generator.cpp) +set_property(TARGET generator PROPERTY CXX_STANDARD 11) +set_property(TARGET generator PROPERTY CXX_STANDARD_REQUIRED ON) +target_link_libraries(generator ${sqlite3_LIBRARIES} ${LIBXML2_LIBRARIES}) diff --git a/generator/generator.cpp b/generator/generator.cpp new file mode 100644 index 0000000..faef5f7 --- /dev/null +++ b/generator/generator.cpp @@ -0,0 +1,1663 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "progress.h" + +struct verb { + std::string infinitive; + std::string past_tense; + std::string past_participle; + std::string ing_form; + std::string s_form; +}; + +struct adjective { + std::string base; + std::string comparative; + std::string superlative; +}; + +struct noun { + std::string singular; + std::string plural; +}; + +struct group { + std::string id; + std::set members; +}; + +std::map groups; +std::map verbs; +std::map adjectives; +std::map nouns; +std::map> wn; +std::map> pronunciations; + +void print_usage() +{ + std::cout << "Verbly Datafile Generator" << std::endl; + std::cout << "-------------------------" << std::endl; + std::cout << "Requires exactly six arguments." << std::endl; + std::cout << "1. The path to a VerbNet data directory." << std::endl; + std::cout << "2. The path to a SemLink vnpbMappings file." << std::endl; + std::cout << "3. The path to an AGID infl.txt file." << std::endl; + std::cout << "4. The path to a WordNet prolog data directory." << std::endl; + std::cout << "5. The path to a CMUDICT pronunciation file." << std::endl; + std::cout << "6. Datafile output path." << std::endl; + + exit(1); +} + +void db_error(sqlite3* ppdb, std::string) +{ + std::cout << "Error writing to output database: " << sqlite3_errmsg(ppdb) << std::endl; + sqlite3_close_v2(ppdb); + print_usage(); +} + +/* +void parse_group(xmlNodePtr top, std::string filename) +{ + xmlChar* key = xmlGetProp(top, (xmlChar*) "ID"); + if (key == 0) + { + std::cout << "Bad VerbNet file format: " << filename << std::endl; + print_usage(); + } + std::string vnid = key; + vnid = vnid.substr(vnid.find_first_of("-")+1); + xmlFree(key); + + group g; + g.id = vnid; + + for (xmlNodePtr node = top->xmlChildrenNode; node != nullptr; node = node->next) + { + if (!xmlStrcmp(node->name, (const xmlChar*) "MEMBERS")) + { + for (xmlNodePtr member = node->xmlChildrenNode; member != nullptr; member = member->next) + { + if (!xmlStrcmp(member->name, (const xmlChar*) "MEMBER")) + { + key = xmlGetProp(member, (xmlChar*) "name"); + g.members.insert(key); + xmlFree(key); + } + } + } else if (!xmlStrcmp(node->name, (const xmlChar*) "FRAMES")) + { + for (xmlNodePtr frame = node->xmlChildrenNode; frame != nullptr; frame = frame->next) + { + if (!xmlStrcmp(frame->name, (const xmlChar*) "FRAME")) + { + for (xmlNodePtr framenode = frame->xmlChildrenNode; framenode != nullptr; framenode = framenode->next) + { + + } + } + } + } + } +}*/ + +int main(int argc, char** argv) +{ + if (argc != 7) + { + print_usage(); + } + + /*DIR* dir; + if ((dir = opendir(argv[1])) == nullptr) + { + std::cout << "Invalid VerbNet data directory." << std::endl; + + print_usage(); + } + + struct dirent* ent; + while ((ent = readdir(dir)) != nullptr) + { + std::string filename(argv[1]); + if (filename.back() != '/') + { + filename += '/'; + } + + filename += ent->d_name; + //std::cout << ent->d_name << std::endl; + + if (filename.rfind(".xml") != filename.size() - 4) + { + continue; + } + + xmlDocPtr doc = xmlParseFile(filename.c_str()); + if (doc == nullptr) + { + std::cout << "Error opening " << filename << std::endl; + print_usage(); + } + + xmlNodePtr top = xmlDocGetRootElement(doc); + if ((top == nullptr) || (xmlStrcmp(top->name, (xmlChar*) "VNCLASS"))) + { + std::cout << "Bad VerbNet file format: " << filename << std::endl; + print_usage(); + } + + parse_group(top, filename); + } + + closedir(dir);*/ + + // Get verbs from AGID + std::cout << "Reading inflections..." << std::endl; + + std::ifstream agidfile(argv[3]); + if (!agidfile.is_open()) + { + std::cout << "Could not open AGID file: " << argv[3] << std::endl; + print_usage(); + } + + for (;;) + { + std::string line; + if (!getline(agidfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + int divider = line.find_first_of(" "); + std::string word = line.substr(0, divider); + line = line.substr(divider+1); + char type = line[0]; + + if (line[1] == '?') + { + line.erase(0, 4); + } else { + line.erase(0, 3); + } + + std::vector forms; + while (!line.empty()) + { + std::string inflection; + if ((divider = line.find(" | ")) != std::string::npos) + { + inflection = line.substr(0, divider); + line = line.substr(divider + 3); + } else { + inflection = line; + line = ""; + } + + if ((divider = inflection.find_first_of(",?")) != std::string::npos) + { + inflection = inflection.substr(0, divider); + } + + forms.push_back(inflection); + } + + switch (type) + { + case 'V': + { + verb v; + v.infinitive = word; + if (forms.size() == 4) + { + v.past_tense = forms[0]; + v.past_participle = forms[1]; + v.ing_form = forms[2]; + v.s_form = forms[3]; + } else if (forms.size() == 3) + { + v.past_tense = forms[0]; + v.past_participle = forms[0]; + v.ing_form = forms[1]; + v.s_form = forms[2]; + } else if (forms.size() == 8) + { + // As of AGID 2014.08.11, this is only "to be" + v.past_tense = forms[0]; + v.past_participle = forms[2]; + v.ing_form = forms[3]; + v.s_form = forms[4]; + } else { + // Words that don't fit the cases above as of AGID 2014.08.11: + // - may and shall do not conjugate the way we want them to + // - methinks only has a past tense and is an outlier + // - wit has five forms, and is archaic/obscure enough that we can ignore it for now + std::cout << "Ignoring verb \"" << word << "\" due to non-standard number of forms." << std::endl; + } + + verbs[word] = v; + + break; + } + + case 'A': + { + adjective adj; + adj.base = word; + if (forms.size() == 2) + { + adj.comparative = forms[0]; + adj.superlative = forms[1]; + } else { + // As of AGID 2014.08.11, this is only "only", which has only the form "onliest" + std::cout << "Ignoring adjective/adverb \"" << word << "\" due to non-standard number of forms." << std::endl; + } + + adjectives[word] = adj; + + break; + } + + case 'N': + { + noun n; + n.singular = word; + if (forms.size() == 1) + { + n.plural = forms[0]; + } else { + // As of AGID 2014.08.11, this is non-existent. + std::cout << "Ignoring noun \"" << word << "\" due to non-standard number of forms." << std::endl; + } + + nouns[word] = n; + + break; + } + } + } + + // Pronounciations + std::cout << "Reading pronunciations..." << std::endl; + + std::ifstream pronfile(argv[5]); + if (!pronfile.is_open()) + { + std::cout << "Could not open CMUDICT file: " << argv[5] << std::endl; + print_usage(); + } + + for (;;) + { + std::string line; + if (!getline(pronfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + std::regex phoneme("([A-Z][^ \\(]*)(?:\\(\\d+\\))? ([A-Z 0-9]+)"); + std::smatch phoneme_data; + if (std::regex_search(line, phoneme_data, phoneme)) + { + std::string canonical(phoneme_data[1]); + std::transform(std::begin(canonical), std::end(canonical), std::begin(canonical), ::tolower); + + pronunciations[canonical].insert(phoneme_data[2]); + } + } + + // Start writing output + std::cout << "Writing schema..." << std::endl; + + sqlite3* ppdb; + if (sqlite3_open_v2(argv[6], &ppdb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) != SQLITE_OK) + { + std::cout << "Error opening output datafile: " << sqlite3_errmsg(ppdb) << std::endl; + print_usage(); + } + + std::ifstream schemafile("schema.sql"); + if (!schemafile.is_open()) + { + std::cout << "Could not find schema file" << std::endl; + print_usage(); + } + + std::stringstream schemabuilder; + for (;;) + { + std::string line; + if (!getline(schemafile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + schemabuilder << line << std::endl; + } + + std::string schema = schemabuilder.str(); + while (!schema.empty()) + { + std::string query; + int divider = schema.find(";"); + if (divider != std::string::npos) + { + query = schema.substr(0, divider+1); + schema = schema.substr(divider+2); + } else { + break; + } + + sqlite3_stmt* schmstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &schmstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + if (sqlite3_step(schmstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(schmstmt); + } + + { + progress ppgs("Writing verbs...", verbs.size()); + for (auto& mapping : verbs) + { + sqlite3_stmt* ppstmt; + std::string query("INSERT INTO verbs (infinitive, past_tense, past_participle, ing_form, s_form) VALUES (?, ?, ?, ?, ?)"); + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_text(ppstmt, 1, mapping.second.infinitive.c_str(), mapping.second.infinitive.length(), SQLITE_STATIC); + sqlite3_bind_text(ppstmt, 2, mapping.second.past_tense.c_str(), mapping.second.past_tense.length(), SQLITE_STATIC); + sqlite3_bind_text(ppstmt, 3, mapping.second.past_participle.c_str(), mapping.second.past_participle.length(), SQLITE_STATIC); + sqlite3_bind_text(ppstmt, 4, mapping.second.ing_form.c_str(), mapping.second.ing_form.length(), SQLITE_STATIC); + sqlite3_bind_text(ppstmt, 5, mapping.second.s_form.c_str(), mapping.second.s_form.length(), SQLITE_STATIC); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + + std::string canonical(mapping.second.infinitive); + std::transform(std::begin(canonical), std::end(canonical), std::begin(canonical), ::tolower); + if (pronunciations.count(canonical) == 1) + { + query = "SELECT last_insert_rowid()"; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + if (sqlite3_step(ppstmt) != SQLITE_ROW) + { + db_error(ppdb, query); + } + + int rowid = sqlite3_column_int(ppstmt, 0); + + sqlite3_finalize(ppstmt); + + for (auto pronunciation : pronunciations[canonical]) + { + query = "INSERT INTO verb_pronunciations (verb_id, pronunciation) VALUES (?, ?)"; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, rowid); + sqlite3_bind_text(ppstmt, 2, pronunciation.c_str(), pronunciation.length(), SQLITE_STATIC); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + + ppgs.update(); + } + } + + // Get nouns/adjectives/adverbs from WordNet + // Useful relations: + // - s: master list + // - ant: antonymy (e.g. happy/sad, sad/happy, happiness/sadness) + // - at: variation (e.g. a measurement can be standard or nonstandard) + // - der: derivation (e.g. happy/happily, happily/happy) + // - hyp: hypernymy/hyponymy (e.g. color/red, color/blue) + // - ins: instantiation (do we need this? let's see) + // - mm: member meronymy/holonymy (e.g. family/mother, family/child) + // - mp: part meronymy/holonymy (e.g. wheel/spoke, wheel/tire) + // - ms: substance meronymy/holonymy (e.g. tire/rubber, doorstop/rubber) + // - per: pertainymy (e.g. something that is Alaskan pertains to Alaska) + // mannernymy (e.g. something done quickly is done in a manner that is quick) + // - sa: specification (e.g. inaccurate (general) can mean imprecise or incorrect (specific)) + // - sim: synonymy (e.g. cheerful/happy, happy/cheerful) + // - syntax: positioning flags for some adjectives + std::string wnpref {argv[4]}; + if (wnpref.back() != '/') + { + wnpref += '/'; + } + + // s table + { + std::ifstream wnsfile(wnpref + "wn_s.pl"); + if (!wnsfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnsfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing nouns, adjectives, and adverbs...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^s\\(([134]\\d{8}),(\\d+),'([\\w ]+)',"); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id = stoi(relation_data[1]); + int wnum = stoi(relation_data[2]); + std::string word = relation_data[3]; + + std::string query; + switch (synset_id / 100000000) + { + case 1: // Noun + { + if (nouns.count(word) == 1) + { + query = "INSERT INTO nouns (singular, plural) VALUES (?, ?)"; + } else { + query = "INSERT INTO nouns (singular) VALUES (?)"; + } + + break; + } + + case 2: // Verb + { + // Ignore + + break; + } + + case 3: // Adjective + { + if (adjectives.count(word) == 1) + { + query = "INSERT INTO adjectives (base_form, comparative, superlative) VALUES (?, ?, ?)"; + } else { + query = "INSERT INTO adjectives (base_form) VALUES (?)"; + } + + break; + } + + case 4: // Adverb + { + if (adjectives.count(word) == 1) + { + query = "INSERT INTO adverbs (base_form, comparative, superlative) VALUES (?, ?, ?)"; + } else { + query = "INSERT INTO adverbs (base_form) VALUES (?)"; + } + + break; + } + } + + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_text(ppstmt, 1, word.c_str(), word.length(), SQLITE_STATIC); + switch (synset_id / 100000000) + { + case 1: // Noun + { + if (nouns.count(word) == 1) + { + sqlite3_bind_text(ppstmt, 2, nouns[word].plural.c_str(), nouns[word].plural.length(), SQLITE_STATIC); + } + + break; + } + + case 3: // Adjective + case 4: // Adverb + { + if (adjectives.count(word) == 1) + { + sqlite3_bind_text(ppstmt, 2, adjectives[word].comparative.c_str(), adjectives[word].comparative.length(), SQLITE_STATIC); + sqlite3_bind_text(ppstmt, 3, adjectives[word].superlative.c_str(), adjectives[word].superlative.length(), SQLITE_STATIC); + } + + break; + } + } + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + + query = "SELECT last_insert_rowid()"; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + if (sqlite3_step(ppstmt) != SQLITE_ROW) + { + db_error(ppdb, query); + } + + int rowid = sqlite3_column_int(ppstmt, 0); + wn[synset_id][wnum] = rowid; + + sqlite3_finalize(ppstmt); + + std::string canonical(word); + std::transform(std::begin(canonical), std::end(canonical), std::begin(canonical), ::tolower); + if (pronunciations.count(canonical) == 1) + { + for (auto pronunciation : pronunciations[canonical]) + { + switch (synset_id / 100000000) + { + case 1: // Noun + { + query = "INSERT INTO noun_pronunciations (noun_id, pronunciation) VALUES (?, ?)"; + + break; + } + + case 3: // Adjective + { + query = "INSERT INTO adjective_pronunciations (adjective_id, pronunciation) VALUES (?, ?)"; + + break; + } + + case 4: // Adverb + { + query = "INSERT INTO adverb_pronunciations (adverb_id, pronunciation) VALUES (?, ?)"; + + break; + } + } + + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, rowid); + sqlite3_bind_text(ppstmt, 2, pronunciation.c_str(), pronunciation.length(), SQLITE_STATIC); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + } + } + + // While we're working on s + { + progress ppgs("Writing word synonyms...", wn.size()); + for (auto sense : wn) + { + ppgs.update(); + + for (auto word1 : sense.second) + { + for (auto word2 : sense.second) + { + if (word1 != word2) + { + std::string query; + switch (sense.first / 100000000) + { + case 1: // Noun + { + query = "INSERT INTO noun_synonymy (noun_1_id, noun_2_id) VALUES (?, ?)"; + + break; + } + + case 2: // Verb + { + // Ignore + + break; + } + + case 3: // Adjective + { + query = "INSERT INTO adjective_synonymy (adjective_1_id, adjective_2_id) VALUES (?, ?)"; + + break; + } + + case 4: // Adverb + { + query = "INSERT INTO adverb_synonymy (adverb_1_id, adverb_2_id) VALUES (?, ?)"; + + break; + } + } + + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, word1.second); + sqlite3_bind_int(ppstmt, 2, word2.second); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + } + } + } + + // ant table + { + std::ifstream wnantfile(wnpref + "wn_ant.pl"); + if (!wnantfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnantfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing antonyms...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^ant\\(([134]\\d{8}),(\\d+),([134]\\d{8}),(\\d+)\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id_1 = stoi(relation_data[1]); + int wnum_1 = stoi(relation_data[2]); + int synset_id_2 = stoi(relation_data[3]); + int wnum_2 = stoi(relation_data[4]); + + std::string query; + switch (synset_id_1 / 100000000) + { + case 1: // Noun + { + query = "INSERT INTO noun_antonymy (noun_1_id, noun_2_id) VALUES (?, ?)"; + + break; + } + + case 2: // Verb + { + // Ignore + + break; + } + + case 3: // Adjective + { + query = "INSERT INTO adjective_antonymy (adjective_1_id, adjective_2_id) VALUES (?, ?)"; + + break; + } + + case 4: // Adverb + { + query = "INSERT INTO adverb_antonymy (adverb_1_id, adverb_2_id) VALUES (?, ?)"; + + break; + } + } + + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, wn[synset_id_1][wnum_1]); + sqlite3_bind_int(ppstmt, 2, wn[synset_id_2][wnum_2]); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + + // at table + { + std::ifstream wnatfile(wnpref + "wn_at.pl"); + if (!wnatfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnatfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing variations...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^at\\((1\\d{8}),(3\\d{8})\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id_1 = stoi(relation_data[1]); + int synset_id_2 = stoi(relation_data[2]); + std::string query("INSERT INTO variation (noun_id, adjective_id) VALUES (?, ?)"); + + for (auto mapping1 : wn[synset_id_1]) + { + for (auto mapping2 : wn[synset_id_2]) + { + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, mapping1.second); + sqlite3_bind_int(ppstmt, 2, mapping2.second); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + } + } + + // der table + { + std::ifstream wnderfile(wnpref + "wn_der.pl"); + if (!wnderfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnderfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing morphological derivation...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^der\\(([134]\\d{8}),(\\d+),([134]\\d{8}),(\\d+)\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id_1 = stoi(relation_data[1]); + int wnum_1 = stoi(relation_data[2]); + int synset_id_2 = stoi(relation_data[3]); + int wnum_2 = stoi(relation_data[4]); + std::string query; + switch (synset_id_1 / 100000000) + { + case 1: // Noun + { + switch (synset_id_2 / 100000000) + { + case 1: // Noun + { + query = "INSERT INTO noun_noun_derivation (noun_1_id, noun_2_id) VALUES (?, ?)"; + break; + } + + case 3: // Adjective + { + query = "INSERT INTO noun_adjective_derivation (noun_id, adjective_id) VALUES (?, ?)"; + break; + } + + case 4: // Adverb + { + query = "INSERT INTO noun_adverb_derivation (noun_id, adverb_id) VALUES (?, ?)"; + break; + } + } + + break; + } + + case 3: // Adjective + { + switch (synset_id_2 / 100000000) + { + case 1: // Noun + { + query = "INSERT INTO noun_adjective_derivation (adjective_id, noun_id) VALUES (?, ?)"; + break; + } + + case 3: // Adjective + { + query = "INSERT INTO adjective_adjective_derivation (adjective_id, adjective_id) VALUES (?, ?)"; + break; + } + + case 4: // Adverb + { + query = "INSERT INTO adjective_adverb_derivation (adjective_id, adverb_id) VALUES (?, ?)"; + break; + } + } + + break; + } + + case 4: // Adverb + { + switch (synset_id_2 / 100000000) + { + case 1: // Noun + { + query = "INSERT INTO noun_adverb_derivation (adverb_id, noun_id) VALUES (?, ?)"; + break; + } + + case 3: // Adjective + { + query = "INSERT INTO adjective_adverb_derivation (adverb_id, adjective_id) VALUES (?, ?)"; + break; + } + + case 4: // Adverb + { + query = "INSERT INTO adverb_adverb_derivation (adverb_1_id, adverb_2_id) VALUES (?, ?)"; + break; + } + } + + break; + } + } + + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, wn[synset_id_1][wnum_1]); + sqlite3_bind_int(ppstmt, 2, wn[synset_id_2][wnum_2]); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + + // hyp table + { + std::ifstream wnhypfile(wnpref + "wn_hyp.pl"); + if (!wnhypfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnhypfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing hypernyms...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^hyp\\((1\\d{8}),(1\\d{8})\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id_1 = stoi(relation_data[1]); + int synset_id_2 = stoi(relation_data[2]); + std::string query("INSERT INTO hypernymy (hyponym_id, hypernym_id) VALUES (?, ?)"); + + for (auto mapping1 : wn[synset_id_1]) + { + for (auto mapping2 : wn[synset_id_2]) + { + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, mapping1.second); + sqlite3_bind_int(ppstmt, 2, mapping2.second); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + } + } + + // ins table + { + std::ifstream wninsfile(wnpref + "wn_ins.pl"); + if (!wninsfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wninsfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing instantiations...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^ins\\((1\\d{8}),(1\\d{8})\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id_1 = stoi(relation_data[1]); + int synset_id_2 = stoi(relation_data[2]); + std::string query("INSERT INTO instantiation (instance_id, class_id) VALUES (?, ?)"); + + for (auto mapping1 : wn[synset_id_1]) + { + for (auto mapping2 : wn[synset_id_2]) + { + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, mapping1.second); + sqlite3_bind_int(ppstmt, 2, mapping2.second); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + } + } + + // mm table + { + std::ifstream wnmmfile(wnpref + "wn_mm.pl"); + if (!wnmmfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnmmfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing member meronyms...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^mm\\((1\\d{8}),(1\\d{8})\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id_1 = stoi(relation_data[1]); + int synset_id_2 = stoi(relation_data[2]); + std::string query("INSERT INTO member_meronymy (holonym_id, meronym_id) VALUES (?, ?)"); + + for (auto mapping1 : wn[synset_id_1]) + { + for (auto mapping2 : wn[synset_id_2]) + { + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, mapping1.second); + sqlite3_bind_int(ppstmt, 2, mapping2.second); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + } + } + + // ms table + { + std::ifstream wnmsfile(wnpref + "wn_ms.pl"); + if (!wnmsfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnmsfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing substance meronyms...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^ms\\((1\\d{8}),(1\\d{8})\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id_1 = stoi(relation_data[1]); + int synset_id_2 = stoi(relation_data[2]); + std::string query("INSERT INTO substance_meronymy (holonym_id, meronym_id) VALUES (?, ?)"); + + for (auto mapping1 : wn[synset_id_1]) + { + for (auto mapping2 : wn[synset_id_2]) + { + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, mapping1.second); + sqlite3_bind_int(ppstmt, 2, mapping2.second); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + } + } + + // mm table + { + std::ifstream wnmpfile(wnpref + "wn_mp.pl"); + if (!wnmpfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnmpfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing part meronyms...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^mp\\((1\\d{8}),(1\\d{8})\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id_1 = stoi(relation_data[1]); + int synset_id_2 = stoi(relation_data[2]); + std::string query("INSERT INTO part_meronymy (holonym_id, meronym_id) VALUES (?, ?)"); + + for (auto mapping1 : wn[synset_id_1]) + { + for (auto mapping2 : wn[synset_id_2]) + { + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, mapping1.second); + sqlite3_bind_int(ppstmt, 2, mapping2.second); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + } + } + + // per table + { + std::ifstream wnperfile(wnpref + "wn_per.pl"); + if (!wnperfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnperfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing pertainyms and mannernyms...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^per\\(([34]\\d{8}),(\\d+),([13]\\d{8}),(\\d+)\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id_1 = stoi(relation_data[1]); + int wnum_1 = stoi(relation_data[2]); + int synset_id_2 = stoi(relation_data[3]); + int wnum_2 = stoi(relation_data[4]); + std::string query; + switch (synset_id_1 / 100000000) + { + case 3: // Adjective + { + // This is a pertainym, the second word should be a noun + // Technically it can be an adjective but we're ignoring that + if (synset_id_2 / 100000000 != 1) + { + continue; + } + + query = "INSERT INTO pertainymy (pertainym_id, noun_id) VALUES (?, ?)"; + + break; + } + + case 4: // Adverb + { + // This is a mannernym, the second word should be an adjective + if (synset_id_2 / 100000000 != 3) + { + continue; + } + + query = "INSERT INTO mannernymy (mannernym_id, adjective_id) VALUES (?, ?)"; + + break; + } + } + + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, wn[synset_id_1][wnum_1]); + sqlite3_bind_int(ppstmt, 2, wn[synset_id_2][wnum_2]); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + + // sa table + { + std::ifstream wnsafile(wnpref + "wn_sa.pl"); + if (!wnsafile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnsafile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing specifications...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^per\\((3\\d{8}),(\\d+),(3\\d{8}),(\\d+)\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id_1 = stoi(relation_data[1]); + int wnum_1 = stoi(relation_data[2]); + int synset_id_2 = stoi(relation_data[3]); + int wnum_2 = stoi(relation_data[4]); + std::string query("INSERT INTO specification (general_id, specific_id) VALUES (?, ?)"); + + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, wn[synset_id_1][wnum_1]); + sqlite3_bind_int(ppstmt, 2, wn[synset_id_2][wnum_2]); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + + // sim table + { + std::ifstream wnsimfile(wnpref + "wn_sim.pl"); + if (!wnsimfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnsimfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing sense synonyms...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^sim\\((3\\d{8}),(3\\d{8})\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id_1 = stoi(relation_data[1]); + int synset_id_2 = stoi(relation_data[2]); + std::string query("INSERT INTO adjective_synonymy (adjective_1_id, adjective_2_id) VALUES (?, ?)"); + + for (auto mapping1 : wn[synset_id_1]) + { + for (auto mapping2 : wn[synset_id_2]) + { + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_int(ppstmt, 1, mapping1.second); + sqlite3_bind_int(ppstmt, 2, mapping2.second); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_reset(ppstmt); + sqlite3_clear_bindings(ppstmt); + + sqlite3_bind_int(ppstmt, 1, mapping2.second); + sqlite3_bind_int(ppstmt, 2, mapping1.second); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + } + } + + // syntax table + { + std::ifstream wnsyntaxfile(wnpref + "wn_syntax.pl"); + if (!wnsyntaxfile.is_open()) + { + std::cout << "Invalid WordNet data directory." << std::endl; + print_usage(); + } + + std::list lines; + for (;;) + { + std::string line; + if (!getline(wnsyntaxfile, line)) + { + break; + } + + if (line.back() == '\r') + { + line.pop_back(); + } + + lines.push_back(line); + } + + progress ppgs("Writing adjective syntax markers...", lines.size()); + for (auto line : lines) + { + ppgs.update(); + + std::regex relation("^syntax\\((3\\d{8}),(\\d+),([ipa])p?\\)\\."); + std::smatch relation_data; + if (!std::regex_search(line, relation_data, relation)) + { + continue; + } + + int synset_id = stoi(relation_data[1]); + int wnum = stoi(relation_data[2]); + std::string syn = relation_data[3]; + std::string query("UPDATE adjectives SET position = ? WHERE adjective_id = ?"); + + sqlite3_stmt* ppstmt; + if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK) + { + db_error(ppdb, query); + } + + sqlite3_bind_text(ppstmt, 1, syn.c_str(), 1, SQLITE_STATIC); + sqlite3_bind_int(ppstmt, 2, wn[synset_id][wnum]); + + if (sqlite3_step(ppstmt) != SQLITE_DONE) + { + db_error(ppdb, query); + } + + sqlite3_finalize(ppstmt); + } + } + + sqlite3_close_v2(ppdb); + + std::cout << "Done." << std::endl; +} diff --git a/generator/progress.h b/generator/progress.h new file mode 100644 index 0000000..81f07a3 --- /dev/null +++ b/generator/progress.h @@ -0,0 +1,50 @@ +#ifndef PROGRESS_H_A34EF856 +#define PROGRESS_H_A34EF856 + +#include + +class progress { + private: + std::string message; + int total; + int cur = 0; + int lprint = 0; + + public: + progress(std::string message, int total) : message(message), total(total) + { + std::cout << message << " 0%" << std::flush; + } + + void update(int val) + { + if (val <= total) + { + cur = val; + } else { + cur = total; + } + + int pp = cur * 100 / total; + if (pp != lprint) + { + lprint = pp; + + std::cout << "\b\b\b\b" << std::right; + std::cout.width(3); + std::cout << pp << "%" << std::flush; + } + } + + void update() + { + update(cur+1); + } + + ~progress() + { + std::cout << "\b\b\b\b100%" << std::endl; + } +}; + +#endif /* end of include guard: PROGRESS_H_A34EF856 */ diff --git a/generator/schema.sql b/generator/schema.sql new file mode 100644 index 0000000..b4efe0a --- /dev/null +++ b/generator/schema.sql @@ -0,0 +1,252 @@ +DROP TABLE IF EXISTS `verbs`; +CREATE TABLE `verbs` ( + `verb_id` INTEGER PRIMARY KEY, + `infinitive` VARCHAR(32) NOT NULL, + `past_tense` VARCHAR(32) NOT NULL, + `past_participle` VARCHAR(32) NOT NULL, + `ing_form` VARCHAR(32) NOT NULL, + `s_form` VARCHAR(32) NOT NULL +); + +DROP TABLE IF EXISTS `groups`; +CREATE TABLE `groups` ( + `group_id` INTEGER PRIMARY KEY, + `parent_id` INTEGER, + FOREIGN KEY (`parent_id`) REFERENCES `groups`(`group_id`) +); + +DROP TABLE IF EXISTS `frames`; +CREATE TABLE `frames` ( + `frame_id` INTEGER PRIMARY KEY, + `group_id` INTEGER NOT NULL, + `data` BLOB NOT NULL, + FOREIGN KEY (`group_id`) REFERENCES `groups`(`group_id`) +); + +DROP TABLE IF EXISTS `verb_groups`; +CREATE TABLE `verb_groups` ( + `verb_id` INTEGER NOT NULL, + `group_id` INTEGER NOT NULL, + FOREIGN KEY (`verb_id`) REFERENCES `verbs`(`verb_id`), + FOREIGN KEY (`group_id`) REFERENCES `groups`(`group_id`) +); + +DROP TABLE IF EXISTS `adjectives`; +CREATE TABLE `adjectives` ( + `adjective_id` INTEGER PRIMARY KEY, + `base_form` VARCHAR(32) NOT NULL, + `comparative` VARCHAR(32), + `superlative` VARCHAR(32), + `position` CHAR(1) +); + +DROP TABLE IF EXISTS `adverbs`; +CREATE TABLE `adverbs` ( + `adverb_id` INTEGER PRIMARY KEY, + `base_form` VARCHAR(32) NOT NULL, + `comparative` VARCHAR(32), + `superlative` VARCHAR(32) +); + +DROP TABLE IF EXISTS `nouns`; +CREATE TABLE `nouns` ( + `noun_id` INTEGER PRIMARY KEY, + `singular` VARCHAR(32) NOT NULL, + `plural` VARCHAR(32) +); + +DROP TABLE IF EXISTS `hypernymy`; +CREATE TABLE `hypernymy` ( + `hypernym_id` INTEGER NOT NULL, + `hyponym_id` INTEGER NOT NULL, + FOREIGN KEY (`hypernym_id`) REFERENCES `nouns`(`noun_id`), + FOREIGN KEY (`hyponym_id`) REFERENCES `nouns`(`noun_id`) +); + +DROP TABLE IF EXISTS `instantiation`; +CREATE TABLE `instantiation` ( + `class_id` INTEGER NOT NULL, + `instance_id` INTEGER NOT NULL, + FOREIGN KEY (`class_id`) REFERENCES `nouns`(`noun_id`), + FOREIGN KEY (`instance_id`) REFERENCES `nouns`(`noun_id`) +); + +DROP TABLE IF EXISTS `member_meronymy`; +CREATE TABLE `member_meronymy` ( + `meronym_id` INTEGER NOT NULL, + `holonym_id` INTEGER NOT NULL, + FOREIGN KEY (`meronym_id`) REFERENCES `nouns`(`noun_id`), + FOREIGN KEY (`holonym_id`) REFERENCES `nouns`(`noun_id`) +); + +DROP TABLE IF EXISTS `part_meronymy`; +CREATE TABLE `part_meronymy` ( + `meronym_id` INTEGER NOT NULL, + `holonym_id` INTEGER NOT NULL, + FOREIGN KEY (`meronym_id`) REFERENCES `nouns`(`noun_id`), + FOREIGN KEY (`holonym_id`) REFERENCES `nouns`(`noun_id`) +); + +DROP TABLE IF EXISTS `substance_meronymy`; +CREATE TABLE `substance_meronymy` ( + `meronym_id` INTEGER NOT NULL, + `holonym_id` INTEGER NOT NULL, + FOREIGN KEY (`meronym_id`) REFERENCES `nouns`(`noun_id`), + FOREIGN KEY (`holonym_id`) REFERENCES `nouns`(`noun_id`) +); + +DROP TABLE IF EXISTS `variation`; +CREATE TABLE `variation` ( + `noun_id` INTEGER NOT NULL, + `adjective_id` INTEGER NOT NULL, + FOREIGN KEY (`noun_id`) REFERENCES `nouns`(`noun_id`), + FOREIGN KEY (`adjective_id`) REFERENCES `adjectives`(`adjective_id`) +); + +DROP TABLE IF EXISTS `noun_antonymy`; +CREATE TABLE `noun_antonymy` ( + `noun_1_id` INTEGER NOT NULL, + `noun_2_id` INTEGER NOT NULL, + FOREIGN KEY (`noun_1_id`) REFERENCES `nouns`(`noun_id`), + FOREIGN KEY (`noun_2_id`) REFERENCES `nouns`(`noun_id`) +); + +DROP TABLE IF EXISTS `adjective_antonymy`; +CREATE TABLE `adjective_antonymy` ( + `adjective_1_id` INTEGER NOT NULL, + `adjective_2_id` INTEGER NOT NULL, + FOREIGN KEY (`adjective_1_id`) REFERENCES `adjectives`(`adjective_id`), + FOREIGN KEY (`adjective_2_id`) REFERENCES `adjectives`(`adjective_id`) +); + +DROP TABLE IF EXISTS `adverb_antonymy`; +CREATE TABLE `adverb_antonymy` ( + `adverb_1_id` INTEGER NOT NULL, + `adverb_2_id` INTEGER NOT NULL, + FOREIGN KEY (`adverb_1_id`) REFERENCES `adverbs`(`adverb_id`), + FOREIGN KEY (`adverb_2_id`) REFERENCES `adverbs`(`adverb_id`) +); + +DROP TABLE IF EXISTS `specification`; +CREATE TABLE `specification` ( + `general_id` INTEGER NOT NULL, + `specific_id` INTEGER NOT NULL, + FOREIGN KEY (`general_id`) REFERENCES `adjectives`(`adjective_id`), + FOREIGN KEY (`specific_id`) REFERENCES `adjectives`(`adjective_id`) +); + +DROP TABLE IF EXISTS `pertainymy`; +CREATE TABLE `pertainymy` ( + `noun_id` INTEGER NOT NULL, + `pertainym_id` INTEGER NOT NULL, + FOREIGN KEY (`noun_id`) REFERENCES `nouns`(`noun_id`), + FOREIGN KEY (`pertainym_id`) REFERENCES `adjectives`(`adjective_id`) +); + +DROP TABLE IF EXISTS `mannernymy`; +CREATE TABLE `mannernymy` ( + `adjective_id` INTEGER NOT NULL, + `mannernym_id` INTEGER NOT NULL, + FOREIGN KEY (`adjective_id`) REFERENCES `adjectives`(`adjective_id`), + FOREIGN KEY (`mannernym_id`) REFERENCES `adverbs`(`adverb_id`) +); + +DROP TABLE IF EXISTS `noun_synonymy`; +CREATE TABLE `noun_synonymy` ( + `noun_1_id` INTEGER NOT NULL, + `noun_2_id` INTEGER NOT NULL, + FOREIGN KEY (`noun_1_id`) REFERENCES `nouns`(`nouns_id`), + FOREIGN KEY (`noun_2_id`) REFERENCES `nouns`(`nouns_id`) +); + +DROP TABLE IF EXISTS `adjective_synonymy`; +CREATE TABLE `adjective_synonymy` ( + `adjective_1_id` INTEGER NOT NULL, + `adjective_2_id` INTEGER NOT NULL, + FOREIGN KEY (`adjective_1_id`) REFERENCES `adjectives`(`adjective_id`), + FOREIGN KEY (`adjective_2_id`) REFERENCES `adjectives`(`adjective_id`) +); + +DROP TABLE IF EXISTS `adverb_synonymy`; +CREATE TABLE `adverb_synonymy` ( + `adverb_1_id` INTEGER NOT NULL, + `adverb_2_id` INTEGER NOT NULL, + FOREIGN KEY (`adverb_1_id`) REFERENCES `adverbs`(`adverb_id`), + FOREIGN KEY (`adverb_2_id`) REFERENCES `adverbs`(`adverb_id`) +); + +DROP TABLE IF EXISTS `noun_pronunciations`; +CREATE TABLE `noun_pronunciations` ( + `noun_id` INTEGER NOT NULL, + `pronunciation` VARCHAR(64) NOT NULL, + FOREIGN KEY (`noun_id`) REFERENCES `nouns`(`noun_id`) +); + +DROP TABLE IF EXISTS `verb_pronunciations`; +CREATE TABLE `verb_pronunciations` ( + `verb_id` INTEGER NOT NULL, + `pronunciation` VARCHAR(64) NOT NULL, + FOREIGN KEY (`verb_id`) REFERENCES `verbs`(`verb_id`) +); + +DROP TABLE IF EXISTS `adjective_pronunciations`; +CREATE TABLE `adjective_pronunciations` ( + `adjective_id` INTEGER NOT NULL, + `pronunciation` VARCHAR(64) NOT NULL, + FOREIGN KEY (`adjective_id`) REFERENCES `adjectives`(`adjective_id`) +); + +DROP TABLE IF EXISTS `adverb_pronunciations`; +CREATE TABLE `adverb_pronunciations` ( + `adverb_id` INTEGER NOT NULL, + `pronunciation` VARCHAR(64) NOT NULL, + FOREIGN KEY (`adverb_id`) REFERENCES `adverbs`(`adverb_id`) +); + +DROP TABLE IF EXISTS `noun_noun_derivation`; +CREATE TABLE `noun_noun_derivation` ( + `noun_1_id` INTEGER NOT NULL, + `noun_2_id` INTEGER NOT NULL, + FOREIGN KEY (`noun_1_id`) REFERENCES `nouns`(`noun_id`), + FOREIGN KEY (`noun_2_id`) REFERENCES `nouns`(`noun_id`) +); + +DROP TABLE IF EXISTS `noun_adjective_derivation`; +CREATE TABLE `noun_adjective_derivation` ( + `noun_id` INTEGER NOT NULL, + `adjective_id` INTEGER NOT NULL, + FOREIGN KEY (`noun_id`) REFERENCES `nouns`(`noun_id`), + FOREIGN KEY (`adjective_id`) REFERENCES `adjectives`(`adjective_id`) +); + +DROP TABLE IF EXISTS `noun_adverb_derivation`; +CREATE TABLE `noun_adverb_derivation` ( + `noun_id` INTEGER NOT NULL, + `adverb_id` INTEGER NOT NULL, + FOREIGN KEY (`noun_id`) REFERENCES `nouns`(`noun_id`), + FOREIGN KEY (`adverb_id`) REFERENCES `adverbs`(`adverb_id`) +); + +DROP TABLE IF EXISTS `adjective_adjective_derivation`; +CREATE TABLE `adjective_adjective_derivation` ( + `adjective_1_id` INTEGER NOT NULL, + `adjective_2_id` INTEGER NOT NULL, + FOREIGN KEY (`adjective_1_id`) REFERENCES `adjectives`(`adjective_id`), + FOREIGN KEY (`adjective_2_id`) REFERENCES `adjectives`(`adjective_id`) +); + +DROP TABLE IF EXISTS `adjective_adverb_derivation`; +CREATE TABLE `adjective_adverb_derivation` ( + `adjective_id` INTEGER NOT NULL, + `adverb_id` INTEGER NOT NULL, + FOREIGN KEY (`adjective_id`) REFERENCES `adjectives`(`adjective_id`), + FOREIGN KEY (`adverb_id`) REFERENCES `adverbs`(`adjective_id`) +); + +DROP TABLE IF EXISTS `adverb_adverb_derivation`; +CREATE TABLE `adverb_adverb_derivation` ( + `adverb_1_id` INTEGER NOT NULL, + `adverb_2_id` INTEGER NOT NULL, + FOREIGN KEY (`adverb_1_id`) REFERENCES `adverbs`(`adverb_id`), + FOREIGN KEY (`adverb_2_id`) REFERENCES `adverbs`(`adverb_id`) +); diff --git a/lib/adjective.cpp b/lib/adjective.cpp new file mode 100644 index 0000000..b2b53e4 --- /dev/null +++ b/lib/adjective.cpp @@ -0,0 +1,690 @@ +#include "verbly.h" + +namespace verbly { + + adjective::adjective(const data& _data, int _id) : word(_data, _id) + { + + } + + std::string adjective::base_form() const + { + return _base_form; + } + + std::string adjective::comparative_form() const + { + return _comparative_form; + } + + std::string adjective::superlative_form() const + { + return _superlative_form; + } + + adjective::positioning adjective::position() const + { + return _position; + } + + bool adjective::has_comparative_form() const + { + return !_comparative_form.empty(); + } + + bool adjective::has_superlative_form() const + { + return !_superlative_form.empty(); + } + + bool adjective::has_position() const + { + return _position != adjective::positioning::undefined; + } + + adjective_query adjective::antonyms() const + { + return _data.adjectives().antonym_of(*this); + } + + adjective_query adjective::synonyms() const + { + return _data.adjectives().synonym_of(*this); + } + + adjective_query adjective::generalizations() const + { + return _data.adjectives().generalization_of(*this); + } + + adjective_query adjective::specifications() const + { + return _data.adjectives().specification_of(*this); + } + + noun_query adjective::anti_pertainyms() const + { + return _data.nouns().anti_pertainym_of(*this); + } + + adverb_query adjective::mannernyms() const + { + return _data.adverbs().mannernym_of(*this); + } + + noun_query adjective::attributes() const + { + return _data.nouns().attribute_of(*this); + } + + adjective_query::adjective_query(const data& _data) : _data(_data) + { + + } + + adjective_query& adjective_query::limit(int _limit) + { + if ((_limit > 0) || (_limit == unlimited)) + { + this->_limit = _limit; + } + + return *this; + } + + adjective_query& adjective_query::random(bool _random) + { + this->_random = _random; + + return *this; + } + + adjective_query& adjective_query::except(const adjective& _word) + { + _except.push_back(_word); + + return *this; + } + + adjective_query& adjective_query::rhymes_with(const word& _word) + { + for (auto rhyme : _word.rhyme_phonemes()) + { + _rhymes.push_back(rhyme); + } + + if (dynamic_cast(&_word) != nullptr) + { + _except.push_back(dynamic_cast(_word)); + } + + return *this; + } + + adjective_query& adjective_query::has_pronunciation(bool _has_prn) + { + this->_has_prn = _has_prn; + + return *this; + } + + adjective_query& adjective_query::is_variant(bool _is_variant) + { + this->_is_variant = _is_variant; + + return *this; + } + + adjective_query& adjective_query::variant_of(const noun& _noun) + { + _variant_of.push_back(_noun); + + return *this; + } + + adjective_query& adjective_query::not_variant_of(const noun& _noun) + { + _not_variant_of.push_back(_noun); + + return *this; + } + + adjective_query& adjective_query::has_antonyms(bool _is_antonymic) + { + this->_is_antonymic = _is_antonymic; + + return *this; + } + + adjective_query& adjective_query::antonym_of(const adjective& _adj) + { + _antonym_of.push_back(_adj); + + return *this; + } + + adjective_query& adjective_query::not_antonym_of(const adjective& _adj) + { + _not_antonym_of.push_back(_adj); + + return *this; + } + + adjective_query& adjective_query::has_synonyms(bool _is_synonymic) + { + this->_is_synonymic = _is_synonymic; + + return *this; + } + + adjective_query& adjective_query::synonym_of(const adjective& _adj) + { + _synonym_of.push_back(_adj); + + return *this; + } + + adjective_query& adjective_query::not_synonym_of(const adjective& _adj) + { + _not_synonym_of.push_back(_adj); + + return *this; + } + + adjective_query& adjective_query::is_generalization(bool _is_generalization) + { + this->_is_generalization = _is_generalization; + + return *this; + } + + adjective_query& adjective_query::generalization_of(const adjective& _adj) + { + _generalization_of.push_back(_adj); + + return *this; + } + + adjective_query& adjective_query::not_generalization_of(const adjective& _adj) + { + _not_generalization_of.push_back(_adj); + + return *this; + } + + adjective_query& adjective_query::is_specification(bool _is_specification) + { + this->_is_specification = _is_specification; + + return *this; + } + + adjective_query& adjective_query::specification_of(const adjective& _adj) + { + _specification_of.push_back(_adj); + + return *this; + } + + adjective_query& adjective_query::not_specification_of(const adjective& _adj) + { + _not_specification_of.push_back(_adj); + + return *this; + } + + adjective_query& adjective_query::is_pertainymic(bool _is_pertainymic) + { + this->_is_pertainymic = _is_pertainymic; + + return *this; + } + + adjective_query& adjective_query::pertainym_of(const noun& _noun) + { + _pertainym_of.push_back(_noun); + + return *this; + } + + adjective_query& adjective_query::is_mannernymic(bool _is_mannernymic) + { + this->_is_mannernymic = _is_mannernymic; + + return *this; + } + + adjective_query& adjective_query::anti_mannernym_of(const adverb& _adv) + { + _anti_mannernym_of.push_back(_adv); + + return *this; + } + + adjective_query& adjective_query::derived_from(const word& _w) + { + if (dynamic_cast(&_w) != nullptr) + { + _derived_from_adjective.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _derived_from_adverb.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _derived_from_noun.push_back(dynamic_cast(_w)); + } + + return *this; + } + + adjective_query& adjective_query::not_derived_from(const word& _w) + { + if (dynamic_cast(&_w) != nullptr) + { + _not_derived_from_adjective.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _not_derived_from_adverb.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _not_derived_from_noun.push_back(dynamic_cast(_w)); + } + + return *this; + } + + std::list adjective_query::run() const + { + std::stringstream construct; + construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives"; + std::list conditions; + + if (_has_prn) + { + conditions.push_back("adjective_id IN (SELECT adjective_id FROM adjective_pronunciations)"); + } + + if (!_rhymes.empty()) + { + std::list clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); + std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + for (auto except : _except) + { + conditions.push_back("adjective_id != @EXCID"); + } + + if (_requires_comparative_form) + { + conditions.push_back("comparative IS NOT NULL"); + } + + if (_requires_superlative_form) + { + conditions.push_back("superlative IS NOT NULL"); + } + + if (_position != adjective::positioning::undefined) + { + switch (_position) + { + case adjective::positioning::predicate: conditions.push_back("position = 'p'"); break; + case adjective::positioning::attributive: conditions.push_back("position = 'a'"); break; + case adjective::positioning::postnominal: conditions.push_back("position = 'i'"); break; + } + } + + if (_is_variant) + { + conditions.push_back("adjective_id IN (SELECT adjective_id FROM variation)"); + } + + if (!_variant_of.empty()) + { + std::list clauses(_variant_of.size(), "noun_id = @ATTRID"); + std::string cond = "adjective_id IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_variant_of.empty()) + { + std::list clauses(_not_variant_of.size(), "noun_id = @NATTRID"); + std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_antonymic) + { + conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy)"); + } + + if (!_antonym_of.empty()) + { + std::list clauses(_antonym_of.size(), "adjective_1_id = @ANTID"); + std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_antonym_of.empty()) + { + std::list clauses(_not_antonym_of.size(), "adjective_1_id = @NANTID"); + std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_synonymic) + { + conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy)"); + } + + if (!_synonym_of.empty()) + { + std::list clauses(_synonym_of.size(), "adjective_1_id = @SYNID"); + std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_synonym_of.empty()) + { + std::list clauses(_not_synonym_of.size(), "adjective_1_id = @NSYNID"); + std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_generalization) + { + conditions.push_back("adjective_id IN (SELECT general_id FROM specification)"); + } + + if (!_generalization_of.empty()) + { + std::list clauses(_generalization_of.size(), "specific_id = @SPECID"); + std::string cond = "adjective_id IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_generalization_of.empty()) + { + std::list clauses(_not_generalization_of.size(), "specific_id = @NSPECID"); + std::string cond = "adjective_id NOT IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_specification) + { + conditions.push_back("adjective_id IN (SELECT specific_id FROM specification)"); + } + + if (!_specification_of.empty()) + { + std::list clauses(_specification_of.size(), "general_id = @GENID"); + std::string cond = "adjective_id IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_specification_of.empty()) + { + std::list clauses(_not_specification_of.size(), "general_id = @NGENID"); + std::string cond = "adjective_id NOT IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_pertainymic) + { + conditions.push_back("adjective_id IN (SELECT pertainym_id FROM pertainymy)"); + } + + if (!_pertainym_of.empty()) + { + std::list clauses(_pertainym_of.size(), "noun_id = @APERID"); + std::string cond = "adjective_id IN (SELECT pertainym_id FROM pertainymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_mannernymic) + { + conditions.push_back("adjective_id IN (SELECT adjective_id FROM mannernymy)"); + } + + if (!_anti_mannernym_of.empty()) + { + std::list clauses(_anti_mannernym_of.size(), "mannernym_id = @MANID"); + std::string cond = "adjective_id IN (SELECT adjective_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_derived_from_adjective.empty()) + { + std::list clauses(_derived_from_adjective.size(), "adjective_2_id = @DERADJ"); + std::string cond = "adjective_id IN (SELECT adjective_1_id FROM adjective_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_derived_from_adjective.empty()) + { + std::list clauses(_not_derived_from_adjective.size(), "adjective_2_id = @NDERADJ"); + std::string cond = "adjective_id NOT IN (SELECT adjective_1_id FROM adjective_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_derived_from_adverb.empty()) + { + std::list clauses(_derived_from_adverb.size(), "adverb_id = @DERADV"); + std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_derived_from_adverb.empty()) + { + std::list clauses(_not_derived_from_adverb.size(), "adverb_id = @NDERADV"); + std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_derived_from_noun.empty()) + { + std::list clauses(_derived_from_noun.size(), "noun_id = @DERN"); + std::string cond = "adjective_id IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_derived_from_noun.empty()) + { + std::list clauses(_not_derived_from_noun.size(), "noun_id = @NDERN"); + std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!conditions.empty()) + { + construct << " WHERE "; + construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); + } + + if (_random) + { + construct << " ORDER BY RANDOM()"; + } + + if (_limit != unlimited) + { + construct << " LIMIT " << _limit; + } + + sqlite3_stmt* ppstmt; + std::string query = construct.str(); + if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); + } + + if (!_rhymes.empty()) + { + int i = 0; + for (auto rhyme : _rhymes) + { + std::string rhymer = "%" + rhyme; + sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); + + i++; + } + } + + for (auto except : _except) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); + } + + for (auto attribute : _variant_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id); + } + + for (auto attribute : _not_variant_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NATTRID"), attribute._id); + } + + for (auto antonym : _antonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); + } + + for (auto antonym : _not_antonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); + } + + for (auto synonym : _synonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); + } + + for (auto synonym : _not_synonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); + } + + for (auto specific : _generalization_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SPECID"), specific._id); + } + + for (auto specific : _not_generalization_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSPECID"), specific._id); + } + + for (auto general : _specification_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GENID"), general._id); + } + + for (auto general : _not_specification_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NGENID"), general._id); + } + + for (auto n : _pertainym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@APERID"), n._id); + } + + for (auto mannernym : _anti_mannernym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MANID"), mannernym._id); + } + + for (auto adj : _derived_from_adjective) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id); + } + + for (auto adj : _not_derived_from_adjective) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id); + } + + for (auto adv : _derived_from_adverb) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id); + } + + for (auto adv : _not_derived_from_adverb) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id); + } + + for (auto n : _derived_from_noun) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id); + } + + for (auto n : _not_derived_from_noun) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id); + } + + std::list output; + while (sqlite3_step(ppstmt) == SQLITE_ROW) + { + adjective tnc {_data, sqlite3_column_int(ppstmt, 0)}; + tnc._base_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 1))); + + if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) + { + tnc._comparative_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 2))); + } + + if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) + { + tnc._superlative_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 3))); + } + + if (sqlite3_column_type(ppstmt, 4) != SQLITE_NULL) + { + std::string adjpos(reinterpret_cast(sqlite3_column_text(ppstmt, 4))); + if (adjpos == "p") + { + tnc._position = adjective::positioning::predicate; + } else if (adjpos == "a") + { + tnc._position = adjective::positioning::attributive; + } else if (adjpos == "i") + { + tnc._position = adjective::positioning::postnominal; + } + } + + output.push_back(tnc); + } + + sqlite3_finalize(ppstmt); + + for (auto& adjective : output) + { + query = "SELECT pronunciation FROM adjective_pronunciations WHERE adjective_id = ?"; + if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); + } + + sqlite3_bind_int(ppstmt, 1, adjective._id); + + while (sqlite3_step(ppstmt) == SQLITE_ROW) + { + std::string pronunciation(reinterpret_cast(sqlite3_column_text(ppstmt, 0))); + auto phonemes = verbly::split>(pronunciation, " "); + + adjective.pronunciations.push_back(phonemes); + } + + sqlite3_finalize(ppstmt); + } + + return output; + } + +}; diff --git a/lib/adjective.h b/lib/adjective.h new file mode 100644 index 0000000..3dcab9b --- /dev/null +++ b/lib/adjective.h @@ -0,0 +1,143 @@ +#ifndef ADJECTIVE_H_87B3FB75 +#define ADJECTIVE_H_87B3FB75 + +namespace verbly { + + class adjective_query; + class adverb_query; + class noun_query; + + class adjective : public word { + public: + enum class positioning { + undefined, + predicate, + attributive, + postnominal + }; + + private: + std::string _base_form; + std::string _comparative_form; + std::string _superlative_form; + positioning _position = positioning::undefined; + + friend class adjective_query; + + public: + adjective(const data& _data, int _id); + + std::string base_form() const; + std::string comparative_form() const; + std::string superlative_form() const; + positioning position() const; + + bool has_comparative_form() const; + bool has_superlative_form() const; + bool has_position() const; + + adjective_query antonyms() const; + adjective_query synonyms() const; + adjective_query generalizations() const; + adjective_query specifications() const; + noun_query anti_pertainyms() const; + adverb_query mannernyms() const; + noun_query attributes() const; + }; + + class adjective_query { + public: + adjective_query(const data& _data); + + adjective_query& limit(int _limit); + adjective_query& random(bool _random); + adjective_query& except(const adjective& _word); + adjective_query& rhymes_with(const word& _word); + adjective_query& has_pronunciation(bool _has_prn); + + adjective_query& requires_comparative_form(bool req); + adjective_query& requires_superlative_form(bool req); + adjective_query& position(adjective::positioning pos); + + adjective_query& is_variant(bool _is_variant); + adjective_query& variant_of(const noun& _noun); + adjective_query& not_variant_of(const noun& _noun); + + adjective_query& has_antonyms(bool _is_antonymic); + adjective_query& antonym_of(const adjective& _adj); + adjective_query& not_antonym_of(const adjective& _adj); + + adjective_query& has_synonyms(bool _is_synonymic); + adjective_query& synonym_of(const adjective& _adj); + adjective_query& not_synonym_of(const adjective& _adj); + + adjective_query& is_generalization(bool _is_generalization); + adjective_query& generalization_of(const adjective& _adj); + adjective_query& not_generalization_of(const adjective& _adj); + + adjective_query& is_specification(bool _is_specification); + adjective_query& specification_of(const adjective& _adj); + adjective_query& not_specification_of(const adjective& _adj); + + adjective_query& is_pertainymic(bool _is_pertainymic); + adjective_query& pertainym_of(const noun& _noun); + + adjective_query& is_mannernymic(bool _is_mannernymic); + adjective_query& anti_mannernym_of(const adverb& _adv); + + adjective_query& derived_from(const word& _w); + adjective_query& not_derived_from(const word& _w); + + std::list run() const; + + const static int unlimited = -1; + + protected: + const data& _data; + int _limit = unlimited; + bool _random = false; + std::list _rhymes; + std::list _except; + bool _has_prn = false; + + bool _requires_comparative_form = false; + bool _requires_superlative_form = false; + adjective::positioning _position = adjective::positioning::undefined; + + bool _is_variant = false; + std::list _variant_of; + std::list _not_variant_of; + + bool _is_antonymic = false; + std::list _antonym_of; + std::list _not_antonym_of; + + bool _is_synonymic = false; + std::list _synonym_of; + std::list _not_synonym_of; + + bool _is_generalization = false; + std::list _generalization_of; + std::list _not_generalization_of; + + bool _is_specification = false; + std::list _specification_of; + std::list _not_specification_of; + + bool _is_pertainymic = false; + std::list _pertainym_of; + + bool _is_mannernymic = false; + std::list _anti_mannernym_of; + + std::list _derived_from_adjective; + std::list _not_derived_from_adjective; + std::list _derived_from_adverb; + std::list _not_derived_from_adverb; + std::list _derived_from_noun; + std::list _not_derived_from_noun; + }; + +}; + +#endif /* end of include guard: ADJECTIVE_H_87B3FB75 */ diff --git a/lib/adverb.cpp b/lib/adverb.cpp new file mode 100644 index 0000000..8fcddad --- /dev/null +++ b/lib/adverb.cpp @@ -0,0 +1,468 @@ +#include "verbly.h" + +namespace verbly { + + adverb::adverb(const data& _data, int _id) : word(_data, _id) + { + + } + + std::string adverb::base_form() const + { + return _base_form; + } + + std::string adverb::comparative_form() const + { + return _comparative_form; + } + + std::string adverb::superlative_form() const + { + return _superlative_form; + } + + bool adverb::has_comparative_form() const + { + return !_comparative_form.empty(); + } + + bool adverb::has_superlative_form() const + { + return !_superlative_form.empty(); + } + + adverb_query adverb::antonyms() const + { + return _data.adverbs().antonym_of(*this); + } + + adverb_query adverb::synonyms() const + { + return _data.adverbs().synonym_of(*this); + } + + adjective_query adverb::anti_mannernyms() const + { + return _data.adjectives().anti_mannernym_of(*this); + } + + adverb_query::adverb_query(const data& _data) : _data(_data) + { + + } + + adverb_query& adverb_query::limit(int _limit) + { + if ((_limit > 0) || (_limit == unlimited)) + { + this->_limit = _limit; + } + + return *this; + } + + adverb_query& adverb_query::random(bool _random) + { + this->_random = _random; + + return *this; + } + + adverb_query& adverb_query::except(const adverb& _word) + { + _except.push_back(_word); + + return *this; + } + + adverb_query& adverb_query::rhymes_with(const word& _word) + { + for (auto rhyme : _word.rhyme_phonemes()) + { + _rhymes.push_back(rhyme); + } + + if (dynamic_cast(&_word) != nullptr) + { + _except.push_back(dynamic_cast(_word)); + } + + return *this; + } + + adverb_query& adverb_query::has_pronunciation(bool _has_prn) + { + this->_has_prn = _has_prn; + + return *this; + } + + adverb_query& adverb_query::requires_comparative_form(bool _arg) + { + _requires_comparative_form = _arg; + + return *this; + } + + adverb_query& adverb_query::requires_superlative_form(bool _arg) + { + _requires_superlative_form = _arg; + + return *this; + } + + adverb_query& adverb_query::has_antonyms(bool _arg) + { + _has_antonyms = _arg; + + return *this; + } + + adverb_query& adverb_query::antonym_of(const adverb& _adv) + { + _antonym_of.push_back(_adv); + + return *this; + } + + adverb_query& adverb_query::not_antonym_of(const adverb& _adv) + { + _not_antonym_of.push_back(_adv); + + return *this; + } + + adverb_query& adverb_query::has_synonyms(bool _arg) + { + _has_synonyms = _arg; + + return *this; + } + + adverb_query& adverb_query::synonym_of(const adverb& _adv) + { + _synonym_of.push_back(_adv); + + return *this; + } + + adverb_query& adverb_query::not_synonym_of(const adverb& _adv) + { + _not_synonym_of.push_back(_adv); + + return *this; + } + + adverb_query& adverb_query::is_mannernymic(bool _arg) + { + _is_mannernymic = _arg; + + return *this; + } + + adverb_query& adverb_query::mannernym_of(const adjective& _adj) + { + _mannernym_of.push_back(_adj); + + return *this; + } + + adverb_query& adverb_query::derived_from(const word& _w) + { + if (dynamic_cast(&_w) != nullptr) + { + _derived_from_adjective.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _derived_from_adverb.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _derived_from_noun.push_back(dynamic_cast(_w)); + } + + return *this; + } + + adverb_query& adverb_query::not_derived_from(const word& _w) + { + if (dynamic_cast(&_w) != nullptr) + { + _not_derived_from_adjective.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _not_derived_from_adverb.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _not_derived_from_noun.push_back(dynamic_cast(_w)); + } + + return *this; + } + + std::list adverb_query::run() const + { + std::stringstream construct; + construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs"; + std::list conditions; + + if (_has_prn) + { + conditions.push_back("adverb_id IN (SELECT adverb_id FROM adverb_pronunciations)"); + } + + if (!_rhymes.empty()) + { + std::list clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); + std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + for (auto except : _except) + { + conditions.push_back("adverb_id != @EXCID"); + } + + if (_requires_comparative_form) + { + conditions.push_back("comparative IS NOT NULL"); + } + + if (_requires_superlative_form) + { + conditions.push_back("superlative IS NOT NULL"); + } + + if (_has_antonyms) + { + conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)"); + } + + if (!_antonym_of.empty()) + { + std::list clauses(_antonym_of.size(), "adverb_1_id = @ANTID"); + std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_antonym_of.empty()) + { + std::list clauses(_not_antonym_of.size(), "adverb_1_id = @NANTID"); + std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_has_synonyms) + { + conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy)"); + } + + if (!_synonym_of.empty()) + { + std::list clauses(_synonym_of.size(), "adverb_1_id = @SYNID"); + std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_synonym_of.empty()) + { + std::list clauses(_not_synonym_of.size(), "adverb_1_id = @NSYNID"); + std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_mannernymic) + { + conditions.push_back("adverb_id IN (SELECT mannernym_id FROM mannernymy)"); + } + + if (!_mannernym_of.empty()) + { + std::list clauses(_mannernym_of.size(), "adjective_id = @AMANID"); + std::string cond = "adverb_id IN (SELECT mannernym_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_derived_from_adjective.empty()) + { + std::list clauses(_derived_from_adjective.size(), "adjective_id = @DERADJ"); + std::string cond = "adverb_id IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_derived_from_adjective.empty()) + { + std::list clauses(_not_derived_from_adjective.size(), "adjective_id = @NDERADJ"); + std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_derived_from_adverb.empty()) + { + std::list clauses(_derived_from_adverb.size(), "adverb_2_id = @DERADV"); + std::string cond = "adverb_id IN (SELECT adverb_1_id FROM adverb_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_derived_from_adverb.empty()) + { + std::list clauses(_not_derived_from_adverb.size(), "adverb_2_id = @NDERADV"); + std::string cond = "adverb_id NOT IN (SELECT adverb_1_id FROM adverb_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_derived_from_noun.empty()) + { + std::list clauses(_derived_from_noun.size(), "noun_id = @DERN"); + std::string cond = "adverb_id IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_derived_from_noun.empty()) + { + std::list clauses(_not_derived_from_noun.size(), "noun_id = @NDERN"); + std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!conditions.empty()) + { + construct << " WHERE "; + construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); + } + + if (_random) + { + construct << " ORDER BY RANDOM()"; + } + + if (_limit != unlimited) + { + construct << " LIMIT " << _limit; + } + + sqlite3_stmt* ppstmt; + std::string query = construct.str(); + if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); + } + + if (!_rhymes.empty()) + { + int i = 0; + for (auto rhyme : _rhymes) + { + std::string rhymer = "%" + rhyme; + sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); + + i++; + } + } + + for (auto except : _except) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); + } + + for (auto antonym : _antonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); + } + + for (auto antonym : _not_antonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); + } + + for (auto synonym : _synonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); + } + + for (auto synonym : _not_synonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); + } + + for (auto adj : _mannernym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id); + } + + for (auto adj : _derived_from_adjective) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id); + } + + for (auto adj : _not_derived_from_adjective) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id); + } + + for (auto adv : _derived_from_adverb) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id); + } + + for (auto adv : _not_derived_from_adverb) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id); + } + + for (auto n : _derived_from_noun) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id); + } + + for (auto n : _not_derived_from_noun) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id); + } + + std::list output; + while (sqlite3_step(ppstmt) == SQLITE_ROW) + { + adverb tnc {_data, sqlite3_column_int(ppstmt, 0)}; + tnc._base_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 1))); + + if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) + { + tnc._comparative_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 2))); + } + + if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) + { + tnc._superlative_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 3))); + } + + output.push_back(tnc); + } + + sqlite3_finalize(ppstmt); + + for (auto& adverb : output) + { + query = "SELECT pronunciation FROM adverb_pronunciations WHERE adverb_id = ?"; + if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); + } + + sqlite3_bind_int(ppstmt, 1, adverb._id); + + while (sqlite3_step(ppstmt) == SQLITE_ROW) + { + std::string pronunciation(reinterpret_cast(sqlite3_column_text(ppstmt, 0))); + auto phonemes = verbly::split>(pronunciation, " "); + + adverb.pronunciations.push_back(phonemes); + } + + sqlite3_finalize(ppstmt); + } + + return output; + } + +}; diff --git a/lib/adverb.h b/lib/adverb.h new file mode 100644 index 0000000..65e3c5c --- /dev/null +++ b/lib/adverb.h @@ -0,0 +1,95 @@ +#ifndef ADVERB_H_86F8302F +#define ADVERB_H_86F8302F + +namespace verbly { + + class adverb : public word { + private: + std::string _base_form; + std::string _comparative_form; + std::string _superlative_form; + + friend class adverb_query; + + public: + adverb(const data& _data, int _id); + + std::string base_form() const; + std::string comparative_form() const; + std::string superlative_form() const; + + bool has_comparative_form() const; + bool has_superlative_form() const; + + adverb_query antonyms() const; + adverb_query synonyms() const; + adjective_query anti_mannernyms() const; + + adverb_query& derived_from(const word& _w); + adverb_query& not_derived_from(const word& _w); + }; + + class adverb_query { + public: + adverb_query(const data& _data); + + adverb_query& limit(int _limit); + adverb_query& random(bool _random); + adverb_query& except(const adverb& _word); + adverb_query& rhymes_with(const word& _word); + adverb_query& has_pronunciation(bool _has_prn); + + adverb_query& requires_comparative_form(bool _arg); + adverb_query& requires_superlative_form(bool _arg); + + adverb_query& has_antonyms(bool _arg); + adverb_query& antonym_of(const adverb& _adv); + adverb_query& not_antonym_of(const adverb& _adv); + + adverb_query& has_synonyms(bool _arg); + adverb_query& synonym_of(const adverb& _adv); + adverb_query& not_synonym_of(const adverb& _adv); + + adverb_query& is_mannernymic(bool _arg); + adverb_query& mannernym_of(const adjective& _adj); + + adverb_query& derived_from(const word& _w); + adverb_query& not_derived_from(const word& _w); + + std::list run() const; + + const static int unlimited = -1; + + private: + const data& _data; + int _limit = unlimited; + bool _random = false; + std::list _rhymes; + std::list _except; + bool _has_prn = false; + + bool _requires_comparative_form = false; + bool _requires_superlative_form = false; + + bool _has_antonyms = false; + std::list _antonym_of; + std::list _not_antonym_of; + + bool _has_synonyms = false; + std::list _synonym_of; + std::list _not_synonym_of; + + bool _is_mannernymic = false; + std::list _mannernym_of; + + std::list _derived_from_adjective; + std::list _not_derived_from_adjective; + std::list _derived_from_adverb; + std::list _not_derived_from_adverb; + std::list _derived_from_noun; + std::list _not_derived_from_noun; + }; + +}; + +#endif /* end of include guard: ADVERB_H_86F8302F */ diff --git a/lib/c++14.h b/lib/c++14.h new file mode 100644 index 0000000..b3efbe2 --- /dev/null +++ b/lib/c++14.h @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +namespace std { + template struct _Unique_if { + typedef unique_ptr _Single_object; + }; + + template struct _Unique_if { + typedef unique_ptr _Unknown_bound; + }; + + template struct _Unique_if { + typedef void _Known_bound; + }; + + template + typename _Unique_if::_Single_object + make_unique(Args&&... args) { + return unique_ptr(new T(std::forward(args)...)); + } + + template + typename _Unique_if::_Unknown_bound + make_unique(size_t n) { + typedef typename remove_extent::type U; + return unique_ptr(new U[n]()); + } + + template + typename _Unique_if::_Known_bound + make_unique(Args&&...) = delete; +} diff --git a/lib/data.cpp b/lib/data.cpp new file mode 100644 index 0000000..57a8850 --- /dev/null +++ b/lib/data.cpp @@ -0,0 +1,50 @@ +#include "verbly.h" + +namespace verbly { + + data::data(std::string datafile) + { + if (sqlite3_open_v2(datafile.c_str(), &ppdb, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) + { + throw std::invalid_argument(sqlite3_errmsg(ppdb)); + } + } + + data::data(data&& other) + { + ppdb = other.ppdb; + } + + data& data::operator=(data&& other) + { + ppdb = other.ppdb; + + return *this; + } + + data::~data() + { + sqlite3_close_v2(ppdb); + } + + verb_query data::verbs() const + { + return verb_query(*this); + } + + adjective_query data::adjectives() const + { + return adjective_query(*this); + } + + adverb_query data::adverbs() const + { + return adverb_query(*this); + } + + noun_query data::nouns() const + { + return noun_query(*this); + } + +}; diff --git a/lib/data.h b/lib/data.h new file mode 100644 index 0000000..37092d7 --- /dev/null +++ b/lib/data.h @@ -0,0 +1,49 @@ +#ifndef DATA_H_C4AEC3DD +#define DATA_H_C4AEC3DD + +#include +#include + +namespace verbly { + + class data; + class word; + class adjective; + class noun; + class verb; + class adverb; + class adjective_query; + class adverb_query; + class noun_query; + class verb_query; + + class data { + private: + sqlite3* ppdb; + + friend class adjective_query; + friend class noun_query; + friend class verb_query; + friend class adverb_query; + + public: + data(std::string datafile); + + data(const data& other) = delete; + data& operator=(const data& other) = delete; + + data(data&& other); + data& operator=(data&& other); + + ~data(); + + verb_query verbs() const; + adjective_query adjectives() const; + adverb_query adverbs() const; + noun_query nouns() const; + + }; + +}; + +#endif /* end of include guard: DATA_H_C4AEC3DD */ diff --git a/lib/noun.cpp b/lib/noun.cpp new file mode 100644 index 0000000..43fda2e --- /dev/null +++ b/lib/noun.cpp @@ -0,0 +1,1032 @@ +#include "verbly.h" + +namespace verbly { + + noun::noun(const data& _data, int _id) : word(_data, _id) + { + + } + + std::string noun::base_form() const + { + return _singular; + } + + std::string noun::singular_form() const + { + return _singular; + } + + std::string noun::plural_form() const + { + return _plural; + } + + bool noun::has_plural_form() const + { + return !_plural.empty(); + } + + noun_query noun::hypernyms() const + { + return _data.nouns().hypernym_of(*this); + } + + noun_query noun::hyponyms() const + { + return _data.nouns().hyponym_of(*this); + } + + noun_query noun::part_meronyms() const + { + return _data.nouns().part_meronym_of(*this); + } + + noun_query noun::part_holonyms() const + { + return _data.nouns().part_holonym_of(*this); + } + + noun_query noun::substance_meronyms() const + { + return _data.nouns().substance_meronym_of(*this); + } + + noun_query noun::substance_holonyms() const + { + return _data.nouns().substance_holonym_of(*this); + } + + noun_query noun::member_meronyms() const + { + return _data.nouns().member_meronym_of(*this); + } + + noun_query noun::member_holonyms() const + { + return _data.nouns().member_holonym_of(*this); + } + + noun_query noun::classes() const + { + return _data.nouns().class_of(*this); + } + + noun_query noun::instances() const + { + return _data.nouns().instance_of(*this); + } + + noun_query noun::synonyms() const + { + return _data.nouns().synonym_of(*this); + } + + noun_query noun::antonyms() const + { + return _data.nouns().antonym_of(*this); + } + + adjective_query noun::pertainyms() const + { + return _data.adjectives().pertainym_of(*this); + } + + adjective_query noun::variations() const + { + return _data.adjectives().variant_of(*this); + } + + noun_query::noun_query(const data& _data) : _data(_data) + { + + } + + noun_query& noun_query::limit(int _limit) + { + if ((_limit > 0) || (_limit == unlimited)) + { + this->_limit = _limit; + } + + return *this; + } + + noun_query& noun_query::random(bool _random) + { + this->_random = _random; + + return *this; + } + + noun_query& noun_query::except(const noun& _word) + { + _except.push_back(_word); + + return *this; + } + + noun_query& noun_query::rhymes_with(const word& _word) + { + for (auto rhyme : _word.rhyme_phonemes()) + { + _rhymes.push_back(rhyme); + } + + if (dynamic_cast(&_word) != nullptr) + { + _except.push_back(dynamic_cast(_word)); + } + + return *this; + } + + noun_query& noun_query::has_pronunciation(bool _has_prn) + { + this->_has_prn = _has_prn; + + return *this; + } + + noun_query& noun_query::is_hypernym(bool _arg) + { + _is_hypernym = _arg; + + return *this; + } + + noun_query& noun_query::hypernym_of(const noun& _noun) + { + _hypernym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_hypernym_of(const noun& _noun) + { + _not_hypernym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::is_hyponym(bool _arg) + { + _is_hyponym = _arg; + + return *this; + } + + noun_query& noun_query::hyponym_of(const noun& _noun) + { + _hyponym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_hyponym_of(const noun& _noun) + { + _not_hyponym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::is_part_meronym(bool _arg) + { + _is_part_meronym = _arg; + + return *this; + } + + noun_query& noun_query::part_meronym_of(const noun& _noun) + { + _part_meronym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_part_meronym_of(const noun& _noun) + { + _not_part_meronym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::is_part_holonym(bool _arg) + { + _is_part_holonym = _arg; + + return *this; + } + + noun_query& noun_query::part_holonym_of(const noun& _noun) + { + _part_holonym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_part_holonym_of(const noun& _noun) + { + _not_part_holonym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::is_substance_meronym(bool _arg) + { + _is_substance_meronym = _arg; + + return *this; + } + + noun_query& noun_query::substance_meronym_of(const noun& _noun) + { + _substance_meronym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_substance_meronym_of(const noun& _noun) + { + _not_substance_meronym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::is_substance_holonym(bool _arg) + { + _is_substance_holonym = _arg; + + return *this; + } + + noun_query& noun_query::substance_holonym_of(const noun& _noun) + { + _substance_holonym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_substance_holonym_of(const noun& _noun) + { + _not_substance_holonym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::is_member_meronym(bool _arg) + { + _is_member_meronym = _arg; + + return *this; + } + + noun_query& noun_query::member_meronym_of(const noun& _noun) + { + _member_meronym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_member_meronym_of(const noun& _noun) + { + _not_member_meronym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::is_member_holonym(bool _arg) + { + _is_member_holonym = _arg; + + return *this; + } + + noun_query& noun_query::member_holonym_of(const noun& _noun) + { + _member_holonym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_member_holonym_of(const noun& _noun) + { + _not_member_holonym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::is_proper(bool _arg) + { + _is_proper = _arg; + + return *this; + } + + noun_query& noun_query::is_not_proper(bool _arg) + { + _is_not_proper = _arg; + + return *this; + } + + noun_query& noun_query::instance_of(const noun& _noun) + { + _instance_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_instance_of(const noun& _noun) + { + _not_instance_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::is_class(bool _arg) + { + _is_class = _arg; + + return *this; + } + + noun_query& noun_query::class_of(const noun& _noun) + { + _class_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_class_of(const noun& _noun) + { + _not_class_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::has_synonyms(bool _arg) + { + _has_synonyms = _arg; + + return *this; + } + + noun_query& noun_query::synonym_of(const noun& _noun) + { + _synonym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_synonym_of(const noun& _noun) + { + _not_synonym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::has_antonyms(bool _arg) + { + _has_antonyms = _arg; + + return *this; + } + + noun_query& noun_query::antonym_of(const noun& _noun) + { + _antonym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::not_antonym_of(const noun& _noun) + { + _not_antonym_of.push_back(_noun); + + return *this; + } + + noun_query& noun_query::has_pertainym(bool _arg) + { + _has_pertainym = _arg; + + return *this; + } + + noun_query& noun_query::anti_pertainym_of(const adjective& _adj) + { + _anti_pertainym_of.push_back(_adj); + + return *this; + } + + noun_query& noun_query::is_attribute(bool _arg) + { + _is_attribute = _arg; + + return *this; + } + + noun_query& noun_query::attribute_of(const adjective& _adj) + { + _attribute_of.push_back(_adj); + + return *this; + } + + noun_query& noun_query::derived_from(const word& _w) + { + if (dynamic_cast(&_w) != nullptr) + { + _derived_from_adjective.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _derived_from_adverb.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _derived_from_noun.push_back(dynamic_cast(_w)); + } + + return *this; + } + + noun_query& noun_query::not_derived_from(const word& _w) + { + if (dynamic_cast(&_w) != nullptr) + { + _not_derived_from_adjective.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _not_derived_from_adverb.push_back(dynamic_cast(_w)); + } else if (dynamic_cast(&_w) != nullptr) + { + _not_derived_from_noun.push_back(dynamic_cast(_w)); + } + + return *this; + } + + std::list noun_query::run() const + { + std::stringstream construct; + construct << "SELECT noun_id, singular, plural FROM nouns"; + std::list conditions; + + if (_has_prn) + { + conditions.push_back("noun_id IN (SELECT noun_id FROM noun_pronunciations)"); + } + + if (!_rhymes.empty()) + { + std::list clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); + std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + for (auto except : _except) + { + conditions.push_back("noun_id != @EXCID"); + } + + if (_is_hypernym) + { + conditions.push_back("noun_id IN (SELECT hypernym_id FROM hypernymy)"); + } + + if (!_hypernym_of.empty()) + { + std::list clauses(_hypernym_of.size(), "hyponym_id = @HYPO"); + std::string cond = "noun_id IN (SELECT hypernym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_hypernym_of.empty()) + { + std::list clauses(_not_hypernym_of.size(), "hyponym_id = @NHYPO"); + std::string cond = "noun_id NOT IN (SELECT hypernym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_hyponym) + { + conditions.push_back("noun_id IN (SELECT hyponym_id FROM hypernymy)"); + } + + if (!_hyponym_of.empty()) + { + std::list clauses(_hyponym_of.size(), "hypernym_id = @HYPER"); + std::string cond = "noun_id IN (SELECT hyponym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_hyponym_of.empty()) + { + std::list clauses(_not_hyponym_of.size(), "hypernym_id = @NHYPER"); + std::string cond = "noun_id NOT IN (SELECT hyponym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_part_meronym) + { + conditions.push_back("noun_id IN (SELECT meronym_id FROM part_meronymy)"); + } + + if (!_part_meronym_of.empty()) + { + std::list clauses(_part_meronym_of.size(), "holonym_id = @PHOLO"); + std::string cond = "noun_id IN (SELECT meronym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_part_meronym_of.empty()) + { + std::list clauses(_not_part_meronym_of.size(), "holonym_id = @NPHOLO"); + std::string cond = "noun_id NOT IN (SELECT meronym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_part_holonym) + { + conditions.push_back("noun_id IN (SELECT holonym_id FROM part_meronymy)"); + } + + if (!_part_holonym_of.empty()) + { + std::list clauses(_part_holonym_of.size(), "meronym_id = @PMERO"); + std::string cond = "noun_id IN (SELECT holonym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_part_holonym_of.empty()) + { + std::list clauses(_not_part_holonym_of.size(), "meronym_id = @NPMERO"); + std::string cond = "noun_id NOT IN (SELECT holonym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_substance_meronym) + { + conditions.push_back("noun_id IN (SELECT meronym_id FROM substance_meronymy)"); + } + + if (!_substance_meronym_of.empty()) + { + std::list clauses(_substance_meronym_of.size(), "holonym_id = @SHOLO"); + std::string cond = "noun_id IN (SELECT meronym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_substance_meronym_of.empty()) + { + std::list clauses(_not_substance_meronym_of.size(), "holonym_id = @NSHOLO"); + std::string cond = "noun_id NOT IN (SELECT meronym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_substance_holonym) + { + conditions.push_back("noun_id IN (SELECT holonym_id FROM substance_meronymy)"); + } + + if (!_substance_holonym_of.empty()) + { + std::list clauses(_substance_holonym_of.size(), "meronym_id = @SMERO"); + std::string cond = "noun_id IN (SELECT holonym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_substance_holonym_of.empty()) + { + std::list clauses(_not_substance_holonym_of.size(), "meronym_id = @NSMERO"); + std::string cond = "noun_id NOT IN (SELECT holonym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_member_meronym) + { + conditions.push_back("noun_id IN (SELECT meronym_id FROM member_meronymy)"); + } + + if (!_member_meronym_of.empty()) + { + std::list clauses(_member_meronym_of.size(), "holonym_id = @MHOLO"); + std::string cond = "noun_id IN (SELECT meronym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_member_meronym_of.empty()) + { + std::list clauses(_not_member_meronym_of.size(), "holonym_id = @NMHOLO"); + std::string cond = "noun_id NOT IN (SELECT meronym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_member_holonym) + { + conditions.push_back("noun_id IN (SELECT holonym_id FROM member_meronym)"); + } + + if (!_member_holonym_of.empty()) + { + std::list clauses(_member_holonym_of.size(), "meronym_id = @MMERO"); + std::string cond = "noun_id IN (SELECT holonym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_member_holonym_of.empty()) + { + std::list clauses(_not_member_holonym_of.size(), "meronym_id = @NMMERO"); + std::string cond = "noun_id NOT IN (SELECT holonym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_proper) + { + conditions.push_back("noun_id IN (SELECT instance_id FROM instantiation)"); + } + + if (_is_not_proper) + { + conditions.push_back("noun_id NOT IN (SELECT instance_id FROM instantiation)"); + } + + if (!_instance_of.empty()) + { + std::list clauses(_instance_of.size(), "class_id = @CLSID"); + std::string cond = "noun_id IN (SELECT instance_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_instance_of.empty()) + { + std::list clauses(_not_instance_of.size(), "class_id = @NCLSID"); + std::string cond = "noun_id NOT IN (SELECT instance_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_class) + { + conditions.push_back("noun_id IN (SELECT class_id FROM instantiation)"); + } + + if (!_class_of.empty()) + { + std::list clauses(_class_of.size(), "instance_id = @INSID"); + std::string cond = "noun_id IN (SELECT class_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_class_of.empty()) + { + std::list clauses(_not_class_of.size(), "instance_id = @NINSID"); + std::string cond = "noun_id NOT IN (SELECT class_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_has_synonyms) + { + conditions.push_back("noun_id IN (SELECT adjective_2_id FROM adjective_synonymy)"); + } + + if (!_synonym_of.empty()) + { + std::list clauses(_synonym_of.size(), "adjective_1_id = @SYNID"); + std::string cond = "noun_id IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_synonym_of.empty()) + { + std::list clauses(_not_synonym_of.size(), "adjective_1_id = @NSYNID"); + std::string cond = "noun_id NOT IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_has_antonyms) + { + conditions.push_back("noun_id IN (SELECT adjective_2_id FROM adjective_antonymy)"); + } + + if (!_antonym_of.empty()) + { + std::list clauses(_antonym_of.size(), "adjective_1_id = @ANTID"); + std::string cond = "noun_id IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_antonym_of.empty()) + { + std::list clauses(_not_antonym_of.size(), "adjective_1_id = @NANTID"); + std::string cond = "noun_id NOT IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_has_pertainym) + { + conditions.push_back("noun_id IN (SELECT noun_id FROM pertainymy)"); + } + + if (!_anti_pertainym_of.empty()) + { + std::list clauses(_anti_pertainym_of.size(), "pertainym_id = @PERID"); + std::string cond = "noun_id IN (SELECT noun_id FROM pertainymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (_is_attribute) + { + conditions.push_back("noun_id IN (SELECT noun_id FROM variation)"); + } + + if (!_attribute_of.empty()) + { + std::list clauses(_attribute_of.size(), "adjective_id = @VALID"); + std::string cond = "noun_id IN (SELECT noun_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_derived_from_adjective.empty()) + { + std::list clauses(_derived_from_adjective.size(), "adjective_id = @DERADJ"); + std::string cond = "noun_id IN (SELECT noun_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_derived_from_adjective.empty()) + { + std::list clauses(_not_derived_from_adjective.size(), "adjective_id = @NDERADJ"); + std::string cond = "noun_id NOT IN (SELECT noun_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_derived_from_adverb.empty()) + { + std::list clauses(_derived_from_adverb.size(), "adverb_id = @DERADV"); + std::string cond = "noun_id IN (SELECT noun_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_derived_from_adverb.empty()) + { + std::list clauses(_not_derived_from_adverb.size(), "adverb_id = @NDERADV"); + std::string cond = "noun_id NOT IN (SELECT noun_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_derived_from_noun.empty()) + { + std::list clauses(_derived_from_noun.size(), "noun_2_id = @DERN"); + std::string cond = "noun_id IN (SELECT noun_1_id FROM noun_noun_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!_not_derived_from_noun.empty()) + { + std::list clauses(_not_derived_from_noun.size(), "noun_2_id = @NDERN"); + std::string cond = "noun_id NOT IN (SELECT noun_1_id FROM noun_noun_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + if (!conditions.empty()) + { + construct << " WHERE "; + construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); + } + + if (_random) + { + construct << " ORDER BY RANDOM()"; + } + + if (_limit != unlimited) + { + construct << " LIMIT " << _limit; + } + + sqlite3_stmt* ppstmt; + std::string query = construct.str(); + if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); + } + + if (!_rhymes.empty()) + { + int i = 0; + for (auto rhyme : _rhymes) + { + std::string rhymer = "%" + rhyme; + sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); + + i++; + } + } + + for (auto except : _except) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); + } + + for (auto hyponym : _hypernym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPO"), hyponym._id); + } + + for (auto hyponym : _not_hypernym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NHYPO"), hyponym._id); + } + + for (auto hypernym : _hyponym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPER"), hypernym._id); + } + + for (auto hypernym : _not_hyponym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NHYPER"), hypernym._id); + } + + for (auto holonym : _part_meronym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PHOLO"), holonym._id); + } + + for (auto holonym : _not_part_meronym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NPHOLO"), holonym._id); + } + + for (auto meronym : _part_holonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PMERO"), meronym._id); + } + + for (auto meronym : _not_part_holonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NPMERO"), meronym._id); + } + + for (auto holonym : _substance_meronym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SHOLO"), holonym._id); + } + + for (auto holonym : _not_substance_meronym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSHOLO"), holonym._id); + } + + for (auto meronym : _substance_holonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SMERO"), meronym._id); + } + + for (auto meronym : _not_substance_holonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSMERO"), meronym._id); + } + + for (auto holonym : _member_meronym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MHOLO"), holonym._id); + } + + for (auto holonym : _not_member_meronym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NMHOLO"), holonym._id); + } + + for (auto meronym : _member_holonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MMERO"), meronym._id); + } + + for (auto meronym : _not_member_holonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NMMERO"), meronym._id); + } + + for (auto cls : _instance_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@CLSID"), cls._id); + } + + for (auto cls : _not_instance_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NCLSID"), cls._id); + } + + for (auto inst : _class_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@INSID"), inst._id); + } + + for (auto inst : _not_class_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NINSID"), inst._id); + } + + for (auto synonym : _synonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); + } + + for (auto synonym : _not_synonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); + } + + for (auto antonym : _antonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); + } + + for (auto antonym : _not_antonym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); + } + + for (auto pertainym : _anti_pertainym_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PERID"), pertainym._id); + } + + for (auto value : _attribute_of) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VALID"), value._id); + } + + for (auto adj : _derived_from_adjective) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id); + } + + for (auto adj : _not_derived_from_adjective) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id); + } + + for (auto adv : _derived_from_adverb) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id); + } + + for (auto adv : _not_derived_from_adverb) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id); + } + + for (auto n : _derived_from_noun) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id); + } + + for (auto n : _not_derived_from_noun) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id); + } + + std::list output; + while (sqlite3_step(ppstmt) == SQLITE_ROW) + { + noun tnc {_data, sqlite3_column_int(ppstmt, 0)}; + tnc._singular = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 1))); + + if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) + { + tnc._plural = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 2))); + } + + output.push_back(tnc); + } + + sqlite3_finalize(ppstmt); + + for (auto& noun : output) + { + query = "SELECT pronunciation FROM noun_pronunciations WHERE noun_id = ?"; + if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); + } + + sqlite3_bind_int(ppstmt, 1, noun._id); + + while (sqlite3_step(ppstmt) == SQLITE_ROW) + { + std::string pronunciation(reinterpret_cast(sqlite3_column_text(ppstmt, 0))); + auto phonemes = verbly::split>(pronunciation, " "); + + noun.pronunciations.push_back(phonemes); + } + + sqlite3_finalize(ppstmt); + } + + return output; + } + +}; diff --git a/lib/noun.h b/lib/noun.h new file mode 100644 index 0000000..da76866 --- /dev/null +++ b/lib/noun.h @@ -0,0 +1,183 @@ +#ifndef NOUN_H_24A03C83 +#define NOUN_H_24A03C83 + +namespace verbly { + + class noun : public word { + private: + std::string _singular; + std::string _plural; + + friend class noun_query; + + public: + noun(const data& _data, int _id); + + std::string base_form() const; + std::string singular_form() const; + std::string plural_form() const; + + bool has_plural_form() const; + + noun_query hypernyms() const; + noun_query hyponyms() const; + noun_query part_meronyms() const; + noun_query part_holonyms() const; + noun_query substance_meronyms() const; + noun_query substance_holonyms() const; + noun_query member_meronyms() const; + noun_query member_holonyms() const; + noun_query classes() const; + noun_query instances() const; + noun_query synonyms() const; + noun_query antonyms() const; + adjective_query pertainyms() const; + adjective_query variations() const; + }; + + class noun_query { + public: + noun_query(const data& _data); + + noun_query& limit(int _limit); + noun_query& random(bool _random); + noun_query& except(const noun& _word); + noun_query& rhymes_with(const word& _word); + noun_query& has_pronunciation(bool _has_prn); + + noun_query& is_hypernym(bool _arg); + noun_query& hypernym_of(const noun& _noun); + noun_query& not_hypernym_of(const noun& _noun); + + noun_query& is_hyponym(bool _arg); + noun_query& hyponym_of(const noun& _noun); + noun_query& not_hyponym_of(const noun& _noun); + + noun_query& is_part_meronym(bool _arg); + noun_query& part_meronym_of(const noun& _noun); + noun_query& not_part_meronym_of(const noun& _noun); + + noun_query& is_part_holonym(bool _arg); + noun_query& part_holonym_of(const noun& _noun); + noun_query& not_part_holonym_of(const noun& _noun); + + noun_query& is_substance_meronym(bool _arg); + noun_query& substance_meronym_of(const noun& _noun); + noun_query& not_substance_meronym_of(const noun& _noun); + + noun_query& is_substance_holonym(bool _arg); + noun_query& substance_holonym_of(const noun& _noun); + noun_query& not_substance_holonym_of(const noun& _noun); + + noun_query& is_member_meronym(bool _arg); + noun_query& member_meronym_of(const noun& _noun); + noun_query& not_member_meronym_of(const noun& _noun); + + noun_query& is_member_holonym(bool _arg); + noun_query& member_holonym_of(const noun& _noun); + noun_query& not_member_holonym_of(const noun& _noun); + + noun_query& is_proper(bool _arg); + noun_query& is_not_proper(bool _arg); + noun_query& instance_of(const noun& _noun); + noun_query& not_instance_of(const noun& _noun); + + noun_query& is_class(bool _arg); + noun_query& class_of(const noun& _noun); + noun_query& not_class_of(const noun& _noun); + + noun_query& has_synonyms(bool _arg); + noun_query& synonym_of(const noun& _noun); + noun_query& not_synonym_of(const noun& _noun); + + noun_query& has_antonyms(bool _arg); + noun_query& antonym_of(const noun& _noun); + noun_query& not_antonym_of(const noun& _noun); + + noun_query& has_pertainym(bool _arg); + noun_query& anti_pertainym_of(const adjective& _adj); + + noun_query& is_attribute(bool _arg); + noun_query& attribute_of(const adjective& _adj); + + noun_query& derived_from(const word& _w); + noun_query& not_derived_from(const word& _w); + + std::list run() const; + + const static int unlimited = -1; + + private: + const data& _data; + int _limit = unlimited; + bool _random = false; + std::list _rhymes; + std::list _except; + bool _has_prn = false; + + bool _is_hypernym = false; + std::list _hypernym_of; + std::list _not_hypernym_of; + + bool _is_hyponym = false; + std::list _hyponym_of; + std::list _not_hyponym_of; + + bool _is_part_meronym = false; + std::list _part_meronym_of; + std::list _not_part_meronym_of; + + bool _is_substance_meronym = false; + std::list _substance_meronym_of; + std::list _not_substance_meronym_of; + + bool _is_member_meronym = false; + std::list _member_meronym_of; + std::list _not_member_meronym_of; + + bool _is_part_holonym = false; + std::list _part_holonym_of; + std::list _not_part_holonym_of; + + bool _is_substance_holonym = false; + std::list _substance_holonym_of; + std::list _not_substance_holonym_of; + + bool _is_member_holonym = false; + std::list _member_holonym_of; + std::list _not_member_holonym_of; + + bool _is_proper = false; + bool _is_not_proper = false; + std::list _instance_of; + std::list _not_instance_of; + + bool _is_class = false; + std::list _class_of; + std::list _not_class_of; + + bool _has_synonyms = false; + std::list _synonym_of; + std::list _not_synonym_of; + + bool _has_antonyms = false; + std::list _antonym_of; + std::list _not_antonym_of; + + bool _has_pertainym = false; + std::list _anti_pertainym_of; + + bool _is_attribute = false; + std::list _attribute_of; + + std::list _derived_from_adjective; + std::list _not_derived_from_adjective; + std::list _derived_from_adverb; + std::list _not_derived_from_adverb; + std::list _derived_from_noun; + std::list _not_derived_from_noun; + }; + +}; + +#endif /* end of include guard: NOUN_H_24A03C83 */ diff --git a/lib/token.cpp b/lib/token.cpp new file mode 100644 index 0000000..aa8f50e --- /dev/null +++ b/lib/token.cpp @@ -0,0 +1,53 @@ +#include "verbly.h" + +namespace verbly { + + token::token(token::type _type) : _type(_type) + { + + } + + token::type token::token_type() const + { + return _type; + } + + verb_token::verb_token(const class verb& _verb) : token(token::type::verb), _verb(&_verb) + { + + } + + const class verb& verb_token::verb() const + { + return *_verb; + } + + verb_token& verb_token::inflect(verb_token::inflection infl) + { + _inflection = infl; + return *this; + } + + bool verb_token::complete() const + { + return true; + } + + std::string verb_token::compile() const + { + switch (_inflection) + { + case inflection::infinitive: return _verb->infinitive_form(); + case inflection::past_tense: return _verb->past_tense_form(); + case inflection::past_participle: return _verb->past_participle_form(); + case inflection::ing_form: return _verb->ing_form(); + case inflection::s_form: return _verb->s_form(); + } + } + + token* verb_token::copy() const + { + return new verb_token(*this); + } + +}; diff --git a/lib/token.h b/lib/token.h new file mode 100644 index 0000000..44d99cb --- /dev/null +++ b/lib/token.h @@ -0,0 +1,313 @@ +#ifndef TOKEN_H_AD62C505 +#define TOKEN_H_AD62C505 + +#include +#include +#include + +namespace verbly { + + class verb; + + class selrestr { + }; + + class synrestr { + }; + + enum class fillin_type { + noun_phrase, + participle_phrase, + adjective, + adverb + }; + + class token { + public: + enum class type { + verb, + fillin, + string, + utterance + }; + + protected: + // General + type _type; + + token(type _type); + + public: + enum type token_type() const; + + virtual bool complete() const = 0; + virtual std::string compile() const = 0; + virtual token* copy() const = 0; + }; + + class verb_token : public token { + public: + enum class inflection { + infinitive, + past_tense, + past_participle, + ing_form, + s_form + }; + + private: + // Verb + const verb* _verb; + inflection _inflection = inflection::infinitive; + + public: + verb_token(const class verb& _verb); + + const class verb& verb() const; + + verb_token& inflect(inflection infl); + + bool complete() const; + + std::string compile() const; + + token* copy() const; + }; + + class utterance_token : public token { + private: + // Utterance + std::list> utterance; + + public: + typedef std::list>::iterator iterator; + /*class iterator { + private: + friend class utterance_token; + + std::list>::iterator it; + + public: + iterator(std::list>::iterator it) : it(it) + { + + } + + iterator& operator++() + { + ++it; + return *this; + } + + iterator& operator--() + { + --it; + return *this; + } + + bool operator==(const iterator& other) const + { + return it == other.it; + } + + bool operator!=(const iterator& other) const + { + return it != other.it; + } + + token& operator*() + { + return **it; + } + + token& operator->() + { + return **it; + } + };*/ + + utterance_token(std::initializer_list tkns) : token(token::type::utterance) + { + for (auto tkn : tkns) + { + utterance.push_back(std::unique_ptr(tkn)); + } + } + + utterance_token(const utterance_token& other) : token(token::type::utterance) + { + for (auto& tkn : other.utterance) + { + utterance.push_back(std::unique_ptr(tkn->copy())); + } + } + + utterance_token(utterance_token&& other) : token(token::type::utterance), utterance(std::move(other.utterance)) + { + + } + + utterance_token& operator=(const utterance_token& other) + { + utterance.clear(); + + for (auto& tkn : other.utterance) + { + utterance.push_back(std::unique_ptr(tkn->copy())); + } + + return *this; + } + + utterance_token& operator=(utterance_token&& other) + { + utterance = std::move(other.utterance); + + return *this; + } + + iterator begin() + { + return std::begin(utterance); + } + + iterator end() + { + return std::end(utterance); + } + + void erase(iterator it) + { + utterance.erase(it); + } + + bool complete() const + { + return std::all_of(std::begin(utterance), std::end(utterance), [] (const std::unique_ptr& tkn) { + return tkn->complete(); + }); + } + + std::string compile() const + { + std::stringstream result; + for (auto& t : utterance) + { + if (t->complete()) + { + result << t->compile() << " "; + } else { + return "Could not compile!"; + } + } + + std::string output = result.str(); + if (output != "") + { + output.pop_back(); + } + + return output; + } + + token* copy() const + { + return new utterance_token(*this); + } + }; + + class fillin_token : public token { + private: + // Fillin + std::string m_theme; + fillin_type m_fillin_type; + + public: + fillin_token(fillin_type ft) : token(token::type::fillin), m_fillin_type(ft) + { + + } + +/* void synrestrs(std::initializer_list ins) + { + m_synrestrs = std::set(ins); + } + + std::set& synrestrs() + { + return m_synrestrs; + } + + void selrestrs(std::initializer_list ins) + { + m_selrestrs = std::set(ins); + } + + std::set& selrestrs() + { + return m_selrestrs; + }*/ + + fillin_token theme(std::string theme) + { + m_theme = theme; + + return *this; + } + + std::string& theme() + { + return m_theme; + } + + fillin_type fillin_type() const + { + return m_fillin_type; + } + + bool complete() const + { + return false; + } + + std::string compile() const + { + return ""; + } + + token* copy() const + { + return new fillin_token(*this); + } + }; + + class string_token : public token { + private: + // String + std::string str; + + public: + string_token(std::string str) : token(token::type::string), str(str) + { + + } + + bool complete() const + { + return true; + } + + std::string compile() const + { + return str; + } + + token* copy() const + { + return new string_token(*this); + } + }; + +}; + +#endif /* end of include guard: TOKEN_H_AD62C505 */ diff --git a/lib/util.h b/lib/util.h new file mode 100644 index 0000000..815b47c --- /dev/null +++ b/lib/util.h @@ -0,0 +1,53 @@ +#ifndef UTIL_H_15DDCA2D +#define UTIL_H_15DDCA2D + +#include +#include +#include + +namespace verbly { + + template + std::string implode(InputIterator first, InputIterator last, std::string delimiter) + { + std::stringstream result; + + for (InputIterator it = first; it != last; it++) + { + if (it != first) + { + result << delimiter; + } + + result << *it; + } + + return result.str(); + } + + template + Container split(std::string input, std::string delimiter) + { + Container result; + + while (!input.empty()) + { + int divider = input.find(" "); + if (divider == std::string::npos) + { + result.push_back(input); + + input = ""; + } else { + result.push_back(input.substr(0, divider)); + + input = input.substr(divider+1); + } + } + + return result; + } + +}; + +#endif /* end of include guard: UTIL_H_15DDCA2D */ diff --git a/lib/verb.cpp b/lib/verb.cpp new file mode 100644 index 0000000..23f7c92 --- /dev/null +++ b/lib/verb.cpp @@ -0,0 +1,193 @@ +#include "verbly.h" + +namespace verbly { + + verb::verb(const data& _data, int _id) : word(_data, _id) + { + + } + + std::string verb::base_form() const + { + return _infinitive; + } + + std::string verb::infinitive_form() const + { + return _infinitive; + } + + std::string verb::past_tense_form() const + { + return _past_tense; + } + + std::string verb::past_participle_form() const + { + return _past_participle; + } + + std::string verb::ing_form() const + { + return _ing_form; + } + + std::string verb::s_form() const + { + return _s_form; + } + + verb_query::verb_query(const data& _data) : _data(_data) + { + + } + + verb_query& verb_query::limit(int _limit) + { + if ((_limit > 0) || (_limit == unlimited)) + { + this->_limit = _limit; + } + + return *this; + } + + verb_query& verb_query::random(bool _random) + { + this->_random = _random; + + return *this; + } + + verb_query& verb_query::except(const verb& _word) + { + _except.push_back(_word); + + return *this; + } + + verb_query& verb_query::rhymes_with(const word& _word) + { + for (auto rhyme : _word.rhyme_phonemes()) + { + _rhymes.push_back(rhyme); + } + + if (dynamic_cast(&_word) != nullptr) + { + _except.push_back(dynamic_cast(_word)); + } + + return *this; + } + + verb_query& verb_query::has_pronunciation(bool _has_prn) + { + this->_has_prn = _has_prn; + + return *this; + } + + std::list verb_query::run() const + { + std::stringstream construct; + construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs"; + std::list conditions; + + if (_has_prn) + { + conditions.push_back("verb_id IN (SELECT verb_id FROM verb_pronunciations)"); + } + + if (!_rhymes.empty()) + { + std::list clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); + std::string cond = "verb_id IN (SELECT verb_id FROM verb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + conditions.push_back(cond); + } + + for (auto except : _except) + { + conditions.push_back("verb_id != @EXCID"); + } + + if (!conditions.empty()) + { + construct << " WHERE "; + construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); + } + + if (_random) + { + construct << " ORDER BY RANDOM()"; + } + + if (_limit != unlimited) + { + construct << " LIMIT " << _limit; + } + + sqlite3_stmt* ppstmt; + std::string query = construct.str(); + if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); + } + + if (!_rhymes.empty()) + { + int i = 0; + for (auto rhyme : _rhymes) + { + std::string rhymer = "%" + rhyme; + sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); + + i++; + } + } + + for (auto except : _except) + { + sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); + } + + std::list output; + while (sqlite3_step(ppstmt) == SQLITE_ROW) + { + verb tnc {_data, sqlite3_column_int(ppstmt, 0)}; + tnc._infinitive = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 1))); + tnc._past_tense = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 2))); + tnc._past_participle = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 3))); + tnc._ing_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 4))); + tnc._s_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 5))); + + output.push_back(tnc); + } + + sqlite3_finalize(ppstmt); + + for (auto& verb : output) + { + query = "SELECT pronunciation FROM verb_pronunciations WHERE verb_id = ?"; + if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) + { + throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); + } + + sqlite3_bind_int(ppstmt, 1, verb._id); + + while (sqlite3_step(ppstmt) == SQLITE_ROW) + { + std::string pronunciation(reinterpret_cast(sqlite3_column_text(ppstmt, 0))); + auto phonemes = verbly::split>(pronunciation, " "); + + verb.pronunciations.push_back(phonemes); + } + + sqlite3_finalize(ppstmt); + } + + return output; + } + +}; diff --git a/lib/verb.h b/lib/verb.h new file mode 100644 index 0000000..7cc87e2 --- /dev/null +++ b/lib/verb.h @@ -0,0 +1,73 @@ +#ifndef VERB_H_BCC929AD +#define VERB_H_BCC929AD + +namespace verbly { + + /*class frame_part { + + }; + + class frame { + private: + std::list content; + std::map::iterator>> predicates; + + public: + frame(std::list content) : content(content) + { + + } + + std::unique_ptr make_utterance() const + { + + } + };*/ + + class verb : public word { + private: + std::string _infinitive; + std::string _past_tense; + std::string _past_participle; + std::string _ing_form; + std::string _s_form; + + friend class verb_query; + + public: + verb(const data& _data, int _id); + + std::string base_form() const; + std::string infinitive_form() const; + std::string past_tense_form() const; + std::string past_participle_form() const; + std::string ing_form() const; + std::string s_form() const; + }; + + class verb_query { + public: + verb_query(const data& _data); + + verb_query& limit(int _limit); + verb_query& random(bool _random); + verb_query& except(const verb& _word); + verb_query& rhymes_with(const word& _word); + verb_query& has_pronunciation(bool _has_prn); + + std::list run() const; + + const static int unlimited = -1; + + private: + const data& _data; + int _limit = unlimited; + bool _random = false; + std::list _rhymes; + std::list _except; + bool _has_prn = false; + }; + +}; + +#endif /* end of include guard: VERB_H_BCC929AD */ diff --git a/lib/verbly.h b/lib/verbly.h new file mode 100644 index 0000000..b9f5367 --- /dev/null +++ b/lib/verbly.h @@ -0,0 +1,14 @@ +#ifndef VERBLY_H_5B39CE50 +#define VERBLY_H_5B39CE50 + +#include "c++14.h" +#include "util.h" +#include "token.h" +#include "data.h" +#include "word.h" +#include "verb.h" +#include "adverb.h" +#include "adjective.h" +#include "noun.h" + +#endif /* end of include guard: VERBLY_H_5B39CE50 */ diff --git a/lib/word.cpp b/lib/word.cpp new file mode 100644 index 0000000..c50e7d3 --- /dev/null +++ b/lib/word.cpp @@ -0,0 +1,32 @@ +#include "verbly.h" + +namespace verbly { + + word::word(const data& _data, int _id) : _data(_data), _id(_id) + { + + } + + std::list word::rhyme_phonemes() const + { + std::list result; + + for (auto pronunciation : pronunciations) + { + auto phemstrt = std::find_if(std::begin(pronunciation), std::end(pronunciation), [] (std::string phoneme) { + return phoneme.find("1") != std::string::npos; + }); + + std::stringstream rhymer; + for (auto it = phemstrt; it != std::end(pronunciation); it++) + { + rhymer << " " << *it; + } + + result.push_back(rhymer.str()); + } + + return result; + } + +}; diff --git a/lib/word.h b/lib/word.h new file mode 100644 index 0000000..23ddb2b --- /dev/null +++ b/lib/word.h @@ -0,0 +1,35 @@ +#ifndef WORD_H_8FC89498 +#define WORD_H_8FC89498 + +namespace verbly { + + class adjective_query; + class verb_query; + class adverb_query; + + template + class query; + + class word { + protected: + const data& _data; + int _id; + + std::list> pronunciations; + + word(const data& _data, int _id); + + friend class adjective_query; + friend class verb_query; + friend class noun_query; + friend class adverb_query; + + public: + virtual std::string base_form() const = 0; + + std::list rhyme_phonemes() const; + }; + +}; + +#endif /* end of include guard: WORD_H_8FC89498 */ diff --git a/noun.cpp b/noun.cpp deleted file mode 100644 index 9336a1c..0000000 --- a/noun.cpp +++ /dev/null @@ -1,916 +0,0 @@ -#include "verbly.h" - -namespace verbly { - - noun::noun(const data& _data, int _id) : word(_data, _id) - { - - } - - std::string noun::base_form() const - { - return _singular; - } - - std::string noun::singular_form() const - { - return _singular; - } - - std::string noun::plural_form() const - { - return _plural; - } - - bool noun::has_plural_form() const - { - return !_plural.empty(); - } - - noun_query noun::hypernyms() const - { - return _data.nouns().hypernym_of(*this); - } - - noun_query noun::hyponyms() const - { - return _data.nouns().hyponym_of(*this); - } - - noun_query noun::part_meronyms() const - { - return _data.nouns().part_meronym_of(*this); - } - - noun_query noun::part_holonyms() const - { - return _data.nouns().part_holonym_of(*this); - } - - noun_query noun::substance_meronyms() const - { - return _data.nouns().substance_meronym_of(*this); - } - - noun_query noun::substance_holonyms() const - { - return _data.nouns().substance_holonym_of(*this); - } - - noun_query noun::member_meronyms() const - { - return _data.nouns().member_meronym_of(*this); - } - - noun_query noun::member_holonyms() const - { - return _data.nouns().member_holonym_of(*this); - } - - noun_query noun::classes() const - { - return _data.nouns().class_of(*this); - } - - noun_query noun::instances() const - { - return _data.nouns().instance_of(*this); - } - - noun_query noun::synonyms() const - { - return _data.nouns().synonym_of(*this); - } - - noun_query noun::antonyms() const - { - return _data.nouns().antonym_of(*this); - } - - adjective_query noun::pertainyms() const - { - return _data.adjectives().pertainym_of(*this); - } - - adjective_query noun::variations() const - { - return _data.adjectives().variant_of(*this); - } - - noun_query::noun_query(const data& _data) : _data(_data) - { - - } - - noun_query& noun_query::limit(int _limit) - { - if ((_limit > 0) || (_limit == unlimited)) - { - this->_limit = _limit; - } - - return *this; - } - - noun_query& noun_query::random(bool _random) - { - this->_random = _random; - - return *this; - } - - noun_query& noun_query::except(const noun& _word) - { - _except.push_back(_word); - - return *this; - } - - noun_query& noun_query::rhymes_with(const word& _word) - { - for (auto rhyme : _word.rhyme_phonemes()) - { - _rhymes.push_back(rhyme); - } - - if (dynamic_cast(&_word) != nullptr) - { - _except.push_back(dynamic_cast(_word)); - } - - return *this; - } - - noun_query& noun_query::has_pronunciation(bool _has_prn) - { - this->_has_prn = _has_prn; - - return *this; - } - - noun_query& noun_query::is_hypernym(bool _arg) - { - _is_hypernym = _arg; - - return *this; - } - - noun_query& noun_query::hypernym_of(const noun& _noun) - { - _hypernym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_hypernym_of(const noun& _noun) - { - _not_hypernym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::is_hyponym(bool _arg) - { - _is_hyponym = _arg; - - return *this; - } - - noun_query& noun_query::hyponym_of(const noun& _noun) - { - _hyponym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_hyponym_of(const noun& _noun) - { - _not_hyponym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::is_part_meronym(bool _arg) - { - _is_part_meronym = _arg; - - return *this; - } - - noun_query& noun_query::part_meronym_of(const noun& _noun) - { - _part_meronym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_part_meronym_of(const noun& _noun) - { - _not_part_meronym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::is_part_holonym(bool _arg) - { - _is_part_holonym = _arg; - - return *this; - } - - noun_query& noun_query::part_holonym_of(const noun& _noun) - { - _part_holonym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_part_holonym_of(const noun& _noun) - { - _not_part_holonym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::is_substance_meronym(bool _arg) - { - _is_substance_meronym = _arg; - - return *this; - } - - noun_query& noun_query::substance_meronym_of(const noun& _noun) - { - _substance_meronym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_substance_meronym_of(const noun& _noun) - { - _not_substance_meronym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::is_substance_holonym(bool _arg) - { - _is_substance_holonym = _arg; - - return *this; - } - - noun_query& noun_query::substance_holonym_of(const noun& _noun) - { - _substance_holonym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_substance_holonym_of(const noun& _noun) - { - _not_substance_holonym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::is_member_meronym(bool _arg) - { - _is_member_meronym = _arg; - - return *this; - } - - noun_query& noun_query::member_meronym_of(const noun& _noun) - { - _member_meronym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_member_meronym_of(const noun& _noun) - { - _not_member_meronym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::is_member_holonym(bool _arg) - { - _is_member_holonym = _arg; - - return *this; - } - - noun_query& noun_query::member_holonym_of(const noun& _noun) - { - _member_holonym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_member_holonym_of(const noun& _noun) - { - _not_member_holonym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::is_proper(bool _arg) - { - _is_proper = _arg; - - return *this; - } - - noun_query& noun_query::instance_of(const noun& _noun) - { - _instance_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_instance_of(const noun& _noun) - { - _not_instance_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::is_class(bool _arg) - { - _is_class = _arg; - - return *this; - } - - noun_query& noun_query::class_of(const noun& _noun) - { - _class_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_class_of(const noun& _noun) - { - _not_class_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::has_synonyms(bool _arg) - { - _has_synonyms = _arg; - - return *this; - } - - noun_query& noun_query::synonym_of(const noun& _noun) - { - _synonym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_synonym_of(const noun& _noun) - { - _not_synonym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::has_antonyms(bool _arg) - { - _has_antonyms = _arg; - - return *this; - } - - noun_query& noun_query::antonym_of(const noun& _noun) - { - _antonym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::not_antonym_of(const noun& _noun) - { - _not_antonym_of.push_back(_noun); - - return *this; - } - - noun_query& noun_query::has_pertainym(bool _arg) - { - _has_pertainym = _arg; - - return *this; - } - - noun_query& noun_query::anti_pertainym_of(const adjective& _adj) - { - _anti_pertainym_of.push_back(_adj); - - return *this; - } - - noun_query& noun_query::is_attribute(bool _arg) - { - _is_attribute = _arg; - - return *this; - } - - noun_query& noun_query::attribute_of(const adjective& _adj) - { - _attribute_of.push_back(_adj); - - return *this; - } - - std::list noun_query::run() const - { - std::stringstream construct; - construct << "SELECT noun_id, singular, plural FROM nouns"; - std::list conditions; - - if (_has_prn) - { - conditions.push_back("noun_id IN (SELECT noun_id FROM noun_pronunciations)"); - } - - if (!_rhymes.empty()) - { - std::list clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); - std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - for (auto except : _except) - { - conditions.push_back("noun_id != @EXCID"); - } - - if (_is_hypernym) - { - conditions.push_back("noun_id IN (SELECT hypernym_id FROM hypernymy)"); - } - - if (!_hypernym_of.empty()) - { - std::list clauses(_hypernym_of.size(), "hyponym_id = @HYPO"); - std::string cond = "noun_id IN (SELECT hypernym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_hypernym_of.empty()) - { - std::list clauses(_not_hypernym_of.size(), "hyponym_id = @NHYPO"); - std::string cond = "noun_id NOT IN (SELECT hypernym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_hyponym) - { - conditions.push_back("noun_id IN (SELECT hyponym_id FROM hypernymy)"); - } - - if (!_hyponym_of.empty()) - { - std::list clauses(_hyponym_of.size(), "hypernym_id = @HYPER"); - std::string cond = "noun_id IN (SELECT hyponym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_hyponym_of.empty()) - { - std::list clauses(_not_hyponym_of.size(), "hypernym_id = @NHYPER"); - std::string cond = "noun_id NOT IN (SELECT hyponym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_part_meronym) - { - conditions.push_back("noun_id IN (SELECT meronym_id FROM part_meronymy)"); - } - - if (!_part_meronym_of.empty()) - { - std::list clauses(_part_meronym_of.size(), "holonym_id = @PHOLO"); - std::string cond = "noun_id IN (SELECT meronym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_part_meronym_of.empty()) - { - std::list clauses(_not_part_meronym_of.size(), "holonym_id = @NPHOLO"); - std::string cond = "noun_id NOT IN (SELECT meronym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_part_holonym) - { - conditions.push_back("noun_id IN (SELECT holonym_id FROM part_meronymy)"); - } - - if (!_part_holonym_of.empty()) - { - std::list clauses(_part_holonym_of.size(), "meronym_id = @PMERO"); - std::string cond = "noun_id IN (SELECT holonym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_part_holonym_of.empty()) - { - std::list clauses(_not_part_holonym_of.size(), "meronym_id = @NPMERO"); - std::string cond = "noun_id NOT IN (SELECT holonym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_substance_meronym) - { - conditions.push_back("noun_id IN (SELECT meronym_id FROM substance_meronymy)"); - } - - if (!_substance_meronym_of.empty()) - { - std::list clauses(_substance_meronym_of.size(), "holonym_id = @SHOLO"); - std::string cond = "noun_id IN (SELECT meronym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_substance_meronym_of.empty()) - { - std::list clauses(_not_substance_meronym_of.size(), "holonym_id = @NSHOLO"); - std::string cond = "noun_id NOT IN (SELECT meronym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_substance_holonym) - { - conditions.push_back("noun_id IN (SELECT holonym_id FROM substance_meronymy)"); - } - - if (!_substance_holonym_of.empty()) - { - std::list clauses(_substance_holonym_of.size(), "meronym_id = @SMERO"); - std::string cond = "noun_id IN (SELECT holonym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_substance_holonym_of.empty()) - { - std::list clauses(_not_substance_holonym_of.size(), "meronym_id = @NSMERO"); - std::string cond = "noun_id NOT IN (SELECT holonym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_member_meronym) - { - conditions.push_back("noun_id IN (SELECT meronym_id FROM member_meronymy)"); - } - - if (!_member_meronym_of.empty()) - { - std::list clauses(_member_meronym_of.size(), "holonym_id = @MHOLO"); - std::string cond = "noun_id IN (SELECT meronym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_member_meronym_of.empty()) - { - std::list clauses(_not_member_meronym_of.size(), "holonym_id = @NMHOLO"); - std::string cond = "noun_id NOT IN (SELECT meronym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_member_holonym) - { - conditions.push_back("noun_id IN (SELECT holonym_id FROM member_meronym)"); - } - - if (!_member_holonym_of.empty()) - { - std::list clauses(_member_holonym_of.size(), "meronym_id = @MMERO"); - std::string cond = "noun_id IN (SELECT holonym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_member_holonym_of.empty()) - { - std::list clauses(_not_member_holonym_of.size(), "meronym_id = @NMMERO"); - std::string cond = "noun_id NOT IN (SELECT holonym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_proper) - { - conditions.push_back("noun_id IN (SELECT instance_id FROM instantiation)"); - } - - if (!_instance_of.empty()) - { - std::list clauses(_instance_of.size(), "class_id = @CLSID"); - std::string cond = "noun_id IN (SELECT instance_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_instance_of.empty()) - { - std::list clauses(_not_instance_of.size(), "class_id = @NCLSID"); - std::string cond = "noun_id NOT IN (SELECT instance_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_class) - { - conditions.push_back("noun_id IN (SELECT class_id FROM instantiation)"); - } - - if (!_class_of.empty()) - { - std::list clauses(_class_of.size(), "instance_id = @INSID"); - std::string cond = "noun_id IN (SELECT class_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_class_of.empty()) - { - std::list clauses(_not_class_of.size(), "instance_id = @NINSID"); - std::string cond = "noun_id NOT IN (SELECT class_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_has_synonyms) - { - conditions.push_back("noun_id IN (SELECT adjective_2_id FROM adjective_synonymy)"); - } - - if (!_synonym_of.empty()) - { - std::list clauses(_synonym_of.size(), "adjective_1_id = @SYNID"); - std::string cond = "noun_id IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_synonym_of.empty()) - { - std::list clauses(_not_synonym_of.size(), "adjective_1_id = @NSYNID"); - std::string cond = "noun_id NOT IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_has_antonyms) - { - conditions.push_back("noun_id IN (SELECT adjective_2_id FROM adjective_antonymy)"); - } - - if (!_antonym_of.empty()) - { - std::list clauses(_antonym_of.size(), "adjective_1_id = @ANTID"); - std::string cond = "noun_id IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!_not_antonym_of.empty()) - { - std::list clauses(_not_antonym_of.size(), "adjective_1_id = @NANTID"); - std::string cond = "noun_id NOT IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_has_pertainym) - { - conditions.push_back("noun_id IN (SELECT noun_id FROM pertainymy)"); - } - - if (!_anti_pertainym_of.empty()) - { - std::list clauses(_anti_pertainym_of.size(), "pertainym_id = @PERID"); - std::string cond = "noun_id IN (SELECT noun_id FROM pertainymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (_is_attribute) - { - conditions.push_back("noun_id IN (SELECT noun_id FROM variation)"); - } - - if (!_attribute_of.empty()) - { - std::list clauses(_attribute_of.size(), "adjective_id = @VALID"); - std::string cond = "noun_id IN (SELECT noun_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - if (!conditions.empty()) - { - construct << " WHERE "; - construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); - } - - if (_random) - { - construct << " ORDER BY RANDOM()"; - } - - if (_limit != unlimited) - { - construct << " LIMIT " << _limit; - } - - sqlite3_stmt* ppstmt; - std::string query = construct.str(); - if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) - { - throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); - } - - if (!_rhymes.empty()) - { - int i = 0; - for (auto rhyme : _rhymes) - { - std::string rhymer = "%" + rhyme; - sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); - - i++; - } - } - - for (auto except : _except) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); - } - - for (auto hyponym : _hypernym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPO"), hyponym._id); - } - - for (auto hyponym : _not_hypernym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NHYPO"), hyponym._id); - } - - for (auto hypernym : _hyponym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPER"), hypernym._id); - } - - for (auto hypernym : _not_hyponym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NHYPER"), hypernym._id); - } - - for (auto holonym : _part_meronym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PHOLO"), holonym._id); - } - - for (auto holonym : _not_part_meronym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NPHOLO"), holonym._id); - } - - for (auto meronym : _part_holonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PMERO"), meronym._id); - } - - for (auto meronym : _not_part_holonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NPMERO"), meronym._id); - } - - for (auto holonym : _substance_meronym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SHOLO"), holonym._id); - } - - for (auto holonym : _not_substance_meronym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSHOLO"), holonym._id); - } - - for (auto meronym : _substance_holonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SMERO"), meronym._id); - } - - for (auto meronym : _not_substance_holonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSMERO"), meronym._id); - } - - for (auto holonym : _member_meronym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MHOLO"), holonym._id); - } - - for (auto holonym : _not_member_meronym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NMHOLO"), holonym._id); - } - - for (auto meronym : _member_holonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MMERO"), meronym._id); - } - - for (auto meronym : _not_member_holonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NMMERO"), meronym._id); - } - - for (auto cls : _instance_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@CLSID"), cls._id); - } - - for (auto cls : _not_instance_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NCLSID"), cls._id); - } - - for (auto inst : _class_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@INSID"), inst._id); - } - - for (auto inst : _not_class_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NINSID"), inst._id); - } - - for (auto synonym : _synonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); - } - - for (auto synonym : _not_synonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); - } - - for (auto antonym : _antonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); - } - - for (auto antonym : _not_antonym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); - } - - for (auto pertainym : _anti_pertainym_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PERID"), pertainym._id); - } - - for (auto value : _attribute_of) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VALID"), value._id); - } - - std::list output; - while (sqlite3_step(ppstmt) == SQLITE_ROW) - { - noun tnc {_data, sqlite3_column_int(ppstmt, 0)}; - tnc._singular = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 1))); - - if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) - { - tnc._plural = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 2))); - } - - output.push_back(tnc); - } - - sqlite3_finalize(ppstmt); - - for (auto& noun : output) - { - query = "SELECT pronunciation FROM noun_pronunciations WHERE noun_id = ?"; - if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) - { - throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); - } - - sqlite3_bind_int(ppstmt, 1, noun._id); - - while (sqlite3_step(ppstmt) == SQLITE_ROW) - { - std::string pronunciation(reinterpret_cast(sqlite3_column_text(ppstmt, 0))); - auto phonemes = verbly::split>(pronunciation, " "); - - noun.pronunciations.push_back(phonemes); - } - - sqlite3_finalize(ppstmt); - } - - return output; - } - -}; diff --git a/noun.h b/noun.h deleted file mode 100644 index f5ba256..0000000 --- a/noun.h +++ /dev/null @@ -1,171 +0,0 @@ -#ifndef NOUN_H_24A03C83 -#define NOUN_H_24A03C83 - -namespace verbly { - - class noun : public word { - private: - std::string _singular; - std::string _plural; - - friend class noun_query; - - public: - noun(const data& _data, int _id); - - std::string base_form() const; - std::string singular_form() const; - std::string plural_form() const; - - bool has_plural_form() const; - - noun_query hypernyms() const; - noun_query hyponyms() const; - noun_query part_meronyms() const; - noun_query part_holonyms() const; - noun_query substance_meronyms() const; - noun_query substance_holonyms() const; - noun_query member_meronyms() const; - noun_query member_holonyms() const; - noun_query classes() const; - noun_query instances() const; - noun_query synonyms() const; - noun_query antonyms() const; - adjective_query pertainyms() const; - adjective_query variations() const; - }; - - class noun_query { - public: - noun_query(const data& _data); - - noun_query& limit(int _limit); - noun_query& random(bool _random); - noun_query& except(const noun& _word); - noun_query& rhymes_with(const word& _word); - noun_query& has_pronunciation(bool _has_prn); - - noun_query& is_hypernym(bool _arg); - noun_query& hypernym_of(const noun& _noun); - noun_query& not_hypernym_of(const noun& _noun); - - noun_query& is_hyponym(bool _arg); - noun_query& hyponym_of(const noun& _noun); - noun_query& not_hyponym_of(const noun& _noun); - - noun_query& is_part_meronym(bool _arg); - noun_query& part_meronym_of(const noun& _noun); - noun_query& not_part_meronym_of(const noun& _noun); - - noun_query& is_part_holonym(bool _arg); - noun_query& part_holonym_of(const noun& _noun); - noun_query& not_part_holonym_of(const noun& _noun); - - noun_query& is_substance_meronym(bool _arg); - noun_query& substance_meronym_of(const noun& _noun); - noun_query& not_substance_meronym_of(const noun& _noun); - - noun_query& is_substance_holonym(bool _arg); - noun_query& substance_holonym_of(const noun& _noun); - noun_query& not_substance_holonym_of(const noun& _noun); - - noun_query& is_member_meronym(bool _arg); - noun_query& member_meronym_of(const noun& _noun); - noun_query& not_member_meronym_of(const noun& _noun); - - noun_query& is_member_holonym(bool _arg); - noun_query& member_holonym_of(const noun& _noun); - noun_query& not_member_holonym_of(const noun& _noun); - - noun_query& is_proper(bool _arg); - noun_query& instance_of(const noun& _noun); - noun_query& not_instance_of(const noun& _noun); - - noun_query& is_class(bool _arg); - noun_query& class_of(const noun& _noun); - noun_query& not_class_of(const noun& _noun); - - noun_query& has_synonyms(bool _arg); - noun_query& synonym_of(const noun& _noun); - noun_query& not_synonym_of(const noun& _noun); - - noun_query& has_antonyms(bool _arg); - noun_query& antonym_of(const noun& _noun); - noun_query& not_antonym_of(const noun& _noun); - - noun_query& has_pertainym(bool _arg); - noun_query& anti_pertainym_of(const adjective& _adj); - - noun_query& is_attribute(bool _arg); - noun_query& attribute_of(const adjective& _adj); - - std::list run() const; - - const static int unlimited = -1; - - private: - const data& _data; - int _limit = unlimited; - bool _random = false; - std::list _rhymes; - std::list _except; - bool _has_prn = false; - - bool _is_hypernym = false; - std::list _hypernym_of; - std::list _not_hypernym_of; - - bool _is_hyponym = false; - std::list _hyponym_of; - std::list _not_hyponym_of; - - bool _is_part_meronym = false; - std::list _part_meronym_of; - std::list _not_part_meronym_of; - - bool _is_substance_meronym = false; - std::list _substance_meronym_of; - std::list _not_substance_meronym_of; - - bool _is_member_meronym = false; - std::list _member_meronym_of; - std::list _not_member_meronym_of; - - bool _is_part_holonym = false; - std::list _part_holonym_of; - std::list _not_part_holonym_of; - - bool _is_substance_holonym = false; - std::list _substance_holonym_of; - std::list _not_substance_holonym_of; - - bool _is_member_holonym = false; - std::list _member_holonym_of; - std::list _not_member_holonym_of; - - bool _is_proper = false; - std::list _instance_of; - std::list _not_instance_of; - - bool _is_class = false; - std::list _class_of; - std::list _not_class_of; - - bool _has_synonyms = false; - std::list _synonym_of; - std::list _not_synonym_of; - - bool _has_antonyms = false; - std::list _antonym_of; - std::list _not_antonym_of; - - bool _has_pertainym = false; - std::list _anti_pertainym_of; - - bool _is_attribute = false; - std::list _attribute_of; - }; - -}; - -#endif /* end of include guard: NOUN_H_24A03C83 */ diff --git a/token.cpp b/token.cpp deleted file mode 100644 index aa8f50e..0000000 --- a/token.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "verbly.h" - -namespace verbly { - - token::token(token::type _type) : _type(_type) - { - - } - - token::type token::token_type() const - { - return _type; - } - - verb_token::verb_token(const class verb& _verb) : token(token::type::verb), _verb(&_verb) - { - - } - - const class verb& verb_token::verb() const - { - return *_verb; - } - - verb_token& verb_token::inflect(verb_token::inflection infl) - { - _inflection = infl; - return *this; - } - - bool verb_token::complete() const - { - return true; - } - - std::string verb_token::compile() const - { - switch (_inflection) - { - case inflection::infinitive: return _verb->infinitive_form(); - case inflection::past_tense: return _verb->past_tense_form(); - case inflection::past_participle: return _verb->past_participle_form(); - case inflection::ing_form: return _verb->ing_form(); - case inflection::s_form: return _verb->s_form(); - } - } - - token* verb_token::copy() const - { - return new verb_token(*this); - } - -}; diff --git a/token.h b/token.h deleted file mode 100644 index 44d99cb..0000000 --- a/token.h +++ /dev/null @@ -1,313 +0,0 @@ -#ifndef TOKEN_H_AD62C505 -#define TOKEN_H_AD62C505 - -#include -#include -#include - -namespace verbly { - - class verb; - - class selrestr { - }; - - class synrestr { - }; - - enum class fillin_type { - noun_phrase, - participle_phrase, - adjective, - adverb - }; - - class token { - public: - enum class type { - verb, - fillin, - string, - utterance - }; - - protected: - // General - type _type; - - token(type _type); - - public: - enum type token_type() const; - - virtual bool complete() const = 0; - virtual std::string compile() const = 0; - virtual token* copy() const = 0; - }; - - class verb_token : public token { - public: - enum class inflection { - infinitive, - past_tense, - past_participle, - ing_form, - s_form - }; - - private: - // Verb - const verb* _verb; - inflection _inflection = inflection::infinitive; - - public: - verb_token(const class verb& _verb); - - const class verb& verb() const; - - verb_token& inflect(inflection infl); - - bool complete() const; - - std::string compile() const; - - token* copy() const; - }; - - class utterance_token : public token { - private: - // Utterance - std::list> utterance; - - public: - typedef std::list>::iterator iterator; - /*class iterator { - private: - friend class utterance_token; - - std::list>::iterator it; - - public: - iterator(std::list>::iterator it) : it(it) - { - - } - - iterator& operator++() - { - ++it; - return *this; - } - - iterator& operator--() - { - --it; - return *this; - } - - bool operator==(const iterator& other) const - { - return it == other.it; - } - - bool operator!=(const iterator& other) const - { - return it != other.it; - } - - token& operator*() - { - return **it; - } - - token& operator->() - { - return **it; - } - };*/ - - utterance_token(std::initializer_list tkns) : token(token::type::utterance) - { - for (auto tkn : tkns) - { - utterance.push_back(std::unique_ptr(tkn)); - } - } - - utterance_token(const utterance_token& other) : token(token::type::utterance) - { - for (auto& tkn : other.utterance) - { - utterance.push_back(std::unique_ptr(tkn->copy())); - } - } - - utterance_token(utterance_token&& other) : token(token::type::utterance), utterance(std::move(other.utterance)) - { - - } - - utterance_token& operator=(const utterance_token& other) - { - utterance.clear(); - - for (auto& tkn : other.utterance) - { - utterance.push_back(std::unique_ptr(tkn->copy())); - } - - return *this; - } - - utterance_token& operator=(utterance_token&& other) - { - utterance = std::move(other.utterance); - - return *this; - } - - iterator begin() - { - return std::begin(utterance); - } - - iterator end() - { - return std::end(utterance); - } - - void erase(iterator it) - { - utterance.erase(it); - } - - bool complete() const - { - return std::all_of(std::begin(utterance), std::end(utterance), [] (const std::unique_ptr& tkn) { - return tkn->complete(); - }); - } - - std::string compile() const - { - std::stringstream result; - for (auto& t : utterance) - { - if (t->complete()) - { - result << t->compile() << " "; - } else { - return "Could not compile!"; - } - } - - std::string output = result.str(); - if (output != "") - { - output.pop_back(); - } - - return output; - } - - token* copy() const - { - return new utterance_token(*this); - } - }; - - class fillin_token : public token { - private: - // Fillin - std::string m_theme; - fillin_type m_fillin_type; - - public: - fillin_token(fillin_type ft) : token(token::type::fillin), m_fillin_type(ft) - { - - } - -/* void synrestrs(std::initializer_list ins) - { - m_synrestrs = std::set(ins); - } - - std::set& synrestrs() - { - return m_synrestrs; - } - - void selrestrs(std::initializer_list ins) - { - m_selrestrs = std::set(ins); - } - - std::set& selrestrs() - { - return m_selrestrs; - }*/ - - fillin_token theme(std::string theme) - { - m_theme = theme; - - return *this; - } - - std::string& theme() - { - return m_theme; - } - - fillin_type fillin_type() const - { - return m_fillin_type; - } - - bool complete() const - { - return false; - } - - std::string compile() const - { - return ""; - } - - token* copy() const - { - return new fillin_token(*this); - } - }; - - class string_token : public token { - private: - // String - std::string str; - - public: - string_token(std::string str) : token(token::type::string), str(str) - { - - } - - bool complete() const - { - return true; - } - - std::string compile() const - { - return str; - } - - token* copy() const - { - return new string_token(*this); - } - }; - -}; - -#endif /* end of include guard: TOKEN_H_AD62C505 */ diff --git a/util.h b/util.h deleted file mode 100644 index 815b47c..0000000 --- a/util.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef UTIL_H_15DDCA2D -#define UTIL_H_15DDCA2D - -#include -#include -#include - -namespace verbly { - - template - std::string implode(InputIterator first, InputIterator last, std::string delimiter) - { - std::stringstream result; - - for (InputIterator it = first; it != last; it++) - { - if (it != first) - { - result << delimiter; - } - - result << *it; - } - - return result.str(); - } - - template - Container split(std::string input, std::string delimiter) - { - Container result; - - while (!input.empty()) - { - int divider = input.find(" "); - if (divider == std::string::npos) - { - result.push_back(input); - - input = ""; - } else { - result.push_back(input.substr(0, divider)); - - input = input.substr(divider+1); - } - } - - return result; - } - -}; - -#endif /* end of include guard: UTIL_H_15DDCA2D */ diff --git a/verb.cpp b/verb.cpp deleted file mode 100644 index 23f7c92..0000000 --- a/verb.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include "verbly.h" - -namespace verbly { - - verb::verb(const data& _data, int _id) : word(_data, _id) - { - - } - - std::string verb::base_form() const - { - return _infinitive; - } - - std::string verb::infinitive_form() const - { - return _infinitive; - } - - std::string verb::past_tense_form() const - { - return _past_tense; - } - - std::string verb::past_participle_form() const - { - return _past_participle; - } - - std::string verb::ing_form() const - { - return _ing_form; - } - - std::string verb::s_form() const - { - return _s_form; - } - - verb_query::verb_query(const data& _data) : _data(_data) - { - - } - - verb_query& verb_query::limit(int _limit) - { - if ((_limit > 0) || (_limit == unlimited)) - { - this->_limit = _limit; - } - - return *this; - } - - verb_query& verb_query::random(bool _random) - { - this->_random = _random; - - return *this; - } - - verb_query& verb_query::except(const verb& _word) - { - _except.push_back(_word); - - return *this; - } - - verb_query& verb_query::rhymes_with(const word& _word) - { - for (auto rhyme : _word.rhyme_phonemes()) - { - _rhymes.push_back(rhyme); - } - - if (dynamic_cast(&_word) != nullptr) - { - _except.push_back(dynamic_cast(_word)); - } - - return *this; - } - - verb_query& verb_query::has_pronunciation(bool _has_prn) - { - this->_has_prn = _has_prn; - - return *this; - } - - std::list verb_query::run() const - { - std::stringstream construct; - construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs"; - std::list conditions; - - if (_has_prn) - { - conditions.push_back("verb_id IN (SELECT verb_id FROM verb_pronunciations)"); - } - - if (!_rhymes.empty()) - { - std::list clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); - std::string cond = "verb_id IN (SELECT verb_id FROM verb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; - conditions.push_back(cond); - } - - for (auto except : _except) - { - conditions.push_back("verb_id != @EXCID"); - } - - if (!conditions.empty()) - { - construct << " WHERE "; - construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); - } - - if (_random) - { - construct << " ORDER BY RANDOM()"; - } - - if (_limit != unlimited) - { - construct << " LIMIT " << _limit; - } - - sqlite3_stmt* ppstmt; - std::string query = construct.str(); - if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) - { - throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); - } - - if (!_rhymes.empty()) - { - int i = 0; - for (auto rhyme : _rhymes) - { - std::string rhymer = "%" + rhyme; - sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); - - i++; - } - } - - for (auto except : _except) - { - sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); - } - - std::list output; - while (sqlite3_step(ppstmt) == SQLITE_ROW) - { - verb tnc {_data, sqlite3_column_int(ppstmt, 0)}; - tnc._infinitive = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 1))); - tnc._past_tense = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 2))); - tnc._past_participle = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 3))); - tnc._ing_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 4))); - tnc._s_form = std::string(reinterpret_cast(sqlite3_column_text(ppstmt, 5))); - - output.push_back(tnc); - } - - sqlite3_finalize(ppstmt); - - for (auto& verb : output) - { - query = "SELECT pronunciation FROM verb_pronunciations WHERE verb_id = ?"; - if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) - { - throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); - } - - sqlite3_bind_int(ppstmt, 1, verb._id); - - while (sqlite3_step(ppstmt) == SQLITE_ROW) - { - std::string pronunciation(reinterpret_cast(sqlite3_column_text(ppstmt, 0))); - auto phonemes = verbly::split>(pronunciation, " "); - - verb.pronunciations.push_back(phonemes); - } - - sqlite3_finalize(ppstmt); - } - - return output; - } - -}; diff --git a/verb.h b/verb.h deleted file mode 100644 index 7cc87e2..0000000 --- a/verb.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef VERB_H_BCC929AD -#define VERB_H_BCC929AD - -namespace verbly { - - /*class frame_part { - - }; - - class frame { - private: - std::list content; - std::map::iterator>> predicates; - - public: - frame(std::list content) : content(content) - { - - } - - std::unique_ptr make_utterance() const - { - - } - };*/ - - class verb : public word { - private: - std::string _infinitive; - std::string _past_tense; - std::string _past_participle; - std::string _ing_form; - std::string _s_form; - - friend class verb_query; - - public: - verb(const data& _data, int _id); - - std::string base_form() const; - std::string infinitive_form() const; - std::string past_tense_form() const; - std::string past_participle_form() const; - std::string ing_form() const; - std::string s_form() const; - }; - - class verb_query { - public: - verb_query(const data& _data); - - verb_query& limit(int _limit); - verb_query& random(bool _random); - verb_query& except(const verb& _word); - verb_query& rhymes_with(const word& _word); - verb_query& has_pronunciation(bool _has_prn); - - std::list run() const; - - const static int unlimited = -1; - - private: - const data& _data; - int _limit = unlimited; - bool _random = false; - std::list _rhymes; - std::list _except; - bool _has_prn = false; - }; - -}; - -#endif /* end of include guard: VERB_H_BCC929AD */ diff --git a/verbly.h b/verbly.h deleted file mode 100644 index b9f5367..0000000 --- a/verbly.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef VERBLY_H_5B39CE50 -#define VERBLY_H_5B39CE50 - -#include "c++14.h" -#include "util.h" -#include "token.h" -#include "data.h" -#include "word.h" -#include "verb.h" -#include "adverb.h" -#include "adjective.h" -#include "noun.h" - -#endif /* end of include guard: VERBLY_H_5B39CE50 */ diff --git a/word.cpp b/word.cpp deleted file mode 100644 index c50e7d3..0000000 --- a/word.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "verbly.h" - -namespace verbly { - - word::word(const data& _data, int _id) : _data(_data), _id(_id) - { - - } - - std::list word::rhyme_phonemes() const - { - std::list result; - - for (auto pronunciation : pronunciations) - { - auto phemstrt = std::find_if(std::begin(pronunciation), std::end(pronunciation), [] (std::string phoneme) { - return phoneme.find("1") != std::string::npos; - }); - - std::stringstream rhymer; - for (auto it = phemstrt; it != std::end(pronunciation); it++) - { - rhymer << " " << *it; - } - - result.push_back(rhymer.str()); - } - - return result; - } - -}; diff --git a/word.h b/word.h deleted file mode 100644 index 23ddb2b..0000000 --- a/word.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef WORD_H_8FC89498 -#define WORD_H_8FC89498 - -namespace verbly { - - class adjective_query; - class verb_query; - class adverb_query; - - template - class query; - - class word { - protected: - const data& _data; - int _id; - - std::list> pronunciations; - - word(const data& _data, int _id); - - friend class adjective_query; - friend class verb_query; - friend class noun_query; - friend class adverb_query; - - public: - virtual std::string base_form() const = 0; - - std::list rhyme_phonemes() const; - }; - -}; - -#endif /* end of include guard: WORD_H_8FC89498 */ -- cgit 1.4.1