diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/adjective.cpp | 655 | ||||
| -rw-r--r-- | lib/adjective.h | 94 | ||||
| -rw-r--r-- | lib/adjective_query.cpp | 819 | ||||
| -rw-r--r-- | lib/adjective_query.h | 91 | ||||
| -rw-r--r-- | lib/adverb.cpp | 443 | ||||
| -rw-r--r-- | lib/adverb.h | 62 | ||||
| -rw-r--r-- | lib/adverb_query.cpp | 514 | ||||
| -rw-r--r-- | lib/adverb_query.h | 65 | ||||
| -rw-r--r-- | lib/c++14.h | 35 | ||||
| -rw-r--r-- | lib/data.cpp | 12 | ||||
| -rw-r--r-- | lib/data.h | 299 | ||||
| -rw-r--r-- | lib/frame.cpp | 320 | ||||
| -rw-r--r-- | lib/frame.h | 118 | ||||
| -rw-r--r-- | lib/frame_query.cpp | 142 | ||||
| -rw-r--r-- | lib/frame_query.h | 21 | ||||
| -rw-r--r-- | lib/noun.cpp | 1010 | ||||
| -rw-r--r-- | lib/noun.h | 150 | ||||
| -rw-r--r-- | lib/noun_query.cpp | 1453 | ||||
| -rw-r--r-- | lib/noun_query.h | 139 | ||||
| -rw-r--r-- | lib/preposition.cpp | 83 | ||||
| -rw-r--r-- | lib/preposition.h | 38 | ||||
| -rw-r--r-- | lib/token.cpp | 617 | ||||
| -rw-r--r-- | lib/token.h | 413 | ||||
| -rw-r--r-- | lib/util.h | 8 | ||||
| -rw-r--r-- | lib/verb.cpp | 169 | ||||
| -rw-r--r-- | lib/verb.h | 45 | ||||
| -rw-r--r-- | lib/verb_query.cpp | 170 | ||||
| -rw-r--r-- | lib/verb_query.h | 34 | ||||
| -rw-r--r-- | lib/verbly.h | 25 | ||||
| -rw-r--r-- | lib/word.cpp | 11 | ||||
| -rw-r--r-- | lib/word.h | 13 |
31 files changed, 5241 insertions, 2827 deletions
| diff --git a/lib/adjective.cpp b/lib/adjective.cpp index b2b53e4..ba8254a 100644 --- a/lib/adjective.cpp +++ b/lib/adjective.cpp | |||
| @@ -2,6 +2,11 @@ | |||
| 2 | 2 | ||
| 3 | namespace verbly { | 3 | namespace verbly { |
| 4 | 4 | ||
| 5 | adjective::adjective() | ||
| 6 | { | ||
| 7 | |||
| 8 | } | ||
| 9 | |||
| 5 | adjective::adjective(const data& _data, int _id) : word(_data, _id) | 10 | adjective::adjective(const data& _data, int _id) : word(_data, _id) |
| 6 | { | 11 | { |
| 7 | 12 | ||
| @@ -9,682 +14,100 @@ namespace verbly { | |||
| 9 | 14 | ||
| 10 | std::string adjective::base_form() const | 15 | std::string adjective::base_form() const |
| 11 | { | 16 | { |
| 17 | assert(_valid == true); | ||
| 18 | |||
| 12 | return _base_form; | 19 | return _base_form; |
| 13 | } | 20 | } |
| 14 | 21 | ||
| 15 | std::string adjective::comparative_form() const | 22 | std::string adjective::comparative_form() const |
| 16 | { | 23 | { |
| 24 | assert(_valid == true); | ||
| 25 | |||
| 17 | return _comparative_form; | 26 | return _comparative_form; |
| 18 | } | 27 | } |
| 19 | 28 | ||
| 20 | std::string adjective::superlative_form() const | 29 | std::string adjective::superlative_form() const |
| 21 | { | 30 | { |
| 31 | assert(_valid == true); | ||
| 32 | |||
| 22 | return _superlative_form; | 33 | return _superlative_form; |
| 23 | } | 34 | } |
| 24 | 35 | ||
| 25 | adjective::positioning adjective::position() const | 36 | adjective::positioning adjective::position() const |
| 26 | { | 37 | { |
| 38 | assert(_valid == true); | ||
| 39 | |||
| 27 | return _position; | 40 | return _position; |
| 28 | } | 41 | } |
| 29 | 42 | ||
| 30 | bool adjective::has_comparative_form() const | 43 | bool adjective::has_comparative_form() const |
| 31 | { | 44 | { |
| 45 | assert(_valid == true); | ||
| 46 | |||
| 32 | return !_comparative_form.empty(); | 47 | return !_comparative_form.empty(); |
| 33 | } | 48 | } |
| 34 | 49 | ||
| 35 | bool adjective::has_superlative_form() const | 50 | bool adjective::has_superlative_form() const |
| 36 | { | 51 | { |
| 52 | assert(_valid == true); | ||
| 53 | |||
| 37 | return !_superlative_form.empty(); | 54 | return !_superlative_form.empty(); |
| 38 | } | 55 | } |
| 39 | 56 | ||
| 40 | bool adjective::has_position() const | 57 | bool adjective::has_position() const |
| 41 | { | 58 | { |
| 59 | assert(_valid == true); | ||
| 60 | |||
| 42 | return _position != adjective::positioning::undefined; | 61 | return _position != adjective::positioning::undefined; |
| 43 | } | 62 | } |
| 44 | 63 | ||
| 45 | adjective_query adjective::antonyms() const | 64 | adjective_query adjective::antonyms() const |
| 46 | { | 65 | { |
| 47 | return _data.adjectives().antonym_of(*this); | 66 | assert(_valid == true); |
| 48 | } | ||
| 49 | |||
| 50 | adjective_query adjective::synonyms() const | ||
| 51 | { | ||
| 52 | return _data.adjectives().synonym_of(*this); | ||
| 53 | } | ||
| 54 | |||
| 55 | adjective_query adjective::generalizations() const | ||
| 56 | { | ||
| 57 | return _data.adjectives().generalization_of(*this); | ||
| 58 | } | ||
| 59 | |||
| 60 | adjective_query adjective::specifications() const | ||
| 61 | { | ||
| 62 | return _data.adjectives().specification_of(*this); | ||
| 63 | } | ||
| 64 | |||
| 65 | noun_query adjective::anti_pertainyms() const | ||
| 66 | { | ||
| 67 | return _data.nouns().anti_pertainym_of(*this); | ||
| 68 | } | ||
| 69 | |||
| 70 | adverb_query adjective::mannernyms() const | ||
| 71 | { | ||
| 72 | return _data.adverbs().mannernym_of(*this); | ||
| 73 | } | ||
| 74 | |||
| 75 | noun_query adjective::attributes() const | ||
| 76 | { | ||
| 77 | return _data.nouns().attribute_of(*this); | ||
| 78 | } | ||
| 79 | |||
| 80 | adjective_query::adjective_query(const data& _data) : _data(_data) | ||
| 81 | { | ||
| 82 | |||
| 83 | } | ||
| 84 | |||
| 85 | adjective_query& adjective_query::limit(int _limit) | ||
| 86 | { | ||
| 87 | if ((_limit > 0) || (_limit == unlimited)) | ||
| 88 | { | ||
| 89 | this->_limit = _limit; | ||
| 90 | } | ||
| 91 | |||
| 92 | return *this; | ||
| 93 | } | ||
| 94 | |||
| 95 | adjective_query& adjective_query::random(bool _random) | ||
| 96 | { | ||
| 97 | this->_random = _random; | ||
| 98 | |||
| 99 | return *this; | ||
| 100 | } | ||
| 101 | |||
| 102 | adjective_query& adjective_query::except(const adjective& _word) | ||
| 103 | { | ||
| 104 | _except.push_back(_word); | ||
| 105 | |||
| 106 | return *this; | ||
| 107 | } | ||
| 108 | |||
| 109 | adjective_query& adjective_query::rhymes_with(const word& _word) | ||
| 110 | { | ||
| 111 | for (auto rhyme : _word.rhyme_phonemes()) | ||
| 112 | { | ||
| 113 | _rhymes.push_back(rhyme); | ||
| 114 | } | ||
| 115 | |||
| 116 | if (dynamic_cast<const adjective*>(&_word) != nullptr) | ||
| 117 | { | ||
| 118 | _except.push_back(dynamic_cast<const adjective&>(_word)); | ||
| 119 | } | ||
| 120 | |||
| 121 | return *this; | ||
| 122 | } | ||
| 123 | |||
| 124 | adjective_query& adjective_query::has_pronunciation(bool _has_prn) | ||
| 125 | { | ||
| 126 | this->_has_prn = _has_prn; | ||
| 127 | |||
| 128 | return *this; | ||
| 129 | } | ||
| 130 | |||
| 131 | adjective_query& adjective_query::is_variant(bool _is_variant) | ||
| 132 | { | ||
| 133 | this->_is_variant = _is_variant; | ||
| 134 | |||
| 135 | return *this; | ||
| 136 | } | ||
| 137 | |||
| 138 | adjective_query& adjective_query::variant_of(const noun& _noun) | ||
| 139 | { | ||
| 140 | _variant_of.push_back(_noun); | ||
| 141 | |||
| 142 | return *this; | ||
| 143 | } | ||
| 144 | |||
| 145 | adjective_query& adjective_query::not_variant_of(const noun& _noun) | ||
| 146 | { | ||
| 147 | _not_variant_of.push_back(_noun); | ||
| 148 | |||
| 149 | return *this; | ||
| 150 | } | ||
| 151 | |||
| 152 | adjective_query& adjective_query::has_antonyms(bool _is_antonymic) | ||
| 153 | { | ||
| 154 | this->_is_antonymic = _is_antonymic; | ||
| 155 | |||
| 156 | return *this; | ||
| 157 | } | ||
| 158 | |||
| 159 | adjective_query& adjective_query::antonym_of(const adjective& _adj) | ||
| 160 | { | ||
| 161 | _antonym_of.push_back(_adj); | ||
| 162 | |||
| 163 | return *this; | ||
| 164 | } | ||
| 165 | |||
| 166 | adjective_query& adjective_query::not_antonym_of(const adjective& _adj) | ||
| 167 | { | ||
| 168 | _not_antonym_of.push_back(_adj); | ||
| 169 | |||
| 170 | return *this; | ||
| 171 | } | ||
| 172 | |||
| 173 | adjective_query& adjective_query::has_synonyms(bool _is_synonymic) | ||
| 174 | { | ||
| 175 | this->_is_synonymic = _is_synonymic; | ||
| 176 | |||
| 177 | return *this; | ||
| 178 | } | ||
| 179 | |||
| 180 | adjective_query& adjective_query::synonym_of(const adjective& _adj) | ||
| 181 | { | ||
| 182 | _synonym_of.push_back(_adj); | ||
| 183 | |||
| 184 | return *this; | ||
| 185 | } | ||
| 186 | |||
| 187 | adjective_query& adjective_query::not_synonym_of(const adjective& _adj) | ||
| 188 | { | ||
| 189 | _not_synonym_of.push_back(_adj); | ||
| 190 | |||
| 191 | return *this; | ||
| 192 | } | ||
| 193 | |||
| 194 | adjective_query& adjective_query::is_generalization(bool _is_generalization) | ||
| 195 | { | ||
| 196 | this->_is_generalization = _is_generalization; | ||
| 197 | |||
| 198 | return *this; | ||
| 199 | } | ||
| 200 | |||
| 201 | adjective_query& adjective_query::generalization_of(const adjective& _adj) | ||
| 202 | { | ||
| 203 | _generalization_of.push_back(_adj); | ||
| 204 | |||
| 205 | return *this; | ||
| 206 | } | ||
| 207 | |||
| 208 | adjective_query& adjective_query::not_generalization_of(const adjective& _adj) | ||
| 209 | { | ||
| 210 | _not_generalization_of.push_back(_adj); | ||
| 211 | |||
| 212 | return *this; | ||
| 213 | } | ||
| 214 | |||
| 215 | adjective_query& adjective_query::is_specification(bool _is_specification) | ||
| 216 | { | ||
| 217 | this->_is_specification = _is_specification; | ||
| 218 | |||
| 219 | return *this; | ||
| 220 | } | ||
| 221 | |||
| 222 | adjective_query& adjective_query::specification_of(const adjective& _adj) | ||
| 223 | { | ||
| 224 | _specification_of.push_back(_adj); | ||
| 225 | 67 | ||
| 226 | return *this; | 68 | return _data->adjectives().antonym_of(*this); |
| 227 | } | 69 | } |
| 228 | 70 | ||
| 229 | adjective_query& adjective_query::not_specification_of(const adjective& _adj) | 71 | adjective_query adjective::synonyms() const |
| 230 | { | ||
| 231 | _not_specification_of.push_back(_adj); | ||
| 232 | |||
| 233 | return *this; | ||
| 234 | } | ||
| 235 | |||
| 236 | adjective_query& adjective_query::is_pertainymic(bool _is_pertainymic) | ||
| 237 | { | ||
| 238 | this->_is_pertainymic = _is_pertainymic; | ||
| 239 | |||
| 240 | return *this; | ||
| 241 | } | ||
| 242 | |||
| 243 | adjective_query& adjective_query::pertainym_of(const noun& _noun) | ||
| 244 | { | 72 | { |
| 245 | _pertainym_of.push_back(_noun); | 73 | assert(_valid == true); |
| 246 | 74 | ||
| 247 | return *this; | 75 | return _data->adjectives().synonym_of(*this); |
| 248 | } | 76 | } |
| 249 | 77 | ||
| 250 | adjective_query& adjective_query::is_mannernymic(bool _is_mannernymic) | 78 | adjective_query adjective::generalizations() const |
| 251 | { | 79 | { |
| 252 | this->_is_mannernymic = _is_mannernymic; | 80 | assert(_valid == true); |
| 253 | 81 | ||
| 254 | return *this; | 82 | return _data->adjectives().generalization_of(*this); |
| 255 | } | 83 | } |
| 256 | 84 | ||
| 257 | adjective_query& adjective_query::anti_mannernym_of(const adverb& _adv) | 85 | adjective_query adjective::specifications() const |
| 258 | { | 86 | { |
| 259 | _anti_mannernym_of.push_back(_adv); | 87 | assert(_valid == true); |
| 260 | 88 | ||
| 261 | return *this; | 89 | return _data->adjectives().specification_of(*this); |
| 262 | } | 90 | } |
| 263 | 91 | ||
| 264 | adjective_query& adjective_query::derived_from(const word& _w) | 92 | noun_query adjective::anti_pertainyms() const |
| 265 | { | 93 | { |
| 266 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | 94 | assert(_valid == true); |
| 267 | { | ||
| 268 | _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 269 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 270 | { | ||
| 271 | _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 272 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 273 | { | ||
| 274 | _derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 275 | } | ||
| 276 | 95 | ||
| 277 | return *this; | 96 | return _data->nouns().anti_pertainym_of(*this); |
| 278 | } | 97 | } |
| 279 | 98 | ||
| 280 | adjective_query& adjective_query::not_derived_from(const word& _w) | 99 | adverb_query adjective::mannernyms() const |
| 281 | { | 100 | { |
| 282 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | 101 | assert(_valid == true); |
| 283 | { | ||
| 284 | _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 285 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 286 | { | ||
| 287 | _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 288 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 289 | { | ||
| 290 | _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 291 | } | ||
| 292 | 102 | ||
| 293 | return *this; | 103 | return _data->adverbs().mannernym_of(*this); |
| 294 | } | 104 | } |
| 295 | 105 | ||
| 296 | std::list<adjective> adjective_query::run() const | 106 | noun_query adjective::attributes() const |
| 297 | { | 107 | { |
| 298 | std::stringstream construct; | 108 | assert(_valid == true); |
| 299 | construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives"; | ||
| 300 | std::list<std::string> conditions; | ||
| 301 | |||
| 302 | if (_has_prn) | ||
| 303 | { | ||
| 304 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM adjective_pronunciations)"); | ||
| 305 | } | ||
| 306 | |||
| 307 | if (!_rhymes.empty()) | ||
| 308 | { | ||
| 309 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
| 310 | std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 311 | conditions.push_back(cond); | ||
| 312 | } | ||
| 313 | |||
| 314 | for (auto except : _except) | ||
| 315 | { | ||
| 316 | conditions.push_back("adjective_id != @EXCID"); | ||
| 317 | } | ||
| 318 | |||
| 319 | if (_requires_comparative_form) | ||
| 320 | { | ||
| 321 | conditions.push_back("comparative IS NOT NULL"); | ||
| 322 | } | ||
| 323 | |||
| 324 | if (_requires_superlative_form) | ||
| 325 | { | ||
| 326 | conditions.push_back("superlative IS NOT NULL"); | ||
| 327 | } | ||
| 328 | |||
| 329 | if (_position != adjective::positioning::undefined) | ||
| 330 | { | ||
| 331 | switch (_position) | ||
| 332 | { | ||
| 333 | case adjective::positioning::predicate: conditions.push_back("position = 'p'"); break; | ||
| 334 | case adjective::positioning::attributive: conditions.push_back("position = 'a'"); break; | ||
| 335 | case adjective::positioning::postnominal: conditions.push_back("position = 'i'"); break; | ||
| 336 | } | ||
| 337 | } | ||
| 338 | |||
| 339 | if (_is_variant) | ||
| 340 | { | ||
| 341 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM variation)"); | ||
| 342 | } | ||
| 343 | |||
| 344 | if (!_variant_of.empty()) | ||
| 345 | { | ||
| 346 | std::list<std::string> clauses(_variant_of.size(), "noun_id = @ATTRID"); | ||
| 347 | std::string cond = "adjective_id IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 348 | conditions.push_back(cond); | ||
| 349 | } | ||
| 350 | |||
| 351 | if (!_not_variant_of.empty()) | ||
| 352 | { | ||
| 353 | std::list<std::string> clauses(_not_variant_of.size(), "noun_id = @NATTRID"); | ||
| 354 | std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 355 | conditions.push_back(cond); | ||
| 356 | } | ||
| 357 | |||
| 358 | if (_is_antonymic) | ||
| 359 | { | ||
| 360 | conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy)"); | ||
| 361 | } | ||
| 362 | |||
| 363 | if (!_antonym_of.empty()) | ||
| 364 | { | ||
| 365 | std::list<std::string> clauses(_antonym_of.size(), "adjective_1_id = @ANTID"); | ||
| 366 | std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 367 | conditions.push_back(cond); | ||
| 368 | } | ||
| 369 | |||
| 370 | if (!_not_antonym_of.empty()) | ||
| 371 | { | ||
| 372 | std::list<std::string> clauses(_not_antonym_of.size(), "adjective_1_id = @NANTID"); | ||
| 373 | std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 374 | conditions.push_back(cond); | ||
| 375 | } | ||
| 376 | 109 | ||
| 377 | if (_is_synonymic) | 110 | return _data->nouns().attribute_of(*this); |
| 378 | { | ||
| 379 | conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy)"); | ||
| 380 | } | ||
| 381 | |||
| 382 | if (!_synonym_of.empty()) | ||
| 383 | { | ||
| 384 | std::list<std::string> clauses(_synonym_of.size(), "adjective_1_id = @SYNID"); | ||
| 385 | std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 386 | conditions.push_back(cond); | ||
| 387 | } | ||
| 388 | |||
| 389 | if (!_not_synonym_of.empty()) | ||
| 390 | { | ||
| 391 | std::list<std::string> clauses(_not_synonym_of.size(), "adjective_1_id = @NSYNID"); | ||
| 392 | std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 393 | conditions.push_back(cond); | ||
| 394 | } | ||
| 395 | |||
| 396 | if (_is_generalization) | ||
| 397 | { | ||
| 398 | conditions.push_back("adjective_id IN (SELECT general_id FROM specification)"); | ||
| 399 | } | ||
| 400 | |||
| 401 | if (!_generalization_of.empty()) | ||
| 402 | { | ||
| 403 | std::list<std::string> clauses(_generalization_of.size(), "specific_id = @SPECID"); | ||
| 404 | std::string cond = "adjective_id IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 405 | conditions.push_back(cond); | ||
| 406 | } | ||
| 407 | |||
| 408 | if (!_not_generalization_of.empty()) | ||
| 409 | { | ||
| 410 | std::list<std::string> clauses(_not_generalization_of.size(), "specific_id = @NSPECID"); | ||
| 411 | std::string cond = "adjective_id NOT IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 412 | conditions.push_back(cond); | ||
| 413 | } | ||
| 414 | |||
| 415 | if (_is_specification) | ||
| 416 | { | ||
| 417 | conditions.push_back("adjective_id IN (SELECT specific_id FROM specification)"); | ||
| 418 | } | ||
| 419 | |||
| 420 | if (!_specification_of.empty()) | ||
| 421 | { | ||
| 422 | std::list<std::string> clauses(_specification_of.size(), "general_id = @GENID"); | ||
| 423 | std::string cond = "adjective_id IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 424 | conditions.push_back(cond); | ||
| 425 | } | ||
| 426 | |||
| 427 | if (!_not_specification_of.empty()) | ||
| 428 | { | ||
| 429 | std::list<std::string> clauses(_not_specification_of.size(), "general_id = @NGENID"); | ||
| 430 | std::string cond = "adjective_id NOT IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 431 | conditions.push_back(cond); | ||
| 432 | } | ||
| 433 | |||
| 434 | if (_is_pertainymic) | ||
| 435 | { | ||
| 436 | conditions.push_back("adjective_id IN (SELECT pertainym_id FROM pertainymy)"); | ||
| 437 | } | ||
| 438 | |||
| 439 | if (!_pertainym_of.empty()) | ||
| 440 | { | ||
| 441 | std::list<std::string> clauses(_pertainym_of.size(), "noun_id = @APERID"); | ||
| 442 | std::string cond = "adjective_id IN (SELECT pertainym_id FROM pertainymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 443 | conditions.push_back(cond); | ||
| 444 | } | ||
| 445 | |||
| 446 | if (_is_mannernymic) | ||
| 447 | { | ||
| 448 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM mannernymy)"); | ||
| 449 | } | ||
| 450 | |||
| 451 | if (!_anti_mannernym_of.empty()) | ||
| 452 | { | ||
| 453 | std::list<std::string> clauses(_anti_mannernym_of.size(), "mannernym_id = @MANID"); | ||
| 454 | std::string cond = "adjective_id IN (SELECT adjective_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 455 | conditions.push_back(cond); | ||
| 456 | } | ||
| 457 | |||
| 458 | if (!_derived_from_adjective.empty()) | ||
| 459 | { | ||
| 460 | std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_2_id = @DERADJ"); | ||
| 461 | std::string cond = "adjective_id IN (SELECT adjective_1_id FROM adjective_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 462 | conditions.push_back(cond); | ||
| 463 | } | ||
| 464 | |||
| 465 | if (!_not_derived_from_adjective.empty()) | ||
| 466 | { | ||
| 467 | std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_2_id = @NDERADJ"); | ||
| 468 | 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 ") + ")"; | ||
| 469 | conditions.push_back(cond); | ||
| 470 | } | ||
| 471 | |||
| 472 | if (!_derived_from_adverb.empty()) | ||
| 473 | { | ||
| 474 | std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_id = @DERADV"); | ||
| 475 | std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 476 | conditions.push_back(cond); | ||
| 477 | } | ||
| 478 | |||
| 479 | if (!_not_derived_from_adverb.empty()) | ||
| 480 | { | ||
| 481 | std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_id = @NDERADV"); | ||
| 482 | std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 483 | conditions.push_back(cond); | ||
| 484 | } | ||
| 485 | |||
| 486 | if (!_derived_from_noun.empty()) | ||
| 487 | { | ||
| 488 | std::list<std::string> clauses(_derived_from_noun.size(), "noun_id = @DERN"); | ||
| 489 | std::string cond = "adjective_id IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 490 | conditions.push_back(cond); | ||
| 491 | } | ||
| 492 | |||
| 493 | if (!_not_derived_from_noun.empty()) | ||
| 494 | { | ||
| 495 | std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_id = @NDERN"); | ||
| 496 | std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 497 | conditions.push_back(cond); | ||
| 498 | } | ||
| 499 | |||
| 500 | if (!conditions.empty()) | ||
| 501 | { | ||
| 502 | construct << " WHERE "; | ||
| 503 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
| 504 | } | ||
| 505 | |||
| 506 | if (_random) | ||
| 507 | { | ||
| 508 | construct << " ORDER BY RANDOM()"; | ||
| 509 | } | ||
| 510 | |||
| 511 | if (_limit != unlimited) | ||
| 512 | { | ||
| 513 | construct << " LIMIT " << _limit; | ||
| 514 | } | ||
| 515 | |||
| 516 | sqlite3_stmt* ppstmt; | ||
| 517 | std::string query = construct.str(); | ||
| 518 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 519 | { | ||
| 520 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 521 | } | ||
| 522 | |||
| 523 | if (!_rhymes.empty()) | ||
| 524 | { | ||
| 525 | int i = 0; | ||
| 526 | for (auto rhyme : _rhymes) | ||
| 527 | { | ||
| 528 | std::string rhymer = "%" + rhyme; | ||
| 529 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
| 530 | |||
| 531 | i++; | ||
| 532 | } | ||
| 533 | } | ||
| 534 | |||
| 535 | for (auto except : _except) | ||
| 536 | { | ||
| 537 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
| 538 | } | ||
| 539 | |||
| 540 | for (auto attribute : _variant_of) | ||
| 541 | { | ||
| 542 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id); | ||
| 543 | } | ||
| 544 | |||
| 545 | for (auto attribute : _not_variant_of) | ||
| 546 | { | ||
| 547 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NATTRID"), attribute._id); | ||
| 548 | } | ||
| 549 | |||
| 550 | for (auto antonym : _antonym_of) | ||
| 551 | { | ||
| 552 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
| 553 | } | ||
| 554 | |||
| 555 | for (auto antonym : _not_antonym_of) | ||
| 556 | { | ||
| 557 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); | ||
| 558 | } | ||
| 559 | |||
| 560 | for (auto synonym : _synonym_of) | ||
| 561 | { | ||
| 562 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
| 563 | } | ||
| 564 | |||
| 565 | for (auto synonym : _not_synonym_of) | ||
| 566 | { | ||
| 567 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); | ||
| 568 | } | ||
| 569 | |||
| 570 | for (auto specific : _generalization_of) | ||
| 571 | { | ||
| 572 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SPECID"), specific._id); | ||
| 573 | } | ||
| 574 | |||
| 575 | for (auto specific : _not_generalization_of) | ||
| 576 | { | ||
| 577 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSPECID"), specific._id); | ||
| 578 | } | ||
| 579 | |||
| 580 | for (auto general : _specification_of) | ||
| 581 | { | ||
| 582 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GENID"), general._id); | ||
| 583 | } | ||
| 584 | |||
| 585 | for (auto general : _not_specification_of) | ||
| 586 | { | ||
| 587 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NGENID"), general._id); | ||
| 588 | } | ||
| 589 | |||
| 590 | for (auto n : _pertainym_of) | ||
| 591 | { | ||
| 592 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@APERID"), n._id); | ||
| 593 | } | ||
| 594 | |||
| 595 | for (auto mannernym : _anti_mannernym_of) | ||
| 596 | { | ||
| 597 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MANID"), mannernym._id); | ||
| 598 | } | ||
| 599 | |||
| 600 | for (auto adj : _derived_from_adjective) | ||
| 601 | { | ||
| 602 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id); | ||
| 603 | } | ||
| 604 | |||
| 605 | for (auto adj : _not_derived_from_adjective) | ||
| 606 | { | ||
| 607 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id); | ||
| 608 | } | ||
| 609 | |||
| 610 | for (auto adv : _derived_from_adverb) | ||
| 611 | { | ||
| 612 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id); | ||
| 613 | } | ||
| 614 | |||
| 615 | for (auto adv : _not_derived_from_adverb) | ||
| 616 | { | ||
| 617 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id); | ||
| 618 | } | ||
| 619 | |||
| 620 | for (auto n : _derived_from_noun) | ||
| 621 | { | ||
| 622 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id); | ||
| 623 | } | ||
| 624 | |||
| 625 | for (auto n : _not_derived_from_noun) | ||
| 626 | { | ||
| 627 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id); | ||
| 628 | } | ||
| 629 | |||
| 630 | std::list<adjective> output; | ||
| 631 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 632 | { | ||
| 633 | adjective tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
| 634 | tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
| 635 | |||
| 636 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
| 637 | { | ||
| 638 | tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
| 639 | } | ||
| 640 | |||
| 641 | if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) | ||
| 642 | { | ||
| 643 | tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
| 644 | } | ||
| 645 | |||
| 646 | if (sqlite3_column_type(ppstmt, 4) != SQLITE_NULL) | ||
| 647 | { | ||
| 648 | std::string adjpos(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 4))); | ||
| 649 | if (adjpos == "p") | ||
| 650 | { | ||
| 651 | tnc._position = adjective::positioning::predicate; | ||
| 652 | } else if (adjpos == "a") | ||
| 653 | { | ||
| 654 | tnc._position = adjective::positioning::attributive; | ||
| 655 | } else if (adjpos == "i") | ||
| 656 | { | ||
| 657 | tnc._position = adjective::positioning::postnominal; | ||
| 658 | } | ||
| 659 | } | ||
| 660 | |||
| 661 | output.push_back(tnc); | ||
| 662 | } | ||
| 663 | |||
| 664 | sqlite3_finalize(ppstmt); | ||
| 665 | |||
| 666 | for (auto& adjective : output) | ||
| 667 | { | ||
| 668 | query = "SELECT pronunciation FROM adjective_pronunciations WHERE adjective_id = ?"; | ||
| 669 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 670 | { | ||
| 671 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 672 | } | ||
| 673 | |||
| 674 | sqlite3_bind_int(ppstmt, 1, adjective._id); | ||
| 675 | |||
| 676 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 677 | { | ||
| 678 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
| 679 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
| 680 | |||
| 681 | adjective.pronunciations.push_back(phonemes); | ||
| 682 | } | ||
| 683 | |||
| 684 | sqlite3_finalize(ppstmt); | ||
| 685 | } | ||
| 686 | |||
| 687 | return output; | ||
| 688 | } | 111 | } |
| 689 | 112 | ||
| 690 | }; | 113 | }; |
| diff --git a/lib/adjective.h b/lib/adjective.h index 3dcab9b..a6eb293 100644 --- a/lib/adjective.h +++ b/lib/adjective.h | |||
| @@ -25,6 +25,7 @@ namespace verbly { | |||
| 25 | friend class adjective_query; | 25 | friend class adjective_query; |
| 26 | 26 | ||
| 27 | public: | 27 | public: |
| 28 | adjective(); | ||
| 28 | adjective(const data& _data, int _id); | 29 | adjective(const data& _data, int _id); |
| 29 | 30 | ||
| 30 | std::string base_form() const; | 31 | std::string base_form() const; |
| @@ -45,99 +46,6 @@ namespace verbly { | |||
| 45 | noun_query attributes() const; | 46 | noun_query attributes() const; |
| 46 | }; | 47 | }; |
| 47 | 48 | ||
| 48 | class adjective_query { | ||
| 49 | public: | ||
| 50 | adjective_query(const data& _data); | ||
| 51 | |||
| 52 | adjective_query& limit(int _limit); | ||
| 53 | adjective_query& random(bool _random); | ||
| 54 | adjective_query& except(const adjective& _word); | ||
| 55 | adjective_query& rhymes_with(const word& _word); | ||
| 56 | adjective_query& has_pronunciation(bool _has_prn); | ||
| 57 | |||
| 58 | adjective_query& requires_comparative_form(bool req); | ||
| 59 | adjective_query& requires_superlative_form(bool req); | ||
| 60 | adjective_query& position(adjective::positioning pos); | ||
| 61 | |||
| 62 | adjective_query& is_variant(bool _is_variant); | ||
| 63 | adjective_query& variant_of(const noun& _noun); | ||
| 64 | adjective_query& not_variant_of(const noun& _noun); | ||
| 65 | |||
| 66 | adjective_query& has_antonyms(bool _is_antonymic); | ||
| 67 | adjective_query& antonym_of(const adjective& _adj); | ||
| 68 | adjective_query& not_antonym_of(const adjective& _adj); | ||
| 69 | |||
| 70 | adjective_query& has_synonyms(bool _is_synonymic); | ||
| 71 | adjective_query& synonym_of(const adjective& _adj); | ||
| 72 | adjective_query& not_synonym_of(const adjective& _adj); | ||
| 73 | |||
| 74 | adjective_query& is_generalization(bool _is_generalization); | ||
| 75 | adjective_query& generalization_of(const adjective& _adj); | ||
| 76 | adjective_query& not_generalization_of(const adjective& _adj); | ||
| 77 | |||
| 78 | adjective_query& is_specification(bool _is_specification); | ||
| 79 | adjective_query& specification_of(const adjective& _adj); | ||
| 80 | adjective_query& not_specification_of(const adjective& _adj); | ||
| 81 | |||
| 82 | adjective_query& is_pertainymic(bool _is_pertainymic); | ||
| 83 | adjective_query& pertainym_of(const noun& _noun); | ||
| 84 | |||
| 85 | adjective_query& is_mannernymic(bool _is_mannernymic); | ||
| 86 | adjective_query& anti_mannernym_of(const adverb& _adv); | ||
| 87 | |||
| 88 | adjective_query& derived_from(const word& _w); | ||
| 89 | adjective_query& not_derived_from(const word& _w); | ||
| 90 | |||
| 91 | std::list<adjective> run() const; | ||
| 92 | |||
| 93 | const static int unlimited = -1; | ||
| 94 | |||
| 95 | protected: | ||
| 96 | const data& _data; | ||
| 97 | int _limit = unlimited; | ||
| 98 | bool _random = false; | ||
| 99 | std::list<std::string> _rhymes; | ||
| 100 | std::list<adjective> _except; | ||
| 101 | bool _has_prn = false; | ||
| 102 | |||
| 103 | bool _requires_comparative_form = false; | ||
| 104 | bool _requires_superlative_form = false; | ||
| 105 | adjective::positioning _position = adjective::positioning::undefined; | ||
| 106 | |||
| 107 | bool _is_variant = false; | ||
| 108 | std::list<noun> _variant_of; | ||
| 109 | std::list<noun> _not_variant_of; | ||
| 110 | |||
| 111 | bool _is_antonymic = false; | ||
| 112 | std::list<adjective> _antonym_of; | ||
| 113 | std::list<adjective> _not_antonym_of; | ||
| 114 | |||
| 115 | bool _is_synonymic = false; | ||
| 116 | std::list<adjective> _synonym_of; | ||
| 117 | std::list<adjective> _not_synonym_of; | ||
| 118 | |||
| 119 | bool _is_generalization = false; | ||
| 120 | std::list<adjective> _generalization_of; | ||
| 121 | std::list<adjective> _not_generalization_of; | ||
| 122 | |||
| 123 | bool _is_specification = false; | ||
| 124 | std::list<adjective> _specification_of; | ||
| 125 | std::list<adjective> _not_specification_of; | ||
| 126 | |||
| 127 | bool _is_pertainymic = false; | ||
| 128 | std::list<noun> _pertainym_of; | ||
| 129 | |||
| 130 | bool _is_mannernymic = false; | ||
| 131 | std::list<adverb> _anti_mannernym_of; | ||
| 132 | |||
| 133 | std::list<adjective> _derived_from_adjective; | ||
| 134 | std::list<adjective> _not_derived_from_adjective; | ||
| 135 | std::list<adverb> _derived_from_adverb; | ||
| 136 | std::list<adverb> _not_derived_from_adverb; | ||
| 137 | std::list<noun> _derived_from_noun; | ||
| 138 | std::list<noun> _not_derived_from_noun; | ||
| 139 | }; | ||
| 140 | |||
| 141 | }; | 49 | }; |
| 142 | 50 | ||
| 143 | #endif /* end of include guard: ADJECTIVE_H_87B3FB75 */ | 51 | #endif /* end of include guard: ADJECTIVE_H_87B3FB75 */ |
| diff --git a/lib/adjective_query.cpp b/lib/adjective_query.cpp new file mode 100644 index 0000000..ec100e3 --- /dev/null +++ b/lib/adjective_query.cpp | |||
| @@ -0,0 +1,819 @@ | |||
| 1 | #include "verbly.h" | ||
| 2 | |||
| 3 | namespace verbly { | ||
| 4 | |||
| 5 | adjective_query::adjective_query(const data& _data) : _data(_data) | ||
| 6 | { | ||
| 7 | |||
| 8 | } | ||
| 9 | |||
| 10 | adjective_query& adjective_query::limit(int _limit) | ||
| 11 | { | ||
| 12 | if ((_limit > 0) || (_limit == unlimited)) | ||
| 13 | { | ||
| 14 | this->_limit = _limit; | ||
| 15 | } | ||
| 16 | |||
| 17 | return *this; | ||
| 18 | } | ||
| 19 | |||
| 20 | adjective_query& adjective_query::random() | ||
| 21 | { | ||
| 22 | this->_random = true; | ||
| 23 | |||
| 24 | return *this; | ||
| 25 | } | ||
| 26 | |||
| 27 | adjective_query& adjective_query::except(const adjective& _word) | ||
| 28 | { | ||
| 29 | _except.push_back(_word); | ||
| 30 | |||
| 31 | return *this; | ||
| 32 | } | ||
| 33 | |||
| 34 | adjective_query& adjective_query::rhymes_with(const word& _word) | ||
| 35 | { | ||
| 36 | for (auto rhyme : _word.rhyme_phonemes()) | ||
| 37 | { | ||
| 38 | _rhymes.push_back(rhyme); | ||
| 39 | } | ||
| 40 | |||
| 41 | if (dynamic_cast<const adjective*>(&_word) != nullptr) | ||
| 42 | { | ||
| 43 | _except.push_back(dynamic_cast<const adjective&>(_word)); | ||
| 44 | } | ||
| 45 | |||
| 46 | return *this; | ||
| 47 | } | ||
| 48 | |||
| 49 | adjective_query& adjective_query::has_pronunciation() | ||
| 50 | { | ||
| 51 | this->_has_prn = true; | ||
| 52 | |||
| 53 | return *this; | ||
| 54 | } | ||
| 55 | |||
| 56 | adjective_query& adjective_query::is_variant() | ||
| 57 | { | ||
| 58 | this->_is_variant = true; | ||
| 59 | |||
| 60 | return *this; | ||
| 61 | } | ||
| 62 | |||
| 63 | adjective_query& adjective_query::variant_of(filter<noun> _f) | ||
| 64 | { | ||
| 65 | _f.clean(); | ||
| 66 | _variant_of = _f; | ||
| 67 | |||
| 68 | return *this; | ||
| 69 | } | ||
| 70 | |||
| 71 | adjective_query& adjective_query::has_antonyms() | ||
| 72 | { | ||
| 73 | this->_is_antonymic = true; | ||
| 74 | |||
| 75 | return *this; | ||
| 76 | } | ||
| 77 | |||
| 78 | adjective_query& adjective_query::antonym_of(filter<adjective> _f) | ||
| 79 | { | ||
| 80 | _f.clean(); | ||
| 81 | _antonym_of = _f; | ||
| 82 | |||
| 83 | return *this; | ||
| 84 | } | ||
| 85 | |||
| 86 | adjective_query& adjective_query::has_synonyms() | ||
| 87 | { | ||
| 88 | this->_is_synonymic = true; | ||
| 89 | |||
| 90 | return *this; | ||
| 91 | } | ||
| 92 | |||
| 93 | adjective_query& adjective_query::synonym_of(filter<adjective> _f) | ||
| 94 | { | ||
| 95 | _f.clean(); | ||
| 96 | _synonym_of = _f; | ||
| 97 | |||
| 98 | return *this; | ||
| 99 | } | ||
| 100 | |||
| 101 | adjective_query& adjective_query::is_generalization() | ||
| 102 | { | ||
| 103 | this->_is_generalization = true; | ||
| 104 | |||
| 105 | return *this; | ||
| 106 | } | ||
| 107 | |||
| 108 | adjective_query& adjective_query::generalization_of(filter<adjective> _f) | ||
| 109 | { | ||
| 110 | _f.clean(); | ||
| 111 | _generalization_of = _f; | ||
| 112 | |||
| 113 | return *this; | ||
| 114 | } | ||
| 115 | |||
| 116 | adjective_query& adjective_query::is_specification() | ||
| 117 | { | ||
| 118 | this->_is_specification = true; | ||
| 119 | |||
| 120 | return *this; | ||
| 121 | } | ||
| 122 | |||
| 123 | adjective_query& adjective_query::specification_of(filter<adjective> _f) | ||
| 124 | { | ||
| 125 | _f.clean(); | ||
| 126 | _specification_of = _f; | ||
| 127 | |||
| 128 | return *this; | ||
| 129 | } | ||
| 130 | |||
| 131 | adjective_query& adjective_query::is_pertainymic() | ||
| 132 | { | ||
| 133 | this->_is_pertainymic = true; | ||
| 134 | |||
| 135 | return *this; | ||
| 136 | } | ||
| 137 | |||
| 138 | adjective_query& adjective_query::pertainym_of(filter<noun> _f) | ||
| 139 | { | ||
| 140 | _f.clean(); | ||
| 141 | _pertainym_of = _f; | ||
| 142 | |||
| 143 | return *this; | ||
| 144 | } | ||
| 145 | |||
| 146 | adjective_query& adjective_query::is_mannernymic() | ||
| 147 | { | ||
| 148 | this->_is_mannernymic = true; | ||
| 149 | |||
| 150 | return *this; | ||
| 151 | } | ||
| 152 | |||
| 153 | adjective_query& adjective_query::anti_mannernym_of(filter<adverb> _f) | ||
| 154 | { | ||
| 155 | _f.clean(); | ||
| 156 | _anti_mannernym_of = _f; | ||
| 157 | |||
| 158 | return *this; | ||
| 159 | } | ||
| 160 | /* | ||
| 161 | adjective_query& adjective_query::derived_from(const word& _w) | ||
| 162 | { | ||
| 163 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | ||
| 164 | { | ||
| 165 | _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 166 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 167 | { | ||
| 168 | _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 169 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 170 | { | ||
| 171 | _derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 172 | } | ||
| 173 | |||
| 174 | return *this; | ||
| 175 | } | ||
| 176 | |||
| 177 | adjective_query& adjective_query::not_derived_from(const word& _w) | ||
| 178 | { | ||
| 179 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | ||
| 180 | { | ||
| 181 | _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 182 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 183 | { | ||
| 184 | _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 185 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 186 | { | ||
| 187 | _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 188 | } | ||
| 189 | |||
| 190 | return *this; | ||
| 191 | } | ||
| 192 | */ | ||
| 193 | std::list<adjective> adjective_query::run() const | ||
| 194 | { | ||
| 195 | std::stringstream construct; | ||
| 196 | construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives"; | ||
| 197 | std::list<std::string> conditions; | ||
| 198 | |||
| 199 | if (_has_prn) | ||
| 200 | { | ||
| 201 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM adjective_pronunciations)"); | ||
| 202 | } | ||
| 203 | |||
| 204 | if (!_rhymes.empty()) | ||
| 205 | { | ||
| 206 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
| 207 | std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 208 | conditions.push_back(cond); | ||
| 209 | } | ||
| 210 | |||
| 211 | for (auto except : _except) | ||
| 212 | { | ||
| 213 | conditions.push_back("adjective_id != @EXCID"); | ||
| 214 | } | ||
| 215 | |||
| 216 | if (_requires_comparative_form) | ||
| 217 | { | ||
| 218 | conditions.push_back("comparative IS NOT NULL"); | ||
| 219 | } | ||
| 220 | |||
| 221 | if (_requires_superlative_form) | ||
| 222 | { | ||
| 223 | conditions.push_back("superlative IS NOT NULL"); | ||
| 224 | } | ||
| 225 | |||
| 226 | switch (_position) | ||
| 227 | { | ||
| 228 | case adjective::positioning::predicate: conditions.push_back("position = 'p'"); break; | ||
| 229 | case adjective::positioning::attributive: conditions.push_back("position = 'a'"); break; | ||
| 230 | case adjective::positioning::postnominal: conditions.push_back("position = 'i'"); break; | ||
| 231 | case adjective::positioning::undefined: break; | ||
| 232 | } | ||
| 233 | |||
| 234 | if (_is_variant) | ||
| 235 | { | ||
| 236 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM variation)"); | ||
| 237 | } | ||
| 238 | |||
| 239 | if (!_variant_of.empty()) | ||
| 240 | { | ||
| 241 | std::stringstream cond; | ||
| 242 | if (_variant_of.get_notlogic()) | ||
| 243 | { | ||
| 244 | cond << "adjective_id NOT IN"; | ||
| 245 | } else { | ||
| 246 | cond << "adjective_id IN"; | ||
| 247 | } | ||
| 248 | |||
| 249 | cond << "(SELECT adjective_id FROM variation WHERE "; | ||
| 250 | |||
| 251 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 252 | switch (f.get_type()) | ||
| 253 | { | ||
| 254 | case filter<noun>::type::singleton: | ||
| 255 | { | ||
| 256 | if (notlogic == f.get_notlogic()) | ||
| 257 | { | ||
| 258 | return "noun_id = @ATTRID"; | ||
| 259 | } else { | ||
| 260 | return "noun_id != @ATTRID"; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | case filter<noun>::type::group: | ||
| 265 | { | ||
| 266 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 267 | |||
| 268 | std::list<std::string> clauses; | ||
| 269 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 270 | return recur(f2, truelogic); | ||
| 271 | }); | ||
| 272 | |||
| 273 | if (truelogic == f.get_orlogic()) | ||
| 274 | { | ||
| 275 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 276 | } else { | ||
| 277 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 278 | } | ||
| 279 | } | ||
| 280 | } | ||
| 281 | }; | ||
| 282 | |||
| 283 | cond << recur(_variant_of, _variant_of.get_notlogic()); | ||
| 284 | cond << ")"; | ||
| 285 | conditions.push_back(cond.str()); | ||
| 286 | } | ||
| 287 | |||
| 288 | if (_is_antonymic) | ||
| 289 | { | ||
| 290 | conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy)"); | ||
| 291 | } | ||
| 292 | |||
| 293 | if (!_antonym_of.empty()) | ||
| 294 | { | ||
| 295 | std::stringstream cond; | ||
| 296 | if (_antonym_of.get_notlogic()) | ||
| 297 | { | ||
| 298 | cond << "adjective_id NOT IN"; | ||
| 299 | } else { | ||
| 300 | cond << "adjective_id IN"; | ||
| 301 | } | ||
| 302 | |||
| 303 | cond << "(SELECT adjective_2_id FROM adjective_antonymy WHERE "; | ||
| 304 | |||
| 305 | std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string { | ||
| 306 | switch (f.get_type()) | ||
| 307 | { | ||
| 308 | case filter<adjective>::type::singleton: | ||
| 309 | { | ||
| 310 | if (notlogic == f.get_notlogic()) | ||
| 311 | { | ||
| 312 | return "adjective_1_id = @ANTID"; | ||
| 313 | } else { | ||
| 314 | return "adjective_1_id != @ANTID"; | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | case filter<adjective>::type::group: | ||
| 319 | { | ||
| 320 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 321 | |||
| 322 | std::list<std::string> clauses; | ||
| 323 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) { | ||
| 324 | return recur(f2, truelogic); | ||
| 325 | }); | ||
| 326 | |||
| 327 | if (truelogic == f.get_orlogic()) | ||
| 328 | { | ||
| 329 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 330 | } else { | ||
| 331 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 332 | } | ||
| 333 | } | ||
| 334 | } | ||
| 335 | }; | ||
| 336 | |||
| 337 | cond << recur(_antonym_of, _antonym_of.get_notlogic()); | ||
| 338 | cond << ")"; | ||
| 339 | conditions.push_back(cond.str()); | ||
| 340 | } | ||
| 341 | |||
| 342 | if (_is_synonymic) | ||
| 343 | { | ||
| 344 | conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy)"); | ||
| 345 | } | ||
| 346 | |||
| 347 | if (!_synonym_of.empty()) | ||
| 348 | { | ||
| 349 | std::stringstream cond; | ||
| 350 | if (_synonym_of.get_notlogic()) | ||
| 351 | { | ||
| 352 | cond << "adjective_id NOT IN"; | ||
| 353 | } else { | ||
| 354 | cond << "adjective_id IN"; | ||
| 355 | } | ||
| 356 | |||
| 357 | cond << "(SELECT adjective_2_id FROM adjective_synonymy WHERE "; | ||
| 358 | |||
| 359 | std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string { | ||
| 360 | switch (f.get_type()) | ||
| 361 | { | ||
| 362 | case filter<adjective>::type::singleton: | ||
| 363 | { | ||
| 364 | if (notlogic == f.get_notlogic()) | ||
| 365 | { | ||
| 366 | return "adjective_1_id = @SYNID"; | ||
| 367 | } else { | ||
| 368 | return "adjective_1_id != @SYNID"; | ||
| 369 | } | ||
| 370 | } | ||
| 371 | |||
| 372 | case filter<adjective>::type::group: | ||
| 373 | { | ||
| 374 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 375 | |||
| 376 | std::list<std::string> clauses; | ||
| 377 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) { | ||
| 378 | return recur(f2, truelogic); | ||
| 379 | }); | ||
| 380 | |||
| 381 | if (truelogic == f.get_orlogic()) | ||
| 382 | { | ||
| 383 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 384 | } else { | ||
| 385 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 386 | } | ||
| 387 | } | ||
| 388 | } | ||
| 389 | }; | ||
| 390 | |||
| 391 | cond << recur(_synonym_of, _synonym_of.get_notlogic()); | ||
| 392 | cond << ")"; | ||
| 393 | conditions.push_back(cond.str()); | ||
| 394 | } | ||
| 395 | |||
| 396 | if (_is_generalization) | ||
| 397 | { | ||
| 398 | conditions.push_back("adjective_id IN (SELECT general_id FROM specification)"); | ||
| 399 | } | ||
| 400 | |||
| 401 | if (!_generalization_of.empty()) | ||
| 402 | { | ||
| 403 | std::stringstream cond; | ||
| 404 | if (_generalization_of.get_notlogic()) | ||
| 405 | { | ||
| 406 | cond << "adjective_id NOT IN"; | ||
| 407 | } else { | ||
| 408 | cond << "adjective_id IN"; | ||
| 409 | } | ||
| 410 | |||
| 411 | cond << "(SELECT general_id FROM specification WHERE "; | ||
| 412 | |||
| 413 | std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string { | ||
| 414 | switch (f.get_type()) | ||
| 415 | { | ||
| 416 | case filter<adjective>::type::singleton: | ||
| 417 | { | ||
| 418 | if (notlogic == f.get_notlogic()) | ||
| 419 | { | ||
| 420 | return "specific_id = @SPECID"; | ||
| 421 | } else { | ||
| 422 | return "specific_id != @SPECID"; | ||
| 423 | } | ||
| 424 | } | ||
| 425 | |||
| 426 | case filter<adjective>::type::group: | ||
| 427 | { | ||
| 428 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 429 | |||
| 430 | std::list<std::string> clauses; | ||
| 431 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) { | ||
| 432 | return recur(f2, truelogic); | ||
| 433 | }); | ||
| 434 | |||
| 435 | if (truelogic == f.get_orlogic()) | ||
| 436 | { | ||
| 437 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 438 | } else { | ||
| 439 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 440 | } | ||
| 441 | } | ||
| 442 | } | ||
| 443 | }; | ||
| 444 | |||
| 445 | cond << recur(_generalization_of, _generalization_of.get_notlogic()); | ||
| 446 | cond << ")"; | ||
| 447 | conditions.push_back(cond.str()); | ||
| 448 | } | ||
| 449 | |||
| 450 | if (_is_specification) | ||
| 451 | { | ||
| 452 | conditions.push_back("adjective_id IN (SELECT specific_id FROM specification)"); | ||
| 453 | } | ||
| 454 | |||
| 455 | if (!_specification_of.empty()) | ||
| 456 | { | ||
| 457 | std::stringstream cond; | ||
| 458 | if (_specification_of.get_notlogic()) | ||
| 459 | { | ||
| 460 | cond << "adjective_id NOT IN"; | ||
| 461 | } else { | ||
| 462 | cond << "adjective_id IN"; | ||
| 463 | } | ||
| 464 | |||
| 465 | cond << "(SELECT specific_id FROM specification WHERE "; | ||
| 466 | |||
| 467 | std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string { | ||
| 468 | switch (f.get_type()) | ||
| 469 | { | ||
| 470 | case filter<adjective>::type::singleton: | ||
| 471 | { | ||
| 472 | if (notlogic == f.get_notlogic()) | ||
| 473 | { | ||
| 474 | return "general_id = @GENID"; | ||
| 475 | } else { | ||
| 476 | return "general_id != @GENID"; | ||
| 477 | } | ||
| 478 | } | ||
| 479 | |||
| 480 | case filter<adjective>::type::group: | ||
| 481 | { | ||
| 482 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 483 | |||
| 484 | std::list<std::string> clauses; | ||
| 485 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) { | ||
| 486 | return recur(f2, truelogic); | ||
| 487 | }); | ||
| 488 | |||
| 489 | if (truelogic == f.get_orlogic()) | ||
| 490 | { | ||
| 491 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 492 | } else { | ||
| 493 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 494 | } | ||
| 495 | } | ||
| 496 | } | ||
| 497 | }; | ||
| 498 | |||
| 499 | cond << recur(_specification_of, _specification_of.get_notlogic()); | ||
| 500 | cond << ")"; | ||
| 501 | conditions.push_back(cond.str()); | ||
| 502 | } | ||
| 503 | |||
| 504 | if (_is_pertainymic) | ||
| 505 | { | ||
| 506 | conditions.push_back("adjective_id IN (SELECT pertainym_id FROM pertainymy)"); | ||
| 507 | } | ||
| 508 | |||
| 509 | if (!_pertainym_of.empty()) | ||
| 510 | { | ||
| 511 | std::stringstream cond; | ||
| 512 | if (_pertainym_of.get_notlogic()) | ||
| 513 | { | ||
| 514 | cond << "adjective_id NOT IN"; | ||
| 515 | } else { | ||
| 516 | cond << "adjective_id IN"; | ||
| 517 | } | ||
| 518 | |||
| 519 | cond << "(SELECT pertainym_id FROM pertainymy WHERE "; | ||
| 520 | |||
| 521 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 522 | switch (f.get_type()) | ||
| 523 | { | ||
| 524 | case filter<noun>::type::singleton: | ||
| 525 | { | ||
| 526 | if (notlogic == f.get_notlogic()) | ||
| 527 | { | ||
| 528 | return "noun_id = @APERID"; | ||
| 529 | } else { | ||
| 530 | return "noun_id != @APERID"; | ||
| 531 | } | ||
| 532 | } | ||
| 533 | |||
| 534 | case filter<noun>::type::group: | ||
| 535 | { | ||
| 536 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 537 | |||
| 538 | std::list<std::string> clauses; | ||
| 539 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 540 | return recur(f2, truelogic); | ||
| 541 | }); | ||
| 542 | |||
| 543 | if (truelogic == f.get_orlogic()) | ||
| 544 | { | ||
| 545 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 546 | } else { | ||
| 547 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 548 | } | ||
| 549 | } | ||
| 550 | } | ||
| 551 | }; | ||
| 552 | |||
| 553 | cond << recur(_pertainym_of, _pertainym_of.get_notlogic()); | ||
| 554 | cond << ")"; | ||
| 555 | conditions.push_back(cond.str()); | ||
| 556 | } | ||
| 557 | |||
| 558 | if (_is_mannernymic) | ||
| 559 | { | ||
| 560 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM mannernymy)"); | ||
| 561 | } | ||
| 562 | |||
| 563 | if (!_anti_mannernym_of.empty()) | ||
| 564 | { | ||
| 565 | std::stringstream cond; | ||
| 566 | if (_anti_mannernym_of.get_notlogic()) | ||
| 567 | { | ||
| 568 | cond << "adjective_id NOT IN"; | ||
| 569 | } else { | ||
| 570 | cond << "adjective_id IN"; | ||
| 571 | } | ||
| 572 | |||
| 573 | cond << "(SELECT adjective_id FROM mannernymy WHERE "; | ||
| 574 | |||
| 575 | std::function<std::string (filter<adverb>, bool)> recur = [&] (filter<adverb> f, bool notlogic) -> std::string { | ||
| 576 | switch (f.get_type()) | ||
| 577 | { | ||
| 578 | case filter<adverb>::type::singleton: | ||
| 579 | { | ||
| 580 | if (notlogic == f.get_notlogic()) | ||
| 581 | { | ||
| 582 | return "mannernym_id = @MANID"; | ||
| 583 | } else { | ||
| 584 | return "mannernym_id != @MANID"; | ||
| 585 | } | ||
| 586 | } | ||
| 587 | |||
| 588 | case filter<adverb>::type::group: | ||
| 589 | { | ||
| 590 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 591 | |||
| 592 | std::list<std::string> clauses; | ||
| 593 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adverb> f2) { | ||
| 594 | return recur(f2, truelogic); | ||
| 595 | }); | ||
| 596 | |||
| 597 | if (truelogic == f.get_orlogic()) | ||
| 598 | { | ||
| 599 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 600 | } else { | ||
| 601 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 602 | } | ||
| 603 | } | ||
| 604 | } | ||
| 605 | }; | ||
| 606 | |||
| 607 | cond << recur(_anti_mannernym_of, _anti_mannernym_of.get_notlogic()); | ||
| 608 | cond << ")"; | ||
| 609 | conditions.push_back(cond.str()); | ||
| 610 | } | ||
| 611 | /* | ||
| 612 | if (!_derived_from_adjective.empty()) | ||
| 613 | { | ||
| 614 | std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_2_id = @DERADJ"); | ||
| 615 | std::string cond = "adjective_id IN (SELECT adjective_1_id FROM adjective_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 616 | conditions.push_back(cond); | ||
| 617 | } | ||
| 618 | |||
| 619 | if (!_not_derived_from_adjective.empty()) | ||
| 620 | { | ||
| 621 | std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_2_id = @NDERADJ"); | ||
| 622 | 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 ") + ")"; | ||
| 623 | conditions.push_back(cond); | ||
| 624 | } | ||
| 625 | |||
| 626 | if (!_derived_from_adverb.empty()) | ||
| 627 | { | ||
| 628 | std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_id = @DERADV"); | ||
| 629 | std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 630 | conditions.push_back(cond); | ||
| 631 | } | ||
| 632 | |||
| 633 | if (!_not_derived_from_adverb.empty()) | ||
| 634 | { | ||
| 635 | std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_id = @NDERADV"); | ||
| 636 | std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 637 | conditions.push_back(cond); | ||
| 638 | } | ||
| 639 | |||
| 640 | if (!_derived_from_noun.empty()) | ||
| 641 | { | ||
| 642 | std::list<std::string> clauses(_derived_from_noun.size(), "noun_id = @DERN"); | ||
| 643 | std::string cond = "adjective_id IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 644 | conditions.push_back(cond); | ||
| 645 | } | ||
| 646 | |||
| 647 | if (!_not_derived_from_noun.empty()) | ||
| 648 | { | ||
| 649 | std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_id = @NDERN"); | ||
| 650 | std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 651 | conditions.push_back(cond); | ||
| 652 | }*/ | ||
| 653 | |||
| 654 | if (!conditions.empty()) | ||
| 655 | { | ||
| 656 | construct << " WHERE "; | ||
| 657 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
| 658 | } | ||
| 659 | |||
| 660 | if (_random) | ||
| 661 | { | ||
| 662 | construct << " ORDER BY RANDOM()"; | ||
| 663 | } | ||
| 664 | |||
| 665 | if (_limit != unlimited) | ||
| 666 | { | ||
| 667 | construct << " LIMIT " << _limit; | ||
| 668 | } | ||
| 669 | |||
| 670 | sqlite3_stmt* ppstmt; | ||
| 671 | std::string query = construct.str(); | ||
| 672 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 673 | { | ||
| 674 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 675 | } | ||
| 676 | |||
| 677 | if (!_rhymes.empty()) | ||
| 678 | { | ||
| 679 | int i = 0; | ||
| 680 | for (auto rhyme : _rhymes) | ||
| 681 | { | ||
| 682 | std::string rhymer = "%" + rhyme; | ||
| 683 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
| 684 | |||
| 685 | i++; | ||
| 686 | } | ||
| 687 | } | ||
| 688 | |||
| 689 | for (auto except : _except) | ||
| 690 | { | ||
| 691 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
| 692 | } | ||
| 693 | |||
| 694 | for (auto attribute : _variant_of.inorder_flatten()) | ||
| 695 | { | ||
| 696 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id); | ||
| 697 | } | ||
| 698 | |||
| 699 | for (auto antonym : _antonym_of.inorder_flatten()) | ||
| 700 | { | ||
| 701 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
| 702 | } | ||
| 703 | |||
| 704 | for (auto synonym : _synonym_of.inorder_flatten()) | ||
| 705 | { | ||
| 706 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
| 707 | } | ||
| 708 | |||
| 709 | for (auto specific : _generalization_of.inorder_flatten()) | ||
| 710 | { | ||
| 711 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SPECID"), specific._id); | ||
| 712 | } | ||
| 713 | |||
| 714 | for (auto general : _specification_of.inorder_flatten()) | ||
| 715 | { | ||
| 716 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GENID"), general._id); | ||
| 717 | } | ||
| 718 | |||
| 719 | for (auto n : _pertainym_of.inorder_flatten()) | ||
| 720 | { | ||
| 721 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@APERID"), n._id); | ||
| 722 | } | ||
| 723 | |||
| 724 | for (auto mannernym : _anti_mannernym_of.inorder_flatten()) | ||
| 725 | { | ||
| 726 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MANID"), mannernym._id); | ||
| 727 | } | ||
| 728 | /* | ||
| 729 | for (auto adj : _derived_from_adjective) | ||
| 730 | { | ||
| 731 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id); | ||
| 732 | } | ||
| 733 | |||
| 734 | for (auto adj : _not_derived_from_adjective) | ||
| 735 | { | ||
| 736 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id); | ||
| 737 | } | ||
| 738 | |||
| 739 | for (auto adv : _derived_from_adverb) | ||
| 740 | { | ||
| 741 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id); | ||
| 742 | } | ||
| 743 | |||
| 744 | for (auto adv : _not_derived_from_adverb) | ||
| 745 | { | ||
| 746 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id); | ||
| 747 | } | ||
| 748 | |||
| 749 | for (auto n : _derived_from_noun) | ||
| 750 | { | ||
| 751 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id); | ||
| 752 | } | ||
| 753 | |||
| 754 | for (auto n : _not_derived_from_noun) | ||
| 755 | { | ||
| 756 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id); | ||
| 757 | } | ||
| 758 | */ | ||
| 759 | std::list<adjective> output; | ||
| 760 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 761 | { | ||
| 762 | adjective tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
| 763 | tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
| 764 | |||
| 765 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
| 766 | { | ||
| 767 | tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
| 768 | } | ||
| 769 | |||
| 770 | if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) | ||
| 771 | { | ||
| 772 | tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
| 773 | } | ||
| 774 | |||
| 775 | if (sqlite3_column_type(ppstmt, 4) != SQLITE_NULL) | ||
| 776 | { | ||
| 777 | std::string adjpos(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 4))); | ||
| 778 | if (adjpos == "p") | ||
| 779 | { | ||
| 780 | tnc._position = adjective::positioning::predicate; | ||
| 781 | } else if (adjpos == "a") | ||
| 782 | { | ||
| 783 | tnc._position = adjective::positioning::attributive; | ||
| 784 | } else if (adjpos == "i") | ||
| 785 | { | ||
| 786 | tnc._position = adjective::positioning::postnominal; | ||
| 787 | } | ||
| 788 | } | ||
| 789 | |||
| 790 | output.push_back(tnc); | ||
| 791 | } | ||
| 792 | |||
| 793 | sqlite3_finalize(ppstmt); | ||
| 794 | |||
| 795 | for (auto& adjective : output) | ||
| 796 | { | ||
| 797 | query = "SELECT pronunciation FROM adjective_pronunciations WHERE adjective_id = ?"; | ||
| 798 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 799 | { | ||
| 800 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 801 | } | ||
| 802 | |||
| 803 | sqlite3_bind_int(ppstmt, 1, adjective._id); | ||
| 804 | |||
| 805 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 806 | { | ||
| 807 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
| 808 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
| 809 | |||
| 810 | adjective.pronunciations.push_back(phonemes); | ||
| 811 | } | ||
| 812 | |||
| 813 | sqlite3_finalize(ppstmt); | ||
| 814 | } | ||
| 815 | |||
| 816 | return output; | ||
| 817 | } | ||
| 818 | |||
| 819 | }; | ||
| diff --git a/lib/adjective_query.h b/lib/adjective_query.h new file mode 100644 index 0000000..e7755cb --- /dev/null +++ b/lib/adjective_query.h | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | #ifndef ADJECTIVE_QUERY_H_05E590FD | ||
| 2 | #define ADJECTIVE_QUERY_H_05E590FD | ||
| 3 | |||
| 4 | namespace verbly { | ||
| 5 | |||
| 6 | class adjective_query { | ||
| 7 | public: | ||
| 8 | adjective_query(const data& _data); | ||
| 9 | |||
| 10 | adjective_query& limit(int _limit); | ||
| 11 | adjective_query& random(); | ||
| 12 | adjective_query& except(const adjective& _word); | ||
| 13 | adjective_query& rhymes_with(const word& _word); | ||
| 14 | adjective_query& has_pronunciation(); | ||
| 15 | |||
| 16 | adjective_query& requires_comparative_form(); | ||
| 17 | adjective_query& requires_superlative_form(); | ||
| 18 | adjective_query& position(adjective::positioning pos); | ||
| 19 | |||
| 20 | adjective_query& is_variant(); | ||
| 21 | adjective_query& variant_of(filter<noun> _f); | ||
| 22 | |||
| 23 | adjective_query& has_antonyms(); | ||
| 24 | adjective_query& antonym_of(filter<adjective> _f); | ||
| 25 | |||
| 26 | adjective_query& has_synonyms(); | ||
| 27 | adjective_query& synonym_of(filter<adjective> _f); | ||
| 28 | |||
| 29 | adjective_query& is_generalization(); | ||
| 30 | adjective_query& generalization_of(filter<adjective> _f); | ||
| 31 | |||
| 32 | adjective_query& is_specification(); | ||
| 33 | adjective_query& specification_of(filter<adjective> _f); | ||
| 34 | |||
| 35 | adjective_query& is_pertainymic(); | ||
| 36 | adjective_query& pertainym_of(filter<noun> _f); | ||
| 37 | |||
| 38 | adjective_query& is_mannernymic(); | ||
| 39 | adjective_query& anti_mannernym_of(filter<adverb> _f); | ||
| 40 | |||
| 41 | /* adjective_query& derived_from(const word& _w); | ||
| 42 | adjective_query& not_derived_from(const word& _w);*/ | ||
| 43 | |||
| 44 | std::list<adjective> run() const; | ||
| 45 | |||
| 46 | const static int unlimited = -1; | ||
| 47 | |||
| 48 | protected: | ||
| 49 | const data& _data; | ||
| 50 | int _limit = unlimited; | ||
| 51 | bool _random = false; | ||
| 52 | std::list<std::string> _rhymes; | ||
| 53 | std::list<adjective> _except; | ||
| 54 | bool _has_prn = false; | ||
| 55 | |||
| 56 | bool _requires_comparative_form = false; | ||
| 57 | bool _requires_superlative_form = false; | ||
| 58 | adjective::positioning _position = adjective::positioning::undefined; | ||
| 59 | |||
| 60 | bool _is_variant = false; | ||
| 61 | filter<noun> _variant_of; | ||
| 62 | |||
| 63 | bool _is_antonymic = false; | ||
| 64 | filter<adjective> _antonym_of; | ||
| 65 | |||
| 66 | bool _is_synonymic = false; | ||
| 67 | filter<adjective> _synonym_of; | ||
| 68 | |||
| 69 | bool _is_generalization = false; | ||
| 70 | filter<adjective> _generalization_of; | ||
| 71 | |||
| 72 | bool _is_specification = false; | ||
| 73 | filter<adjective> _specification_of; | ||
| 74 | |||
| 75 | bool _is_pertainymic = false; | ||
| 76 | filter<noun> _pertainym_of; | ||
| 77 | |||
| 78 | bool _is_mannernymic = false; | ||
| 79 | filter<adverb> _anti_mannernym_of; | ||
| 80 | |||
| 81 | /* std::list<adjective> _derived_from_adjective; | ||
| 82 | std::list<adjective> _not_derived_from_adjective; | ||
| 83 | std::list<adverb> _derived_from_adverb; | ||
| 84 | std::list<adverb> _not_derived_from_adverb; | ||
| 85 | std::list<noun> _derived_from_noun; | ||
| 86 | std::list<noun> _not_derived_from_noun;*/ | ||
| 87 | }; | ||
| 88 | |||
| 89 | }; | ||
| 90 | |||
| 91 | #endif /* end of include guard: ADJECTIVE_QUERY_H_05E590FD */ | ||
| diff --git a/lib/adverb.cpp b/lib/adverb.cpp index 8fcddad..442574e 100644 --- a/lib/adverb.cpp +++ b/lib/adverb.cpp | |||
| @@ -2,6 +2,11 @@ | |||
| 2 | 2 | ||
| 3 | namespace verbly { | 3 | namespace verbly { |
| 4 | 4 | ||
| 5 | adverb::adverb() | ||
| 6 | { | ||
| 7 | |||
| 8 | } | ||
| 9 | |||
| 5 | adverb::adverb(const data& _data, int _id) : word(_data, _id) | 10 | adverb::adverb(const data& _data, int _id) : word(_data, _id) |
| 6 | { | 11 | { |
| 7 | 12 | ||
| @@ -9,460 +14,58 @@ namespace verbly { | |||
| 9 | 14 | ||
| 10 | std::string adverb::base_form() const | 15 | std::string adverb::base_form() const |
| 11 | { | 16 | { |
| 17 | assert(_valid == true); | ||
| 18 | |||
| 12 | return _base_form; | 19 | return _base_form; |
| 13 | } | 20 | } |
| 14 | 21 | ||
| 15 | std::string adverb::comparative_form() const | 22 | std::string adverb::comparative_form() const |
| 16 | { | 23 | { |
| 24 | assert(_valid == true); | ||
| 25 | |||
| 17 | return _comparative_form; | 26 | return _comparative_form; |
| 18 | } | 27 | } |
| 19 | 28 | ||
| 20 | std::string adverb::superlative_form() const | 29 | std::string adverb::superlative_form() const |
| 21 | { | 30 | { |
| 31 | assert(_valid == true); | ||
| 32 | |||
| 22 | return _superlative_form; | 33 | return _superlative_form; |
| 23 | } | 34 | } |
| 24 | 35 | ||
| 25 | bool adverb::has_comparative_form() const | 36 | bool adverb::has_comparative_form() const |
| 26 | { | 37 | { |
| 38 | assert(_valid == true); | ||
| 39 | |||
| 27 | return !_comparative_form.empty(); | 40 | return !_comparative_form.empty(); |
| 28 | } | 41 | } |
| 29 | 42 | ||
| 30 | bool adverb::has_superlative_form() const | 43 | bool adverb::has_superlative_form() const |
| 31 | { | 44 | { |
| 45 | assert(_valid == true); | ||
| 46 | |||
| 32 | return !_superlative_form.empty(); | 47 | return !_superlative_form.empty(); |
| 33 | } | 48 | } |
| 34 | 49 | ||
| 35 | adverb_query adverb::antonyms() const | 50 | adverb_query adverb::antonyms() const |
| 36 | { | 51 | { |
| 37 | return _data.adverbs().antonym_of(*this); | 52 | assert(_valid == true); |
| 38 | } | ||
| 39 | |||
| 40 | adverb_query adverb::synonyms() const | ||
| 41 | { | ||
| 42 | return _data.adverbs().synonym_of(*this); | ||
| 43 | } | ||
| 44 | |||
| 45 | adjective_query adverb::anti_mannernyms() const | ||
| 46 | { | ||
| 47 | return _data.adjectives().anti_mannernym_of(*this); | ||
| 48 | } | ||
| 49 | |||
| 50 | adverb_query::adverb_query(const data& _data) : _data(_data) | ||
| 51 | { | ||
| 52 | |||
| 53 | } | ||
| 54 | |||
| 55 | adverb_query& adverb_query::limit(int _limit) | ||
| 56 | { | ||
| 57 | if ((_limit > 0) || (_limit == unlimited)) | ||
| 58 | { | ||
| 59 | this->_limit = _limit; | ||
| 60 | } | ||
| 61 | |||
| 62 | return *this; | ||
| 63 | } | ||
| 64 | |||
| 65 | adverb_query& adverb_query::random(bool _random) | ||
| 66 | { | ||
| 67 | this->_random = _random; | ||
| 68 | |||
| 69 | return *this; | ||
| 70 | } | ||
| 71 | |||
| 72 | adverb_query& adverb_query::except(const adverb& _word) | ||
| 73 | { | ||
| 74 | _except.push_back(_word); | ||
| 75 | 53 | ||
| 76 | return *this; | 54 | return _data->adverbs().antonym_of(*this); |
| 77 | } | 55 | } |
| 78 | 56 | ||
| 79 | adverb_query& adverb_query::rhymes_with(const word& _word) | 57 | adverb_query adverb::synonyms() const |
| 80 | { | ||
| 81 | for (auto rhyme : _word.rhyme_phonemes()) | ||
| 82 | { | ||
| 83 | _rhymes.push_back(rhyme); | ||
| 84 | } | ||
| 85 | |||
| 86 | if (dynamic_cast<const adverb*>(&_word) != nullptr) | ||
| 87 | { | ||
| 88 | _except.push_back(dynamic_cast<const adverb&>(_word)); | ||
| 89 | } | ||
| 90 | |||
| 91 | return *this; | ||
| 92 | } | ||
| 93 | |||
| 94 | adverb_query& adverb_query::has_pronunciation(bool _has_prn) | ||
| 95 | { | ||
| 96 | this->_has_prn = _has_prn; | ||
| 97 | |||
| 98 | return *this; | ||
| 99 | } | ||
| 100 | |||
| 101 | adverb_query& adverb_query::requires_comparative_form(bool _arg) | ||
| 102 | { | ||
| 103 | _requires_comparative_form = _arg; | ||
| 104 | |||
| 105 | return *this; | ||
| 106 | } | ||
| 107 | |||
| 108 | adverb_query& adverb_query::requires_superlative_form(bool _arg) | ||
| 109 | { | ||
| 110 | _requires_superlative_form = _arg; | ||
| 111 | |||
| 112 | return *this; | ||
| 113 | } | ||
| 114 | |||
| 115 | adverb_query& adverb_query::has_antonyms(bool _arg) | ||
| 116 | { | ||
| 117 | _has_antonyms = _arg; | ||
| 118 | |||
| 119 | return *this; | ||
| 120 | } | ||
| 121 | |||
| 122 | adverb_query& adverb_query::antonym_of(const adverb& _adv) | ||
| 123 | { | ||
| 124 | _antonym_of.push_back(_adv); | ||
| 125 | |||
| 126 | return *this; | ||
| 127 | } | ||
| 128 | |||
| 129 | adverb_query& adverb_query::not_antonym_of(const adverb& _adv) | ||
| 130 | { | ||
| 131 | _not_antonym_of.push_back(_adv); | ||
| 132 | |||
| 133 | return *this; | ||
| 134 | } | ||
| 135 | |||
| 136 | adverb_query& adverb_query::has_synonyms(bool _arg) | ||
| 137 | { | ||
| 138 | _has_synonyms = _arg; | ||
| 139 | |||
| 140 | return *this; | ||
| 141 | } | ||
| 142 | |||
| 143 | adverb_query& adverb_query::synonym_of(const adverb& _adv) | ||
| 144 | { | ||
| 145 | _synonym_of.push_back(_adv); | ||
| 146 | |||
| 147 | return *this; | ||
| 148 | } | ||
| 149 | |||
| 150 | adverb_query& adverb_query::not_synonym_of(const adverb& _adv) | ||
| 151 | { | ||
| 152 | _not_synonym_of.push_back(_adv); | ||
| 153 | |||
| 154 | return *this; | ||
| 155 | } | ||
| 156 | |||
| 157 | adverb_query& adverb_query::is_mannernymic(bool _arg) | ||
| 158 | { | ||
| 159 | _is_mannernymic = _arg; | ||
| 160 | |||
| 161 | return *this; | ||
| 162 | } | ||
| 163 | |||
| 164 | adverb_query& adverb_query::mannernym_of(const adjective& _adj) | ||
| 165 | { | ||
| 166 | _mannernym_of.push_back(_adj); | ||
| 167 | |||
| 168 | return *this; | ||
| 169 | } | ||
| 170 | |||
| 171 | adverb_query& adverb_query::derived_from(const word& _w) | ||
| 172 | { | ||
| 173 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | ||
| 174 | { | ||
| 175 | _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 176 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 177 | { | ||
| 178 | _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 179 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 180 | { | ||
| 181 | _derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 182 | } | ||
| 183 | |||
| 184 | return *this; | ||
| 185 | } | ||
| 186 | |||
| 187 | adverb_query& adverb_query::not_derived_from(const word& _w) | ||
| 188 | { | 58 | { |
| 189 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | 59 | assert(_valid == true); |
| 190 | { | ||
| 191 | _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 192 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 193 | { | ||
| 194 | _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 195 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 196 | { | ||
| 197 | _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 198 | } | ||
| 199 | 60 | ||
| 200 | return *this; | 61 | return _data->adverbs().synonym_of(*this); |
| 201 | } | 62 | } |
| 202 | 63 | ||
| 203 | std::list<adverb> adverb_query::run() const | 64 | adjective_query adverb::anti_mannernyms() const |
| 204 | { | 65 | { |
| 205 | std::stringstream construct; | 66 | assert(_valid == true); |
| 206 | construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs"; | ||
| 207 | std::list<std::string> conditions; | ||
| 208 | |||
| 209 | if (_has_prn) | ||
| 210 | { | ||
| 211 | conditions.push_back("adverb_id IN (SELECT adverb_id FROM adverb_pronunciations)"); | ||
| 212 | } | ||
| 213 | |||
| 214 | if (!_rhymes.empty()) | ||
| 215 | { | ||
| 216 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
| 217 | std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 218 | conditions.push_back(cond); | ||
| 219 | } | ||
| 220 | |||
| 221 | for (auto except : _except) | ||
| 222 | { | ||
| 223 | conditions.push_back("adverb_id != @EXCID"); | ||
| 224 | } | ||
| 225 | |||
| 226 | if (_requires_comparative_form) | ||
| 227 | { | ||
| 228 | conditions.push_back("comparative IS NOT NULL"); | ||
| 229 | } | ||
| 230 | |||
| 231 | if (_requires_superlative_form) | ||
| 232 | { | ||
| 233 | conditions.push_back("superlative IS NOT NULL"); | ||
| 234 | } | ||
| 235 | |||
| 236 | if (_has_antonyms) | ||
| 237 | { | ||
| 238 | conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)"); | ||
| 239 | } | ||
| 240 | |||
| 241 | if (!_antonym_of.empty()) | ||
| 242 | { | ||
| 243 | std::list<std::string> clauses(_antonym_of.size(), "adverb_1_id = @ANTID"); | ||
| 244 | std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 245 | conditions.push_back(cond); | ||
| 246 | } | ||
| 247 | |||
| 248 | if (!_not_antonym_of.empty()) | ||
| 249 | { | ||
| 250 | std::list<std::string> clauses(_not_antonym_of.size(), "adverb_1_id = @NANTID"); | ||
| 251 | std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 252 | conditions.push_back(cond); | ||
| 253 | } | ||
| 254 | |||
| 255 | if (_has_synonyms) | ||
| 256 | { | ||
| 257 | conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy)"); | ||
| 258 | } | ||
| 259 | 67 | ||
| 260 | if (!_synonym_of.empty()) | 68 | return _data->adjectives().anti_mannernym_of(*this); |
| 261 | { | ||
| 262 | std::list<std::string> clauses(_synonym_of.size(), "adverb_1_id = @SYNID"); | ||
| 263 | std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 264 | conditions.push_back(cond); | ||
| 265 | } | ||
| 266 | |||
| 267 | if (!_not_synonym_of.empty()) | ||
| 268 | { | ||
| 269 | std::list<std::string> clauses(_not_synonym_of.size(), "adverb_1_id = @NSYNID"); | ||
| 270 | std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 271 | conditions.push_back(cond); | ||
| 272 | } | ||
| 273 | |||
| 274 | if (_is_mannernymic) | ||
| 275 | { | ||
| 276 | conditions.push_back("adverb_id IN (SELECT mannernym_id FROM mannernymy)"); | ||
| 277 | } | ||
| 278 | |||
| 279 | if (!_mannernym_of.empty()) | ||
| 280 | { | ||
| 281 | std::list<std::string> clauses(_mannernym_of.size(), "adjective_id = @AMANID"); | ||
| 282 | std::string cond = "adverb_id IN (SELECT mannernym_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 283 | conditions.push_back(cond); | ||
| 284 | } | ||
| 285 | |||
| 286 | if (!_derived_from_adjective.empty()) | ||
| 287 | { | ||
| 288 | std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_id = @DERADJ"); | ||
| 289 | std::string cond = "adverb_id IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 290 | conditions.push_back(cond); | ||
| 291 | } | ||
| 292 | |||
| 293 | if (!_not_derived_from_adjective.empty()) | ||
| 294 | { | ||
| 295 | std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_id = @NDERADJ"); | ||
| 296 | std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 297 | conditions.push_back(cond); | ||
| 298 | } | ||
| 299 | |||
| 300 | if (!_derived_from_adverb.empty()) | ||
| 301 | { | ||
| 302 | std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_2_id = @DERADV"); | ||
| 303 | std::string cond = "adverb_id IN (SELECT adverb_1_id FROM adverb_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 304 | conditions.push_back(cond); | ||
| 305 | } | ||
| 306 | |||
| 307 | if (!_not_derived_from_adverb.empty()) | ||
| 308 | { | ||
| 309 | std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_2_id = @NDERADV"); | ||
| 310 | 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 ") + ")"; | ||
| 311 | conditions.push_back(cond); | ||
| 312 | } | ||
| 313 | |||
| 314 | if (!_derived_from_noun.empty()) | ||
| 315 | { | ||
| 316 | std::list<std::string> clauses(_derived_from_noun.size(), "noun_id = @DERN"); | ||
| 317 | std::string cond = "adverb_id IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 318 | conditions.push_back(cond); | ||
| 319 | } | ||
| 320 | |||
| 321 | if (!_not_derived_from_noun.empty()) | ||
| 322 | { | ||
| 323 | std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_id = @NDERN"); | ||
| 324 | std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 325 | conditions.push_back(cond); | ||
| 326 | } | ||
| 327 | |||
| 328 | if (!conditions.empty()) | ||
| 329 | { | ||
| 330 | construct << " WHERE "; | ||
| 331 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
| 332 | } | ||
| 333 | |||
| 334 | if (_random) | ||
| 335 | { | ||
| 336 | construct << " ORDER BY RANDOM()"; | ||
| 337 | } | ||
| 338 | |||
| 339 | if (_limit != unlimited) | ||
| 340 | { | ||
| 341 | construct << " LIMIT " << _limit; | ||
| 342 | } | ||
| 343 | |||
| 344 | sqlite3_stmt* ppstmt; | ||
| 345 | std::string query = construct.str(); | ||
| 346 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 347 | { | ||
| 348 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 349 | } | ||
| 350 | |||
| 351 | if (!_rhymes.empty()) | ||
| 352 | { | ||
| 353 | int i = 0; | ||
| 354 | for (auto rhyme : _rhymes) | ||
| 355 | { | ||
| 356 | std::string rhymer = "%" + rhyme; | ||
| 357 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
| 358 | |||
| 359 | i++; | ||
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 | for (auto except : _except) | ||
| 364 | { | ||
| 365 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
| 366 | } | ||
| 367 | |||
| 368 | for (auto antonym : _antonym_of) | ||
| 369 | { | ||
| 370 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
| 371 | } | ||
| 372 | |||
| 373 | for (auto antonym : _not_antonym_of) | ||
| 374 | { | ||
| 375 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); | ||
| 376 | } | ||
| 377 | |||
| 378 | for (auto synonym : _synonym_of) | ||
| 379 | { | ||
| 380 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
| 381 | } | ||
| 382 | |||
| 383 | for (auto synonym : _not_synonym_of) | ||
| 384 | { | ||
| 385 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); | ||
| 386 | } | ||
| 387 | |||
| 388 | for (auto adj : _mannernym_of) | ||
| 389 | { | ||
| 390 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id); | ||
| 391 | } | ||
| 392 | |||
| 393 | for (auto adj : _derived_from_adjective) | ||
| 394 | { | ||
| 395 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id); | ||
| 396 | } | ||
| 397 | |||
| 398 | for (auto adj : _not_derived_from_adjective) | ||
| 399 | { | ||
| 400 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id); | ||
| 401 | } | ||
| 402 | |||
| 403 | for (auto adv : _derived_from_adverb) | ||
| 404 | { | ||
| 405 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id); | ||
| 406 | } | ||
| 407 | |||
| 408 | for (auto adv : _not_derived_from_adverb) | ||
| 409 | { | ||
| 410 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id); | ||
| 411 | } | ||
| 412 | |||
| 413 | for (auto n : _derived_from_noun) | ||
| 414 | { | ||
| 415 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id); | ||
| 416 | } | ||
| 417 | |||
| 418 | for (auto n : _not_derived_from_noun) | ||
| 419 | { | ||
| 420 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id); | ||
| 421 | } | ||
| 422 | |||
| 423 | std::list<adverb> output; | ||
| 424 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 425 | { | ||
| 426 | adverb tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
| 427 | tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
| 428 | |||
| 429 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
| 430 | { | ||
| 431 | tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
| 432 | } | ||
| 433 | |||
| 434 | if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) | ||
| 435 | { | ||
| 436 | tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
| 437 | } | ||
| 438 | |||
| 439 | output.push_back(tnc); | ||
| 440 | } | ||
| 441 | |||
| 442 | sqlite3_finalize(ppstmt); | ||
| 443 | |||
| 444 | for (auto& adverb : output) | ||
| 445 | { | ||
| 446 | query = "SELECT pronunciation FROM adverb_pronunciations WHERE adverb_id = ?"; | ||
| 447 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 448 | { | ||
| 449 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 450 | } | ||
| 451 | |||
| 452 | sqlite3_bind_int(ppstmt, 1, adverb._id); | ||
| 453 | |||
| 454 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 455 | { | ||
| 456 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
| 457 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
| 458 | |||
| 459 | adverb.pronunciations.push_back(phonemes); | ||
| 460 | } | ||
| 461 | |||
| 462 | sqlite3_finalize(ppstmt); | ||
| 463 | } | ||
| 464 | |||
| 465 | return output; | ||
| 466 | } | 69 | } |
| 467 | 70 | ||
| 468 | }; | 71 | }; |
| diff --git a/lib/adverb.h b/lib/adverb.h index 65e3c5c..56d4e28 100644 --- a/lib/adverb.h +++ b/lib/adverb.h | |||
| @@ -12,6 +12,7 @@ namespace verbly { | |||
| 12 | friend class adverb_query; | 12 | friend class adverb_query; |
| 13 | 13 | ||
| 14 | public: | 14 | public: |
| 15 | adverb(); | ||
| 15 | adverb(const data& _data, int _id); | 16 | adverb(const data& _data, int _id); |
| 16 | 17 | ||
| 17 | std::string base_form() const; | 18 | std::string base_form() const; |
| @@ -29,67 +30,6 @@ namespace verbly { | |||
| 29 | adverb_query& not_derived_from(const word& _w); | 30 | adverb_query& not_derived_from(const word& _w); |
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | class adverb_query { | ||
| 33 | public: | ||
| 34 | adverb_query(const data& _data); | ||
| 35 | |||
| 36 | adverb_query& limit(int _limit); | ||
| 37 | adverb_query& random(bool _random); | ||
| 38 | adverb_query& except(const adverb& _word); | ||
| 39 | adverb_query& rhymes_with(const word& _word); | ||
| 40 | adverb_query& has_pronunciation(bool _has_prn); | ||
| 41 | |||
| 42 | adverb_query& requires_comparative_form(bool _arg); | ||
| 43 | adverb_query& requires_superlative_form(bool _arg); | ||
| 44 | |||
| 45 | adverb_query& has_antonyms(bool _arg); | ||
| 46 | adverb_query& antonym_of(const adverb& _adv); | ||
| 47 | adverb_query& not_antonym_of(const adverb& _adv); | ||
| 48 | |||
| 49 | adverb_query& has_synonyms(bool _arg); | ||
| 50 | adverb_query& synonym_of(const adverb& _adv); | ||
| 51 | adverb_query& not_synonym_of(const adverb& _adv); | ||
| 52 | |||
| 53 | adverb_query& is_mannernymic(bool _arg); | ||
| 54 | adverb_query& mannernym_of(const adjective& _adj); | ||
| 55 | |||
| 56 | adverb_query& derived_from(const word& _w); | ||
| 57 | adverb_query& not_derived_from(const word& _w); | ||
| 58 | |||
| 59 | std::list<adverb> run() const; | ||
| 60 | |||
| 61 | const static int unlimited = -1; | ||
| 62 | |||
| 63 | private: | ||
| 64 | const data& _data; | ||
| 65 | int _limit = unlimited; | ||
| 66 | bool _random = false; | ||
| 67 | std::list<std::string> _rhymes; | ||
| 68 | std::list<adverb> _except; | ||
| 69 | bool _has_prn = false; | ||
| 70 | |||
| 71 | bool _requires_comparative_form = false; | ||
| 72 | bool _requires_superlative_form = false; | ||
| 73 | |||
| 74 | bool _has_antonyms = false; | ||
| 75 | std::list<adverb> _antonym_of; | ||
| 76 | std::list<adverb> _not_antonym_of; | ||
| 77 | |||
| 78 | bool _has_synonyms = false; | ||
| 79 | std::list<adverb> _synonym_of; | ||
| 80 | std::list<adverb> _not_synonym_of; | ||
| 81 | |||
| 82 | bool _is_mannernymic = false; | ||
| 83 | std::list<adjective> _mannernym_of; | ||
| 84 | |||
| 85 | std::list<adjective> _derived_from_adjective; | ||
| 86 | std::list<adjective> _not_derived_from_adjective; | ||
| 87 | std::list<adverb> _derived_from_adverb; | ||
| 88 | std::list<adverb> _not_derived_from_adverb; | ||
| 89 | std::list<noun> _derived_from_noun; | ||
| 90 | std::list<noun> _not_derived_from_noun; | ||
| 91 | }; | ||
| 92 | |||
| 93 | }; | 33 | }; |
| 94 | 34 | ||
| 95 | #endif /* end of include guard: ADVERB_H_86F8302F */ | 35 | #endif /* end of include guard: ADVERB_H_86F8302F */ |
| diff --git a/lib/adverb_query.cpp b/lib/adverb_query.cpp new file mode 100644 index 0000000..639f16f --- /dev/null +++ b/lib/adverb_query.cpp | |||
| @@ -0,0 +1,514 @@ | |||
| 1 | #include "verbly.h" | ||
| 2 | |||
| 3 | namespace verbly { | ||
| 4 | |||
| 5 | adverb_query::adverb_query(const data& _data) : _data(_data) | ||
| 6 | { | ||
| 7 | |||
| 8 | } | ||
| 9 | |||
| 10 | adverb_query& adverb_query::limit(int _limit) | ||
| 11 | { | ||
| 12 | if ((_limit > 0) || (_limit == unlimited)) | ||
| 13 | { | ||
| 14 | this->_limit = _limit; | ||
| 15 | } | ||
| 16 | |||
| 17 | return *this; | ||
| 18 | } | ||
| 19 | |||
| 20 | adverb_query& adverb_query::random() | ||
| 21 | { | ||
| 22 | this->_random = true; | ||
| 23 | |||
| 24 | return *this; | ||
| 25 | } | ||
| 26 | |||
| 27 | adverb_query& adverb_query::except(const adverb& _word) | ||
| 28 | { | ||
| 29 | _except.push_back(_word); | ||
| 30 | |||
| 31 | return *this; | ||
| 32 | } | ||
| 33 | |||
| 34 | adverb_query& adverb_query::rhymes_with(const word& _word) | ||
| 35 | { | ||
| 36 | for (auto rhyme : _word.rhyme_phonemes()) | ||
| 37 | { | ||
| 38 | _rhymes.push_back(rhyme); | ||
| 39 | } | ||
| 40 | |||
| 41 | if (dynamic_cast<const adverb*>(&_word) != nullptr) | ||
| 42 | { | ||
| 43 | _except.push_back(dynamic_cast<const adverb&>(_word)); | ||
| 44 | } | ||
| 45 | |||
| 46 | return *this; | ||
| 47 | } | ||
| 48 | |||
| 49 | adverb_query& adverb_query::has_pronunciation() | ||
| 50 | { | ||
| 51 | this->_has_prn = true; | ||
| 52 | |||
| 53 | return *this; | ||
| 54 | } | ||
| 55 | |||
| 56 | adverb_query& adverb_query::requires_comparative_form() | ||
| 57 | { | ||
| 58 | _requires_comparative_form = true; | ||
| 59 | |||
| 60 | return *this; | ||
| 61 | } | ||
| 62 | |||
| 63 | adverb_query& adverb_query::requires_superlative_form() | ||
| 64 | { | ||
| 65 | _requires_superlative_form = true; | ||
| 66 | |||
| 67 | return *this; | ||
| 68 | } | ||
| 69 | |||
| 70 | adverb_query& adverb_query::has_antonyms() | ||
| 71 | { | ||
| 72 | _has_antonyms = true; | ||
| 73 | |||
| 74 | return *this; | ||
| 75 | } | ||
| 76 | |||
| 77 | adverb_query& adverb_query::antonym_of(filter<adverb> _f) | ||
| 78 | { | ||
| 79 | _f.clean(); | ||
| 80 | _antonym_of = _f; | ||
| 81 | |||
| 82 | return *this; | ||
| 83 | } | ||
| 84 | |||
| 85 | adverb_query& adverb_query::has_synonyms() | ||
| 86 | { | ||
| 87 | _has_synonyms = true; | ||
| 88 | |||
| 89 | return *this; | ||
| 90 | } | ||
| 91 | |||
| 92 | adverb_query& adverb_query::synonym_of(filter<adverb> _f) | ||
| 93 | { | ||
| 94 | _f.clean(); | ||
| 95 | _synonym_of = _f; | ||
| 96 | |||
| 97 | return *this; | ||
| 98 | } | ||
| 99 | |||
| 100 | adverb_query& adverb_query::is_mannernymic() | ||
| 101 | { | ||
| 102 | _is_mannernymic = true; | ||
| 103 | |||
| 104 | return *this; | ||
| 105 | } | ||
| 106 | |||
| 107 | adverb_query& adverb_query::mannernym_of(filter<adjective> _f) | ||
| 108 | { | ||
| 109 | _f.clean(); | ||
| 110 | _mannernym_of = _f; | ||
| 111 | |||
| 112 | return *this; | ||
| 113 | } | ||
| 114 | /* | ||
| 115 | adverb_query& adverb_query::derived_from(const word& _w) | ||
| 116 | { | ||
| 117 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | ||
| 118 | { | ||
| 119 | _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 120 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 121 | { | ||
| 122 | _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 123 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 124 | { | ||
| 125 | _derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 126 | } | ||
| 127 | |||
| 128 | return *this; | ||
| 129 | } | ||
| 130 | |||
| 131 | adverb_query& adverb_query::not_derived_from(const word& _w) | ||
| 132 | { | ||
| 133 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | ||
| 134 | { | ||
| 135 | _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 136 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 137 | { | ||
| 138 | _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 139 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 140 | { | ||
| 141 | _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 142 | } | ||
| 143 | |||
| 144 | return *this; | ||
| 145 | } | ||
| 146 | */ | ||
| 147 | std::list<adverb> adverb_query::run() const | ||
| 148 | { | ||
| 149 | std::stringstream construct; | ||
| 150 | construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs"; | ||
| 151 | std::list<std::string> conditions; | ||
| 152 | |||
| 153 | if (_has_prn) | ||
| 154 | { | ||
| 155 | conditions.push_back("adverb_id IN (SELECT adverb_id FROM adverb_pronunciations)"); | ||
| 156 | } | ||
| 157 | |||
| 158 | if (!_rhymes.empty()) | ||
| 159 | { | ||
| 160 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
| 161 | std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 162 | conditions.push_back(cond); | ||
| 163 | } | ||
| 164 | |||
| 165 | for (auto except : _except) | ||
| 166 | { | ||
| 167 | conditions.push_back("adverb_id != @EXCID"); | ||
| 168 | } | ||
| 169 | |||
| 170 | if (_requires_comparative_form) | ||
| 171 | { | ||
| 172 | conditions.push_back("comparative IS NOT NULL"); | ||
| 173 | } | ||
| 174 | |||
| 175 | if (_requires_superlative_form) | ||
| 176 | { | ||
| 177 | conditions.push_back("superlative IS NOT NULL"); | ||
| 178 | } | ||
| 179 | |||
| 180 | if (_has_antonyms) | ||
| 181 | { | ||
| 182 | conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)"); | ||
| 183 | } | ||
| 184 | |||
| 185 | if (!_antonym_of.empty()) | ||
| 186 | { | ||
| 187 | std::stringstream cond; | ||
| 188 | if (_antonym_of.get_notlogic()) | ||
| 189 | { | ||
| 190 | cond << "adverb_id NOT IN"; | ||
| 191 | } else { | ||
| 192 | cond << "adverb_id IN"; | ||
| 193 | } | ||
| 194 | |||
| 195 | cond << "(SELECT adverb_2_id FROM adverb_antonymy WHERE "; | ||
| 196 | |||
| 197 | std::function<std::string (filter<adverb>, bool)> recur = [&] (filter<adverb> f, bool notlogic) -> std::string { | ||
| 198 | switch (f.get_type()) | ||
| 199 | { | ||
| 200 | case filter<adverb>::type::singleton: | ||
| 201 | { | ||
| 202 | if (notlogic == f.get_notlogic()) | ||
| 203 | { | ||
| 204 | return "adverb_1_id = @ANTID"; | ||
| 205 | } else { | ||
| 206 | return "adverb_1_id != @ANTID"; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | case filter<adverb>::type::group: | ||
| 211 | { | ||
| 212 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 213 | |||
| 214 | std::list<std::string> clauses; | ||
| 215 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adverb> f2) { | ||
| 216 | return recur(f2, truelogic); | ||
| 217 | }); | ||
| 218 | |||
| 219 | if (truelogic == f.get_orlogic()) | ||
| 220 | { | ||
| 221 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 222 | } else { | ||
| 223 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | } | ||
| 227 | }; | ||
| 228 | |||
| 229 | cond << recur(_antonym_of, _antonym_of.get_notlogic()); | ||
| 230 | cond << ")"; | ||
| 231 | conditions.push_back(cond.str()); | ||
| 232 | } | ||
| 233 | |||
| 234 | if (_has_synonyms) | ||
| 235 | { | ||
| 236 | conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy)"); | ||
| 237 | } | ||
| 238 | |||
| 239 | if (!_synonym_of.empty()) | ||
| 240 | { | ||
| 241 | std::stringstream cond; | ||
| 242 | if (_antonym_of.get_notlogic()) | ||
| 243 | { | ||
| 244 | cond << "adverb_id NOT IN"; | ||
| 245 | } else { | ||
| 246 | cond << "adverb_id IN"; | ||
| 247 | } | ||
| 248 | |||
| 249 | cond << "(SELECT adverb_2_id FROM adverb_synonymy WHERE "; | ||
| 250 | |||
| 251 | std::function<std::string (filter<adverb>, bool)> recur = [&] (filter<adverb> f, bool notlogic) -> std::string { | ||
| 252 | switch (f.get_type()) | ||
| 253 | { | ||
| 254 | case filter<adverb>::type::singleton: | ||
| 255 | { | ||
| 256 | if (notlogic == f.get_notlogic()) | ||
| 257 | { | ||
| 258 | return "adverb_1_id = @SYNID"; | ||
| 259 | } else { | ||
| 260 | return "adverb_1_id != @SYNID"; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | case filter<adverb>::type::group: | ||
| 265 | { | ||
| 266 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 267 | |||
| 268 | std::list<std::string> clauses; | ||
| 269 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adverb> f2) { | ||
| 270 | return recur(f2, truelogic); | ||
| 271 | }); | ||
| 272 | |||
| 273 | if (truelogic == f.get_orlogic()) | ||
| 274 | { | ||
| 275 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 276 | } else { | ||
| 277 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 278 | } | ||
| 279 | } | ||
| 280 | } | ||
| 281 | }; | ||
| 282 | |||
| 283 | cond << recur(_synonym_of, _synonym_of.get_notlogic()); | ||
| 284 | cond << ")"; | ||
| 285 | conditions.push_back(cond.str()); | ||
| 286 | } | ||
| 287 | |||
| 288 | if (_is_mannernymic) | ||
| 289 | { | ||
| 290 | conditions.push_back("adverb_id IN (SELECT mannernym_id FROM mannernymy)"); | ||
| 291 | } | ||
| 292 | |||
| 293 | if (!_mannernym_of.empty()) | ||
| 294 | { | ||
| 295 | std::stringstream cond; | ||
| 296 | if (_antonym_of.get_notlogic()) | ||
| 297 | { | ||
| 298 | cond << "adverb_id NOT IN"; | ||
| 299 | } else { | ||
| 300 | cond << "adverb_id IN"; | ||
| 301 | } | ||
| 302 | |||
| 303 | cond << "(SELECT mannernym_id FROM mannernymy WHERE "; | ||
| 304 | |||
| 305 | std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string { | ||
| 306 | switch (f.get_type()) | ||
| 307 | { | ||
| 308 | case filter<adjective>::type::singleton: | ||
| 309 | { | ||
| 310 | if (notlogic == f.get_notlogic()) | ||
| 311 | { | ||
| 312 | return "adjective_id = @AMANID"; | ||
| 313 | } else { | ||
| 314 | return "adjective_id != @AMANID"; | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | case filter<adjective>::type::group: | ||
| 319 | { | ||
| 320 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 321 | |||
| 322 | std::list<std::string> clauses; | ||
| 323 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) { | ||
| 324 | return recur(f2, truelogic); | ||
| 325 | }); | ||
| 326 | |||
| 327 | if (truelogic == f.get_orlogic()) | ||
| 328 | { | ||
| 329 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 330 | } else { | ||
| 331 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 332 | } | ||
| 333 | } | ||
| 334 | } | ||
| 335 | }; | ||
| 336 | |||
| 337 | cond << recur(_mannernym_of, _mannernym_of.get_notlogic()); | ||
| 338 | cond << ")"; | ||
| 339 | conditions.push_back(cond.str()); | ||
| 340 | } | ||
| 341 | |||
| 342 | /* if (!_derived_from_adjective.empty()) | ||
| 343 | { | ||
| 344 | std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_id = @DERADJ"); | ||
| 345 | std::string cond = "adverb_id IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 346 | conditions.push_back(cond); | ||
| 347 | } | ||
| 348 | |||
| 349 | if (!_not_derived_from_adjective.empty()) | ||
| 350 | { | ||
| 351 | std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_id = @NDERADJ"); | ||
| 352 | std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 353 | conditions.push_back(cond); | ||
| 354 | } | ||
| 355 | |||
| 356 | if (!_derived_from_adverb.empty()) | ||
| 357 | { | ||
| 358 | std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_2_id = @DERADV"); | ||
| 359 | std::string cond = "adverb_id IN (SELECT adverb_1_id FROM adverb_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 360 | conditions.push_back(cond); | ||
| 361 | } | ||
| 362 | |||
| 363 | if (!_not_derived_from_adverb.empty()) | ||
| 364 | { | ||
| 365 | std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_2_id = @NDERADV"); | ||
| 366 | 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 ") + ")"; | ||
| 367 | conditions.push_back(cond); | ||
| 368 | } | ||
| 369 | |||
| 370 | if (!_derived_from_noun.empty()) | ||
| 371 | { | ||
| 372 | std::list<std::string> clauses(_derived_from_noun.size(), "noun_id = @DERN"); | ||
| 373 | std::string cond = "adverb_id IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 374 | conditions.push_back(cond); | ||
| 375 | } | ||
| 376 | |||
| 377 | if (!_not_derived_from_noun.empty()) | ||
| 378 | { | ||
| 379 | std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_id = @NDERN"); | ||
| 380 | std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 381 | conditions.push_back(cond); | ||
| 382 | }*/ | ||
| 383 | |||
| 384 | if (!conditions.empty()) | ||
| 385 | { | ||
| 386 | construct << " WHERE "; | ||
| 387 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
| 388 | } | ||
| 389 | |||
| 390 | if (_random) | ||
| 391 | { | ||
| 392 | construct << " ORDER BY RANDOM()"; | ||
| 393 | } | ||
| 394 | |||
| 395 | if (_limit != unlimited) | ||
| 396 | { | ||
| 397 | construct << " LIMIT " << _limit; | ||
| 398 | } | ||
| 399 | |||
| 400 | sqlite3_stmt* ppstmt; | ||
| 401 | std::string query = construct.str(); | ||
| 402 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 403 | { | ||
| 404 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 405 | } | ||
| 406 | |||
| 407 | if (!_rhymes.empty()) | ||
| 408 | { | ||
| 409 | int i = 0; | ||
| 410 | for (auto rhyme : _rhymes) | ||
| 411 | { | ||
| 412 | std::string rhymer = "%" + rhyme; | ||
| 413 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
| 414 | |||
| 415 | i++; | ||
| 416 | } | ||
| 417 | } | ||
| 418 | |||
| 419 | for (auto except : _except) | ||
| 420 | { | ||
| 421 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
| 422 | } | ||
| 423 | |||
| 424 | for (auto antonym : _antonym_of.inorder_flatten()) | ||
| 425 | { | ||
| 426 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
| 427 | } | ||
| 428 | |||
| 429 | for (auto synonym : _synonym_of.inorder_flatten()) | ||
| 430 | { | ||
| 431 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
| 432 | } | ||
| 433 | |||
| 434 | for (auto adj : _mannernym_of.inorder_flatten()) | ||
| 435 | { | ||
| 436 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id); | ||
| 437 | } | ||
| 438 | /* | ||
| 439 | for (auto adj : _derived_from_adjective) | ||
| 440 | { | ||
| 441 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id); | ||
| 442 | } | ||
| 443 | |||
| 444 | for (auto adj : _not_derived_from_adjective) | ||
| 445 | { | ||
| 446 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id); | ||
| 447 | } | ||
| 448 | |||
| 449 | for (auto adv : _derived_from_adverb) | ||
| 450 | { | ||
| 451 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id); | ||
| 452 | } | ||
| 453 | |||
| 454 | for (auto adv : _not_derived_from_adverb) | ||
| 455 | { | ||
| 456 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id); | ||
| 457 | } | ||
| 458 | |||
| 459 | for (auto n : _derived_from_noun) | ||
| 460 | { | ||
| 461 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id); | ||
| 462 | } | ||
| 463 | |||
| 464 | for (auto n : _not_derived_from_noun) | ||
| 465 | { | ||
| 466 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id); | ||
| 467 | }*/ | ||
| 468 | |||
| 469 | std::list<adverb> output; | ||
| 470 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 471 | { | ||
| 472 | adverb tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
| 473 | tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
| 474 | |||
| 475 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
| 476 | { | ||
| 477 | tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
| 478 | } | ||
| 479 | |||
| 480 | if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) | ||
| 481 | { | ||
| 482 | tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
| 483 | } | ||
| 484 | |||
| 485 | output.push_back(tnc); | ||
| 486 | } | ||
| 487 | |||
| 488 | sqlite3_finalize(ppstmt); | ||
| 489 | |||
| 490 | for (auto& adverb : output) | ||
| 491 | { | ||
| 492 | query = "SELECT pronunciation FROM adverb_pronunciations WHERE adverb_id = ?"; | ||
| 493 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 494 | { | ||
| 495 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 496 | } | ||
| 497 | |||
| 498 | sqlite3_bind_int(ppstmt, 1, adverb._id); | ||
| 499 | |||
| 500 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 501 | { | ||
| 502 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
| 503 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
| 504 | |||
| 505 | adverb.pronunciations.push_back(phonemes); | ||
| 506 | } | ||
| 507 | |||
| 508 | sqlite3_finalize(ppstmt); | ||
| 509 | } | ||
| 510 | |||
| 511 | return output; | ||
| 512 | } | ||
| 513 | |||
| 514 | }; | ||
| diff --git a/lib/adverb_query.h b/lib/adverb_query.h new file mode 100644 index 0000000..20f9ce5 --- /dev/null +++ b/lib/adverb_query.h | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | #ifndef ADVERB_QUERY_H_CA13CCDD | ||
| 2 | #define ADVERB_QUERY_H_CA13CCDD | ||
| 3 | |||
| 4 | namespace verbly { | ||
| 5 | |||
| 6 | class adverb_query { | ||
| 7 | public: | ||
| 8 | adverb_query(const data& _data); | ||
| 9 | |||
| 10 | adverb_query& limit(int _limit); | ||
| 11 | adverb_query& random(); | ||
| 12 | adverb_query& except(const adverb& _word); | ||
| 13 | adverb_query& rhymes_with(const word& _word); | ||
| 14 | adverb_query& has_pronunciation(); | ||
| 15 | |||
| 16 | adverb_query& requires_comparative_form(); | ||
| 17 | adverb_query& requires_superlative_form(); | ||
| 18 | |||
| 19 | adverb_query& has_antonyms(); | ||
| 20 | adverb_query& antonym_of(filter<adverb> _f); | ||
| 21 | |||
| 22 | adverb_query& has_synonyms(); | ||
| 23 | adverb_query& synonym_of(filter<adverb> _f); | ||
| 24 | |||
| 25 | adverb_query& is_mannernymic(); | ||
| 26 | adverb_query& mannernym_of(filter<adjective> _f); | ||
| 27 | |||
| 28 | /* adverb_query& derived_from(const word& _w); | ||
| 29 | adverb_query& not_derived_from(const word& _w);*/ | ||
| 30 | |||
| 31 | std::list<adverb> run() const; | ||
| 32 | |||
| 33 | const static int unlimited = -1; | ||
| 34 | |||
| 35 | private: | ||
| 36 | const data& _data; | ||
| 37 | int _limit = unlimited; | ||
| 38 | bool _random = false; | ||
| 39 | std::list<std::string> _rhymes; | ||
| 40 | std::list<adverb> _except; | ||
| 41 | bool _has_prn = false; | ||
| 42 | |||
| 43 | bool _requires_comparative_form = false; | ||
| 44 | bool _requires_superlative_form = false; | ||
| 45 | |||
| 46 | bool _has_antonyms = false; | ||
| 47 | filter<adverb> _antonym_of; | ||
| 48 | |||
| 49 | bool _has_synonyms = false; | ||
| 50 | filter<adverb> _synonym_of; | ||
| 51 | |||
| 52 | bool _is_mannernymic = false; | ||
| 53 | filter<adjective> _mannernym_of; | ||
| 54 | |||
| 55 | /* std::list<adjective> _derived_from_adjective; | ||
| 56 | std::list<adjective> _not_derived_from_adjective; | ||
| 57 | std::list<adverb> _derived_from_adverb; | ||
| 58 | std::list<adverb> _not_derived_from_adverb; | ||
| 59 | std::list<noun> _derived_from_noun; | ||
| 60 | std::list<noun> _not_derived_from_noun;*/ | ||
| 61 | }; | ||
| 62 | |||
| 63 | }; | ||
| 64 | |||
| 65 | #endif /* end of include guard: ADVERB_QUERY_H_CA13CCDD */ | ||
| diff --git a/lib/c++14.h b/lib/c++14.h deleted file mode 100644 index b3efbe2..0000000 --- a/lib/c++14.h +++ /dev/null | |||
| @@ -1,35 +0,0 @@ | |||
| 1 | #include <cstddef> | ||
| 2 | #include <memory> | ||
| 3 | #include <type_traits> | ||
| 4 | #include <utility> | ||
| 5 | |||
| 6 | namespace std { | ||
| 7 | template<class T> struct _Unique_if { | ||
| 8 | typedef unique_ptr<T> _Single_object; | ||
| 9 | }; | ||
| 10 | |||
| 11 | template<class T> struct _Unique_if<T[]> { | ||
| 12 | typedef unique_ptr<T[]> _Unknown_bound; | ||
| 13 | }; | ||
| 14 | |||
| 15 | template<class T, size_t N> struct _Unique_if<T[N]> { | ||
| 16 | typedef void _Known_bound; | ||
| 17 | }; | ||
| 18 | |||
| 19 | template<class T, class... Args> | ||
| 20 | typename _Unique_if<T>::_Single_object | ||
| 21 | make_unique(Args&&... args) { | ||
| 22 | return unique_ptr<T>(new T(std::forward<Args>(args)...)); | ||
| 23 | } | ||
| 24 | |||
| 25 | template<class T> | ||
| 26 | typename _Unique_if<T>::_Unknown_bound | ||
| 27 | make_unique(size_t n) { | ||
| 28 | typedef typename remove_extent<T>::type U; | ||
| 29 | return unique_ptr<T>(new U[n]()); | ||
| 30 | } | ||
| 31 | |||
| 32 | template<class T, class... Args> | ||
| 33 | typename _Unique_if<T>::_Known_bound | ||
| 34 | make_unique(Args&&...) = delete; | ||
| 35 | } | ||
| diff --git a/lib/data.cpp b/lib/data.cpp index 57a8850..5a9397b 100644 --- a/lib/data.cpp +++ b/lib/data.cpp | |||
| @@ -46,5 +46,15 @@ namespace verbly { | |||
| 46 | { | 46 | { |
| 47 | return noun_query(*this); | 47 | return noun_query(*this); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | frame_query data::frames() const | ||
| 51 | { | ||
| 52 | return frame_query(*this); | ||
| 53 | } | ||
| 54 | |||
| 55 | preposition_query data::prepositions() const | ||
| 56 | { | ||
| 57 | return preposition_query(*this); | ||
| 58 | } | ||
| 59 | |||
| 50 | }; | 60 | }; |
| diff --git a/lib/data.h b/lib/data.h index 37092d7..6c2d580 100644 --- a/lib/data.h +++ b/lib/data.h | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | #define DATA_H_C4AEC3DD | 2 | #define DATA_H_C4AEC3DD |
| 3 | 3 | ||
| 4 | #include <sqlite3.h> | 4 | #include <sqlite3.h> |
| 5 | #include <stdexcept> | ||
| 6 | 5 | ||
| 7 | namespace verbly { | 6 | namespace verbly { |
| 8 | 7 | ||
| @@ -12,10 +11,13 @@ namespace verbly { | |||
| 12 | class noun; | 11 | class noun; |
| 13 | class verb; | 12 | class verb; |
| 14 | class adverb; | 13 | class adverb; |
| 14 | class frame; | ||
| 15 | class adjective_query; | 15 | class adjective_query; |
| 16 | class adverb_query; | 16 | class adverb_query; |
| 17 | class noun_query; | 17 | class noun_query; |
| 18 | class verb_query; | 18 | class verb_query; |
| 19 | class frame_query; | ||
| 20 | class preposition_query; | ||
| 19 | 21 | ||
| 20 | class data { | 22 | class data { |
| 21 | private: | 23 | private: |
| @@ -25,6 +27,8 @@ namespace verbly { | |||
| 25 | friend class noun_query; | 27 | friend class noun_query; |
| 26 | friend class verb_query; | 28 | friend class verb_query; |
| 27 | friend class adverb_query; | 29 | friend class adverb_query; |
| 30 | friend class frame_query; | ||
| 31 | friend class preposition_query; | ||
| 28 | 32 | ||
| 29 | public: | 33 | public: |
| 30 | data(std::string datafile); | 34 | data(std::string datafile); |
| @@ -41,9 +45,302 @@ namespace verbly { | |||
| 41 | adjective_query adjectives() const; | 45 | adjective_query adjectives() const; |
| 42 | adverb_query adverbs() const; | 46 | adverb_query adverbs() const; |
| 43 | noun_query nouns() const; | 47 | noun_query nouns() const; |
| 48 | frame_query frames() const; | ||
| 49 | preposition_query prepositions() const; | ||
| 44 | 50 | ||
| 45 | }; | 51 | }; |
| 46 | 52 | ||
| 53 | template <class T> | ||
| 54 | class filter { | ||
| 55 | public: | ||
| 56 | enum class type { | ||
| 57 | singleton, | ||
| 58 | group | ||
| 59 | }; | ||
| 60 | |||
| 61 | typedef filter<T> value_type; | ||
| 62 | |||
| 63 | type get_type() const | ||
| 64 | { | ||
| 65 | return _type; | ||
| 66 | } | ||
| 67 | |||
| 68 | filter(const filter<T>& other) | ||
| 69 | { | ||
| 70 | _type = other._type; | ||
| 71 | _notlogic = other._notlogic; | ||
| 72 | |||
| 73 | switch (_type) | ||
| 74 | { | ||
| 75 | case type::singleton: | ||
| 76 | { | ||
| 77 | new(&_singleton.elem) T(other._singleton.elem); | ||
| 78 | |||
| 79 | break; | ||
| 80 | } | ||
| 81 | |||
| 82 | case type::group: | ||
| 83 | { | ||
| 84 | new(&_group.elems) std::list<filter<T>>(other._group.elems); | ||
| 85 | _group.orlogic = other._group.orlogic; | ||
| 86 | |||
| 87 | break; | ||
| 88 | } | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | filter<T>& operator=(const filter<T>& other) | ||
| 93 | { | ||
| 94 | this->~filter(); | ||
| 95 | |||
| 96 | _type = other._type; | ||
| 97 | _notlogic = other._notlogic; | ||
| 98 | |||
| 99 | switch (_type) | ||
| 100 | { | ||
| 101 | case type::singleton: | ||
| 102 | { | ||
| 103 | new(&_singleton.elem) T(other._singleton.elem); | ||
| 104 | |||
| 105 | break; | ||
| 106 | } | ||
| 107 | |||
| 108 | case type::group: | ||
| 109 | { | ||
| 110 | new(&_group.elems) std::list<filter<T>>(other._group.elems); | ||
| 111 | _group.orlogic = other._group.orlogic; | ||
| 112 | |||
| 113 | break; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | return *this; | ||
| 118 | } | ||
| 119 | |||
| 120 | ~filter() | ||
| 121 | { | ||
| 122 | switch (_type) | ||
| 123 | { | ||
| 124 | case type::singleton: | ||
| 125 | { | ||
| 126 | _singleton.elem.~T(); | ||
| 127 | |||
| 128 | break; | ||
| 129 | } | ||
| 130 | |||
| 131 | case type::group: | ||
| 132 | { | ||
| 133 | using list_type = std::list<filter<T>>; | ||
| 134 | _group.elems.~list_type(); | ||
| 135 | |||
| 136 | break; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | bool get_notlogic() const | ||
| 142 | { | ||
| 143 | return _notlogic; | ||
| 144 | } | ||
| 145 | |||
| 146 | void set_notlogic(bool _nl) | ||
| 147 | { | ||
| 148 | _notlogic = _nl; | ||
| 149 | } | ||
| 150 | |||
| 151 | std::list<T> inorder_flatten() const | ||
| 152 | { | ||
| 153 | std::list<T> result; | ||
| 154 | |||
| 155 | if (_type == type::singleton) | ||
| 156 | { | ||
| 157 | result.push_back(_singleton.elem); | ||
| 158 | } else if (_type == type::group) | ||
| 159 | { | ||
| 160 | for (auto elem : _group.elems) | ||
| 161 | { | ||
| 162 | auto l = elem.inorder_flatten(); | ||
| 163 | result.insert(std::end(result), std::begin(l), std::end(l)); | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | return result; | ||
| 168 | } | ||
| 169 | |||
| 170 | std::set<T> uniq_flatten() const | ||
| 171 | { | ||
| 172 | std::set<T> result; | ||
| 173 | |||
| 174 | if (_type == type::singleton) | ||
| 175 | { | ||
| 176 | result.insert(_singleton.elem); | ||
| 177 | } else if (_type == type::group) | ||
| 178 | { | ||
| 179 | for (auto elem : _group.elems) | ||
| 180 | { | ||
| 181 | auto l = elem.uniq_flatten(); | ||
| 182 | result.insert(std::begin(l), std::end(l)); | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | return result; | ||
| 187 | } | ||
| 188 | |||
| 189 | void clean() | ||
| 190 | { | ||
| 191 | if (_type == type::group) | ||
| 192 | { | ||
| 193 | std::list<typename std::list<filter<T>>::iterator> toremove; | ||
| 194 | for (auto it = _group.elems.begin(); it != _group.elems.end(); it++) | ||
| 195 | { | ||
| 196 | it->clean(); | ||
| 197 | |||
| 198 | if (it->get_type() == type::group) | ||
| 199 | { | ||
| 200 | if (it->_group.elems.size() == 0) | ||
| 201 | { | ||
| 202 | toremove.push_back(it); | ||
| 203 | } else if (it->_group.elems.size() == 1) | ||
| 204 | { | ||
| 205 | bool truelogic = it->_notlogic != it->_group.elems.front()._notlogic; | ||
| 206 | *it = it->_group.elems.front(); | ||
| 207 | it->_notlogic = truelogic; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | for (auto rem : toremove) | ||
| 213 | { | ||
| 214 | _group.elems.erase(rem); | ||
| 215 | } | ||
| 216 | |||
| 217 | if (_group.elems.size() == 1) | ||
| 218 | { | ||
| 219 | bool truelogic = _notlogic != _group.elems.front()._notlogic; | ||
| 220 | *this = _group.elems.front(); | ||
| 221 | _notlogic = truelogic; | ||
| 222 | } | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 226 | // Singleton | ||
| 227 | filter(T _elem, bool _notlogic = false) : _type(type::singleton) | ||
| 228 | { | ||
| 229 | new(&_singleton.elem) T(_elem); | ||
| 230 | this->_notlogic = _notlogic; | ||
| 231 | } | ||
| 232 | |||
| 233 | filter<T>& operator=(T _elem) | ||
| 234 | { | ||
| 235 | *this = filter<T>{_elem}; | ||
| 236 | |||
| 237 | return *this; | ||
| 238 | } | ||
| 239 | |||
| 240 | T get_elem() const | ||
| 241 | { | ||
| 242 | assert(_type == type::singleton); | ||
| 243 | |||
| 244 | return _singleton.elem; | ||
| 245 | } | ||
| 246 | |||
| 247 | void set_elem(T _elem) | ||
| 248 | { | ||
| 249 | assert(_type == type::singleton); | ||
| 250 | |||
| 251 | _singleton.elem = _elem; | ||
| 252 | } | ||
| 253 | |||
| 254 | // Group | ||
| 255 | typedef typename std::list<filter<T>>::iterator iterator; | ||
| 256 | |||
| 257 | filter() : _type(type::group) | ||
| 258 | { | ||
| 259 | new(&_group.elems) std::list<filter<T>>(); | ||
| 260 | _group.orlogic = false; | ||
| 261 | } | ||
| 262 | |||
| 263 | filter(std::initializer_list<filter<T>> _init) : _type(type::group) | ||
| 264 | { | ||
| 265 | new(&_group.elems) std::list<filter<T>>(_init); | ||
| 266 | _group.orlogic = false; | ||
| 267 | } | ||
| 268 | |||
| 269 | iterator begin() | ||
| 270 | { | ||
| 271 | assert(_type == type::group); | ||
| 272 | |||
| 273 | return _group.elems.begin(); | ||
| 274 | } | ||
| 275 | |||
| 276 | iterator end() | ||
| 277 | { | ||
| 278 | assert(_type == type::group); | ||
| 279 | |||
| 280 | return _group.elems.end(); | ||
| 281 | } | ||
| 282 | |||
| 283 | filter<T>& operator<<(filter<T> _elem) | ||
| 284 | { | ||
| 285 | assert(_type == type::group); | ||
| 286 | |||
| 287 | _group.elems.push_back(_elem); | ||
| 288 | |||
| 289 | return *this; | ||
| 290 | } | ||
| 291 | |||
| 292 | void push_back(filter<T> _elem) | ||
| 293 | { | ||
| 294 | assert(_type == type::group); | ||
| 295 | |||
| 296 | _group.elems.push_back(_elem); | ||
| 297 | } | ||
| 298 | |||
| 299 | bool get_orlogic() const | ||
| 300 | { | ||
| 301 | assert(_type == type::group); | ||
| 302 | |||
| 303 | return _group.orlogic; | ||
| 304 | } | ||
| 305 | |||
| 306 | void set_orlogic(bool _ol) | ||
| 307 | { | ||
| 308 | assert(_type == type::group); | ||
| 309 | |||
| 310 | _group.orlogic = _ol; | ||
| 311 | } | ||
| 312 | |||
| 313 | bool empty() const | ||
| 314 | { | ||
| 315 | if (_type == type::group) | ||
| 316 | { | ||
| 317 | return _group.elems.empty(); | ||
| 318 | } else { | ||
| 319 | return false; | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | int size() const | ||
| 324 | { | ||
| 325 | assert(_type == type::group); | ||
| 326 | |||
| 327 | return _group.elems.size(); | ||
| 328 | } | ||
| 329 | |||
| 330 | private: | ||
| 331 | type _type; | ||
| 332 | bool _notlogic = false; | ||
| 333 | union { | ||
| 334 | struct { | ||
| 335 | T elem; | ||
| 336 | } _singleton; | ||
| 337 | struct { | ||
| 338 | std::list<filter<T>> elems; | ||
| 339 | bool orlogic; | ||
| 340 | } _group; | ||
| 341 | }; | ||
| 342 | }; | ||
| 343 | |||
| 47 | }; | 344 | }; |
| 48 | 345 | ||
| 49 | #endif /* end of include guard: DATA_H_C4AEC3DD */ | 346 | #endif /* end of include guard: DATA_H_C4AEC3DD */ |
| diff --git a/lib/frame.cpp b/lib/frame.cpp new file mode 100644 index 0000000..ccec81b --- /dev/null +++ b/lib/frame.cpp | |||
| @@ -0,0 +1,320 @@ | |||
| 1 | #include "verbly.h" | ||
| 2 | |||
| 3 | namespace verbly { | ||
| 4 | |||
| 5 | frame::selrestr::type frame::selrestr::get_type() const | ||
| 6 | { | ||
| 7 | return _type; | ||
| 8 | } | ||
| 9 | |||
| 10 | frame::selrestr::selrestr(const selrestr& other) | ||
| 11 | { | ||
| 12 | _type = other._type; | ||
| 13 | |||
| 14 | switch (_type) | ||
| 15 | { | ||
| 16 | case frame::selrestr::type::singleton: | ||
| 17 | { | ||
| 18 | _singleton.pos = other._singleton.pos; | ||
| 19 | new(&_singleton.restriction) std::string(other._singleton.restriction); | ||
| 20 | |||
| 21 | break; | ||
| 22 | } | ||
| 23 | |||
| 24 | case frame::selrestr::type::group: | ||
| 25 | { | ||
| 26 | new(&_group.children) std::list<selrestr>(other._group.children); | ||
| 27 | _group.orlogic = other._group.orlogic; | ||
| 28 | |||
| 29 | break; | ||
| 30 | } | ||
| 31 | |||
| 32 | case frame::selrestr::type::empty: | ||
| 33 | { | ||
| 34 | // Nothing! | ||
| 35 | |||
| 36 | break; | ||
| 37 | } | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | frame::selrestr::~selrestr() | ||
| 42 | { | ||
| 43 | switch (_type) | ||
| 44 | { | ||
| 45 | case frame::selrestr::type::singleton: | ||
| 46 | { | ||
| 47 | using string_type = std::string; | ||
| 48 | _singleton.restriction.~string_type(); | ||
| 49 | |||
| 50 | break; | ||
| 51 | } | ||
| 52 | |||
| 53 | case frame::selrestr::type::group: | ||
| 54 | { | ||
| 55 | using list_type = std::list<selrestr>; | ||
| 56 | _group.children.~list_type(); | ||
| 57 | |||
| 58 | break; | ||
| 59 | } | ||
| 60 | |||
| 61 | case frame::selrestr::type::empty: | ||
| 62 | { | ||
| 63 | // Nothing! | ||
| 64 | |||
| 65 | break; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | frame::selrestr& frame::selrestr::operator=(const selrestr& other) | ||
| 71 | { | ||
| 72 | this->~selrestr(); | ||
| 73 | |||
| 74 | _type = other._type; | ||
| 75 | |||
| 76 | switch (_type) | ||
| 77 | { | ||
| 78 | case frame::selrestr::type::singleton: | ||
| 79 | { | ||
| 80 | _singleton.pos = other._singleton.pos; | ||
| 81 | new(&_singleton.restriction) std::string(other._singleton.restriction); | ||
| 82 | |||
| 83 | break; | ||
| 84 | } | ||
| 85 | |||
| 86 | case frame::selrestr::type::group: | ||
| 87 | { | ||
| 88 | new(&_group.children) std::list<selrestr>(other._group.children); | ||
| 89 | _group.orlogic = other._group.orlogic; | ||
| 90 | |||
| 91 | break; | ||
| 92 | } | ||
| 93 | |||
| 94 | case frame::selrestr::type::empty: | ||
| 95 | { | ||
| 96 | // Nothing! | ||
| 97 | |||
| 98 | break; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | return *this; | ||
| 103 | } | ||
| 104 | |||
| 105 | frame::selrestr::selrestr() : _type(frame::selrestr::type::empty) | ||
| 106 | { | ||
| 107 | |||
| 108 | } | ||
| 109 | |||
| 110 | frame::selrestr::selrestr(std::string restriction, bool pos) : _type(frame::selrestr::type::singleton) | ||
| 111 | { | ||
| 112 | new(&_singleton.restriction) std::string(restriction); | ||
| 113 | _singleton.pos = pos; | ||
| 114 | } | ||
| 115 | |||
| 116 | std::string frame::selrestr::get_restriction() const | ||
| 117 | { | ||
| 118 | assert(_type == frame::selrestr::type::singleton); | ||
| 119 | |||
| 120 | return _singleton.restriction; | ||
| 121 | } | ||
| 122 | |||
| 123 | bool frame::selrestr::get_pos() const | ||
| 124 | { | ||
| 125 | assert(_type == frame::selrestr::type::singleton); | ||
| 126 | |||
| 127 | return _singleton.pos; | ||
| 128 | } | ||
| 129 | |||
| 130 | frame::selrestr::selrestr(std::list<selrestr> children, bool orlogic) : _type(frame::selrestr::type::group) | ||
| 131 | { | ||
| 132 | new(&_group.children) std::list<selrestr>(children); | ||
| 133 | _group.orlogic = orlogic; | ||
| 134 | } | ||
| 135 | |||
| 136 | std::list<frame::selrestr> frame::selrestr::get_children() const | ||
| 137 | { | ||
| 138 | assert(_type == frame::selrestr::type::group); | ||
| 139 | |||
| 140 | return _group.children; | ||
| 141 | } | ||
| 142 | |||
| 143 | std::list<frame::selrestr>::const_iterator frame::selrestr::begin() const | ||
| 144 | { | ||
| 145 | assert(_type == frame::selrestr::type::group); | ||
| 146 | |||
| 147 | return _group.children.begin(); | ||
| 148 | } | ||
| 149 | |||
| 150 | std::list<frame::selrestr>::const_iterator frame::selrestr::end() const | ||
| 151 | { | ||
| 152 | assert(_type == frame::selrestr::type::group); | ||
| 153 | |||
| 154 | return _group.children.end(); | ||
| 155 | } | ||
| 156 | |||
| 157 | bool frame::selrestr::get_orlogic() const | ||
| 158 | { | ||
| 159 | assert(_type == frame::selrestr::type::group); | ||
| 160 | |||
| 161 | return _group.orlogic; | ||
| 162 | } | ||
| 163 | |||
| 164 | frame::part::type frame::part::get_type() const | ||
| 165 | { | ||
| 166 | return _type; | ||
| 167 | } | ||
| 168 | |||
| 169 | frame::part::part() | ||
| 170 | { | ||
| 171 | |||
| 172 | } | ||
| 173 | |||
| 174 | frame::part::part(const part& other) | ||
| 175 | { | ||
| 176 | _type = other._type; | ||
| 177 | |||
| 178 | switch (_type) | ||
| 179 | { | ||
| 180 | case frame::part::type::noun_phrase: | ||
| 181 | { | ||
| 182 | new(&_noun_phrase.role) std::string(other._noun_phrase.role); | ||
| 183 | new(&_noun_phrase.selrestrs) selrestr(other._noun_phrase.selrestrs); | ||
| 184 | new(&_noun_phrase.synrestrs) std::set<std::string>(other._noun_phrase.synrestrs); | ||
| 185 | |||
| 186 | break; | ||
| 187 | } | ||
| 188 | |||
| 189 | case frame::part::type::literal_preposition: | ||
| 190 | { | ||
| 191 | new(&_literal_preposition.choices) std::vector<std::string>(other._literal_preposition.choices); | ||
| 192 | |||
| 193 | break; | ||
| 194 | } | ||
| 195 | |||
| 196 | case frame::part::type::selection_preposition: | ||
| 197 | { | ||
| 198 | new(&_selection_preposition.preprestrs) std::vector<std::string>(other._selection_preposition.preprestrs); | ||
| 199 | |||
| 200 | break; | ||
| 201 | } | ||
| 202 | |||
| 203 | case frame::part::type::literal: | ||
| 204 | { | ||
| 205 | new(&_literal.lexval) std::string(other._literal.lexval); | ||
| 206 | |||
| 207 | break; | ||
| 208 | } | ||
| 209 | |||
| 210 | default: | ||
| 211 | { | ||
| 212 | // Nothing! | ||
| 213 | |||
| 214 | break; | ||
| 215 | } | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 219 | frame::part::~part() | ||
| 220 | { | ||
| 221 | switch (_type) | ||
| 222 | { | ||
| 223 | case frame::part::type::noun_phrase: | ||
| 224 | { | ||
| 225 | using string_type = std::string; | ||
| 226 | using set_type = std::set<std::string>; | ||
| 227 | |||
| 228 | _noun_phrase.role.~string_type(); | ||
| 229 | _noun_phrase.selrestrs.~selrestr(); | ||
| 230 | _noun_phrase.synrestrs.~set_type(); | ||
| 231 | |||
| 232 | break; | ||
| 233 | } | ||
| 234 | |||
| 235 | case frame::part::type::literal_preposition: | ||
| 236 | { | ||
| 237 | using vector_type = std::vector<std::string>; | ||
| 238 | _literal_preposition.choices.~vector_type(); | ||
| 239 | |||
| 240 | break; | ||
| 241 | } | ||
| 242 | |||
| 243 | case frame::part::type::selection_preposition: | ||
| 244 | { | ||
| 245 | using vector_type = std::vector<std::string>; | ||
| 246 | _selection_preposition.preprestrs.~vector_type(); | ||
| 247 | |||
| 248 | break; | ||
| 249 | } | ||
| 250 | |||
| 251 | case frame::part::type::literal: | ||
| 252 | { | ||
| 253 | using string_type = std::string; | ||
| 254 | _literal.lexval.~string_type(); | ||
| 255 | |||
| 256 | break; | ||
| 257 | } | ||
| 258 | |||
| 259 | default: | ||
| 260 | { | ||
| 261 | // Nothing! | ||
| 262 | |||
| 263 | break; | ||
| 264 | } | ||
| 265 | } | ||
| 266 | } | ||
| 267 | |||
| 268 | std::string frame::part::get_role() const | ||
| 269 | { | ||
| 270 | assert(_type == frame::part::type::noun_phrase); | ||
| 271 | |||
| 272 | return _noun_phrase.role; | ||
| 273 | } | ||
| 274 | |||
| 275 | frame::selrestr frame::part::get_selrestrs() const | ||
| 276 | { | ||
| 277 | assert(_type == frame::part::type::noun_phrase); | ||
| 278 | |||
| 279 | return _noun_phrase.selrestrs; | ||
| 280 | } | ||
| 281 | |||
| 282 | std::set<std::string> frame::part::get_synrestrs() const | ||
| 283 | { | ||
| 284 | assert(_type == frame::part::type::noun_phrase); | ||
| 285 | |||
| 286 | return _noun_phrase.synrestrs; | ||
| 287 | } | ||
| 288 | |||
| 289 | std::vector<std::string> frame::part::get_choices() const | ||
| 290 | { | ||
| 291 | assert(_type == frame::part::type::literal_preposition); | ||
| 292 | |||
| 293 | return _literal_preposition.choices; | ||
| 294 | } | ||
| 295 | |||
| 296 | std::vector<std::string> frame::part::get_preprestrs() const | ||
| 297 | { | ||
| 298 | assert(_type == frame::part::type::selection_preposition); | ||
| 299 | |||
| 300 | return _selection_preposition.preprestrs; | ||
| 301 | } | ||
| 302 | |||
| 303 | std::string frame::part::get_literal() const | ||
| 304 | { | ||
| 305 | assert(_type == frame::part::type::literal); | ||
| 306 | |||
| 307 | return _literal.lexval; | ||
| 308 | } | ||
| 309 | |||
| 310 | std::vector<frame::part> frame::parts() const | ||
| 311 | { | ||
| 312 | return _parts; | ||
| 313 | } | ||
| 314 | |||
| 315 | std::map<std::string, frame::selrestr> frame::roles() const | ||
| 316 | { | ||
| 317 | return _roles; | ||
| 318 | } | ||
| 319 | |||
| 320 | }; | ||
| diff --git a/lib/frame.h b/lib/frame.h new file mode 100644 index 0000000..fa57e1b --- /dev/null +++ b/lib/frame.h | |||
| @@ -0,0 +1,118 @@ | |||
| 1 | #ifndef FRAME_H_9A5D90FE | ||
| 2 | #define FRAME_H_9A5D90FE | ||
| 3 | |||
| 4 | namespace verbly { | ||
| 5 | |||
| 6 | class frame_query; | ||
| 7 | |||
| 8 | class frame { | ||
| 9 | public: | ||
| 10 | class selrestr { | ||
| 11 | public: | ||
| 12 | enum class type { | ||
| 13 | empty, | ||
| 14 | singleton, | ||
| 15 | group | ||
| 16 | }; | ||
| 17 | |||
| 18 | type get_type() const; | ||
| 19 | selrestr(const selrestr& other); | ||
| 20 | ~selrestr(); | ||
| 21 | selrestr& operator=(const selrestr& other); | ||
| 22 | |||
| 23 | // Empty | ||
| 24 | selrestr(); | ||
| 25 | |||
| 26 | // Singleton | ||
| 27 | selrestr(std::string restriction, bool pos); | ||
| 28 | std::string get_restriction() const; | ||
| 29 | bool get_pos() const; | ||
| 30 | |||
| 31 | // Group | ||
| 32 | selrestr(std::list<selrestr> children, bool orlogic); | ||
| 33 | std::list<selrestr> get_children() const; | ||
| 34 | std::list<selrestr>::const_iterator begin() const; | ||
| 35 | std::list<selrestr>::const_iterator end() const; | ||
| 36 | bool get_orlogic() const; | ||
| 37 | |||
| 38 | private: | ||
| 39 | union { | ||
| 40 | struct { | ||
| 41 | bool pos; | ||
| 42 | std::string restriction; | ||
| 43 | } _singleton; | ||
| 44 | struct { | ||
| 45 | std::list<selrestr> children; | ||
| 46 | bool orlogic; | ||
| 47 | } _group; | ||
| 48 | }; | ||
| 49 | type _type; | ||
| 50 | }; | ||
| 51 | |||
| 52 | class part { | ||
| 53 | public: | ||
| 54 | enum class type { | ||
| 55 | noun_phrase, | ||
| 56 | verb, | ||
| 57 | literal_preposition, | ||
| 58 | selection_preposition, | ||
| 59 | adjective, | ||
| 60 | adverb, | ||
| 61 | literal | ||
| 62 | }; | ||
| 63 | |||
| 64 | type get_type() const; | ||
| 65 | part(const part& other); | ||
| 66 | ~part(); | ||
| 67 | |||
| 68 | // Noun phrase | ||
| 69 | std::string get_role() const; | ||
| 70 | selrestr get_selrestrs() const; | ||
| 71 | std::set<std::string> get_synrestrs() const; | ||
| 72 | |||
| 73 | // Literal preposition | ||
| 74 | std::vector<std::string> get_choices() const; | ||
| 75 | |||
| 76 | // Selection preposition | ||
| 77 | std::vector<std::string> get_preprestrs() const; | ||
| 78 | |||
| 79 | // Literal | ||
| 80 | std::string get_literal() const; | ||
| 81 | |||
| 82 | private: | ||
| 83 | friend class frame_query; | ||
| 84 | |||
| 85 | part(); | ||
| 86 | |||
| 87 | union { | ||
| 88 | struct { | ||
| 89 | std::string role; | ||
| 90 | selrestr selrestrs; | ||
| 91 | std::set<std::string> synrestrs; | ||
| 92 | } _noun_phrase; | ||
| 93 | struct { | ||
| 94 | std::vector<std::string> choices; | ||
| 95 | } _literal_preposition; | ||
| 96 | struct { | ||
| 97 | std::vector<std::string> preprestrs; | ||
| 98 | } _selection_preposition; | ||
| 99 | struct { | ||
| 100 | std::string lexval; | ||
| 101 | } _literal; | ||
| 102 | }; | ||
| 103 | type _type; | ||
| 104 | }; | ||
| 105 | |||
| 106 | std::vector<part> parts() const; | ||
| 107 | std::map<std::string, selrestr> roles() const; | ||
| 108 | |||
| 109 | private: | ||
| 110 | friend class frame_query; | ||
| 111 | |||
| 112 | std::vector<part> _parts; | ||
| 113 | std::map<std::string, selrestr> _roles; | ||
| 114 | }; | ||
| 115 | |||
| 116 | }; | ||
| 117 | |||
| 118 | #endif /* end of include guard: FRAME_H_9A5D90FE */ | ||
| diff --git a/lib/frame_query.cpp b/lib/frame_query.cpp new file mode 100644 index 0000000..6583da4 --- /dev/null +++ b/lib/frame_query.cpp | |||
| @@ -0,0 +1,142 @@ | |||
| 1 | #include "verbly.h" | ||
| 2 | #include <json.hpp> | ||
| 3 | |||
| 4 | using json = nlohmann::json; | ||
| 5 | |||
| 6 | namespace verbly { | ||
| 7 | |||
| 8 | frame_query::frame_query(const data& _data) : _data(_data) | ||
| 9 | { | ||
| 10 | |||
| 11 | } | ||
| 12 | |||
| 13 | frame_query& frame_query::for_verb(const verb& _v) | ||
| 14 | { | ||
| 15 | _for_verb.push_back(_v); | ||
| 16 | |||
| 17 | return *this; | ||
| 18 | } | ||
| 19 | |||
| 20 | frame::selrestr parse_selrestr(const json data) | ||
| 21 | { | ||
| 22 | if (data.find("children") != data.end()) | ||
| 23 | { | ||
| 24 | std::list<frame::selrestr> children; | ||
| 25 | std::transform(std::begin(data["children"]), std::end(data["children"]), std::back_inserter(children), &parse_selrestr); | ||
| 26 | |||
| 27 | return frame::selrestr{children, data["logic"] == "or"}; | ||
| 28 | } else if (data.find("type") != data.end()) | ||
| 29 | { | ||
| 30 | return frame::selrestr{data["type"].get<std::string>(), data["pos"].get<bool>()}; | ||
| 31 | } else { | ||
| 32 | return frame::selrestr{}; | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | std::list<frame> frame_query::run() const | ||
| 37 | { | ||
| 38 | std::stringstream construct; | ||
| 39 | construct << "SELECT frames.data, groups.data FROM frames INNER JOIN groups ON frames.group_id = groups.group_id"; | ||
| 40 | |||
| 41 | if (!_for_verb.empty()) | ||
| 42 | { | ||
| 43 | std::list<std::string> clauses(_for_verb.size(), "verb_id = @VERID"); | ||
| 44 | construct << " WHERE frames.group_id IN (SELECT group_id FROM verb_groups WHERE "; | ||
| 45 | construct << verbly::implode(std::begin(clauses), std::end(clauses), " OR "); | ||
| 46 | construct << ")"; | ||
| 47 | } | ||
| 48 | |||
| 49 | sqlite3_stmt* ppstmt; | ||
| 50 | std::string query = construct.str(); | ||
| 51 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 52 | { | ||
| 53 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 54 | } | ||
| 55 | |||
| 56 | for (auto verb : _for_verb) | ||
| 57 | { | ||
| 58 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VERID"), verb._id); | ||
| 59 | } | ||
| 60 | |||
| 61 | std::list<frame> output; | ||
| 62 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 63 | { | ||
| 64 | frame f; | ||
| 65 | |||
| 66 | std::string fdatat(reinterpret_cast<const char*>(sqlite3_column_blob(ppstmt, 0))); | ||
| 67 | const json fdata = json::parse(fdatat); | ||
| 68 | for (const auto& part : fdata) | ||
| 69 | { | ||
| 70 | frame::part p; | ||
| 71 | |||
| 72 | if (part["type"] == "np") | ||
| 73 | { | ||
| 74 | p._type = frame::part::type::noun_phrase; | ||
| 75 | new(&p._noun_phrase.role) std::string(part["role"].get<std::string>()); | ||
| 76 | new(&p._noun_phrase.selrestrs) frame::selrestr(parse_selrestr(part["selrestrs"])); | ||
| 77 | new(&p._noun_phrase.synrestrs) std::set<std::string>(); | ||
| 78 | for (auto synrestr : part["synrestrs"]) | ||
| 79 | { | ||
| 80 | p._noun_phrase.synrestrs.insert(synrestr.get<std::string>()); | ||
| 81 | } | ||
| 82 | } else if (part["type"] == "pp") | ||
| 83 | { | ||
| 84 | if (!part["values"].empty()) | ||
| 85 | { | ||
| 86 | p._type = frame::part::type::literal_preposition; | ||
| 87 | new(&p._literal_preposition.choices) std::vector<std::string>(); | ||
| 88 | for (auto choice : part["values"]) | ||
| 89 | { | ||
| 90 | p._literal_preposition.choices.push_back(choice.get<std::string>()); | ||
| 91 | } | ||
| 92 | } else if (!part["preprestrs"].empty()) | ||
| 93 | { | ||
| 94 | p._type = frame::part::type::selection_preposition; | ||
| 95 | new(&p._selection_preposition.preprestrs) std::vector<std::string>(); | ||
| 96 | for (auto preprestr : part["preprestrs"]) | ||
| 97 | { | ||
| 98 | p._selection_preposition.preprestrs.push_back(preprestr.get<std::string>()); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } else if (part["type"] == "v") | ||
| 102 | { | ||
| 103 | p._type = frame::part::type::verb; | ||
| 104 | } else if (part["type"] == "adj") | ||
| 105 | { | ||
| 106 | p._type = frame::part::type::adjective; | ||
| 107 | } else if (part["type"] == "adv") | ||
| 108 | { | ||
| 109 | p._type = frame::part::type::adverb; | ||
| 110 | } else if (part["type"] == "lex") | ||
| 111 | { | ||
| 112 | p._type = frame::part::type::literal; | ||
| 113 | new(&p._literal.lexval) std::string(part["value"].get<std::string>()); | ||
| 114 | } | ||
| 115 | |||
| 116 | f._parts.push_back(p); | ||
| 117 | } | ||
| 118 | |||
| 119 | std::string rdatat(reinterpret_cast<const char*>(sqlite3_column_blob(ppstmt, 1))); | ||
| 120 | const json rdata = json::parse(rdatat); | ||
| 121 | for (const auto& role : rdata) | ||
| 122 | { | ||
| 123 | std::string rt = role["type"]; | ||
| 124 | frame::selrestr rs; | ||
| 125 | |||
| 126 | if (role.find("selrestrs") != role.end()) | ||
| 127 | { | ||
| 128 | rs = parse_selrestr(role["selrestrs"]); | ||
| 129 | } | ||
| 130 | |||
| 131 | f._roles[rt] = rs; | ||
| 132 | } | ||
| 133 | |||
| 134 | output.push_back(f); | ||
| 135 | } | ||
| 136 | |||
| 137 | sqlite3_finalize(ppstmt); | ||
| 138 | |||
| 139 | return output; | ||
| 140 | } | ||
| 141 | |||
| 142 | }; | ||
| diff --git a/lib/frame_query.h b/lib/frame_query.h new file mode 100644 index 0000000..dd11d16 --- /dev/null +++ b/lib/frame_query.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #ifndef FRAME_QUERY_H_334B9D47 | ||
| 2 | #define FRAME_QUERY_H_334B9D47 | ||
| 3 | |||
| 4 | namespace verbly { | ||
| 5 | |||
| 6 | class frame_query { | ||
| 7 | public: | ||
| 8 | frame_query(const data& _data); | ||
| 9 | |||
| 10 | frame_query& for_verb(const verb& _v); | ||
| 11 | |||
| 12 | std::list<frame> run() const; | ||
| 13 | |||
| 14 | private: | ||
| 15 | const data& _data; | ||
| 16 | std::list<verb> _for_verb; | ||
| 17 | }; | ||
| 18 | |||
| 19 | }; | ||
| 20 | |||
| 21 | #endif /* end of include guard: FRAME_QUERY_H_334B9D47 */ | ||
| diff --git a/lib/noun.cpp b/lib/noun.cpp index 81e6613..f575117 100644 --- a/lib/noun.cpp +++ b/lib/noun.cpp | |||
| @@ -1,7 +1,14 @@ | |||
| 1 | #include "verbly.h" | 1 | #include "verbly.h" |
| 2 | #include <set> | ||
| 3 | #include <iostream> | ||
| 2 | 4 | ||
| 3 | namespace verbly { | 5 | namespace verbly { |
| 4 | 6 | ||
| 7 | noun::noun() | ||
| 8 | { | ||
| 9 | |||
| 10 | } | ||
| 11 | |||
| 5 | noun::noun(const data& _data, int _id) : word(_data, _id) | 12 | noun::noun(const data& _data, int _id) : word(_data, _id) |
| 6 | { | 13 | { |
| 7 | 14 | ||
| @@ -9,1036 +16,147 @@ namespace verbly { | |||
| 9 | 16 | ||
| 10 | std::string noun::base_form() const | 17 | std::string noun::base_form() const |
| 11 | { | 18 | { |
| 19 | assert(_valid == true); | ||
| 20 | |||
| 12 | return _singular; | 21 | return _singular; |
| 13 | } | 22 | } |
| 14 | 23 | ||
| 15 | std::string noun::singular_form() const | 24 | std::string noun::singular_form() const |
| 16 | { | 25 | { |
| 26 | assert(_valid == true); | ||
| 27 | |||
| 17 | return _singular; | 28 | return _singular; |
| 18 | } | 29 | } |
| 19 | 30 | ||
| 20 | std::string noun::plural_form() const | 31 | std::string noun::plural_form() const |
| 21 | { | 32 | { |
| 33 | assert(_valid == true); | ||
| 34 | |||
| 22 | return _plural; | 35 | return _plural; |
| 23 | } | 36 | } |
| 24 | 37 | ||
| 25 | bool noun::has_plural_form() const | 38 | bool noun::has_plural_form() const |
| 26 | { | 39 | { |
| 40 | assert(_valid == true); | ||
| 41 | |||
| 27 | return !_plural.empty(); | 42 | return !_plural.empty(); |
| 28 | } | 43 | } |
| 29 | 44 | ||
| 30 | noun_query noun::hypernyms() const | 45 | noun_query noun::hypernyms() const |
| 31 | { | 46 | { |
| 32 | return _data.nouns().hypernym_of(*this); | 47 | assert(_valid == true); |
| 33 | } | ||
| 34 | |||
| 35 | noun_query noun::hyponyms() const | ||
| 36 | { | ||
| 37 | return _data.nouns().hyponym_of(*this); | ||
| 38 | } | ||
| 39 | |||
| 40 | noun_query noun::part_meronyms() const | ||
| 41 | { | ||
| 42 | return _data.nouns().part_meronym_of(*this); | ||
| 43 | } | ||
| 44 | |||
| 45 | noun_query noun::part_holonyms() const | ||
| 46 | { | ||
| 47 | return _data.nouns().part_holonym_of(*this); | ||
| 48 | } | ||
| 49 | |||
| 50 | noun_query noun::substance_meronyms() const | ||
| 51 | { | ||
| 52 | return _data.nouns().substance_meronym_of(*this); | ||
| 53 | } | ||
| 54 | |||
| 55 | noun_query noun::substance_holonyms() const | ||
| 56 | { | ||
| 57 | return _data.nouns().substance_holonym_of(*this); | ||
| 58 | } | ||
| 59 | |||
| 60 | noun_query noun::member_meronyms() const | ||
| 61 | { | ||
| 62 | return _data.nouns().member_meronym_of(*this); | ||
| 63 | } | ||
| 64 | |||
| 65 | noun_query noun::member_holonyms() const | ||
| 66 | { | ||
| 67 | return _data.nouns().member_holonym_of(*this); | ||
| 68 | } | ||
| 69 | |||
| 70 | noun_query noun::classes() const | ||
| 71 | { | ||
| 72 | return _data.nouns().class_of(*this); | ||
| 73 | } | ||
| 74 | |||
| 75 | noun_query noun::instances() const | ||
| 76 | { | ||
| 77 | return _data.nouns().instance_of(*this); | ||
| 78 | } | ||
| 79 | |||
| 80 | noun_query noun::synonyms() const | ||
| 81 | { | ||
| 82 | return _data.nouns().synonym_of(*this); | ||
| 83 | } | ||
| 84 | |||
| 85 | noun_query noun::antonyms() const | ||
| 86 | { | ||
| 87 | return _data.nouns().antonym_of(*this); | ||
| 88 | } | ||
| 89 | |||
| 90 | adjective_query noun::pertainyms() const | ||
| 91 | { | ||
| 92 | return _data.adjectives().pertainym_of(*this); | ||
| 93 | } | ||
| 94 | |||
| 95 | adjective_query noun::variations() const | ||
| 96 | { | ||
| 97 | return _data.adjectives().variant_of(*this); | ||
| 98 | } | ||
| 99 | |||
| 100 | noun_query::noun_query(const data& _data) : _data(_data) | ||
| 101 | { | ||
| 102 | |||
| 103 | } | ||
| 104 | |||
| 105 | noun_query& noun_query::limit(int _limit) | ||
| 106 | { | ||
| 107 | if ((_limit > 0) || (_limit == unlimited)) | ||
| 108 | { | ||
| 109 | this->_limit = _limit; | ||
| 110 | } | ||
| 111 | |||
| 112 | return *this; | ||
| 113 | } | ||
| 114 | |||
| 115 | noun_query& noun_query::random(bool _random) | ||
| 116 | { | ||
| 117 | this->_random = _random; | ||
| 118 | |||
| 119 | return *this; | ||
| 120 | } | ||
| 121 | |||
| 122 | noun_query& noun_query::except(const noun& _word) | ||
| 123 | { | ||
| 124 | _except.push_back(_word); | ||
| 125 | |||
| 126 | return *this; | ||
| 127 | } | ||
| 128 | |||
| 129 | noun_query& noun_query::rhymes_with(const word& _word) | ||
| 130 | { | ||
| 131 | for (auto rhyme : _word.rhyme_phonemes()) | ||
| 132 | { | ||
| 133 | _rhymes.push_back(rhyme); | ||
| 134 | } | ||
| 135 | |||
| 136 | if (dynamic_cast<const noun*>(&_word) != nullptr) | ||
| 137 | { | ||
| 138 | _except.push_back(dynamic_cast<const noun&>(_word)); | ||
| 139 | } | ||
| 140 | |||
| 141 | return *this; | ||
| 142 | } | ||
| 143 | |||
| 144 | noun_query& noun_query::has_pronunciation(bool _has_prn) | ||
| 145 | { | ||
| 146 | this->_has_prn = _has_prn; | ||
| 147 | |||
| 148 | return *this; | ||
| 149 | } | ||
| 150 | |||
| 151 | noun_query& noun_query::is_hypernym(bool _arg) | ||
| 152 | { | ||
| 153 | _is_hypernym = _arg; | ||
| 154 | |||
| 155 | return *this; | ||
| 156 | } | ||
| 157 | |||
| 158 | noun_query& noun_query::hypernym_of(const noun& _noun) | ||
| 159 | { | ||
| 160 | _hypernym_of.push_back(_noun); | ||
| 161 | |||
| 162 | return *this; | ||
| 163 | } | ||
| 164 | |||
| 165 | noun_query& noun_query::not_hypernym_of(const noun& _noun) | ||
| 166 | { | ||
| 167 | _not_hypernym_of.push_back(_noun); | ||
| 168 | |||
| 169 | return *this; | ||
| 170 | } | ||
| 171 | |||
| 172 | noun_query& noun_query::is_hyponym(bool _arg) | ||
| 173 | { | ||
| 174 | _is_hyponym = _arg; | ||
| 175 | |||
| 176 | return *this; | ||
| 177 | } | ||
| 178 | |||
| 179 | noun_query& noun_query::hyponym_of(const noun& _noun) | ||
| 180 | { | ||
| 181 | _hyponym_of.push_back(_noun); | ||
| 182 | |||
| 183 | return *this; | ||
| 184 | } | ||
| 185 | |||
| 186 | noun_query& noun_query::not_hyponym_of(const noun& _noun) | ||
| 187 | { | ||
| 188 | _not_hyponym_of.push_back(_noun); | ||
| 189 | |||
| 190 | return *this; | ||
| 191 | } | ||
| 192 | |||
| 193 | noun_query& noun_query::is_part_meronym(bool _arg) | ||
| 194 | { | ||
| 195 | _is_part_meronym = _arg; | ||
| 196 | |||
| 197 | return *this; | ||
| 198 | } | ||
| 199 | |||
| 200 | noun_query& noun_query::part_meronym_of(const noun& _noun) | ||
| 201 | { | ||
| 202 | _part_meronym_of.push_back(_noun); | ||
| 203 | 48 | ||
| 204 | return *this; | 49 | return _data->nouns().hypernym_of(*this); |
| 205 | } | 50 | } |
| 206 | 51 | ||
| 207 | noun_query& noun_query::not_part_meronym_of(const noun& _noun) | 52 | noun_query noun::full_hypernyms() const |
| 208 | { | 53 | { |
| 209 | _not_part_meronym_of.push_back(_noun); | 54 | assert(_valid == true); |
| 210 | 55 | ||
| 211 | return *this; | 56 | return _data->nouns().full_hypernym_of(*this); |
| 212 | } | 57 | } |
| 213 | 58 | ||
| 214 | noun_query& noun_query::is_part_holonym(bool _arg) | 59 | noun_query noun::hyponyms() const |
| 215 | { | ||
| 216 | _is_part_holonym = _arg; | ||
| 217 | |||
| 218 | return *this; | ||
| 219 | } | ||
| 220 | |||
| 221 | noun_query& noun_query::part_holonym_of(const noun& _noun) | ||
| 222 | { | ||
| 223 | _part_holonym_of.push_back(_noun); | ||
| 224 | |||
| 225 | return *this; | ||
| 226 | } | ||
| 227 | |||
| 228 | noun_query& noun_query::not_part_holonym_of(const noun& _noun) | ||
| 229 | { | ||
| 230 | _not_part_holonym_of.push_back(_noun); | ||
| 231 | |||
| 232 | return *this; | ||
| 233 | } | ||
| 234 | |||
| 235 | noun_query& noun_query::is_substance_meronym(bool _arg) | ||
| 236 | { | ||
| 237 | _is_substance_meronym = _arg; | ||
| 238 | |||
| 239 | return *this; | ||
| 240 | } | ||
| 241 | |||
| 242 | noun_query& noun_query::substance_meronym_of(const noun& _noun) | ||
| 243 | { | ||
| 244 | _substance_meronym_of.push_back(_noun); | ||
| 245 | |||
| 246 | return *this; | ||
| 247 | } | ||
| 248 | |||
| 249 | noun_query& noun_query::not_substance_meronym_of(const noun& _noun) | ||
| 250 | { | ||
| 251 | _not_substance_meronym_of.push_back(_noun); | ||
| 252 | |||
| 253 | return *this; | ||
| 254 | } | ||
| 255 | |||
| 256 | noun_query& noun_query::is_substance_holonym(bool _arg) | ||
| 257 | { | ||
| 258 | _is_substance_holonym = _arg; | ||
| 259 | |||
| 260 | return *this; | ||
| 261 | } | ||
| 262 | |||
| 263 | noun_query& noun_query::substance_holonym_of(const noun& _noun) | ||
| 264 | { | ||
| 265 | _substance_holonym_of.push_back(_noun); | ||
| 266 | |||
| 267 | return *this; | ||
| 268 | } | ||
| 269 | |||
| 270 | noun_query& noun_query::not_substance_holonym_of(const noun& _noun) | ||
| 271 | { | ||
| 272 | _not_substance_holonym_of.push_back(_noun); | ||
| 273 | |||
| 274 | return *this; | ||
| 275 | } | ||
| 276 | |||
| 277 | noun_query& noun_query::is_member_meronym(bool _arg) | ||
| 278 | { | ||
| 279 | _is_member_meronym = _arg; | ||
| 280 | |||
| 281 | return *this; | ||
| 282 | } | ||
| 283 | |||
| 284 | noun_query& noun_query::member_meronym_of(const noun& _noun) | ||
| 285 | { | ||
| 286 | _member_meronym_of.push_back(_noun); | ||
| 287 | |||
| 288 | return *this; | ||
| 289 | } | ||
| 290 | |||
| 291 | noun_query& noun_query::not_member_meronym_of(const noun& _noun) | ||
| 292 | { | ||
| 293 | _not_member_meronym_of.push_back(_noun); | ||
| 294 | |||
| 295 | return *this; | ||
| 296 | } | ||
| 297 | |||
| 298 | noun_query& noun_query::is_member_holonym(bool _arg) | ||
| 299 | { | ||
| 300 | _is_member_holonym = _arg; | ||
| 301 | |||
| 302 | return *this; | ||
| 303 | } | ||
| 304 | |||
| 305 | noun_query& noun_query::member_holonym_of(const noun& _noun) | ||
| 306 | { | ||
| 307 | _member_holonym_of.push_back(_noun); | ||
| 308 | |||
| 309 | return *this; | ||
| 310 | } | ||
| 311 | |||
| 312 | noun_query& noun_query::not_member_holonym_of(const noun& _noun) | ||
| 313 | { | ||
| 314 | _not_member_holonym_of.push_back(_noun); | ||
| 315 | |||
| 316 | return *this; | ||
| 317 | } | ||
| 318 | |||
| 319 | noun_query& noun_query::is_proper(bool _arg) | ||
| 320 | { | ||
| 321 | _is_proper = _arg; | ||
| 322 | |||
| 323 | return *this; | ||
| 324 | } | ||
| 325 | |||
| 326 | noun_query& noun_query::is_not_proper(bool _arg) | ||
| 327 | { | ||
| 328 | _is_not_proper = _arg; | ||
| 329 | |||
| 330 | return *this; | ||
| 331 | } | ||
| 332 | |||
| 333 | noun_query& noun_query::is_instance(bool _arg) | ||
| 334 | { | ||
| 335 | _is_instance = _arg; | ||
| 336 | |||
| 337 | return *this; | ||
| 338 | } | ||
| 339 | |||
| 340 | noun_query& noun_query::instance_of(const noun& _noun) | ||
| 341 | { | ||
| 342 | _instance_of.push_back(_noun); | ||
| 343 | |||
| 344 | return *this; | ||
| 345 | } | ||
| 346 | |||
| 347 | noun_query& noun_query::not_instance_of(const noun& _noun) | ||
| 348 | { | ||
| 349 | _not_instance_of.push_back(_noun); | ||
| 350 | |||
| 351 | return *this; | ||
| 352 | } | ||
| 353 | |||
| 354 | noun_query& noun_query::is_class(bool _arg) | ||
| 355 | { | ||
| 356 | _is_class = _arg; | ||
| 357 | |||
| 358 | return *this; | ||
| 359 | } | ||
| 360 | |||
| 361 | noun_query& noun_query::class_of(const noun& _noun) | ||
| 362 | { | 60 | { |
| 363 | _class_of.push_back(_noun); | 61 | assert(_valid == true); |
| 364 | 62 | ||
| 365 | return *this; | 63 | return _data->nouns().hyponym_of(*this); |
| 366 | } | 64 | } |
| 367 | 65 | ||
| 368 | noun_query& noun_query::not_class_of(const noun& _noun) | 66 | noun_query noun::full_hyponyms() const |
| 369 | { | 67 | { |
| 370 | _not_class_of.push_back(_noun); | 68 | assert(_valid == true); |
| 371 | 69 | ||
| 372 | return *this; | 70 | return _data->nouns().full_hyponym_of(*this); |
| 373 | } | 71 | } |
| 374 | 72 | ||
| 375 | noun_query& noun_query::has_synonyms(bool _arg) | 73 | noun_query noun::part_meronyms() const |
| 376 | { | 74 | { |
| 377 | _has_synonyms = _arg; | 75 | assert(_valid == true); |
| 378 | 76 | ||
| 379 | return *this; | 77 | return _data->nouns().part_meronym_of(*this); |
| 380 | } | 78 | } |
| 381 | 79 | ||
| 382 | noun_query& noun_query::synonym_of(const noun& _noun) | 80 | noun_query noun::part_holonyms() const |
| 383 | { | 81 | { |
| 384 | _synonym_of.push_back(_noun); | 82 | assert(_valid == true); |
| 385 | 83 | ||
| 386 | return *this; | 84 | return _data->nouns().part_holonym_of(*this); |
| 387 | } | 85 | } |
| 388 | 86 | ||
| 389 | noun_query& noun_query::not_synonym_of(const noun& _noun) | 87 | noun_query noun::substance_meronyms() const |
| 390 | { | 88 | { |
| 391 | _not_synonym_of.push_back(_noun); | 89 | assert(_valid == true); |
| 392 | 90 | ||
| 393 | return *this; | 91 | return _data->nouns().substance_meronym_of(*this); |
| 394 | } | 92 | } |
| 395 | 93 | ||
| 396 | noun_query& noun_query::has_antonyms(bool _arg) | 94 | noun_query noun::substance_holonyms() const |
| 397 | { | 95 | { |
| 398 | _has_antonyms = _arg; | 96 | assert(_valid == true); |
| 399 | 97 | ||
| 400 | return *this; | 98 | return _data->nouns().substance_holonym_of(*this); |
| 401 | } | 99 | } |
| 402 | 100 | ||
| 403 | noun_query& noun_query::antonym_of(const noun& _noun) | 101 | noun_query noun::member_meronyms() const |
| 404 | { | 102 | { |
| 405 | _antonym_of.push_back(_noun); | 103 | assert(_valid == true); |
| 406 | 104 | ||
| 407 | return *this; | 105 | return _data->nouns().member_meronym_of(*this); |
| 408 | } | 106 | } |
| 409 | 107 | ||
| 410 | noun_query& noun_query::not_antonym_of(const noun& _noun) | 108 | noun_query noun::member_holonyms() const |
| 411 | { | 109 | { |
| 412 | _not_antonym_of.push_back(_noun); | 110 | assert(_valid == true); |
| 413 | 111 | ||
| 414 | return *this; | 112 | return _data->nouns().member_holonym_of(*this); |
| 415 | } | 113 | } |
| 416 | 114 | ||
| 417 | noun_query& noun_query::has_pertainym(bool _arg) | 115 | noun_query noun::classes() const |
| 418 | { | 116 | { |
| 419 | _has_pertainym = _arg; | 117 | assert(_valid == true); |
| 420 | 118 | ||
| 421 | return *this; | 119 | return _data->nouns().class_of(*this); |
| 422 | } | 120 | } |
| 423 | 121 | ||
| 424 | noun_query& noun_query::anti_pertainym_of(const adjective& _adj) | 122 | noun_query noun::instances() const |
| 425 | { | 123 | { |
| 426 | _anti_pertainym_of.push_back(_adj); | 124 | assert(_valid == true); |
| 427 | 125 | ||
| 428 | return *this; | 126 | return _data->nouns().instance_of(*this); |
| 429 | } | 127 | } |
| 430 | 128 | ||
| 431 | noun_query& noun_query::is_attribute(bool _arg) | 129 | noun_query noun::synonyms() const |
| 432 | { | 130 | { |
| 433 | _is_attribute = _arg; | 131 | assert(_valid == true); |
| 434 | 132 | ||
| 435 | return *this; | 133 | return _data->nouns().synonym_of(*this); |
| 436 | } | 134 | } |
| 437 | 135 | ||
| 438 | noun_query& noun_query::attribute_of(const adjective& _adj) | 136 | noun_query noun::antonyms() const |
| 439 | { | 137 | { |
| 440 | _attribute_of.push_back(_adj); | 138 | assert(_valid == true); |
| 441 | 139 | ||
| 442 | return *this; | 140 | return _data->nouns().antonym_of(*this); |
| 443 | } | 141 | } |
| 444 | 142 | ||
| 445 | noun_query& noun_query::derived_from(const word& _w) | 143 | adjective_query noun::pertainyms() const |
| 446 | { | 144 | { |
| 447 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | 145 | assert(_valid == true); |
| 448 | { | ||
| 449 | _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 450 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 451 | { | ||
| 452 | _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 453 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 454 | { | ||
| 455 | _derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 456 | } | ||
| 457 | 146 | ||
| 458 | return *this; | 147 | return _data->adjectives().pertainym_of(*this); |
| 459 | } | 148 | } |
| 460 | 149 | ||
| 461 | noun_query& noun_query::not_derived_from(const word& _w) | 150 | adjective_query noun::variations() const |
| 462 | { | 151 | { |
| 463 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | 152 | assert(_valid == true); |
| 464 | { | ||
| 465 | _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 466 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 467 | { | ||
| 468 | _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 469 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 470 | { | ||
| 471 | _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 472 | } | ||
| 473 | 153 | ||
| 474 | return *this; | 154 | return _data->adjectives().variant_of(*this); |
| 475 | } | 155 | } |
| 476 | 156 | ||
| 477 | std::list<noun> noun_query::run() const | 157 | bool noun::operator<(const noun& other) const |
| 478 | { | 158 | { |
| 479 | std::stringstream construct; | 159 | return _id < other._id; |
| 480 | construct << "SELECT noun_id, singular, plural FROM nouns"; | ||
| 481 | std::list<std::string> conditions; | ||
| 482 | |||
| 483 | if (_has_prn) | ||
| 484 | { | ||
| 485 | conditions.push_back("noun_id IN (SELECT noun_id FROM noun_pronunciations)"); | ||
| 486 | } | ||
| 487 | |||
| 488 | if (!_rhymes.empty()) | ||
| 489 | { | ||
| 490 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
| 491 | std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 492 | conditions.push_back(cond); | ||
| 493 | } | ||
| 494 | |||
| 495 | for (auto except : _except) | ||
| 496 | { | ||
| 497 | conditions.push_back("noun_id != @EXCID"); | ||
| 498 | } | ||
| 499 | |||
| 500 | if (_is_hypernym) | ||
| 501 | { | ||
| 502 | conditions.push_back("noun_id IN (SELECT hypernym_id FROM hypernymy)"); | ||
| 503 | } | ||
| 504 | |||
| 505 | if (!_hypernym_of.empty()) | ||
| 506 | { | ||
| 507 | std::list<std::string> clauses(_hypernym_of.size(), "hyponym_id = @HYPO"); | ||
| 508 | std::string cond = "noun_id IN (SELECT hypernym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 509 | conditions.push_back(cond); | ||
| 510 | } | ||
| 511 | |||
| 512 | if (!_not_hypernym_of.empty()) | ||
| 513 | { | ||
| 514 | std::list<std::string> clauses(_not_hypernym_of.size(), "hyponym_id = @NHYPO"); | ||
| 515 | std::string cond = "noun_id NOT IN (SELECT hypernym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 516 | conditions.push_back(cond); | ||
| 517 | } | ||
| 518 | |||
| 519 | if (_is_hyponym) | ||
| 520 | { | ||
| 521 | conditions.push_back("noun_id IN (SELECT hyponym_id FROM hypernymy)"); | ||
| 522 | } | ||
| 523 | |||
| 524 | if (!_hyponym_of.empty()) | ||
| 525 | { | ||
| 526 | std::list<std::string> clauses(_hyponym_of.size(), "hypernym_id = @HYPER"); | ||
| 527 | std::string cond = "noun_id IN (SELECT hyponym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 528 | conditions.push_back(cond); | ||
| 529 | } | ||
| 530 | |||
| 531 | if (!_not_hyponym_of.empty()) | ||
| 532 | { | ||
| 533 | std::list<std::string> clauses(_not_hyponym_of.size(), "hypernym_id = @NHYPER"); | ||
| 534 | std::string cond = "noun_id NOT IN (SELECT hyponym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 535 | conditions.push_back(cond); | ||
| 536 | } | ||
| 537 | |||
| 538 | if (_is_part_meronym) | ||
| 539 | { | ||
| 540 | conditions.push_back("noun_id IN (SELECT meronym_id FROM part_meronymy)"); | ||
| 541 | } | ||
| 542 | |||
| 543 | if (!_part_meronym_of.empty()) | ||
| 544 | { | ||
| 545 | std::list<std::string> clauses(_part_meronym_of.size(), "holonym_id = @PHOLO"); | ||
| 546 | std::string cond = "noun_id IN (SELECT meronym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 547 | conditions.push_back(cond); | ||
| 548 | } | ||
| 549 | |||
| 550 | if (!_not_part_meronym_of.empty()) | ||
| 551 | { | ||
| 552 | std::list<std::string> clauses(_not_part_meronym_of.size(), "holonym_id = @NPHOLO"); | ||
| 553 | std::string cond = "noun_id NOT IN (SELECT meronym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 554 | conditions.push_back(cond); | ||
| 555 | } | ||
| 556 | |||
| 557 | if (_is_part_holonym) | ||
| 558 | { | ||
| 559 | conditions.push_back("noun_id IN (SELECT holonym_id FROM part_meronymy)"); | ||
| 560 | } | ||
| 561 | |||
| 562 | if (!_part_holonym_of.empty()) | ||
| 563 | { | ||
| 564 | std::list<std::string> clauses(_part_holonym_of.size(), "meronym_id = @PMERO"); | ||
| 565 | std::string cond = "noun_id IN (SELECT holonym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 566 | conditions.push_back(cond); | ||
| 567 | } | ||
| 568 | |||
| 569 | if (!_not_part_holonym_of.empty()) | ||
| 570 | { | ||
| 571 | std::list<std::string> clauses(_not_part_holonym_of.size(), "meronym_id = @NPMERO"); | ||
| 572 | std::string cond = "noun_id NOT IN (SELECT holonym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 573 | conditions.push_back(cond); | ||
| 574 | } | ||
| 575 | |||
| 576 | if (_is_substance_meronym) | ||
| 577 | { | ||
| 578 | conditions.push_back("noun_id IN (SELECT meronym_id FROM substance_meronymy)"); | ||
| 579 | } | ||
| 580 | |||
| 581 | if (!_substance_meronym_of.empty()) | ||
| 582 | { | ||
| 583 | std::list<std::string> clauses(_substance_meronym_of.size(), "holonym_id = @SHOLO"); | ||
| 584 | std::string cond = "noun_id IN (SELECT meronym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 585 | conditions.push_back(cond); | ||
| 586 | } | ||
| 587 | |||
| 588 | if (!_not_substance_meronym_of.empty()) | ||
| 589 | { | ||
| 590 | std::list<std::string> clauses(_not_substance_meronym_of.size(), "holonym_id = @NSHOLO"); | ||
| 591 | std::string cond = "noun_id NOT IN (SELECT meronym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 592 | conditions.push_back(cond); | ||
| 593 | } | ||
| 594 | |||
| 595 | if (_is_substance_holonym) | ||
| 596 | { | ||
| 597 | conditions.push_back("noun_id IN (SELECT holonym_id FROM substance_meronymy)"); | ||
| 598 | } | ||
| 599 | |||
| 600 | if (!_substance_holonym_of.empty()) | ||
| 601 | { | ||
| 602 | std::list<std::string> clauses(_substance_holonym_of.size(), "meronym_id = @SMERO"); | ||
| 603 | std::string cond = "noun_id IN (SELECT holonym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 604 | conditions.push_back(cond); | ||
| 605 | } | ||
| 606 | |||
| 607 | if (!_not_substance_holonym_of.empty()) | ||
| 608 | { | ||
| 609 | std::list<std::string> clauses(_not_substance_holonym_of.size(), "meronym_id = @NSMERO"); | ||
| 610 | std::string cond = "noun_id NOT IN (SELECT holonym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 611 | conditions.push_back(cond); | ||
| 612 | } | ||
| 613 | |||
| 614 | if (_is_member_meronym) | ||
| 615 | { | ||
| 616 | conditions.push_back("noun_id IN (SELECT meronym_id FROM member_meronymy)"); | ||
| 617 | } | ||
| 618 | |||
| 619 | if (!_member_meronym_of.empty()) | ||
| 620 | { | ||
| 621 | std::list<std::string> clauses(_member_meronym_of.size(), "holonym_id = @MHOLO"); | ||
| 622 | std::string cond = "noun_id IN (SELECT meronym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 623 | conditions.push_back(cond); | ||
| 624 | } | ||
| 625 | |||
| 626 | if (!_not_member_meronym_of.empty()) | ||
| 627 | { | ||
| 628 | std::list<std::string> clauses(_not_member_meronym_of.size(), "holonym_id = @NMHOLO"); | ||
| 629 | std::string cond = "noun_id NOT IN (SELECT meronym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 630 | conditions.push_back(cond); | ||
| 631 | } | ||
| 632 | |||
| 633 | if (_is_member_holonym) | ||
| 634 | { | ||
| 635 | conditions.push_back("noun_id IN (SELECT holonym_id FROM member_meronym)"); | ||
| 636 | } | ||
| 637 | |||
| 638 | if (!_member_holonym_of.empty()) | ||
| 639 | { | ||
| 640 | std::list<std::string> clauses(_member_holonym_of.size(), "meronym_id = @MMERO"); | ||
| 641 | std::string cond = "noun_id IN (SELECT holonym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 642 | conditions.push_back(cond); | ||
| 643 | } | ||
| 644 | |||
| 645 | if (!_not_member_holonym_of.empty()) | ||
| 646 | { | ||
| 647 | std::list<std::string> clauses(_not_member_holonym_of.size(), "meronym_id = @NMMERO"); | ||
| 648 | std::string cond = "noun_id NOT IN (SELECT holonym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 649 | conditions.push_back(cond); | ||
| 650 | } | ||
| 651 | |||
| 652 | if (_is_proper) | ||
| 653 | { | ||
| 654 | conditions.push_back("proper = 1"); | ||
| 655 | } | ||
| 656 | |||
| 657 | if (_is_not_proper) | ||
| 658 | { | ||
| 659 | conditions.push_back("proper = 0"); | ||
| 660 | } | ||
| 661 | |||
| 662 | if (_is_instance) | ||
| 663 | { | ||
| 664 | conditions.push_back("noun_id IN (SELECT instance_id FROM instantiation)"); | ||
| 665 | } | ||
| 666 | |||
| 667 | if (!_instance_of.empty()) | ||
| 668 | { | ||
| 669 | std::list<std::string> clauses(_instance_of.size(), "class_id = @CLSID"); | ||
| 670 | std::string cond = "noun_id IN (SELECT instance_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 671 | conditions.push_back(cond); | ||
| 672 | } | ||
| 673 | |||
| 674 | if (!_not_instance_of.empty()) | ||
| 675 | { | ||
| 676 | std::list<std::string> clauses(_not_instance_of.size(), "class_id = @NCLSID"); | ||
| 677 | std::string cond = "noun_id NOT IN (SELECT instance_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 678 | conditions.push_back(cond); | ||
| 679 | } | ||
| 680 | |||
| 681 | if (_is_class) | ||
| 682 | { | ||
| 683 | conditions.push_back("noun_id IN (SELECT class_id FROM instantiation)"); | ||
| 684 | } | ||
| 685 | |||
| 686 | if (!_class_of.empty()) | ||
| 687 | { | ||
| 688 | std::list<std::string> clauses(_class_of.size(), "instance_id = @INSID"); | ||
| 689 | std::string cond = "noun_id IN (SELECT class_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 690 | conditions.push_back(cond); | ||
| 691 | } | ||
| 692 | |||
| 693 | if (!_not_class_of.empty()) | ||
| 694 | { | ||
| 695 | std::list<std::string> clauses(_not_class_of.size(), "instance_id = @NINSID"); | ||
| 696 | std::string cond = "noun_id NOT IN (SELECT class_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 697 | conditions.push_back(cond); | ||
| 698 | } | ||
| 699 | |||
| 700 | if (_has_synonyms) | ||
| 701 | { | ||
| 702 | conditions.push_back("noun_id IN (SELECT adjective_2_id FROM adjective_synonymy)"); | ||
| 703 | } | ||
| 704 | |||
| 705 | if (!_synonym_of.empty()) | ||
| 706 | { | ||
| 707 | std::list<std::string> clauses(_synonym_of.size(), "adjective_1_id = @SYNID"); | ||
| 708 | std::string cond = "noun_id IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 709 | conditions.push_back(cond); | ||
| 710 | } | ||
| 711 | |||
| 712 | if (!_not_synonym_of.empty()) | ||
| 713 | { | ||
| 714 | std::list<std::string> clauses(_not_synonym_of.size(), "adjective_1_id = @NSYNID"); | ||
| 715 | std::string cond = "noun_id NOT IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 716 | conditions.push_back(cond); | ||
| 717 | } | ||
| 718 | |||
| 719 | if (_has_antonyms) | ||
| 720 | { | ||
| 721 | conditions.push_back("noun_id IN (SELECT adjective_2_id FROM adjective_antonymy)"); | ||
| 722 | } | ||
| 723 | |||
| 724 | if (!_antonym_of.empty()) | ||
| 725 | { | ||
| 726 | std::list<std::string> clauses(_antonym_of.size(), "adjective_1_id = @ANTID"); | ||
| 727 | std::string cond = "noun_id IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 728 | conditions.push_back(cond); | ||
| 729 | } | ||
| 730 | |||
| 731 | if (!_not_antonym_of.empty()) | ||
| 732 | { | ||
| 733 | std::list<std::string> clauses(_not_antonym_of.size(), "adjective_1_id = @NANTID"); | ||
| 734 | std::string cond = "noun_id NOT IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 735 | conditions.push_back(cond); | ||
| 736 | } | ||
| 737 | |||
| 738 | if (_has_pertainym) | ||
| 739 | { | ||
| 740 | conditions.push_back("noun_id IN (SELECT noun_id FROM pertainymy)"); | ||
| 741 | } | ||
| 742 | |||
| 743 | if (!_anti_pertainym_of.empty()) | ||
| 744 | { | ||
| 745 | std::list<std::string> clauses(_anti_pertainym_of.size(), "pertainym_id = @PERID"); | ||
| 746 | std::string cond = "noun_id IN (SELECT noun_id FROM pertainymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 747 | conditions.push_back(cond); | ||
| 748 | } | ||
| 749 | |||
| 750 | if (_is_attribute) | ||
| 751 | { | ||
| 752 | conditions.push_back("noun_id IN (SELECT noun_id FROM variation)"); | ||
| 753 | } | ||
| 754 | |||
| 755 | if (!_attribute_of.empty()) | ||
| 756 | { | ||
| 757 | std::list<std::string> clauses(_attribute_of.size(), "adjective_id = @VALID"); | ||
| 758 | std::string cond = "noun_id IN (SELECT noun_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 759 | conditions.push_back(cond); | ||
| 760 | } | ||
| 761 | |||
| 762 | if (!_derived_from_adjective.empty()) | ||
| 763 | { | ||
| 764 | std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_id = @DERADJ"); | ||
| 765 | std::string cond = "noun_id IN (SELECT noun_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 766 | conditions.push_back(cond); | ||
| 767 | } | ||
| 768 | |||
| 769 | if (!_not_derived_from_adjective.empty()) | ||
| 770 | { | ||
| 771 | std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_id = @NDERADJ"); | ||
| 772 | std::string cond = "noun_id NOT IN (SELECT noun_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 773 | conditions.push_back(cond); | ||
| 774 | } | ||
| 775 | |||
| 776 | if (!_derived_from_adverb.empty()) | ||
| 777 | { | ||
| 778 | std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_id = @DERADV"); | ||
| 779 | std::string cond = "noun_id IN (SELECT noun_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 780 | conditions.push_back(cond); | ||
| 781 | } | ||
| 782 | |||
| 783 | if (!_not_derived_from_adverb.empty()) | ||
| 784 | { | ||
| 785 | std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_id = @NDERADV"); | ||
| 786 | std::string cond = "noun_id NOT IN (SELECT noun_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 787 | conditions.push_back(cond); | ||
| 788 | } | ||
| 789 | |||
| 790 | if (!_derived_from_noun.empty()) | ||
| 791 | { | ||
| 792 | std::list<std::string> clauses(_derived_from_noun.size(), "noun_2_id = @DERN"); | ||
| 793 | std::string cond = "noun_id IN (SELECT noun_1_id FROM noun_noun_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 794 | conditions.push_back(cond); | ||
| 795 | } | ||
| 796 | |||
| 797 | if (!_not_derived_from_noun.empty()) | ||
| 798 | { | ||
| 799 | std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_2_id = @NDERN"); | ||
| 800 | 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 ") + ")"; | ||
| 801 | conditions.push_back(cond); | ||
| 802 | } | ||
| 803 | |||
| 804 | if (!conditions.empty()) | ||
| 805 | { | ||
| 806 | construct << " WHERE "; | ||
| 807 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
| 808 | } | ||
| 809 | |||
| 810 | if (_random) | ||
| 811 | { | ||
| 812 | construct << " ORDER BY RANDOM()"; | ||
| 813 | } | ||
| 814 | |||
| 815 | if (_limit != unlimited) | ||
| 816 | { | ||
| 817 | construct << " LIMIT " << _limit; | ||
| 818 | } | ||
| 819 | |||
| 820 | sqlite3_stmt* ppstmt; | ||
| 821 | std::string query = construct.str(); | ||
| 822 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 823 | { | ||
| 824 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 825 | } | ||
| 826 | |||
| 827 | if (!_rhymes.empty()) | ||
| 828 | { | ||
| 829 | int i = 0; | ||
| 830 | for (auto rhyme : _rhymes) | ||
| 831 | { | ||
| 832 | std::string rhymer = "%" + rhyme; | ||
| 833 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
| 834 | |||
| 835 | i++; | ||
| 836 | } | ||
| 837 | } | ||
| 838 | |||
| 839 | for (auto except : _except) | ||
| 840 | { | ||
| 841 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
| 842 | } | ||
| 843 | |||
| 844 | for (auto hyponym : _hypernym_of) | ||
| 845 | { | ||
| 846 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPO"), hyponym._id); | ||
| 847 | } | ||
| 848 | |||
| 849 | for (auto hyponym : _not_hypernym_of) | ||
| 850 | { | ||
| 851 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NHYPO"), hyponym._id); | ||
| 852 | } | ||
| 853 | |||
| 854 | for (auto hypernym : _hyponym_of) | ||
| 855 | { | ||
| 856 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPER"), hypernym._id); | ||
| 857 | } | ||
| 858 | |||
| 859 | for (auto hypernym : _not_hyponym_of) | ||
| 860 | { | ||
| 861 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NHYPER"), hypernym._id); | ||
| 862 | } | ||
| 863 | |||
| 864 | for (auto holonym : _part_meronym_of) | ||
| 865 | { | ||
| 866 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PHOLO"), holonym._id); | ||
| 867 | } | ||
| 868 | |||
| 869 | for (auto holonym : _not_part_meronym_of) | ||
| 870 | { | ||
| 871 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NPHOLO"), holonym._id); | ||
| 872 | } | ||
| 873 | |||
| 874 | for (auto meronym : _part_holonym_of) | ||
| 875 | { | ||
| 876 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PMERO"), meronym._id); | ||
| 877 | } | ||
| 878 | |||
| 879 | for (auto meronym : _not_part_holonym_of) | ||
| 880 | { | ||
| 881 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NPMERO"), meronym._id); | ||
| 882 | } | ||
| 883 | |||
| 884 | for (auto holonym : _substance_meronym_of) | ||
| 885 | { | ||
| 886 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SHOLO"), holonym._id); | ||
| 887 | } | ||
| 888 | |||
| 889 | for (auto holonym : _not_substance_meronym_of) | ||
| 890 | { | ||
| 891 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSHOLO"), holonym._id); | ||
| 892 | } | ||
| 893 | |||
| 894 | for (auto meronym : _substance_holonym_of) | ||
| 895 | { | ||
| 896 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SMERO"), meronym._id); | ||
| 897 | } | ||
| 898 | |||
| 899 | for (auto meronym : _not_substance_holonym_of) | ||
| 900 | { | ||
| 901 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSMERO"), meronym._id); | ||
| 902 | } | ||
| 903 | |||
| 904 | for (auto holonym : _member_meronym_of) | ||
| 905 | { | ||
| 906 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MHOLO"), holonym._id); | ||
| 907 | } | ||
| 908 | |||
| 909 | for (auto holonym : _not_member_meronym_of) | ||
| 910 | { | ||
| 911 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NMHOLO"), holonym._id); | ||
| 912 | } | ||
| 913 | |||
| 914 | for (auto meronym : _member_holonym_of) | ||
| 915 | { | ||
| 916 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MMERO"), meronym._id); | ||
| 917 | } | ||
| 918 | |||
| 919 | for (auto meronym : _not_member_holonym_of) | ||
| 920 | { | ||
| 921 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NMMERO"), meronym._id); | ||
| 922 | } | ||
| 923 | |||
| 924 | for (auto cls : _instance_of) | ||
| 925 | { | ||
| 926 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@CLSID"), cls._id); | ||
| 927 | } | ||
| 928 | |||
| 929 | for (auto cls : _not_instance_of) | ||
| 930 | { | ||
| 931 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NCLSID"), cls._id); | ||
| 932 | } | ||
| 933 | |||
| 934 | for (auto inst : _class_of) | ||
| 935 | { | ||
| 936 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@INSID"), inst._id); | ||
| 937 | } | ||
| 938 | |||
| 939 | for (auto inst : _not_class_of) | ||
| 940 | { | ||
| 941 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NINSID"), inst._id); | ||
| 942 | } | ||
| 943 | |||
| 944 | for (auto synonym : _synonym_of) | ||
| 945 | { | ||
| 946 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
| 947 | } | ||
| 948 | |||
| 949 | for (auto synonym : _not_synonym_of) | ||
| 950 | { | ||
| 951 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); | ||
| 952 | } | ||
| 953 | |||
| 954 | for (auto antonym : _antonym_of) | ||
| 955 | { | ||
| 956 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
| 957 | } | ||
| 958 | |||
| 959 | for (auto antonym : _not_antonym_of) | ||
| 960 | { | ||
| 961 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); | ||
| 962 | } | ||
| 963 | |||
| 964 | for (auto pertainym : _anti_pertainym_of) | ||
| 965 | { | ||
| 966 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PERID"), pertainym._id); | ||
| 967 | } | ||
| 968 | |||
| 969 | for (auto value : _attribute_of) | ||
| 970 | { | ||
| 971 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VALID"), value._id); | ||
| 972 | } | ||
| 973 | |||
| 974 | for (auto adj : _derived_from_adjective) | ||
| 975 | { | ||
| 976 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id); | ||
| 977 | } | ||
| 978 | |||
| 979 | for (auto adj : _not_derived_from_adjective) | ||
| 980 | { | ||
| 981 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id); | ||
| 982 | } | ||
| 983 | |||
| 984 | for (auto adv : _derived_from_adverb) | ||
| 985 | { | ||
| 986 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id); | ||
| 987 | } | ||
| 988 | |||
| 989 | for (auto adv : _not_derived_from_adverb) | ||
| 990 | { | ||
| 991 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id); | ||
| 992 | } | ||
| 993 | |||
| 994 | for (auto n : _derived_from_noun) | ||
| 995 | { | ||
| 996 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id); | ||
| 997 | } | ||
| 998 | |||
| 999 | for (auto n : _not_derived_from_noun) | ||
| 1000 | { | ||
| 1001 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id); | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | std::list<noun> output; | ||
| 1005 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 1006 | { | ||
| 1007 | noun tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
| 1008 | tnc._singular = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
| 1009 | |||
| 1010 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
| 1011 | { | ||
| 1012 | tnc._plural = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | output.push_back(tnc); | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | sqlite3_finalize(ppstmt); | ||
| 1019 | |||
| 1020 | for (auto& noun : output) | ||
| 1021 | { | ||
| 1022 | query = "SELECT pronunciation FROM noun_pronunciations WHERE noun_id = ?"; | ||
| 1023 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 1024 | { | ||
| 1025 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | sqlite3_bind_int(ppstmt, 1, noun._id); | ||
| 1029 | |||
| 1030 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 1031 | { | ||
| 1032 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
| 1033 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
| 1034 | |||
| 1035 | noun.pronunciations.push_back(phonemes); | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | sqlite3_finalize(ppstmt); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | return output; | ||
| 1042 | } | 160 | } |
| 1043 | 161 | ||
| 1044 | }; | 162 | }; |
| diff --git a/lib/noun.h b/lib/noun.h index fbc2f9e..77601d0 100644 --- a/lib/noun.h +++ b/lib/noun.h | |||
| @@ -11,6 +11,7 @@ namespace verbly { | |||
| 11 | friend class noun_query; | 11 | friend class noun_query; |
| 12 | 12 | ||
| 13 | public: | 13 | public: |
| 14 | noun(); | ||
| 14 | noun(const data& _data, int _id); | 15 | noun(const data& _data, int _id); |
| 15 | 16 | ||
| 16 | std::string base_form() const; | 17 | std::string base_form() const; |
| @@ -20,7 +21,9 @@ namespace verbly { | |||
| 20 | bool has_plural_form() const; | 21 | bool has_plural_form() const; |
| 21 | 22 | ||
| 22 | noun_query hypernyms() const; | 23 | noun_query hypernyms() const; |
| 24 | noun_query full_hypernyms() const; | ||
| 23 | noun_query hyponyms() const; | 25 | noun_query hyponyms() const; |
| 26 | noun_query full_hyponyms() const; | ||
| 24 | noun_query part_meronyms() const; | 27 | noun_query part_meronyms() const; |
| 25 | noun_query part_holonyms() const; | 28 | noun_query part_holonyms() const; |
| 26 | noun_query substance_meronyms() const; | 29 | noun_query substance_meronyms() const; |
| @@ -33,153 +36,8 @@ namespace verbly { | |||
| 33 | noun_query antonyms() const; | 36 | noun_query antonyms() const; |
| 34 | adjective_query pertainyms() const; | 37 | adjective_query pertainyms() const; |
| 35 | adjective_query variations() const; | 38 | adjective_query variations() const; |
| 36 | }; | ||
| 37 | |||
| 38 | class noun_query { | ||
| 39 | public: | ||
| 40 | noun_query(const data& _data); | ||
| 41 | |||
| 42 | noun_query& limit(int _limit); | ||
| 43 | noun_query& random(bool _random); | ||
| 44 | noun_query& except(const noun& _word); | ||
| 45 | noun_query& rhymes_with(const word& _word); | ||
| 46 | noun_query& has_pronunciation(bool _has_prn); | ||
| 47 | |||
| 48 | noun_query& is_hypernym(bool _arg); | ||
| 49 | noun_query& hypernym_of(const noun& _noun); | ||
| 50 | noun_query& not_hypernym_of(const noun& _noun); | ||
| 51 | |||
| 52 | noun_query& is_hyponym(bool _arg); | ||
| 53 | noun_query& hyponym_of(const noun& _noun); | ||
| 54 | noun_query& not_hyponym_of(const noun& _noun); | ||
| 55 | |||
| 56 | noun_query& is_part_meronym(bool _arg); | ||
| 57 | noun_query& part_meronym_of(const noun& _noun); | ||
| 58 | noun_query& not_part_meronym_of(const noun& _noun); | ||
| 59 | |||
| 60 | noun_query& is_part_holonym(bool _arg); | ||
| 61 | noun_query& part_holonym_of(const noun& _noun); | ||
| 62 | noun_query& not_part_holonym_of(const noun& _noun); | ||
| 63 | |||
| 64 | noun_query& is_substance_meronym(bool _arg); | ||
| 65 | noun_query& substance_meronym_of(const noun& _noun); | ||
| 66 | noun_query& not_substance_meronym_of(const noun& _noun); | ||
| 67 | |||
| 68 | noun_query& is_substance_holonym(bool _arg); | ||
| 69 | noun_query& substance_holonym_of(const noun& _noun); | ||
| 70 | noun_query& not_substance_holonym_of(const noun& _noun); | ||
| 71 | |||
| 72 | noun_query& is_member_meronym(bool _arg); | ||
| 73 | noun_query& member_meronym_of(const noun& _noun); | ||
| 74 | noun_query& not_member_meronym_of(const noun& _noun); | ||
| 75 | |||
| 76 | noun_query& is_member_holonym(bool _arg); | ||
| 77 | noun_query& member_holonym_of(const noun& _noun); | ||
| 78 | noun_query& not_member_holonym_of(const noun& _noun); | ||
| 79 | |||
| 80 | noun_query& is_proper(bool _arg); | ||
| 81 | noun_query& is_not_proper(bool _arg); | ||
| 82 | |||
| 83 | noun_query& is_instance(bool _arg); | ||
| 84 | noun_query& instance_of(const noun& _noun); | ||
| 85 | noun_query& not_instance_of(const noun& _noun); | ||
| 86 | |||
| 87 | noun_query& is_class(bool _arg); | ||
| 88 | noun_query& class_of(const noun& _noun); | ||
| 89 | noun_query& not_class_of(const noun& _noun); | ||
| 90 | |||
| 91 | noun_query& has_synonyms(bool _arg); | ||
| 92 | noun_query& synonym_of(const noun& _noun); | ||
| 93 | noun_query& not_synonym_of(const noun& _noun); | ||
| 94 | |||
| 95 | noun_query& has_antonyms(bool _arg); | ||
| 96 | noun_query& antonym_of(const noun& _noun); | ||
| 97 | noun_query& not_antonym_of(const noun& _noun); | ||
| 98 | |||
| 99 | noun_query& has_pertainym(bool _arg); | ||
| 100 | noun_query& anti_pertainym_of(const adjective& _adj); | ||
| 101 | |||
| 102 | noun_query& is_attribute(bool _arg); | ||
| 103 | noun_query& attribute_of(const adjective& _adj); | ||
| 104 | |||
| 105 | noun_query& derived_from(const word& _w); | ||
| 106 | noun_query& not_derived_from(const word& _w); | ||
| 107 | |||
| 108 | std::list<noun> run() const; | ||
| 109 | |||
| 110 | const static int unlimited = -1; | ||
| 111 | |||
| 112 | private: | ||
| 113 | const data& _data; | ||
| 114 | int _limit = unlimited; | ||
| 115 | bool _random = false; | ||
| 116 | std::list<std::string> _rhymes; | ||
| 117 | std::list<noun> _except; | ||
| 118 | bool _has_prn = false; | ||
| 119 | |||
| 120 | bool _is_hypernym = false; | ||
| 121 | std::list<noun> _hypernym_of; | ||
| 122 | std::list<noun> _not_hypernym_of; | ||
| 123 | |||
| 124 | bool _is_hyponym = false; | ||
| 125 | std::list<noun> _hyponym_of; | ||
| 126 | std::list<noun> _not_hyponym_of; | ||
| 127 | |||
| 128 | bool _is_part_meronym = false; | ||
| 129 | std::list<noun> _part_meronym_of; | ||
| 130 | std::list<noun> _not_part_meronym_of; | ||
| 131 | |||
| 132 | bool _is_substance_meronym = false; | ||
| 133 | std::list<noun> _substance_meronym_of; | ||
| 134 | std::list<noun> _not_substance_meronym_of; | ||
| 135 | |||
| 136 | bool _is_member_meronym = false; | ||
| 137 | std::list<noun> _member_meronym_of; | ||
| 138 | std::list<noun> _not_member_meronym_of; | ||
| 139 | |||
| 140 | bool _is_part_holonym = false; | ||
| 141 | std::list<noun> _part_holonym_of; | ||
| 142 | std::list<noun> _not_part_holonym_of; | ||
| 143 | |||
| 144 | bool _is_substance_holonym = false; | ||
| 145 | std::list<noun> _substance_holonym_of; | ||
| 146 | std::list<noun> _not_substance_holonym_of; | ||
| 147 | |||
| 148 | bool _is_member_holonym = false; | ||
| 149 | std::list<noun> _member_holonym_of; | ||
| 150 | std::list<noun> _not_member_holonym_of; | ||
| 151 | |||
| 152 | bool _is_proper = false; | ||
| 153 | bool _is_not_proper = false; | ||
| 154 | |||
| 155 | bool _is_instance = false; | ||
| 156 | std::list<noun> _instance_of; | ||
| 157 | std::list<noun> _not_instance_of; | ||
| 158 | |||
| 159 | bool _is_class = false; | ||
| 160 | std::list<noun> _class_of; | ||
| 161 | std::list<noun> _not_class_of; | ||
| 162 | |||
| 163 | bool _has_synonyms = false; | ||
| 164 | std::list<noun> _synonym_of; | ||
| 165 | std::list<noun> _not_synonym_of; | ||
| 166 | |||
| 167 | bool _has_antonyms = false; | ||
| 168 | std::list<noun> _antonym_of; | ||
| 169 | std::list<noun> _not_antonym_of; | ||
| 170 | |||
| 171 | bool _has_pertainym = false; | ||
| 172 | std::list<adjective> _anti_pertainym_of; | ||
| 173 | |||
| 174 | bool _is_attribute = false; | ||
| 175 | std::list<adjective> _attribute_of; | ||
| 176 | 39 | ||
| 177 | std::list<adjective> _derived_from_adjective; | 40 | bool operator<(const noun& other) const; |
| 178 | std::list<adjective> _not_derived_from_adjective; | ||
| 179 | std::list<adverb> _derived_from_adverb; | ||
| 180 | std::list<adverb> _not_derived_from_adverb; | ||
| 181 | std::list<noun> _derived_from_noun; | ||
| 182 | std::list<noun> _not_derived_from_noun; | ||
| 183 | }; | 41 | }; |
| 184 | 42 | ||
| 185 | }; | 43 | }; |
| diff --git a/lib/noun_query.cpp b/lib/noun_query.cpp new file mode 100644 index 0000000..cb11577 --- /dev/null +++ b/lib/noun_query.cpp | |||
| @@ -0,0 +1,1453 @@ | |||
| 1 | #include "verbly.h" | ||
| 2 | |||
| 3 | namespace verbly { | ||
| 4 | |||
| 5 | noun_query::noun_query(const data& _data) : _data(_data) | ||
| 6 | { | ||
| 7 | |||
| 8 | } | ||
| 9 | |||
| 10 | noun_query& noun_query::limit(int _limit) | ||
| 11 | { | ||
| 12 | if ((_limit > 0) || (_limit == unlimited)) | ||
| 13 | { | ||
| 14 | this->_limit = _limit; | ||
| 15 | } | ||
| 16 | |||
| 17 | return *this; | ||
| 18 | } | ||
| 19 | |||
| 20 | noun_query& noun_query::random() | ||
| 21 | { | ||
| 22 | this->_random = true; | ||
| 23 | |||
| 24 | return *this; | ||
| 25 | } | ||
| 26 | |||
| 27 | noun_query& noun_query::except(const noun& _word) | ||
| 28 | { | ||
| 29 | _except.push_back(_word); | ||
| 30 | |||
| 31 | return *this; | ||
| 32 | } | ||
| 33 | |||
| 34 | noun_query& noun_query::rhymes_with(const word& _word) | ||
| 35 | { | ||
| 36 | for (auto rhyme : _word.rhyme_phonemes()) | ||
| 37 | { | ||
| 38 | _rhymes.push_back(rhyme); | ||
| 39 | } | ||
| 40 | |||
| 41 | if (dynamic_cast<const noun*>(&_word) != nullptr) | ||
| 42 | { | ||
| 43 | _except.push_back(dynamic_cast<const noun&>(_word)); | ||
| 44 | } | ||
| 45 | |||
| 46 | return *this; | ||
| 47 | } | ||
| 48 | |||
| 49 | noun_query& noun_query::has_pronunciation() | ||
| 50 | { | ||
| 51 | this->_has_prn = true; | ||
| 52 | |||
| 53 | return *this; | ||
| 54 | } | ||
| 55 | |||
| 56 | noun_query& noun_query::with_singular_form(std::string _arg) | ||
| 57 | { | ||
| 58 | _with_singular_form.push_back(_arg); | ||
| 59 | |||
| 60 | return *this; | ||
| 61 | } | ||
| 62 | |||
| 63 | noun_query& noun_query::is_hypernym() | ||
| 64 | { | ||
| 65 | _is_hypernym = true; | ||
| 66 | |||
| 67 | return *this; | ||
| 68 | } | ||
| 69 | |||
| 70 | noun_query& noun_query::hypernym_of(filter<noun> _f) | ||
| 71 | { | ||
| 72 | _f.clean(); | ||
| 73 | _hypernym_of = _f; | ||
| 74 | |||
| 75 | return *this; | ||
| 76 | } | ||
| 77 | |||
| 78 | noun_query& noun_query::full_hypernym_of(filter<noun> _f) | ||
| 79 | { | ||
| 80 | _f.clean(); | ||
| 81 | _full_hypernym_of = _f; | ||
| 82 | |||
| 83 | return *this; | ||
| 84 | } | ||
| 85 | |||
| 86 | noun_query& noun_query::is_hyponym() | ||
| 87 | { | ||
| 88 | _is_hyponym = true; | ||
| 89 | |||
| 90 | return *this; | ||
| 91 | } | ||
| 92 | |||
| 93 | noun_query& noun_query::hyponym_of(filter<noun> _f) | ||
| 94 | { | ||
| 95 | _f.clean(); | ||
| 96 | _hyponym_of = _f; | ||
| 97 | |||
| 98 | return *this; | ||
| 99 | } | ||
| 100 | |||
| 101 | noun_query& noun_query::full_hyponym_of(filter<noun> _f) | ||
| 102 | { | ||
| 103 | _f.clean(); | ||
| 104 | _full_hyponym_of = _f; | ||
| 105 | |||
| 106 | return *this; | ||
| 107 | } | ||
| 108 | |||
| 109 | noun_query& noun_query::is_part_meronym() | ||
| 110 | { | ||
| 111 | _is_part_meronym = true; | ||
| 112 | |||
| 113 | return *this; | ||
| 114 | } | ||
| 115 | |||
| 116 | noun_query& noun_query::part_meronym_of(filter<noun> _f) | ||
| 117 | { | ||
| 118 | _f.clean(); | ||
| 119 | _part_meronym_of = _f; | ||
| 120 | |||
| 121 | return *this; | ||
| 122 | } | ||
| 123 | |||
| 124 | noun_query& noun_query::is_part_holonym() | ||
| 125 | { | ||
| 126 | _is_part_holonym = true; | ||
| 127 | |||
| 128 | return *this; | ||
| 129 | } | ||
| 130 | |||
| 131 | noun_query& noun_query::part_holonym_of(filter<noun> _f) | ||
| 132 | { | ||
| 133 | _f.clean(); | ||
| 134 | _part_holonym_of = _f; | ||
| 135 | |||
| 136 | return *this; | ||
| 137 | } | ||
| 138 | |||
| 139 | noun_query& noun_query::is_substance_meronym() | ||
| 140 | { | ||
| 141 | _is_substance_meronym = true; | ||
| 142 | |||
| 143 | return *this; | ||
| 144 | } | ||
| 145 | |||
| 146 | noun_query& noun_query::substance_meronym_of(filter<noun> _f) | ||
| 147 | { | ||
| 148 | _f.clean(); | ||
| 149 | _substance_meronym_of = _f; | ||
| 150 | |||
| 151 | return *this; | ||
| 152 | } | ||
| 153 | |||
| 154 | noun_query& noun_query::is_substance_holonym() | ||
| 155 | { | ||
| 156 | _is_substance_holonym = true; | ||
| 157 | |||
| 158 | return *this; | ||
| 159 | } | ||
| 160 | |||
| 161 | noun_query& noun_query::substance_holonym_of(filter<noun> _f) | ||
| 162 | { | ||
| 163 | _f.clean(); | ||
| 164 | _substance_holonym_of = _f; | ||
| 165 | |||
| 166 | return *this; | ||
| 167 | } | ||
| 168 | |||
| 169 | noun_query& noun_query::is_member_meronym() | ||
| 170 | { | ||
| 171 | _is_member_meronym = true; | ||
| 172 | |||
| 173 | return *this; | ||
| 174 | } | ||
| 175 | |||
| 176 | noun_query& noun_query::member_meronym_of(filter<noun> _f) | ||
| 177 | { | ||
| 178 | _f.clean(); | ||
| 179 | _member_meronym_of = _f; | ||
| 180 | |||
| 181 | return *this; | ||
| 182 | } | ||
| 183 | |||
| 184 | noun_query& noun_query::is_member_holonym() | ||
| 185 | { | ||
| 186 | _is_member_holonym = true; | ||
| 187 | |||
| 188 | return *this; | ||
| 189 | } | ||
| 190 | |||
| 191 | noun_query& noun_query::member_holonym_of(filter<noun> _f) | ||
| 192 | { | ||
| 193 | _f.clean(); | ||
| 194 | _member_holonym_of = _f; | ||
| 195 | |||
| 196 | return *this; | ||
| 197 | } | ||
| 198 | |||
| 199 | noun_query& noun_query::is_proper() | ||
| 200 | { | ||
| 201 | _is_proper = true; | ||
| 202 | |||
| 203 | return *this; | ||
| 204 | } | ||
| 205 | |||
| 206 | noun_query& noun_query::is_not_proper() | ||
| 207 | { | ||
| 208 | _is_not_proper = true; | ||
| 209 | |||
| 210 | return *this; | ||
| 211 | } | ||
| 212 | |||
| 213 | noun_query& noun_query::is_instance() | ||
| 214 | { | ||
| 215 | _is_instance = true; | ||
| 216 | |||
| 217 | return *this; | ||
| 218 | } | ||
| 219 | |||
| 220 | noun_query& noun_query::instance_of(filter<noun> _f) | ||
| 221 | { | ||
| 222 | _f.clean(); | ||
| 223 | _instance_of = _f; | ||
| 224 | |||
| 225 | return *this; | ||
| 226 | } | ||
| 227 | |||
| 228 | noun_query& noun_query::is_class() | ||
| 229 | { | ||
| 230 | _is_class = true; | ||
| 231 | |||
| 232 | return *this; | ||
| 233 | } | ||
| 234 | |||
| 235 | noun_query& noun_query::class_of(filter<noun> _f) | ||
| 236 | { | ||
| 237 | _f.clean(); | ||
| 238 | _class_of = _f; | ||
| 239 | |||
| 240 | return *this; | ||
| 241 | } | ||
| 242 | |||
| 243 | noun_query& noun_query::has_synonyms() | ||
| 244 | { | ||
| 245 | _has_synonyms = true; | ||
| 246 | |||
| 247 | return *this; | ||
| 248 | } | ||
| 249 | |||
| 250 | noun_query& noun_query::synonym_of(filter<noun> _f) | ||
| 251 | { | ||
| 252 | _f.clean(); | ||
| 253 | _synonym_of = _f; | ||
| 254 | |||
| 255 | return *this; | ||
| 256 | } | ||
| 257 | |||
| 258 | noun_query& noun_query::has_antonyms() | ||
| 259 | { | ||
| 260 | _has_antonyms = true; | ||
| 261 | |||
| 262 | return *this; | ||
| 263 | } | ||
| 264 | |||
| 265 | noun_query& noun_query::antonym_of(filter<noun> _f) | ||
| 266 | { | ||
| 267 | _f.clean(); | ||
| 268 | _antonym_of = _f; | ||
| 269 | |||
| 270 | return *this; | ||
| 271 | } | ||
| 272 | |||
| 273 | noun_query& noun_query::has_pertainym() | ||
| 274 | { | ||
| 275 | _has_pertainym = true; | ||
| 276 | |||
| 277 | return *this; | ||
| 278 | } | ||
| 279 | |||
| 280 | noun_query& noun_query::anti_pertainym_of(filter<adjective> _f) | ||
| 281 | { | ||
| 282 | _f.clean(); | ||
| 283 | _anti_pertainym_of = _f; | ||
| 284 | |||
| 285 | return *this; | ||
| 286 | } | ||
| 287 | |||
| 288 | noun_query& noun_query::is_attribute() | ||
| 289 | { | ||
| 290 | _is_attribute = true; | ||
| 291 | |||
| 292 | return *this; | ||
| 293 | } | ||
| 294 | |||
| 295 | noun_query& noun_query::attribute_of(filter<adjective> _f) | ||
| 296 | { | ||
| 297 | _f.clean(); | ||
| 298 | _attribute_of = _f; | ||
| 299 | |||
| 300 | return *this; | ||
| 301 | } | ||
| 302 | /* | ||
| 303 | noun_query& noun_query::derived_from(const word& _w) | ||
| 304 | { | ||
| 305 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | ||
| 306 | { | ||
| 307 | _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 308 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 309 | { | ||
| 310 | _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 311 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 312 | { | ||
| 313 | _derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 314 | } | ||
| 315 | |||
| 316 | return *this; | ||
| 317 | } | ||
| 318 | |||
| 319 | noun_query& noun_query::not_derived_from(const word& _w) | ||
| 320 | { | ||
| 321 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | ||
| 322 | { | ||
| 323 | _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
| 324 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
| 325 | { | ||
| 326 | _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
| 327 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
| 328 | { | ||
| 329 | _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
| 330 | } | ||
| 331 | |||
| 332 | return *this; | ||
| 333 | }*/ | ||
| 334 | |||
| 335 | std::list<noun> noun_query::run() const | ||
| 336 | { | ||
| 337 | std::stringstream construct; | ||
| 338 | |||
| 339 | if (!_full_hypernym_of.empty() || !_full_hyponym_of.empty()) | ||
| 340 | { | ||
| 341 | construct << "WITH RECURSIVE "; | ||
| 342 | |||
| 343 | std::list<std::string> ctes; | ||
| 344 | |||
| 345 | for (auto hyponym : _full_hypernym_of.uniq_flatten()) | ||
| 346 | { | ||
| 347 | ctes.push_back("hypernym_tree_" + std::to_string(hyponym._id) + " AS (SELECT hypernym_id FROM hypernymy WHERE hyponym_id = " + std::to_string(hyponym._id) + " UNION SELECT h.hypernym_id FROM hypernym_tree_" + std::to_string(hyponym._id) + " AS t INNER JOIN hypernymy AS h ON t.hypernym_id = h.hyponym_id)"); | ||
| 348 | } | ||
| 349 | |||
| 350 | for (auto hypernym : _full_hyponym_of.uniq_flatten()) | ||
| 351 | { | ||
| 352 | ctes.push_back("hyponym_tree_" + std::to_string(hypernym._id) + " AS (SELECT hyponym_id FROM hypernymy WHERE hypernym_id = " + std::to_string(hypernym._id) + " UNION SELECT h.hyponym_id FROM hyponym_tree_" + std::to_string(hypernym._id) + " AS t INNER JOIN hypernymy AS h ON t.hyponym_id = h.hypernym_id)"); | ||
| 353 | } | ||
| 354 | |||
| 355 | construct << verbly::implode(std::begin(ctes), std::end(ctes), ", "); | ||
| 356 | construct << " "; | ||
| 357 | } | ||
| 358 | |||
| 359 | construct << "SELECT noun_id, singular, plural FROM nouns"; | ||
| 360 | std::list<std::string> conditions; | ||
| 361 | |||
| 362 | if (_has_prn) | ||
| 363 | { | ||
| 364 | conditions.push_back("noun_id IN (SELECT noun_id FROM noun_pronunciations)"); | ||
| 365 | } | ||
| 366 | |||
| 367 | if (!_rhymes.empty()) | ||
| 368 | { | ||
| 369 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
| 370 | std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 371 | conditions.push_back(cond); | ||
| 372 | } | ||
| 373 | |||
| 374 | for (auto except : _except) | ||
| 375 | { | ||
| 376 | conditions.push_back("noun_id != @EXCID"); | ||
| 377 | } | ||
| 378 | |||
| 379 | if (!_with_singular_form.empty()) | ||
| 380 | { | ||
| 381 | std::list<std::string> clauses(_with_singular_form.size(), "singular = @SFORM"); | ||
| 382 | std::string cond = "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 383 | conditions.push_back(cond); | ||
| 384 | } | ||
| 385 | |||
| 386 | if (_is_hypernym) | ||
| 387 | { | ||
| 388 | conditions.push_back("noun_id IN (SELECT hypernym_id FROM hypernymy)"); | ||
| 389 | } | ||
| 390 | |||
| 391 | if (!_hypernym_of.empty()) | ||
| 392 | { | ||
| 393 | std::stringstream cond; | ||
| 394 | if (_hypernym_of.get_notlogic()) | ||
| 395 | { | ||
| 396 | cond << "noun_id NOT IN"; | ||
| 397 | } else { | ||
| 398 | cond << "noun_id IN"; | ||
| 399 | } | ||
| 400 | |||
| 401 | cond << "(SELECT hypernym_id FROM hypernymy WHERE "; | ||
| 402 | |||
| 403 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 404 | switch (f.get_type()) | ||
| 405 | { | ||
| 406 | case filter<noun>::type::singleton: | ||
| 407 | { | ||
| 408 | if (notlogic == f.get_notlogic()) | ||
| 409 | { | ||
| 410 | return "hyponym_id = @HYPO"; | ||
| 411 | } else { | ||
| 412 | return "hyponym_id != @HYPO"; | ||
| 413 | } | ||
| 414 | } | ||
| 415 | |||
| 416 | case filter<noun>::type::group: | ||
| 417 | { | ||
| 418 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 419 | |||
| 420 | std::list<std::string> clauses; | ||
| 421 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 422 | return recur(f2, truelogic); | ||
| 423 | }); | ||
| 424 | |||
| 425 | if (truelogic == f.get_orlogic()) | ||
| 426 | { | ||
| 427 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 428 | } else { | ||
| 429 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 430 | } | ||
| 431 | } | ||
| 432 | } | ||
| 433 | }; | ||
| 434 | |||
| 435 | cond << recur(_hypernym_of, _hypernym_of.get_notlogic()); | ||
| 436 | cond << ")"; | ||
| 437 | conditions.push_back(cond.str()); | ||
| 438 | } | ||
| 439 | |||
| 440 | if (!_full_hypernym_of.empty()) | ||
| 441 | { | ||
| 442 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 443 | switch (f.get_type()) | ||
| 444 | { | ||
| 445 | case filter<noun>::type::singleton: | ||
| 446 | { | ||
| 447 | if (notlogic == f.get_notlogic()) | ||
| 448 | { | ||
| 449 | return "noun_id IN (SELECT hypernym_id FROM hypernym_tree_" + std::to_string(f.get_elem()._id) + ")"; | ||
| 450 | } else { | ||
| 451 | return "noun_id NOT IN (SELECT hypernym_id FROM hypernym_tree_" + std::to_string(f.get_elem()._id) + ")"; | ||
| 452 | } | ||
| 453 | } | ||
| 454 | |||
| 455 | case filter<noun>::type::group: | ||
| 456 | { | ||
| 457 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 458 | |||
| 459 | std::list<std::string> clauses; | ||
| 460 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 461 | return recur(f2, truelogic); | ||
| 462 | }); | ||
| 463 | |||
| 464 | if (truelogic == f.get_orlogic()) | ||
| 465 | { | ||
| 466 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 467 | } else { | ||
| 468 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 469 | } | ||
| 470 | } | ||
| 471 | } | ||
| 472 | }; | ||
| 473 | |||
| 474 | conditions.push_back(recur(_full_hypernym_of, false)); | ||
| 475 | } | ||
| 476 | |||
| 477 | if (!_full_hyponym_of.empty()) | ||
| 478 | { | ||
| 479 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 480 | switch (f.get_type()) | ||
| 481 | { | ||
| 482 | case filter<noun>::type::singleton: | ||
| 483 | { | ||
| 484 | if (notlogic == f.get_notlogic()) | ||
| 485 | { | ||
| 486 | return "noun_id IN (SELECT hyponym_id FROM hyponym_tree_" + std::to_string(f.get_elem()._id) + ")"; | ||
| 487 | } else { | ||
| 488 | return "noun_id NOT IN (SELECT hyponym_id FROM hyponym_tree_" + std::to_string(f.get_elem()._id) + ")"; | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | case filter<noun>::type::group: | ||
| 493 | { | ||
| 494 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 495 | |||
| 496 | std::list<std::string> clauses; | ||
| 497 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 498 | return recur(f2, truelogic); | ||
| 499 | }); | ||
| 500 | |||
| 501 | if (truelogic == f.get_orlogic()) | ||
| 502 | { | ||
| 503 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 504 | } else { | ||
| 505 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 506 | } | ||
| 507 | } | ||
| 508 | } | ||
| 509 | }; | ||
| 510 | |||
| 511 | conditions.push_back(recur(_full_hyponym_of, false)); | ||
| 512 | } | ||
| 513 | |||
| 514 | if (_is_hyponym) | ||
| 515 | { | ||
| 516 | conditions.push_back("noun_id IN (SELECT hyponym_id FROM hypernymy)"); | ||
| 517 | } | ||
| 518 | |||
| 519 | if (!_hyponym_of.empty()) | ||
| 520 | { | ||
| 521 | std::stringstream cond; | ||
| 522 | if (_hyponym_of.get_notlogic()) | ||
| 523 | { | ||
| 524 | cond << "noun_id NOT IN"; | ||
| 525 | } else { | ||
| 526 | cond << "noun_id IN"; | ||
| 527 | } | ||
| 528 | |||
| 529 | cond << "(SELECT hyponym_id FROM hypernymy WHERE "; | ||
| 530 | |||
| 531 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 532 | switch (f.get_type()) | ||
| 533 | { | ||
| 534 | case filter<noun>::type::singleton: | ||
| 535 | { | ||
| 536 | if (notlogic == f.get_notlogic()) | ||
| 537 | { | ||
| 538 | return "hypernym_id = @HYPER"; | ||
| 539 | } else { | ||
| 540 | return "hypernym_id != @HYPER"; | ||
| 541 | } | ||
| 542 | } | ||
| 543 | |||
| 544 | case filter<noun>::type::group: | ||
| 545 | { | ||
| 546 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 547 | |||
| 548 | std::list<std::string> clauses; | ||
| 549 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 550 | return recur(f2, truelogic); | ||
| 551 | }); | ||
| 552 | |||
| 553 | if (truelogic == f.get_orlogic()) | ||
| 554 | { | ||
| 555 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 556 | } else { | ||
| 557 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 558 | } | ||
| 559 | } | ||
| 560 | } | ||
| 561 | }; | ||
| 562 | |||
| 563 | cond << recur(_hyponym_of, _hyponym_of.get_notlogic()); | ||
| 564 | cond << ")"; | ||
| 565 | conditions.push_back(cond.str()); | ||
| 566 | } | ||
| 567 | |||
| 568 | if (_is_part_meronym) | ||
| 569 | { | ||
| 570 | conditions.push_back("noun_id IN (SELECT meronym_id FROM part_meronymy)"); | ||
| 571 | } | ||
| 572 | |||
| 573 | if (!_part_meronym_of.empty()) | ||
| 574 | { | ||
| 575 | std::stringstream cond; | ||
| 576 | if (_part_meronym_of.get_notlogic()) | ||
| 577 | { | ||
| 578 | cond << "noun_id NOT IN"; | ||
| 579 | } else { | ||
| 580 | cond << "noun_id IN"; | ||
| 581 | } | ||
| 582 | |||
| 583 | cond << "(SELECT meronym_id FROM part_meronymy WHERE "; | ||
| 584 | |||
| 585 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 586 | switch (f.get_type()) | ||
| 587 | { | ||
| 588 | case filter<noun>::type::singleton: | ||
| 589 | { | ||
| 590 | if (notlogic == f.get_notlogic()) | ||
| 591 | { | ||
| 592 | return "holonym_id = @PHOLO"; | ||
| 593 | } else { | ||
| 594 | return "holonym_id != @PHOLO"; | ||
| 595 | } | ||
| 596 | } | ||
| 597 | |||
| 598 | case filter<noun>::type::group: | ||
| 599 | { | ||
| 600 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 601 | |||
| 602 | std::list<std::string> clauses; | ||
| 603 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 604 | return recur(f2, truelogic); | ||
| 605 | }); | ||
| 606 | |||
| 607 | if (truelogic == f.get_orlogic()) | ||
| 608 | { | ||
| 609 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 610 | } else { | ||
| 611 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 612 | } | ||
| 613 | } | ||
| 614 | } | ||
| 615 | }; | ||
| 616 | |||
| 617 | cond << recur(_part_meronym_of, _part_meronym_of.get_notlogic()); | ||
| 618 | cond << ")"; | ||
| 619 | conditions.push_back(cond.str()); | ||
| 620 | } | ||
| 621 | |||
| 622 | if (_is_part_holonym) | ||
| 623 | { | ||
| 624 | conditions.push_back("noun_id IN (SELECT holonym_id FROM part_meronymy)"); | ||
| 625 | } | ||
| 626 | |||
| 627 | if (!_part_holonym_of.empty()) | ||
| 628 | { | ||
| 629 | std::stringstream cond; | ||
| 630 | if (_part_holonym_of.get_notlogic()) | ||
| 631 | { | ||
| 632 | cond << "noun_id NOT IN"; | ||
| 633 | } else { | ||
| 634 | cond << "noun_id IN"; | ||
| 635 | } | ||
| 636 | |||
| 637 | cond << "(SELECT holonym_id FROM part_meronymy WHERE "; | ||
| 638 | |||
| 639 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 640 | switch (f.get_type()) | ||
| 641 | { | ||
| 642 | case filter<noun>::type::singleton: | ||
| 643 | { | ||
| 644 | if (notlogic == f.get_notlogic()) | ||
| 645 | { | ||
| 646 | return "meronym_id = @PMERO"; | ||
| 647 | } else { | ||
| 648 | return "meronym_id != @PMERO"; | ||
| 649 | } | ||
| 650 | } | ||
| 651 | |||
| 652 | case filter<noun>::type::group: | ||
| 653 | { | ||
| 654 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 655 | |||
| 656 | std::list<std::string> clauses; | ||
| 657 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 658 | return recur(f2, truelogic); | ||
| 659 | }); | ||
| 660 | |||
| 661 | if (truelogic == f.get_orlogic()) | ||
| 662 | { | ||
| 663 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 664 | } else { | ||
| 665 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 666 | } | ||
| 667 | } | ||
| 668 | } | ||
| 669 | }; | ||
| 670 | |||
| 671 | cond << recur(_part_holonym_of, _part_holonym_of.get_notlogic()); | ||
| 672 | cond << ")"; | ||
| 673 | conditions.push_back(cond.str()); | ||
| 674 | } | ||
| 675 | |||
| 676 | if (_is_substance_meronym) | ||
| 677 | { | ||
| 678 | conditions.push_back("noun_id IN (SELECT meronym_id FROM substance_meronymy)"); | ||
| 679 | } | ||
| 680 | |||
| 681 | if (!_substance_meronym_of.empty()) | ||
| 682 | { | ||
| 683 | std::stringstream cond; | ||
| 684 | if (_substance_meronym_of.get_notlogic()) | ||
| 685 | { | ||
| 686 | cond << "noun_id NOT IN"; | ||
| 687 | } else { | ||
| 688 | cond << "noun_id IN"; | ||
| 689 | } | ||
| 690 | |||
| 691 | cond << "(SELECT meronym_id FROM substance_meronymy WHERE "; | ||
| 692 | |||
| 693 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 694 | switch (f.get_type()) | ||
| 695 | { | ||
| 696 | case filter<noun>::type::singleton: | ||
| 697 | { | ||
| 698 | if (notlogic == f.get_notlogic()) | ||
| 699 | { | ||
| 700 | return "holonym_id = @SHOLO"; | ||
| 701 | } else { | ||
| 702 | return "holonym_id != @SHOLO"; | ||
| 703 | } | ||
| 704 | } | ||
| 705 | |||
| 706 | case filter<noun>::type::group: | ||
| 707 | { | ||
| 708 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 709 | |||
| 710 | std::list<std::string> clauses; | ||
| 711 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 712 | return recur(f2, truelogic); | ||
| 713 | }); | ||
| 714 | |||
| 715 | if (truelogic == f.get_orlogic()) | ||
| 716 | { | ||
| 717 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 718 | } else { | ||
| 719 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 720 | } | ||
| 721 | } | ||
| 722 | } | ||
| 723 | }; | ||
| 724 | |||
| 725 | cond << recur(_substance_meronym_of, _substance_meronym_of.get_notlogic()); | ||
| 726 | cond << ")"; | ||
| 727 | conditions.push_back(cond.str()); | ||
| 728 | } | ||
| 729 | |||
| 730 | if (_is_substance_holonym) | ||
| 731 | { | ||
| 732 | conditions.push_back("noun_id IN (SELECT holonym_id FROM substance_meronymy)"); | ||
| 733 | } | ||
| 734 | |||
| 735 | if (!_substance_holonym_of.empty()) | ||
| 736 | { | ||
| 737 | std::stringstream cond; | ||
| 738 | if (_substance_holonym_of.get_notlogic()) | ||
| 739 | { | ||
| 740 | cond << "noun_id NOT IN"; | ||
| 741 | } else { | ||
| 742 | cond << "noun_id IN"; | ||
| 743 | } | ||
| 744 | |||
| 745 | cond << "(SELECT holonym_id FROM substance_meronymy WHERE "; | ||
| 746 | |||
| 747 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 748 | switch (f.get_type()) | ||
| 749 | { | ||
| 750 | case filter<noun>::type::singleton: | ||
| 751 | { | ||
| 752 | if (notlogic == f.get_notlogic()) | ||
| 753 | { | ||
| 754 | return "meronym_id = @SMERO"; | ||
| 755 | } else { | ||
| 756 | return "meronym_id != @SMERO"; | ||
| 757 | } | ||
| 758 | } | ||
| 759 | |||
| 760 | case filter<noun>::type::group: | ||
| 761 | { | ||
| 762 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 763 | |||
| 764 | std::list<std::string> clauses; | ||
| 765 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 766 | return recur(f2, truelogic); | ||
| 767 | }); | ||
| 768 | |||
| 769 | if (truelogic == f.get_orlogic()) | ||
| 770 | { | ||
| 771 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 772 | } else { | ||
| 773 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 774 | } | ||
| 775 | } | ||
| 776 | } | ||
| 777 | }; | ||
| 778 | |||
| 779 | cond << recur(_substance_holonym_of, _substance_holonym_of.get_notlogic()); | ||
| 780 | cond << ")"; | ||
| 781 | conditions.push_back(cond.str()); | ||
| 782 | } | ||
| 783 | |||
| 784 | if (_is_member_meronym) | ||
| 785 | { | ||
| 786 | conditions.push_back("noun_id IN (SELECT meronym_id FROM member_meronymy)"); | ||
| 787 | } | ||
| 788 | |||
| 789 | if (!_member_meronym_of.empty()) | ||
| 790 | { | ||
| 791 | std::stringstream cond; | ||
| 792 | if (_member_meronym_of.get_notlogic()) | ||
| 793 | { | ||
| 794 | cond << "noun_id NOT IN"; | ||
| 795 | } else { | ||
| 796 | cond << "noun_id IN"; | ||
| 797 | } | ||
| 798 | |||
| 799 | cond << "(SELECT meronym_id FROM member_meronymy WHERE "; | ||
| 800 | |||
| 801 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 802 | switch (f.get_type()) | ||
| 803 | { | ||
| 804 | case filter<noun>::type::singleton: | ||
| 805 | { | ||
| 806 | if (notlogic == f.get_notlogic()) | ||
| 807 | { | ||
| 808 | return "holonym_id = @MHOLO"; | ||
| 809 | } else { | ||
| 810 | return "holonym_id != @MHOLO"; | ||
| 811 | } | ||
| 812 | } | ||
| 813 | |||
| 814 | case filter<noun>::type::group: | ||
| 815 | { | ||
| 816 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 817 | |||
| 818 | std::list<std::string> clauses; | ||
| 819 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 820 | return recur(f2, truelogic); | ||
| 821 | }); | ||
| 822 | |||
| 823 | if (truelogic == f.get_orlogic()) | ||
| 824 | { | ||
| 825 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 826 | } else { | ||
| 827 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 828 | } | ||
| 829 | } | ||
| 830 | } | ||
| 831 | }; | ||
| 832 | |||
| 833 | cond << recur(_member_meronym_of, _member_meronym_of.get_notlogic()); | ||
| 834 | cond << ")"; | ||
| 835 | conditions.push_back(cond.str()); | ||
| 836 | } | ||
| 837 | |||
| 838 | if (_is_member_holonym) | ||
| 839 | { | ||
| 840 | conditions.push_back("noun_id IN (SELECT holonym_id FROM member_meronym)"); | ||
| 841 | } | ||
| 842 | |||
| 843 | if (!_member_holonym_of.empty()) | ||
| 844 | { | ||
| 845 | std::stringstream cond; | ||
| 846 | if (_member_holonym_of.get_notlogic()) | ||
| 847 | { | ||
| 848 | cond << "noun_id NOT IN"; | ||
| 849 | } else { | ||
| 850 | cond << "noun_id IN"; | ||
| 851 | } | ||
| 852 | |||
| 853 | cond << "(SELECT holonym_id FROM member_meronymy WHERE "; | ||
| 854 | |||
| 855 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 856 | switch (f.get_type()) | ||
| 857 | { | ||
| 858 | case filter<noun>::type::singleton: | ||
| 859 | { | ||
| 860 | if (notlogic == f.get_notlogic()) | ||
| 861 | { | ||
| 862 | return "meronym_id = @MMERO"; | ||
| 863 | } else { | ||
| 864 | return "meronym_id != @MMERO"; | ||
| 865 | } | ||
| 866 | } | ||
| 867 | |||
| 868 | case filter<noun>::type::group: | ||
| 869 | { | ||
| 870 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 871 | |||
| 872 | std::list<std::string> clauses; | ||
| 873 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 874 | return recur(f2, truelogic); | ||
| 875 | }); | ||
| 876 | |||
| 877 | if (truelogic == f.get_orlogic()) | ||
| 878 | { | ||
| 879 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 880 | } else { | ||
| 881 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 882 | } | ||
| 883 | } | ||
| 884 | } | ||
| 885 | }; | ||
| 886 | |||
| 887 | cond << recur(_member_holonym_of, _member_holonym_of.get_notlogic()); | ||
| 888 | cond << ")"; | ||
| 889 | conditions.push_back(cond.str()); | ||
| 890 | } | ||
| 891 | |||
| 892 | if (_is_proper) | ||
| 893 | { | ||
| 894 | conditions.push_back("proper = 1"); | ||
| 895 | } | ||
| 896 | |||
| 897 | if (_is_not_proper) | ||
| 898 | { | ||
| 899 | conditions.push_back("proper = 0"); | ||
| 900 | } | ||
| 901 | |||
| 902 | if (_is_instance) | ||
| 903 | { | ||
| 904 | conditions.push_back("noun_id IN (SELECT instance_id FROM instantiation)"); | ||
| 905 | } | ||
| 906 | |||
| 907 | if (!_instance_of.empty()) | ||
| 908 | { | ||
| 909 | std::stringstream cond; | ||
| 910 | if (_instance_of.get_notlogic()) | ||
| 911 | { | ||
| 912 | cond << "noun_id NOT IN"; | ||
| 913 | } else { | ||
| 914 | cond << "noun_id IN"; | ||
| 915 | } | ||
| 916 | |||
| 917 | cond << "(SELECT instance_id FROM instantiation WHERE "; | ||
| 918 | |||
| 919 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 920 | switch (f.get_type()) | ||
| 921 | { | ||
| 922 | case filter<noun>::type::singleton: | ||
| 923 | { | ||
| 924 | if (notlogic == f.get_notlogic()) | ||
| 925 | { | ||
| 926 | return "class_id = @CLSID"; | ||
| 927 | } else { | ||
| 928 | return "class_id != @CLSID"; | ||
| 929 | } | ||
| 930 | } | ||
| 931 | |||
| 932 | case filter<noun>::type::group: | ||
| 933 | { | ||
| 934 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 935 | |||
| 936 | std::list<std::string> clauses; | ||
| 937 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 938 | return recur(f2, truelogic); | ||
| 939 | }); | ||
| 940 | |||
| 941 | if (truelogic == f.get_orlogic()) | ||
| 942 | { | ||
| 943 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 944 | } else { | ||
| 945 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 946 | } | ||
| 947 | } | ||
| 948 | } | ||
| 949 | }; | ||
| 950 | |||
| 951 | cond << recur(_instance_of, _instance_of.get_notlogic()); | ||
| 952 | cond << ")"; | ||
| 953 | conditions.push_back(cond.str()); | ||
| 954 | } | ||
| 955 | |||
| 956 | if (_is_class) | ||
| 957 | { | ||
| 958 | conditions.push_back("noun_id IN (SELECT class_id FROM instantiation)"); | ||
| 959 | } | ||
| 960 | |||
| 961 | if (!_class_of.empty()) | ||
| 962 | { | ||
| 963 | std::stringstream cond; | ||
| 964 | if (_class_of.get_notlogic()) | ||
| 965 | { | ||
| 966 | cond << "noun_id NOT IN"; | ||
| 967 | } else { | ||
| 968 | cond << "noun_id IN"; | ||
| 969 | } | ||
| 970 | |||
| 971 | cond << "(SELECT class_id FROM instantiation WHERE "; | ||
| 972 | |||
| 973 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 974 | switch (f.get_type()) | ||
| 975 | { | ||
| 976 | case filter<noun>::type::singleton: | ||
| 977 | { | ||
| 978 | if (notlogic == f.get_notlogic()) | ||
| 979 | { | ||
| 980 | return "instance_id = @INSID"; | ||
| 981 | } else { | ||
| 982 | return "instance_id != @INSID"; | ||
| 983 | } | ||
| 984 | } | ||
| 985 | |||
| 986 | case filter<noun>::type::group: | ||
| 987 | { | ||
| 988 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 989 | |||
| 990 | std::list<std::string> clauses; | ||
| 991 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 992 | return recur(f2, truelogic); | ||
| 993 | }); | ||
| 994 | |||
| 995 | if (truelogic == f.get_orlogic()) | ||
| 996 | { | ||
| 997 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 998 | } else { | ||
| 999 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 1000 | } | ||
| 1001 | } | ||
| 1002 | } | ||
| 1003 | }; | ||
| 1004 | |||
| 1005 | cond << recur(_class_of, _class_of.get_notlogic()); | ||
| 1006 | cond << ")"; | ||
| 1007 | conditions.push_back(cond.str()); | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | if (_has_synonyms) | ||
| 1011 | { | ||
| 1012 | conditions.push_back("noun_id IN (SELECT noun_2_id FROM noun_synonymy)"); | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | if (!_synonym_of.empty()) | ||
| 1016 | { | ||
| 1017 | std::stringstream cond; | ||
| 1018 | if (_synonym_of.get_notlogic()) | ||
| 1019 | { | ||
| 1020 | cond << "noun_id NOT IN"; | ||
| 1021 | } else { | ||
| 1022 | cond << "noun_id IN"; | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | cond << "(SELECT noun_2_id FROM noun_synonymy WHERE "; | ||
| 1026 | |||
| 1027 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 1028 | switch (f.get_type()) | ||
| 1029 | { | ||
| 1030 | case filter<noun>::type::singleton: | ||
| 1031 | { | ||
| 1032 | if (notlogic == f.get_notlogic()) | ||
| 1033 | { | ||
| 1034 | return "noun_1_id = @SYNID"; | ||
| 1035 | } else { | ||
| 1036 | return "noun_1_id != @SYNID"; | ||
| 1037 | } | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | case filter<noun>::type::group: | ||
| 1041 | { | ||
| 1042 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 1043 | |||
| 1044 | std::list<std::string> clauses; | ||
| 1045 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 1046 | return recur(f2, truelogic); | ||
| 1047 | }); | ||
| 1048 | |||
| 1049 | if (truelogic == f.get_orlogic()) | ||
| 1050 | { | ||
| 1051 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 1052 | } else { | ||
| 1053 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 1054 | } | ||
| 1055 | } | ||
| 1056 | } | ||
| 1057 | }; | ||
| 1058 | |||
| 1059 | cond << recur(_synonym_of, _synonym_of.get_notlogic()); | ||
| 1060 | cond << ")"; | ||
| 1061 | conditions.push_back(cond.str()); | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | if (_has_antonyms) | ||
| 1065 | { | ||
| 1066 | conditions.push_back("noun_id IN (SELECT noun_2_id FROM noun_antonymy)"); | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | if (!_antonym_of.empty()) | ||
| 1070 | { | ||
| 1071 | std::stringstream cond; | ||
| 1072 | if (_antonym_of.get_notlogic()) | ||
| 1073 | { | ||
| 1074 | cond << "noun_id NOT IN"; | ||
| 1075 | } else { | ||
| 1076 | cond << "noun_id IN"; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | cond << "(SELECT noun_2_id FROM noun_antonymy WHERE "; | ||
| 1080 | |||
| 1081 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
| 1082 | switch (f.get_type()) | ||
| 1083 | { | ||
| 1084 | case filter<noun>::type::singleton: | ||
| 1085 | { | ||
| 1086 | if (notlogic == f.get_notlogic()) | ||
| 1087 | { | ||
| 1088 | return "noun_1_id = @ANTID"; | ||
| 1089 | } else { | ||
| 1090 | return "noun_1_id != @ANTID"; | ||
| 1091 | } | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | case filter<noun>::type::group: | ||
| 1095 | { | ||
| 1096 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 1097 | |||
| 1098 | std::list<std::string> clauses; | ||
| 1099 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
| 1100 | return recur(f2, truelogic); | ||
| 1101 | }); | ||
| 1102 | |||
| 1103 | if (truelogic == f.get_orlogic()) | ||
| 1104 | { | ||
| 1105 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 1106 | } else { | ||
| 1107 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 1108 | } | ||
| 1109 | } | ||
| 1110 | } | ||
| 1111 | }; | ||
| 1112 | |||
| 1113 | cond << recur(_antonym_of, _antonym_of.get_notlogic()); | ||
| 1114 | cond << ")"; | ||
| 1115 | conditions.push_back(cond.str()); | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | if (_has_pertainym) | ||
| 1119 | { | ||
| 1120 | conditions.push_back("noun_id IN (SELECT noun_id FROM pertainymy)"); | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | if (!_anti_pertainym_of.empty()) | ||
| 1124 | { | ||
| 1125 | std::stringstream cond; | ||
| 1126 | if (_anti_pertainym_of.get_notlogic()) | ||
| 1127 | { | ||
| 1128 | cond << "noun_id NOT IN"; | ||
| 1129 | } else { | ||
| 1130 | cond << "noun_id IN"; | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | cond << "(SELECT noun_id FROM pertainymy WHERE "; | ||
| 1134 | |||
| 1135 | std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string { | ||
| 1136 | switch (f.get_type()) | ||
| 1137 | { | ||
| 1138 | case filter<adjective>::type::singleton: | ||
| 1139 | { | ||
| 1140 | if (notlogic == f.get_notlogic()) | ||
| 1141 | { | ||
| 1142 | return "pertainym_id = @PERID"; | ||
| 1143 | } else { | ||
| 1144 | return "pertainym_id != @PERID"; | ||
| 1145 | } | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | case filter<adjective>::type::group: | ||
| 1149 | { | ||
| 1150 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 1151 | |||
| 1152 | std::list<std::string> clauses; | ||
| 1153 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) { | ||
| 1154 | return recur(f2, truelogic); | ||
| 1155 | }); | ||
| 1156 | |||
| 1157 | if (truelogic == f.get_orlogic()) | ||
| 1158 | { | ||
| 1159 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 1160 | } else { | ||
| 1161 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 1162 | } | ||
| 1163 | } | ||
| 1164 | } | ||
| 1165 | }; | ||
| 1166 | |||
| 1167 | cond << recur(_anti_pertainym_of, _anti_pertainym_of.get_notlogic()); | ||
| 1168 | cond << ")"; | ||
| 1169 | conditions.push_back(cond.str()); | ||
| 1170 | } | ||
| 1171 | |||
| 1172 | if (_is_attribute) | ||
| 1173 | { | ||
| 1174 | conditions.push_back("noun_id IN (SELECT noun_id FROM variation)"); | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | if (!_attribute_of.empty()) | ||
| 1178 | { | ||
| 1179 | std::stringstream cond; | ||
| 1180 | if (_attribute_of.get_notlogic()) | ||
| 1181 | { | ||
| 1182 | cond << "noun_id NOT IN"; | ||
| 1183 | } else { | ||
| 1184 | cond << "noun_id IN"; | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | cond << "(SELECT noun_id FROM variation WHERE "; | ||
| 1188 | |||
| 1189 | std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string { | ||
| 1190 | switch (f.get_type()) | ||
| 1191 | { | ||
| 1192 | case filter<adjective>::type::singleton: | ||
| 1193 | { | ||
| 1194 | if (notlogic == f.get_notlogic()) | ||
| 1195 | { | ||
| 1196 | return "adjective_id = @VALID"; | ||
| 1197 | } else { | ||
| 1198 | return "adjective_id != @VALID"; | ||
| 1199 | } | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | case filter<adjective>::type::group: | ||
| 1203 | { | ||
| 1204 | bool truelogic = notlogic != f.get_notlogic(); | ||
| 1205 | |||
| 1206 | std::list<std::string> clauses; | ||
| 1207 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) { | ||
| 1208 | return recur(f2, truelogic); | ||
| 1209 | }); | ||
| 1210 | |||
| 1211 | if (truelogic == f.get_orlogic()) | ||
| 1212 | { | ||
| 1213 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
| 1214 | } else { | ||
| 1215 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 1216 | } | ||
| 1217 | } | ||
| 1218 | } | ||
| 1219 | }; | ||
| 1220 | |||
| 1221 | cond << recur(_attribute_of, _attribute_of.get_notlogic()); | ||
| 1222 | cond << ")"; | ||
| 1223 | conditions.push_back(cond.str()); | ||
| 1224 | } | ||
| 1225 | /* | ||
| 1226 | if (!_derived_from_adjective.empty()) | ||
| 1227 | { | ||
| 1228 | std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_id = @DERADJ"); | ||
| 1229 | std::string cond = "noun_id IN (SELECT noun_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 1230 | conditions.push_back(cond); | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | if (!_not_derived_from_adjective.empty()) | ||
| 1234 | { | ||
| 1235 | std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_id = @NDERADJ"); | ||
| 1236 | std::string cond = "noun_id NOT IN (SELECT noun_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 1237 | conditions.push_back(cond); | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | if (!_derived_from_adverb.empty()) | ||
| 1241 | { | ||
| 1242 | std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_id = @DERADV"); | ||
| 1243 | std::string cond = "noun_id IN (SELECT noun_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 1244 | conditions.push_back(cond); | ||
| 1245 | } | ||
| 1246 | |||
| 1247 | if (!_not_derived_from_adverb.empty()) | ||
| 1248 | { | ||
| 1249 | std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_id = @NDERADV"); | ||
| 1250 | std::string cond = "noun_id NOT IN (SELECT noun_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 1251 | conditions.push_back(cond); | ||
| 1252 | } | ||
| 1253 | |||
| 1254 | if (!_derived_from_noun.empty()) | ||
| 1255 | { | ||
| 1256 | std::list<std::string> clauses(_derived_from_noun.size(), "noun_2_id = @DERN"); | ||
| 1257 | std::string cond = "noun_id IN (SELECT noun_1_id FROM noun_noun_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 1258 | conditions.push_back(cond); | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | if (!_not_derived_from_noun.empty()) | ||
| 1262 | { | ||
| 1263 | std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_2_id = @NDERN"); | ||
| 1264 | 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 ") + ")"; | ||
| 1265 | conditions.push_back(cond); | ||
| 1266 | } | ||
| 1267 | */ | ||
| 1268 | if (!conditions.empty()) | ||
| 1269 | { | ||
| 1270 | construct << " WHERE "; | ||
| 1271 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | if (_random) | ||
| 1275 | { | ||
| 1276 | construct << " ORDER BY RANDOM()"; | ||
| 1277 | } | ||
| 1278 | |||
| 1279 | if (_limit != unlimited) | ||
| 1280 | { | ||
| 1281 | construct << " LIMIT " << _limit; | ||
| 1282 | } | ||
| 1283 | |||
| 1284 | sqlite3_stmt* ppstmt; | ||
| 1285 | std::string query = construct.str(); | ||
| 1286 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 1287 | { | ||
| 1288 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | if (!_rhymes.empty()) | ||
| 1292 | { | ||
| 1293 | int i = 0; | ||
| 1294 | for (auto rhyme : _rhymes) | ||
| 1295 | { | ||
| 1296 | std::string rhymer = "%" + rhyme; | ||
| 1297 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
| 1298 | |||
| 1299 | i++; | ||
| 1300 | } | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | for (auto except : _except) | ||
| 1304 | { | ||
| 1305 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
| 1306 | } | ||
| 1307 | |||
| 1308 | for (auto sform : _with_singular_form) | ||
| 1309 | { | ||
| 1310 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SFORM"), sform.c_str(), sform.size(), SQLITE_STATIC); | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | for (auto hyponym : _hypernym_of.inorder_flatten()) | ||
| 1314 | { | ||
| 1315 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPO"), hyponym._id); | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | for (auto hypernym : _hyponym_of.inorder_flatten()) | ||
| 1319 | { | ||
| 1320 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPER"), hypernym._id); | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | for (auto holonym : _part_meronym_of.inorder_flatten()) | ||
| 1324 | { | ||
| 1325 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PHOLO"), holonym._id); | ||
| 1326 | } | ||
| 1327 | |||
| 1328 | for (auto meronym : _part_holonym_of.inorder_flatten()) | ||
| 1329 | { | ||
| 1330 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PMERO"), meronym._id); | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | for (auto holonym : _substance_meronym_of.inorder_flatten()) | ||
| 1334 | { | ||
| 1335 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SHOLO"), holonym._id); | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | for (auto meronym : _substance_holonym_of.inorder_flatten()) | ||
| 1339 | { | ||
| 1340 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SMERO"), meronym._id); | ||
| 1341 | } | ||
| 1342 | |||
| 1343 | for (auto holonym : _member_meronym_of.inorder_flatten()) | ||
| 1344 | { | ||
| 1345 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MHOLO"), holonym._id); | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | for (auto meronym : _member_holonym_of.inorder_flatten()) | ||
| 1349 | { | ||
| 1350 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MMERO"), meronym._id); | ||
| 1351 | } | ||
| 1352 | |||
| 1353 | for (auto cls : _instance_of.inorder_flatten()) | ||
| 1354 | { | ||
| 1355 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@CLSID"), cls._id); | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | for (auto inst : _class_of.inorder_flatten()) | ||
| 1359 | { | ||
| 1360 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@INSID"), inst._id); | ||
| 1361 | } | ||
| 1362 | |||
| 1363 | for (auto synonym : _synonym_of.inorder_flatten()) | ||
| 1364 | { | ||
| 1365 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
| 1366 | } | ||
| 1367 | |||
| 1368 | for (auto antonym : _antonym_of.inorder_flatten()) | ||
| 1369 | { | ||
| 1370 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
| 1371 | } | ||
| 1372 | |||
| 1373 | for (auto pertainym : _anti_pertainym_of.inorder_flatten()) | ||
| 1374 | { | ||
| 1375 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PERID"), pertainym._id); | ||
| 1376 | } | ||
| 1377 | |||
| 1378 | for (auto value : _attribute_of.inorder_flatten()) | ||
| 1379 | { | ||
| 1380 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VALID"), value._id); | ||
| 1381 | } | ||
| 1382 | /* | ||
| 1383 | for (auto adj : _derived_from_adjective) | ||
| 1384 | { | ||
| 1385 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id); | ||
| 1386 | } | ||
| 1387 | |||
| 1388 | for (auto adj : _not_derived_from_adjective) | ||
| 1389 | { | ||
| 1390 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id); | ||
| 1391 | } | ||
| 1392 | |||
| 1393 | for (auto adv : _derived_from_adverb) | ||
| 1394 | { | ||
| 1395 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id); | ||
| 1396 | } | ||
| 1397 | |||
| 1398 | for (auto adv : _not_derived_from_adverb) | ||
| 1399 | { | ||
| 1400 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id); | ||
| 1401 | } | ||
| 1402 | |||
| 1403 | for (auto n : _derived_from_noun) | ||
| 1404 | { | ||
| 1405 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id); | ||
| 1406 | } | ||
| 1407 | |||
| 1408 | for (auto n : _not_derived_from_noun) | ||
| 1409 | { | ||
| 1410 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id); | ||
| 1411 | } | ||
| 1412 | */ | ||
| 1413 | std::list<noun> output; | ||
| 1414 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 1415 | { | ||
| 1416 | noun tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
| 1417 | tnc._singular = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
| 1418 | |||
| 1419 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
| 1420 | { | ||
| 1421 | tnc._plural = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
| 1422 | } | ||
| 1423 | |||
| 1424 | output.push_back(tnc); | ||
| 1425 | } | ||
| 1426 | |||
| 1427 | sqlite3_finalize(ppstmt); | ||
| 1428 | |||
| 1429 | for (auto& noun : output) | ||
| 1430 | { | ||
| 1431 | query = "SELECT pronunciation FROM noun_pronunciations WHERE noun_id = ?"; | ||
| 1432 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 1433 | { | ||
| 1434 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 1435 | } | ||
| 1436 | |||
| 1437 | sqlite3_bind_int(ppstmt, 1, noun._id); | ||
| 1438 | |||
| 1439 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 1440 | { | ||
| 1441 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
| 1442 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
| 1443 | |||
| 1444 | noun.pronunciations.push_back(phonemes); | ||
| 1445 | } | ||
| 1446 | |||
| 1447 | sqlite3_finalize(ppstmt); | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | return output; | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | }; | ||
| diff --git a/lib/noun_query.h b/lib/noun_query.h new file mode 100644 index 0000000..0c41a68 --- /dev/null +++ b/lib/noun_query.h | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | #ifndef NOUN_QUERY_H_5DE51DD7 | ||
| 2 | #define NOUN_QUERY_H_5DE51DD7 | ||
| 3 | |||
| 4 | namespace verbly { | ||
| 5 | |||
| 6 | class noun_query { | ||
| 7 | public: | ||
| 8 | noun_query(const data& _data); | ||
| 9 | |||
| 10 | noun_query& limit(int _limit); | ||
| 11 | noun_query& random(); | ||
| 12 | noun_query& except(const noun& _word); | ||
| 13 | noun_query& rhymes_with(const word& _word); | ||
| 14 | noun_query& has_pronunciation(); | ||
| 15 | |||
| 16 | noun_query& with_singular_form(std::string _arg); | ||
| 17 | |||
| 18 | noun_query& is_hypernym(); | ||
| 19 | noun_query& hypernym_of(filter<noun> _f); | ||
| 20 | noun_query& full_hypernym_of(filter<noun> _f); | ||
| 21 | |||
| 22 | noun_query& is_hyponym(); | ||
| 23 | noun_query& hyponym_of(filter<noun> _f); | ||
| 24 | noun_query& full_hyponym_of(filter<noun> _f); | ||
| 25 | |||
| 26 | noun_query& is_part_meronym(); | ||
| 27 | noun_query& part_meronym_of(filter<noun> _f); | ||
| 28 | |||
| 29 | noun_query& is_part_holonym(); | ||
| 30 | noun_query& part_holonym_of(filter<noun> _f); | ||
| 31 | |||
| 32 | noun_query& is_substance_meronym(); | ||
| 33 | noun_query& substance_meronym_of(filter<noun> _f); | ||
| 34 | |||
| 35 | noun_query& is_substance_holonym(); | ||
| 36 | noun_query& substance_holonym_of(filter<noun> _f); | ||
| 37 | |||
| 38 | noun_query& is_member_meronym(); | ||
| 39 | noun_query& member_meronym_of(filter<noun> _f); | ||
| 40 | |||
| 41 | noun_query& is_member_holonym(); | ||
| 42 | noun_query& member_holonym_of(filter<noun> _f); | ||
| 43 | |||
| 44 | noun_query& is_proper(); | ||
| 45 | noun_query& is_not_proper(); | ||
| 46 | |||
| 47 | noun_query& is_instance(); | ||
| 48 | noun_query& instance_of(filter<noun> _f); | ||
| 49 | |||
| 50 | noun_query& is_class(); | ||
| 51 | noun_query& class_of(filter<noun> _f); | ||
| 52 | |||
| 53 | noun_query& has_synonyms(); | ||
| 54 | noun_query& synonym_of(filter<noun> _f); | ||
| 55 | |||
| 56 | noun_query& has_antonyms(); | ||
| 57 | noun_query& antonym_of(filter<noun> _f); | ||
| 58 | |||
| 59 | noun_query& has_pertainym(); | ||
| 60 | noun_query& anti_pertainym_of(filter<adjective> _f); | ||
| 61 | |||
| 62 | noun_query& is_attribute(); | ||
| 63 | noun_query& attribute_of(filter<adjective> _f); | ||
| 64 | |||
| 65 | /* noun_query& derived_from(const word& _w); | ||
| 66 | noun_query& not_derived_from(const word& _w);*/ | ||
| 67 | |||
| 68 | std::list<noun> run() const; | ||
| 69 | |||
| 70 | const static int unlimited = -1; | ||
| 71 | |||
| 72 | private: | ||
| 73 | const data& _data; | ||
| 74 | int _limit = unlimited; | ||
| 75 | bool _random = false; | ||
| 76 | std::list<std::string> _rhymes; | ||
| 77 | std::list<noun> _except; | ||
| 78 | bool _has_prn = false; | ||
| 79 | |||
| 80 | std::list<std::string> _with_singular_form; | ||
| 81 | |||
| 82 | bool _is_hypernym = false; | ||
| 83 | filter<noun> _hypernym_of; | ||
| 84 | filter<noun> _full_hypernym_of; | ||
| 85 | |||
| 86 | bool _is_hyponym = false; | ||
| 87 | filter<noun> _hyponym_of; | ||
| 88 | filter<noun> _full_hyponym_of; | ||
| 89 | |||
| 90 | bool _is_part_meronym = false; | ||
| 91 | filter<noun> _part_meronym_of; | ||
| 92 | |||
| 93 | bool _is_substance_meronym = false; | ||
| 94 | filter<noun> _substance_meronym_of; | ||
| 95 | |||
| 96 | bool _is_member_meronym = false; | ||
| 97 | filter<noun> _member_meronym_of; | ||
| 98 | |||
| 99 | bool _is_part_holonym = false; | ||
| 100 | filter<noun> _part_holonym_of; | ||
| 101 | |||
| 102 | bool _is_substance_holonym = false; | ||
| 103 | filter<noun> _substance_holonym_of; | ||
| 104 | |||
| 105 | bool _is_member_holonym = false; | ||
| 106 | filter<noun> _member_holonym_of; | ||
| 107 | |||
| 108 | bool _is_proper = false; | ||
| 109 | bool _is_not_proper = false; | ||
| 110 | |||
| 111 | bool _is_instance = false; | ||
| 112 | filter<noun> _instance_of; | ||
| 113 | |||
| 114 | bool _is_class = false; | ||
| 115 | filter<noun> _class_of; | ||
| 116 | |||
| 117 | bool _has_synonyms = false; | ||
| 118 | filter<noun> _synonym_of; | ||
| 119 | |||
| 120 | bool _has_antonyms = false; | ||
| 121 | filter<noun> _antonym_of; | ||
| 122 | |||
| 123 | bool _has_pertainym = false; | ||
| 124 | filter<adjective> _anti_pertainym_of; | ||
| 125 | |||
| 126 | bool _is_attribute = false; | ||
| 127 | filter<adjective> _attribute_of; | ||
| 128 | |||
| 129 | /* std::list<adjective> _derived_from_adjective; | ||
| 130 | std::list<adjective> _not_derived_from_adjective; | ||
| 131 | std::list<adverb> _derived_from_adverb; | ||
| 132 | std::list<adverb> _not_derived_from_adverb; | ||
| 133 | std::list<noun> _derived_from_noun; | ||
| 134 | std::list<noun> _not_derived_from_noun;*/ | ||
| 135 | }; | ||
| 136 | |||
| 137 | }; | ||
| 138 | |||
| 139 | #endif /* end of include guard: NOUN_QUERY_H_5DE51DD7 */ | ||
| diff --git a/lib/preposition.cpp b/lib/preposition.cpp new file mode 100644 index 0000000..c619bbf --- /dev/null +++ b/lib/preposition.cpp | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | #include "verbly.h" | ||
| 2 | |||
| 3 | namespace verbly { | ||
| 4 | |||
| 5 | std::string preposition::get_form() const | ||
| 6 | { | ||
| 7 | return form; | ||
| 8 | } | ||
| 9 | |||
| 10 | preposition_query::preposition_query(const data& _data) : _data(_data) | ||
| 11 | { | ||
| 12 | |||
| 13 | } | ||
| 14 | |||
| 15 | preposition_query& preposition_query::limit(int _limit) | ||
| 16 | { | ||
| 17 | this->_limit = _limit; | ||
| 18 | |||
| 19 | return *this; | ||
| 20 | } | ||
| 21 | |||
| 22 | preposition_query& preposition_query::random() | ||
| 23 | { | ||
| 24 | _random = true; | ||
| 25 | |||
| 26 | return *this; | ||
| 27 | } | ||
| 28 | |||
| 29 | preposition_query& preposition_query::in_group(std::string _arg) | ||
| 30 | { | ||
| 31 | _in_group.push_back(_arg); | ||
| 32 | |||
| 33 | return *this; | ||
| 34 | } | ||
| 35 | |||
| 36 | std::list<preposition> preposition_query::run() const | ||
| 37 | { | ||
| 38 | std::stringstream construct; | ||
| 39 | construct << "SELECT form FROM prepositions"; | ||
| 40 | |||
| 41 | if (!_in_group.empty()) | ||
| 42 | { | ||
| 43 | std::list<std::string> clauses(_in_group.size(), "groupname = @GNAME"); | ||
| 44 | construct << " WHERE preposition_id IN (SELECT preposition_id FROM preposition_groups WHERE "; | ||
| 45 | construct << verbly::implode(std::begin(clauses), std::end(clauses), " OR "); | ||
| 46 | construct << ")"; | ||
| 47 | } | ||
| 48 | |||
| 49 | if (_random) | ||
| 50 | { | ||
| 51 | construct << " ORDER BY RANDOM()"; | ||
| 52 | } | ||
| 53 | |||
| 54 | if (_limit != unlimited) | ||
| 55 | { | ||
| 56 | construct << " LIMIT " << _limit; | ||
| 57 | } | ||
| 58 | |||
| 59 | sqlite3_stmt* ppstmt; | ||
| 60 | std::string query = construct.str(); | ||
| 61 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 62 | { | ||
| 63 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 64 | } | ||
| 65 | |||
| 66 | for (auto& group : _in_group) | ||
| 67 | { | ||
| 68 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GNAME"), group.c_str(), group.length(), SQLITE_STATIC); | ||
| 69 | } | ||
| 70 | |||
| 71 | std::list<preposition> output; | ||
| 72 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 73 | { | ||
| 74 | preposition pp; | ||
| 75 | pp.form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
| 76 | |||
| 77 | output.push_back(pp); | ||
| 78 | } | ||
| 79 | |||
| 80 | return output; | ||
| 81 | } | ||
| 82 | |||
| 83 | }; | ||
| diff --git a/lib/preposition.h b/lib/preposition.h new file mode 100644 index 0000000..89f24fa --- /dev/null +++ b/lib/preposition.h | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | #ifndef PREPOSITION_H_FF908021 | ||
| 2 | #define PREPOSITION_H_FF908021 | ||
| 3 | |||
| 4 | namespace verbly { | ||
| 5 | |||
| 6 | class preposition_query; | ||
| 7 | |||
| 8 | class preposition { | ||
| 9 | public: | ||
| 10 | std::string get_form() const; | ||
| 11 | |||
| 12 | private: | ||
| 13 | friend class preposition_query; | ||
| 14 | |||
| 15 | std::string form; | ||
| 16 | }; | ||
| 17 | |||
| 18 | class preposition_query { | ||
| 19 | public: | ||
| 20 | preposition_query(const data& _data); | ||
| 21 | |||
| 22 | preposition_query& limit(int _limit); | ||
| 23 | preposition_query& random(); | ||
| 24 | preposition_query& in_group(std::string _arg); | ||
| 25 | |||
| 26 | std::list<preposition> run() const; | ||
| 27 | |||
| 28 | const static int unlimited = -1; | ||
| 29 | private: | ||
| 30 | const data& _data; | ||
| 31 | int _limit = unlimited; | ||
| 32 | bool _random = false; | ||
| 33 | std::list<std::string> _in_group; | ||
| 34 | }; | ||
| 35 | |||
| 36 | }; | ||
| 37 | |||
| 38 | #endif /* end of include guard: PREPOSITION_H_FF908021 */ | ||
| diff --git a/lib/token.cpp b/lib/token.cpp index facab8a..1e25acb 100644 --- a/lib/token.cpp +++ b/lib/token.cpp | |||
| @@ -2,52 +2,627 @@ | |||
| 2 | 2 | ||
| 3 | namespace verbly { | 3 | namespace verbly { |
| 4 | 4 | ||
| 5 | token::token(token::type _type) : _type(_type) | 5 | token::type token::get_type() const |
| 6 | { | 6 | { |
| 7 | 7 | return _type; | |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | token::type token::token_type() const | 10 | int token::get_extra() const |
| 11 | { | 11 | { |
| 12 | return _type; | 12 | return _extra; |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | verb_token::verb_token(const verb& _verb) : token(token::type::verb), _verb(&_verb) | 15 | void token::set_extra(int _arg) |
| 16 | { | 16 | { |
| 17 | 17 | _extra = _arg; | |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | const verb& verb_token::get_verb() const | 20 | token::token(const token& other) |
| 21 | { | 21 | { |
| 22 | return *_verb; | 22 | _type = other._type; |
| 23 | |||
| 24 | switch (_type) | ||
| 25 | { | ||
| 26 | case token::type::verb: | ||
| 27 | { | ||
| 28 | new(&_verb._verb) verb(other._verb._verb); | ||
| 29 | _verb._infl = other._verb._infl; | ||
| 30 | |||
| 31 | break; | ||
| 32 | } | ||
| 33 | |||
| 34 | case token::type::noun: | ||
| 35 | { | ||
| 36 | new(&_noun._noun) noun(other._noun._noun); | ||
| 37 | _noun._infl = other._noun._infl; | ||
| 38 | |||
| 39 | break; | ||
| 40 | } | ||
| 41 | |||
| 42 | case token::type::adjective: | ||
| 43 | { | ||
| 44 | new(&_adjective._adjective) adjective(other._adjective._adjective); | ||
| 45 | _adjective._infl = other._adjective._infl; | ||
| 46 | |||
| 47 | break; | ||
| 48 | } | ||
| 49 | |||
| 50 | case token::type::adverb: | ||
| 51 | { | ||
| 52 | new(&_adverb._adverb) adverb(other._adverb._adverb); | ||
| 53 | _adverb._infl = other._adverb._infl; | ||
| 54 | |||
| 55 | break; | ||
| 56 | } | ||
| 57 | |||
| 58 | case token::type::preposition: | ||
| 59 | { | ||
| 60 | new(&_preposition._preposition) preposition(other._preposition._preposition); | ||
| 61 | |||
| 62 | break; | ||
| 63 | } | ||
| 64 | |||
| 65 | case token::type::fillin: | ||
| 66 | { | ||
| 67 | _fillin._type = other._fillin._type; | ||
| 68 | |||
| 69 | break; | ||
| 70 | } | ||
| 71 | |||
| 72 | case token::type::string: | ||
| 73 | { | ||
| 74 | new(&_string._str) std::string(other._string._str); | ||
| 75 | |||
| 76 | break; | ||
| 77 | } | ||
| 78 | |||
| 79 | case token::type::utterance: | ||
| 80 | { | ||
| 81 | new(&_utterance._utterance) std::list<token>(other._utterance._utterance); | ||
| 82 | |||
| 83 | break; | ||
| 84 | } | ||
| 85 | } | ||
| 23 | } | 86 | } |
| 24 | 87 | ||
| 25 | verb_token& verb_token::inflect(verb_token::inflection infl) | 88 | token& token::operator=(const token& other) |
| 26 | { | 89 | { |
| 27 | _inflection = infl; | 90 | this->~token(); |
| 91 | |||
| 92 | _type = other._type; | ||
| 93 | |||
| 94 | switch (_type) | ||
| 95 | { | ||
| 96 | case token::type::verb: | ||
| 97 | { | ||
| 98 | new(&_verb._verb) verb(other._verb._verb); | ||
| 99 | _verb._infl = other._verb._infl; | ||
| 100 | |||
| 101 | break; | ||
| 102 | } | ||
| 103 | |||
| 104 | case token::type::noun: | ||
| 105 | { | ||
| 106 | new(&_noun._noun) noun(other._noun._noun); | ||
| 107 | _noun._infl = other._noun._infl; | ||
| 108 | |||
| 109 | break; | ||
| 110 | } | ||
| 111 | |||
| 112 | case token::type::adjective: | ||
| 113 | { | ||
| 114 | new(&_adjective._adjective) adjective(other._adjective._adjective); | ||
| 115 | _adjective._infl = other._adjective._infl; | ||
| 116 | |||
| 117 | break; | ||
| 118 | } | ||
| 119 | |||
| 120 | case token::type::adverb: | ||
| 121 | { | ||
| 122 | new(&_adverb._adverb) adverb(other._adverb._adverb); | ||
| 123 | _adverb._infl = other._adverb._infl; | ||
| 124 | |||
| 125 | break; | ||
| 126 | } | ||
| 127 | |||
| 128 | case token::type::preposition: | ||
| 129 | { | ||
| 130 | new(&_preposition._preposition) preposition(other._preposition._preposition); | ||
| 131 | |||
| 132 | break; | ||
| 133 | } | ||
| 134 | |||
| 135 | case token::type::fillin: | ||
| 136 | { | ||
| 137 | _fillin._type = other._fillin._type; | ||
| 138 | |||
| 139 | break; | ||
| 140 | } | ||
| 141 | |||
| 142 | case token::type::string: | ||
| 143 | { | ||
| 144 | new(&_string._str) std::string(other._string._str); | ||
| 145 | |||
| 146 | break; | ||
| 147 | } | ||
| 148 | |||
| 149 | case token::type::utterance: | ||
| 150 | { | ||
| 151 | new(&_utterance._utterance) std::list<token>(other._utterance._utterance); | ||
| 152 | |||
| 153 | break; | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 28 | return *this; | 157 | return *this; |
| 29 | } | 158 | } |
| 30 | 159 | ||
| 31 | bool verb_token::complete() const | 160 | token::~token() |
| 32 | { | 161 | { |
| 33 | return true; | 162 | switch (_type) |
| 163 | { | ||
| 164 | case token::type::verb: | ||
| 165 | { | ||
| 166 | _verb._verb.~verb(); | ||
| 167 | |||
| 168 | break; | ||
| 169 | } | ||
| 170 | |||
| 171 | case token::type::noun: | ||
| 172 | { | ||
| 173 | _noun._noun.~noun(); | ||
| 174 | |||
| 175 | break; | ||
| 176 | } | ||
| 177 | |||
| 178 | case token::type::adjective: | ||
| 179 | { | ||
| 180 | _adjective._adjective.~adjective(); | ||
| 181 | |||
| 182 | break; | ||
| 183 | } | ||
| 184 | |||
| 185 | case token::type::adverb: | ||
| 186 | { | ||
| 187 | _adverb._adverb.~adverb(); | ||
| 188 | |||
| 189 | break; | ||
| 190 | } | ||
| 191 | |||
| 192 | case token::type::preposition: | ||
| 193 | { | ||
| 194 | _preposition._preposition.~preposition(); | ||
| 195 | |||
| 196 | break; | ||
| 197 | } | ||
| 198 | |||
| 199 | case token::type::fillin: | ||
| 200 | { | ||
| 201 | // Nothing! | ||
| 202 | |||
| 203 | break; | ||
| 204 | } | ||
| 205 | |||
| 206 | case token::type::string: | ||
| 207 | { | ||
| 208 | using string_type = std::string; | ||
| 209 | _string._str.~string_type(); | ||
| 210 | |||
| 211 | break; | ||
| 212 | } | ||
| 213 | |||
| 214 | case token::type::utterance: | ||
| 215 | { | ||
| 216 | using list_type = std::list<token>; | ||
| 217 | _utterance._utterance.~list_type(); | ||
| 218 | |||
| 219 | break; | ||
| 220 | } | ||
| 221 | } | ||
| 34 | } | 222 | } |
| 35 | 223 | ||
| 36 | std::string verb_token::compile() const | 224 | bool token::is_complete() const |
| 37 | { | 225 | { |
| 38 | switch (_inflection) | 226 | if (_type == token::type::utterance) |
| 39 | { | 227 | { |
| 40 | case inflection::infinitive: return _verb->infinitive_form(); | 228 | return std::all_of(std::begin(_utterance._utterance), std::end(_utterance._utterance), [] (const token& tkn) { |
| 41 | case inflection::past_tense: return _verb->past_tense_form(); | 229 | return tkn.is_complete(); |
| 42 | case inflection::past_participle: return _verb->past_participle_form(); | 230 | }); |
| 43 | case inflection::ing_form: return _verb->ing_form(); | 231 | } else if (_type == token::type::fillin) |
| 44 | case inflection::s_form: return _verb->s_form(); | 232 | { |
| 233 | return false; | ||
| 234 | } else { | ||
| 235 | return true; | ||
| 45 | } | 236 | } |
| 46 | } | 237 | } |
| 47 | 238 | ||
| 48 | token* verb_token::copy() const | 239 | std::string token::compile() const |
| 240 | { | ||
| 241 | switch (_type) | ||
| 242 | { | ||
| 243 | case token::type::verb: | ||
| 244 | { | ||
| 245 | switch (_verb._infl) | ||
| 246 | { | ||
| 247 | case token::verb_inflection::infinitive: return _verb._verb.infinitive_form(); | ||
| 248 | case token::verb_inflection::past_tense: return _verb._verb.past_tense_form(); | ||
| 249 | case token::verb_inflection::past_participle: return _verb._verb.past_participle_form(); | ||
| 250 | case token::verb_inflection::ing_form: return _verb._verb.ing_form(); | ||
| 251 | case token::verb_inflection::s_form: return _verb._verb.s_form(); | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | case token::type::noun: | ||
| 256 | { | ||
| 257 | switch (_noun._infl) | ||
| 258 | { | ||
| 259 | case token::noun_inflection::singular: return _noun._noun.singular_form(); | ||
| 260 | case token::noun_inflection::plural: return _noun._noun.plural_form(); | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | case token::type::adjective: | ||
| 265 | { | ||
| 266 | switch (_adjective._infl) | ||
| 267 | { | ||
| 268 | case token::adjective_inflection::base: return _adjective._adjective.base_form(); | ||
| 269 | case token::adjective_inflection::comparative: return _adjective._adjective.comparative_form(); | ||
| 270 | case token::adjective_inflection::superlative: return _adjective._adjective.superlative_form(); | ||
| 271 | } | ||
| 272 | } | ||
| 273 | |||
| 274 | case token::type::adverb: | ||
| 275 | { | ||
| 276 | switch (_adverb._infl) | ||
| 277 | { | ||
| 278 | case token::adverb_inflection::base: return _adverb._adverb.base_form(); | ||
| 279 | case token::adverb_inflection::comparative: return _adverb._adverb.comparative_form(); | ||
| 280 | case token::adverb_inflection::superlative: return _adverb._adverb.superlative_form(); | ||
| 281 | } | ||
| 282 | } | ||
| 283 | |||
| 284 | case token::type::preposition: return _preposition._preposition.get_form(); | ||
| 285 | case token::type::string: return _string._str; | ||
| 286 | |||
| 287 | case token::type::fillin: | ||
| 288 | { | ||
| 289 | throw std::runtime_error("Cannot compile a fillin token."); | ||
| 290 | } | ||
| 291 | |||
| 292 | case token::type::utterance: | ||
| 293 | { | ||
| 294 | std::list<std::string> compiled; | ||
| 295 | std::transform(std::begin(_utterance._utterance), std::end(_utterance._utterance), std::back_inserter(compiled), [] (token tkn) { | ||
| 296 | return tkn.compile(); | ||
| 297 | }); | ||
| 298 | |||
| 299 | return verbly::implode(std::begin(compiled), std::end(compiled), " "); | ||
| 300 | } | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | token::token(verb _verb) : _type(type::verb) | ||
| 305 | { | ||
| 306 | new(&this->_verb._verb) verb(_verb); | ||
| 307 | this->_verb._infl = verb_inflection::infinitive; | ||
| 308 | } | ||
| 309 | |||
| 310 | token::token(verb _verb, verb_inflection _infl) : token(_verb) | ||
| 311 | { | ||
| 312 | this->_verb._infl = _infl; | ||
| 313 | } | ||
| 314 | |||
| 315 | token& token::operator=(verb _verb) | ||
| 316 | { | ||
| 317 | *this = token{_verb}; | ||
| 318 | |||
| 319 | return *this; | ||
| 320 | } | ||
| 321 | |||
| 322 | verb token::get_verb() const | ||
| 323 | { | ||
| 324 | assert(_type == type::verb); | ||
| 325 | |||
| 326 | return _verb._verb; | ||
| 327 | } | ||
| 328 | |||
| 329 | void token::set_verb(verb _verb) | ||
| 330 | { | ||
| 331 | assert(_type == type::verb); | ||
| 332 | |||
| 333 | this->_verb._verb = _verb; | ||
| 334 | } | ||
| 335 | |||
| 336 | token::verb_inflection token::get_verb_inflection() const | ||
| 337 | { | ||
| 338 | assert(_type == type::verb); | ||
| 339 | |||
| 340 | return _verb._infl; | ||
| 341 | } | ||
| 342 | |||
| 343 | void token::set_verb_inflection(verb_inflection _infl) | ||
| 344 | { | ||
| 345 | assert(_type == type::verb); | ||
| 346 | |||
| 347 | _verb._infl = _infl; | ||
| 348 | } | ||
| 349 | |||
| 350 | token::token(noun _noun) : _type(type::noun) | ||
| 351 | { | ||
| 352 | new(&this->_noun._noun) noun(_noun); | ||
| 353 | this->_noun._infl = noun_inflection::singular; | ||
| 354 | } | ||
| 355 | |||
| 356 | token::token(noun _noun, noun_inflection _infl) : token(_noun) | ||
| 357 | { | ||
| 358 | this->_noun._infl = _infl; | ||
| 359 | } | ||
| 360 | |||
| 361 | token& token::operator=(noun _noun) | ||
| 49 | { | 362 | { |
| 50 | return new verb_token(*this); | 363 | *this = token{_noun}; |
| 364 | |||
| 365 | return *this; | ||
| 366 | } | ||
| 367 | |||
| 368 | noun token::get_noun() const | ||
| 369 | { | ||
| 370 | assert(_type == type::noun); | ||
| 371 | |||
| 372 | return _noun._noun; | ||
| 373 | } | ||
| 374 | |||
| 375 | void token::set_noun(noun _noun) | ||
| 376 | { | ||
| 377 | assert(_type == type::noun); | ||
| 378 | |||
| 379 | this->_noun._noun = _noun; | ||
| 380 | } | ||
| 381 | |||
| 382 | token::noun_inflection token::get_noun_inflection() const | ||
| 383 | { | ||
| 384 | assert(_type == type::noun); | ||
| 385 | |||
| 386 | return _noun._infl; | ||
| 387 | } | ||
| 388 | |||
| 389 | void token::set_noun_inflection(noun_inflection _infl) | ||
| 390 | { | ||
| 391 | assert(_type == type::noun); | ||
| 392 | |||
| 393 | _noun._infl = _infl; | ||
| 394 | } | ||
| 395 | |||
| 396 | token::token(adjective _adjective) : _type(type::adjective) | ||
| 397 | { | ||
| 398 | new(&this->_adjective._adjective) adjective(_adjective); | ||
| 399 | this->_adjective._infl = adjective_inflection::base; | ||
| 400 | } | ||
| 401 | |||
| 402 | token::token(adjective _adjective, adjective_inflection _infl) : token(_adjective) | ||
| 403 | { | ||
| 404 | this->_adjective._infl = _infl; | ||
| 405 | } | ||
| 406 | |||
| 407 | token& token::operator=(adjective _adjective) | ||
| 408 | { | ||
| 409 | *this = token{_adjective}; | ||
| 410 | |||
| 411 | return *this; | ||
| 412 | } | ||
| 413 | |||
| 414 | adjective token::get_adjective() const | ||
| 415 | { | ||
| 416 | assert(_type == type::adjective); | ||
| 417 | |||
| 418 | return _adjective._adjective; | ||
| 419 | } | ||
| 420 | |||
| 421 | void token::set_adjective(adjective _adjective) | ||
| 422 | { | ||
| 423 | assert(_type == type::adjective); | ||
| 424 | |||
| 425 | this->_adjective._adjective = _adjective; | ||
| 426 | } | ||
| 427 | |||
| 428 | token::adjective_inflection token::get_adjective_inflection() const | ||
| 429 | { | ||
| 430 | assert(_type == type::adjective); | ||
| 431 | |||
| 432 | return _adjective._infl; | ||
| 433 | } | ||
| 434 | |||
| 435 | void token::set_adjective_inflection(adjective_inflection _infl) | ||
| 436 | { | ||
| 437 | assert(_type == type::adjective); | ||
| 438 | |||
| 439 | _adjective._infl = _infl; | ||
| 440 | } | ||
| 441 | |||
| 442 | token::token(adverb _adverb) : _type(type::adverb) | ||
| 443 | { | ||
| 444 | new(&this->_adverb._adverb) adverb(_adverb); | ||
| 445 | this->_adverb._infl = adverb_inflection::base; | ||
| 446 | } | ||
| 447 | |||
| 448 | token::token(adverb _adverb, adverb_inflection _infl) : token(_adverb) | ||
| 449 | { | ||
| 450 | this->_adverb._infl = _infl; | ||
| 451 | } | ||
| 452 | |||
| 453 | token& token::operator=(adverb _adverb) | ||
| 454 | { | ||
| 455 | *this = token{_adverb}; | ||
| 456 | |||
| 457 | return *this; | ||
| 458 | } | ||
| 459 | |||
| 460 | adverb token::get_adverb() const | ||
| 461 | { | ||
| 462 | assert(_type == type::adverb); | ||
| 463 | |||
| 464 | return _adverb._adverb; | ||
| 465 | } | ||
| 466 | |||
| 467 | void token::set_adverb(adverb _adverb) | ||
| 468 | { | ||
| 469 | assert(_type == type::adverb); | ||
| 470 | |||
| 471 | this->_adverb._adverb = _adverb; | ||
| 472 | } | ||
| 473 | |||
| 474 | token::adverb_inflection token::get_adverb_inflection() const | ||
| 475 | { | ||
| 476 | assert(_type == type::adverb); | ||
| 477 | |||
| 478 | return _adverb._infl; | ||
| 479 | } | ||
| 480 | |||
| 481 | void token::set_adverb_inflection(adverb_inflection _infl) | ||
| 482 | { | ||
| 483 | assert(_type == type::adverb); | ||
| 484 | |||
| 485 | _adverb._infl = _infl; | ||
| 486 | } | ||
| 487 | |||
| 488 | token::token(preposition _preposition) : _type(type::preposition) | ||
| 489 | { | ||
| 490 | new(&this->_preposition._preposition) preposition(_preposition); | ||
| 491 | } | ||
| 492 | |||
| 493 | token& token::operator=(preposition _preposition) | ||
| 494 | { | ||
| 495 | *this = token{_preposition}; | ||
| 496 | |||
| 497 | return *this; | ||
| 498 | } | ||
| 499 | |||
| 500 | preposition token::get_preposition() const | ||
| 501 | { | ||
| 502 | assert(_type == type::preposition); | ||
| 503 | |||
| 504 | return _preposition._preposition; | ||
| 505 | } | ||
| 506 | |||
| 507 | void token::set_preposition(preposition _preposition) | ||
| 508 | { | ||
| 509 | assert(_type == type::preposition); | ||
| 510 | |||
| 511 | this->_preposition._preposition = _preposition; | ||
| 512 | } | ||
| 513 | |||
| 514 | token::token(fillin_type _ft) : _type(type::fillin) | ||
| 515 | { | ||
| 516 | _fillin._type = _ft; | ||
| 517 | } | ||
| 518 | |||
| 519 | token& token::operator=(fillin_type _ft) | ||
| 520 | { | ||
| 521 | *this = token{_ft}; | ||
| 522 | |||
| 523 | return *this; | ||
| 524 | } | ||
| 525 | |||
| 526 | token::fillin_type token::get_fillin_type() const | ||
| 527 | { | ||
| 528 | assert(_type == type::fillin); | ||
| 529 | |||
| 530 | return _fillin._type; | ||
| 531 | } | ||
| 532 | |||
| 533 | void token::set_fillin_type(fillin_type _ft) | ||
| 534 | { | ||
| 535 | assert(_type == type::fillin); | ||
| 536 | |||
| 537 | _fillin._type = _ft; | ||
| 538 | } | ||
| 539 | |||
| 540 | token::token() : _type(type::utterance) | ||
| 541 | { | ||
| 542 | new(&_utterance._utterance) std::list<token>(); | ||
| 543 | } | ||
| 544 | |||
| 545 | token::token(std::initializer_list<token> _init) : _type(type::utterance) | ||
| 546 | { | ||
| 547 | new(&_utterance._utterance) std::list<token>(_init); | ||
| 548 | } | ||
| 549 | |||
| 550 | token::iterator token::begin() | ||
| 551 | { | ||
| 552 | assert(_type == type::utterance); | ||
| 553 | |||
| 554 | return _utterance._utterance.begin(); | ||
| 555 | } | ||
| 556 | |||
| 557 | token::iterator token::end() | ||
| 558 | { | ||
| 559 | assert(_type == type::utterance); | ||
| 560 | |||
| 561 | return _utterance._utterance.end(); | ||
| 562 | } | ||
| 563 | |||
| 564 | token& token::operator<<(token _tkn) | ||
| 565 | { | ||
| 566 | assert(_type == type::utterance); | ||
| 567 | |||
| 568 | _utterance._utterance.push_back(_tkn); | ||
| 569 | |||
| 570 | return *this; | ||
| 571 | } | ||
| 572 | |||
| 573 | void token::push_back(token _tkn) | ||
| 574 | { | ||
| 575 | assert(_type == type::utterance); | ||
| 576 | |||
| 577 | _utterance._utterance.push_back(_tkn); | ||
| 578 | } | ||
| 579 | |||
| 580 | void token::insert(iterator before, token _tkn) | ||
| 581 | { | ||
| 582 | assert(_type == type::utterance); | ||
| 583 | |||
| 584 | _utterance._utterance.insert(before, _tkn); | ||
| 585 | } | ||
| 586 | |||
| 587 | void token::replace(iterator torepl, token _tkn) | ||
| 588 | { | ||
| 589 | assert(_type == type::utterance); | ||
| 590 | |||
| 591 | _utterance._utterance.insert(torepl, _tkn); | ||
| 592 | _utterance._utterance.erase(torepl); | ||
| 593 | } | ||
| 594 | |||
| 595 | void token::erase(iterator toer) | ||
| 596 | { | ||
| 597 | assert(_type == type::utterance); | ||
| 598 | |||
| 599 | _utterance._utterance.erase(toer); | ||
| 600 | } | ||
| 601 | |||
| 602 | token::token(std::string _str) : _type(type::string) | ||
| 603 | { | ||
| 604 | new(&_string._str) std::string(_str); | ||
| 605 | } | ||
| 606 | |||
| 607 | token& token::operator=(std::string _str) | ||
| 608 | { | ||
| 609 | *this = token{_str}; | ||
| 610 | |||
| 611 | return *this; | ||
| 612 | } | ||
| 613 | |||
| 614 | std::string token::get_string() const | ||
| 615 | { | ||
| 616 | assert(_type == type::string); | ||
| 617 | |||
| 618 | return _string._str; | ||
| 619 | } | ||
| 620 | |||
| 621 | void token::set_string(std::string _str) | ||
| 622 | { | ||
| 623 | assert(_type == type::string); | ||
| 624 | |||
| 625 | _string._str = _str; | ||
| 51 | } | 626 | } |
| 52 | 627 | ||
| 53 | }; | 628 | }; |
| diff --git a/lib/token.h b/lib/token.h index b22032b..788a106 100644 --- a/lib/token.h +++ b/lib/token.h | |||
| @@ -1,314 +1,169 @@ | |||
| 1 | #ifndef TOKEN_H_AD62C505 | 1 | #ifndef TOKEN_H_AD62C505 |
| 2 | #define TOKEN_H_AD62C505 | 2 | #define TOKEN_H_AD62C505 |
| 3 | 3 | ||
| 4 | #include <string> | ||
| 5 | #include <list> | ||
| 6 | #include <sstream> | ||
| 7 | #include <algorithm> | ||
| 8 | |||
| 9 | namespace verbly { | 4 | namespace verbly { |
| 10 | 5 | ||
| 11 | class verb; | ||
| 12 | |||
| 13 | class selrestr { | ||
| 14 | }; | ||
| 15 | |||
| 16 | class synrestr { | ||
| 17 | }; | ||
| 18 | |||
| 19 | enum class fillin_type { | ||
| 20 | noun_phrase, | ||
| 21 | participle_phrase, | ||
| 22 | adjective, | ||
| 23 | adverb | ||
| 24 | }; | ||
| 25 | |||
| 26 | class token { | 6 | class token { |
| 27 | public: | 7 | public: |
| 28 | enum class type { | 8 | enum class type { |
| 29 | verb, | 9 | verb, |
| 10 | noun, | ||
| 11 | adjective, | ||
| 12 | adverb, | ||
| 13 | preposition, | ||
| 30 | fillin, | 14 | fillin, |
| 31 | string, | 15 | utterance, |
| 32 | utterance | 16 | string |
| 33 | }; | 17 | }; |
| 34 | 18 | ||
| 35 | protected: | 19 | enum class verb_inflection { |
| 36 | // General | ||
| 37 | type _type; | ||
| 38 | |||
| 39 | token(type _type); | ||
| 40 | |||
| 41 | public: | ||
| 42 | enum type token_type() const; | ||
| 43 | |||
| 44 | virtual bool complete() const = 0; | ||
| 45 | virtual std::string compile() const = 0; | ||
| 46 | virtual token* copy() const = 0; | ||
| 47 | }; | ||
| 48 | |||
| 49 | class verb_token : public token { | ||
| 50 | public: | ||
| 51 | enum class inflection { | ||
| 52 | infinitive, | 20 | infinitive, |
| 53 | past_tense, | 21 | past_tense, |
| 54 | past_participle, | 22 | past_participle, |
| 55 | ing_form, | 23 | s_form, |
| 56 | s_form | 24 | ing_form |
| 57 | }; | 25 | }; |
| 58 | 26 | ||
| 59 | private: | 27 | enum class noun_inflection { |
| 60 | // Verb | 28 | singular, |
| 61 | const verb* _verb; | 29 | plural |
| 62 | inflection _inflection = inflection::infinitive; | 30 | }; |
| 63 | |||
| 64 | public: | ||
| 65 | verb_token(const verb& _verb); | ||
| 66 | |||
| 67 | const verb& get_verb() const; | ||
| 68 | |||
| 69 | verb_token& inflect(inflection infl); | ||
| 70 | |||
| 71 | bool complete() const; | ||
| 72 | |||
| 73 | std::string compile() const; | ||
| 74 | |||
| 75 | token* copy() const; | ||
| 76 | }; | ||
| 77 | |||
| 78 | class utterance_token : public token { | ||
| 79 | private: | ||
| 80 | // Utterance | ||
| 81 | std::list<std::unique_ptr<token>> utterance; | ||
| 82 | |||
| 83 | public: | ||
| 84 | typedef std::list<std::unique_ptr<token>>::iterator iterator; | ||
| 85 | /*class iterator { | ||
| 86 | private: | ||
| 87 | friend class utterance_token; | ||
| 88 | |||
| 89 | std::list<std::unique_ptr<token>>::iterator it; | ||
| 90 | |||
| 91 | public: | ||
| 92 | iterator(std::list<std::unique_ptr<token>>::iterator it) : it(it) | ||
| 93 | { | ||
| 94 | |||
| 95 | } | ||
| 96 | |||
| 97 | iterator& operator++() | ||
| 98 | { | ||
| 99 | ++it; | ||
| 100 | return *this; | ||
| 101 | } | ||
| 102 | |||
| 103 | iterator& operator--() | ||
| 104 | { | ||
| 105 | --it; | ||
| 106 | return *this; | ||
| 107 | } | ||
| 108 | |||
| 109 | bool operator==(const iterator& other) const | ||
| 110 | { | ||
| 111 | return it == other.it; | ||
| 112 | } | ||
| 113 | |||
| 114 | bool operator!=(const iterator& other) const | ||
| 115 | { | ||
| 116 | return it != other.it; | ||
| 117 | } | ||
| 118 | |||
| 119 | token& operator*() | ||
| 120 | { | ||
| 121 | return **it; | ||
| 122 | } | ||
| 123 | |||
| 124 | token& operator->() | ||
| 125 | { | ||
| 126 | return **it; | ||
| 127 | } | ||
| 128 | };*/ | ||
| 129 | |||
| 130 | utterance_token(std::initializer_list<token*> tkns) : token(token::type::utterance) | ||
| 131 | { | ||
| 132 | for (auto tkn : tkns) | ||
| 133 | { | ||
| 134 | utterance.push_back(std::unique_ptr<token>(tkn)); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | utterance_token(const utterance_token& other) : token(token::type::utterance) | ||
| 139 | { | ||
| 140 | for (auto& tkn : other.utterance) | ||
| 141 | { | ||
| 142 | utterance.push_back(std::unique_ptr<token>(tkn->copy())); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | 31 | ||
| 146 | utterance_token(utterance_token&& other) : token(token::type::utterance), utterance(std::move(other.utterance)) | 32 | enum class adjective_inflection { |
| 147 | { | 33 | base, |
| 148 | 34 | comparative, | |
| 149 | } | 35 | superlative |
| 36 | }; | ||
| 150 | 37 | ||
| 151 | utterance_token& operator=(const utterance_token& other) | 38 | enum class adverb_inflection { |
| 152 | { | 39 | base, |
| 153 | utterance.clear(); | 40 | comparative, |
| 154 | 41 | superlative | |
| 155 | for (auto& tkn : other.utterance) | 42 | }; |
| 156 | { | ||
| 157 | utterance.push_back(std::unique_ptr<token>(tkn->copy())); | ||
| 158 | } | ||
| 159 | |||
| 160 | return *this; | ||
| 161 | } | ||
| 162 | 43 | ||
| 163 | utterance_token& operator=(utterance_token&& other) | 44 | enum class fillin_type { |
| 164 | { | 45 | generic, |
| 165 | utterance = std::move(other.utterance); | 46 | noun_phrase, |
| 166 | 47 | adjective_phrase, | |
| 167 | return *this; | 48 | adverb_phrase, |
| 168 | } | 49 | participle_phrase, |
| 50 | infinitive_phrase | ||
| 51 | }; | ||
| 169 | 52 | ||
| 170 | iterator begin() | 53 | type get_type() const; |
| 171 | { | ||
| 172 | return std::begin(utterance); | ||
| 173 | } | ||
| 174 | 54 | ||
| 175 | iterator end() | 55 | int get_extra() const; |
| 176 | { | 56 | void set_extra(int _arg); |
| 177 | return std::end(utterance); | ||
| 178 | } | ||
| 179 | 57 | ||
| 180 | void erase(iterator it) | 58 | token(const token& other); |
| 181 | { | 59 | token& operator=(const token& other); |
| 182 | utterance.erase(it); | 60 | ~token(); |
| 183 | } | ||
| 184 | 61 | ||
| 185 | bool complete() const | 62 | bool is_complete() const; |
| 186 | { | 63 | std::string compile() const; |
| 187 | return std::all_of(std::begin(utterance), std::end(utterance), [] (const std::unique_ptr<token>& tkn) { | ||
| 188 | return tkn->complete(); | ||
| 189 | }); | ||
| 190 | } | ||
| 191 | 64 | ||
| 192 | std::string compile() const | 65 | // Verb |
| 193 | { | 66 | token(verb _verb); |
| 194 | std::stringstream result; | 67 | token(verb _verb, verb_inflection _infl); |
| 195 | for (auto& t : utterance) | 68 | token& operator=(verb _verb); |
| 196 | { | 69 | verb get_verb() const; |
| 197 | if (t->complete()) | 70 | void set_verb(verb _verb); |
| 198 | { | 71 | verb_inflection get_verb_inflection() const; |
| 199 | result << t->compile() << " "; | 72 | void set_verb_inflection(verb_inflection _infl); |
| 200 | } else { | 73 | |
| 201 | return "Could not compile!"; | 74 | // Noun |
| 202 | } | 75 | token(noun _noun); |
| 203 | } | 76 | token(noun _noun, noun_inflection _infl); |
| 204 | 77 | token& operator=(noun _noun); | |
| 205 | std::string output = result.str(); | 78 | noun get_noun() const; |
| 206 | if (output != "") | 79 | void set_noun(noun _noun); |
| 207 | { | 80 | noun_inflection get_noun_inflection() const; |
| 208 | output.pop_back(); | 81 | void set_noun_inflection(noun_inflection _infl); |
| 209 | } | 82 | |
| 210 | 83 | // Adjective | |
| 211 | return output; | 84 | token(adjective _adjective); |
| 212 | } | 85 | token(adjective _adjective, adjective_inflection _infl); |
| 86 | token& operator=(adjective _adjective); | ||
| 87 | adjective get_adjective() const; | ||
| 88 | void set_adjective(adjective _adjective); | ||
| 89 | adjective_inflection get_adjective_inflection() const; | ||
| 90 | void set_adjective_inflection(adjective_inflection _infl); | ||
| 91 | |||
| 92 | // Adverb | ||
| 93 | token(adverb _adverb); | ||
| 94 | token(adverb _adverb, adverb_inflection _infl); | ||
| 95 | token& operator=(adverb _adverb); | ||
| 96 | adverb get_adverb() const; | ||
| 97 | void set_adverb(adverb _adverb); | ||
| 98 | adverb_inflection get_adverb_inflection() const; | ||
| 99 | void set_adverb_inflection(adverb_inflection _infl); | ||
| 100 | |||
| 101 | // Preposition | ||
| 102 | token(preposition _preposition); | ||
| 103 | token& operator=(preposition _preposition); | ||
| 104 | preposition get_preposition() const; | ||
| 105 | void set_preposition(preposition _preposition); | ||
| 213 | 106 | ||
| 214 | token* copy() const | ||
| 215 | { | ||
| 216 | return new utterance_token(*this); | ||
| 217 | } | ||
| 218 | }; | ||
| 219 | |||
| 220 | class fillin_token : public token { | ||
| 221 | private: | ||
| 222 | // Fillin | 107 | // Fillin |
| 223 | std::string m_theme; | 108 | token(fillin_type _ft); |
| 224 | fillin_type m_fillin_type; | 109 | token& operator=(fillin_type _ft); |
| 225 | 110 | fillin_type get_fillin_type() const; | |
| 226 | public: | 111 | void set_fillin_type(fillin_type _ft); |
| 227 | fillin_token(fillin_type ft) : token(token::type::fillin), m_fillin_type(ft) | ||
| 228 | { | ||
| 229 | |||
| 230 | } | ||
| 231 | |||
| 232 | /* void synrestrs(std::initializer_list<synrestr> ins) | ||
| 233 | { | ||
| 234 | m_synrestrs = std::set<synrestr>(ins); | ||
| 235 | } | ||
| 236 | |||
| 237 | std::set<synrestr>& synrestrs() | ||
| 238 | { | ||
| 239 | return m_synrestrs; | ||
| 240 | } | ||
| 241 | |||
| 242 | void selrestrs(std::initializer_list<selrestr> ins) | ||
| 243 | { | ||
| 244 | m_selrestrs = std::set<selrestr>(ins); | ||
| 245 | } | ||
| 246 | |||
| 247 | std::set<selrestr>& selrestrs() | ||
| 248 | { | ||
| 249 | return m_selrestrs; | ||
| 250 | }*/ | ||
| 251 | |||
| 252 | fillin_token theme(std::string theme) | ||
| 253 | { | ||
| 254 | m_theme = theme; | ||
| 255 | |||
| 256 | return *this; | ||
| 257 | } | ||
| 258 | 112 | ||
| 259 | std::string& theme() | 113 | // Utterance |
| 260 | { | 114 | typedef std::list<token>::iterator iterator; |
| 261 | return m_theme; | 115 | |
| 262 | } | 116 | token(); |
| 263 | 117 | token(std::initializer_list<token> _init); | |
| 264 | fillin_type get_fillin_type() const | 118 | iterator begin(); |
| 265 | { | 119 | iterator end(); |
| 266 | return m_fillin_type; | 120 | token& operator<<(token _tkn); |
| 267 | } | 121 | void push_back(token _tkn); |
| 268 | 122 | void insert(iterator before, token _tkn); | |
| 269 | bool complete() const | 123 | void replace(iterator torepl, token _tkn); |
| 270 | { | 124 | void erase(iterator toer); |
| 271 | return false; | ||
| 272 | } | ||
| 273 | |||
| 274 | std::string compile() const | ||
| 275 | { | ||
| 276 | return ""; | ||
| 277 | } | ||
| 278 | 125 | ||
| 279 | token* copy() const | ||
| 280 | { | ||
| 281 | return new fillin_token(*this); | ||
| 282 | } | ||
| 283 | }; | ||
| 284 | |||
| 285 | class string_token : public token { | ||
| 286 | private: | ||
| 287 | // String | 126 | // String |
| 288 | std::string str; | 127 | token(std::string _str); |
| 289 | 128 | token& operator=(std::string _str); | |
| 290 | public: | 129 | std::string get_string() const; |
| 291 | string_token(std::string str) : token(token::type::string), str(str) | 130 | void set_string(std::string _str); |
| 292 | { | ||
| 293 | |||
| 294 | } | ||
| 295 | |||
| 296 | bool complete() const | ||
| 297 | { | ||
| 298 | return true; | ||
| 299 | } | ||
| 300 | 131 | ||
| 301 | std::string compile() const | 132 | private: |
| 302 | { | 133 | type _type; |
| 303 | return str; | 134 | int _extra = 0; |
| 304 | } | 135 | union { |
| 305 | 136 | struct { | |
| 306 | token* copy() const | 137 | verb _verb; |
| 307 | { | 138 | verb_inflection _infl; |
| 308 | return new string_token(*this); | 139 | } _verb; |
| 309 | } | 140 | struct { |
| 141 | noun _noun; | ||
| 142 | noun_inflection _infl; | ||
| 143 | } _noun; | ||
| 144 | struct { | ||
| 145 | adjective _adjective; | ||
| 146 | adjective_inflection _infl; | ||
| 147 | } _adjective; | ||
| 148 | struct { | ||
| 149 | adverb _adverb; | ||
| 150 | adverb_inflection _infl; | ||
| 151 | } _adverb; | ||
| 152 | struct { | ||
| 153 | preposition _preposition; | ||
| 154 | } _preposition; | ||
| 155 | struct { | ||
| 156 | fillin_type _type; | ||
| 157 | } _fillin; | ||
| 158 | struct { | ||
| 159 | std::string _str; | ||
| 160 | } _string; | ||
| 161 | struct { | ||
| 162 | std::list<token> _utterance; | ||
| 163 | } _utterance; | ||
| 164 | }; | ||
| 310 | }; | 165 | }; |
| 311 | 166 | ||
| 312 | }; | 167 | }; |
| 313 | 168 | ||
| 314 | #endif /* end of include guard: TOKEN_H_AD62C505 */ | 169 | #endif /* end of include guard: TOKEN_H_AD62C505 */ |
| diff --git a/lib/util.h b/lib/util.h index 815b47c..fb5fe67 100644 --- a/lib/util.h +++ b/lib/util.h | |||
| @@ -1,10 +1,6 @@ | |||
| 1 | #ifndef UTIL_H_15DDCA2D | 1 | #ifndef UTIL_H_15DDCA2D |
| 2 | #define UTIL_H_15DDCA2D | 2 | #define UTIL_H_15DDCA2D |
| 3 | 3 | ||
| 4 | #include <string> | ||
| 5 | #include <iterator> | ||
| 6 | #include <sstream> | ||
| 7 | |||
| 8 | namespace verbly { | 4 | namespace verbly { |
| 9 | 5 | ||
| 10 | template <class InputIterator> | 6 | template <class InputIterator> |
| @@ -32,7 +28,7 @@ namespace verbly { | |||
| 32 | 28 | ||
| 33 | while (!input.empty()) | 29 | while (!input.empty()) |
| 34 | { | 30 | { |
| 35 | int divider = input.find(" "); | 31 | int divider = input.find(delimiter); |
| 36 | if (divider == std::string::npos) | 32 | if (divider == std::string::npos) |
| 37 | { | 33 | { |
| 38 | result.push_back(input); | 34 | result.push_back(input); |
| @@ -41,7 +37,7 @@ namespace verbly { | |||
| 41 | } else { | 37 | } else { |
| 42 | result.push_back(input.substr(0, divider)); | 38 | result.push_back(input.substr(0, divider)); |
| 43 | 39 | ||
| 44 | input = input.substr(divider+1); | 40 | input = input.substr(divider+delimiter.length()); |
| 45 | } | 41 | } |
| 46 | } | 42 | } |
| 47 | 43 | ||
| diff --git a/lib/verb.cpp b/lib/verb.cpp index 23f7c92..1f45d53 100644 --- a/lib/verb.cpp +++ b/lib/verb.cpp | |||
| @@ -2,6 +2,11 @@ | |||
| 2 | 2 | ||
| 3 | namespace verbly { | 3 | namespace verbly { |
| 4 | 4 | ||
| 5 | verb::verb() | ||
| 6 | { | ||
| 7 | |||
| 8 | } | ||
| 9 | |||
| 5 | verb::verb(const data& _data, int _id) : word(_data, _id) | 10 | verb::verb(const data& _data, int _id) : word(_data, _id) |
| 6 | { | 11 | { |
| 7 | 12 | ||
| @@ -9,185 +14,51 @@ namespace verbly { | |||
| 9 | 14 | ||
| 10 | std::string verb::base_form() const | 15 | std::string verb::base_form() const |
| 11 | { | 16 | { |
| 17 | assert(_valid == true); | ||
| 18 | |||
| 12 | return _infinitive; | 19 | return _infinitive; |
| 13 | } | 20 | } |
| 14 | 21 | ||
| 15 | std::string verb::infinitive_form() const | 22 | std::string verb::infinitive_form() const |
| 16 | { | 23 | { |
| 24 | assert(_valid == true); | ||
| 25 | |||
| 17 | return _infinitive; | 26 | return _infinitive; |
| 18 | } | 27 | } |
| 19 | 28 | ||
| 20 | std::string verb::past_tense_form() const | 29 | std::string verb::past_tense_form() const |
| 21 | { | 30 | { |
| 31 | assert(_valid == true); | ||
| 32 | |||
| 22 | return _past_tense; | 33 | return _past_tense; |
| 23 | } | 34 | } |
| 24 | 35 | ||
| 25 | std::string verb::past_participle_form() const | 36 | std::string verb::past_participle_form() const |
| 26 | { | 37 | { |
| 38 | assert(_valid == true); | ||
| 39 | |||
| 27 | return _past_participle; | 40 | return _past_participle; |
| 28 | } | 41 | } |
| 29 | 42 | ||
| 30 | std::string verb::ing_form() const | 43 | std::string verb::ing_form() const |
| 31 | { | 44 | { |
| 45 | assert(_valid == true); | ||
| 46 | |||
| 32 | return _ing_form; | 47 | return _ing_form; |
| 33 | } | 48 | } |
| 34 | 49 | ||
| 35 | std::string verb::s_form() const | 50 | std::string verb::s_form() const |
| 36 | { | 51 | { |
| 37 | return _s_form; | 52 | assert(_valid == true); |
| 38 | } | ||
| 39 | |||
| 40 | verb_query::verb_query(const data& _data) : _data(_data) | ||
| 41 | { | ||
| 42 | |||
| 43 | } | ||
| 44 | |||
| 45 | verb_query& verb_query::limit(int _limit) | ||
| 46 | { | ||
| 47 | if ((_limit > 0) || (_limit == unlimited)) | ||
| 48 | { | ||
| 49 | this->_limit = _limit; | ||
| 50 | } | ||
| 51 | |||
| 52 | return *this; | ||
| 53 | } | ||
| 54 | |||
| 55 | verb_query& verb_query::random(bool _random) | ||
| 56 | { | ||
| 57 | this->_random = _random; | ||
| 58 | |||
| 59 | return *this; | ||
| 60 | } | ||
| 61 | |||
| 62 | verb_query& verb_query::except(const verb& _word) | ||
| 63 | { | ||
| 64 | _except.push_back(_word); | ||
| 65 | |||
| 66 | return *this; | ||
| 67 | } | ||
| 68 | |||
| 69 | verb_query& verb_query::rhymes_with(const word& _word) | ||
| 70 | { | ||
| 71 | for (auto rhyme : _word.rhyme_phonemes()) | ||
| 72 | { | ||
| 73 | _rhymes.push_back(rhyme); | ||
| 74 | } | ||
| 75 | |||
| 76 | if (dynamic_cast<const verb*>(&_word) != nullptr) | ||
| 77 | { | ||
| 78 | _except.push_back(dynamic_cast<const verb&>(_word)); | ||
| 79 | } | ||
| 80 | 53 | ||
| 81 | return *this; | 54 | return _s_form; |
| 82 | } | 55 | } |
| 83 | 56 | ||
| 84 | verb_query& verb_query::has_pronunciation(bool _has_prn) | 57 | frame_query verb::frames() const |
| 85 | { | 58 | { |
| 86 | this->_has_prn = _has_prn; | 59 | assert(_valid == true); |
| 87 | 60 | ||
| 88 | return *this; | 61 | return _data->frames().for_verb(*this); |
| 89 | } | 62 | } |
| 90 | |||
| 91 | std::list<verb> verb_query::run() const | ||
| 92 | { | ||
| 93 | std::stringstream construct; | ||
| 94 | construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs"; | ||
| 95 | std::list<std::string> conditions; | ||
| 96 | |||
| 97 | if (_has_prn) | ||
| 98 | { | ||
| 99 | conditions.push_back("verb_id IN (SELECT verb_id FROM verb_pronunciations)"); | ||
| 100 | } | ||
| 101 | |||
| 102 | if (!_rhymes.empty()) | ||
| 103 | { | ||
| 104 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
| 105 | std::string cond = "verb_id IN (SELECT verb_id FROM verb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 106 | conditions.push_back(cond); | ||
| 107 | } | ||
| 108 | |||
| 109 | for (auto except : _except) | ||
| 110 | { | ||
| 111 | conditions.push_back("verb_id != @EXCID"); | ||
| 112 | } | ||
| 113 | 63 | ||
| 114 | if (!conditions.empty()) | ||
| 115 | { | ||
| 116 | construct << " WHERE "; | ||
| 117 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
| 118 | } | ||
| 119 | |||
| 120 | if (_random) | ||
| 121 | { | ||
| 122 | construct << " ORDER BY RANDOM()"; | ||
| 123 | } | ||
| 124 | |||
| 125 | if (_limit != unlimited) | ||
| 126 | { | ||
| 127 | construct << " LIMIT " << _limit; | ||
| 128 | } | ||
| 129 | |||
| 130 | sqlite3_stmt* ppstmt; | ||
| 131 | std::string query = construct.str(); | ||
| 132 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 133 | { | ||
| 134 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 135 | } | ||
| 136 | |||
| 137 | if (!_rhymes.empty()) | ||
| 138 | { | ||
| 139 | int i = 0; | ||
| 140 | for (auto rhyme : _rhymes) | ||
| 141 | { | ||
| 142 | std::string rhymer = "%" + rhyme; | ||
| 143 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
| 144 | |||
| 145 | i++; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | for (auto except : _except) | ||
| 150 | { | ||
| 151 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
| 152 | } | ||
| 153 | |||
| 154 | std::list<verb> output; | ||
| 155 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 156 | { | ||
| 157 | verb tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
| 158 | tnc._infinitive = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
| 159 | tnc._past_tense = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
| 160 | tnc._past_participle = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
| 161 | tnc._ing_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 4))); | ||
| 162 | tnc._s_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 5))); | ||
| 163 | |||
| 164 | output.push_back(tnc); | ||
| 165 | } | ||
| 166 | |||
| 167 | sqlite3_finalize(ppstmt); | ||
| 168 | |||
| 169 | for (auto& verb : output) | ||
| 170 | { | ||
| 171 | query = "SELECT pronunciation FROM verb_pronunciations WHERE verb_id = ?"; | ||
| 172 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 173 | { | ||
| 174 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 175 | } | ||
| 176 | |||
| 177 | sqlite3_bind_int(ppstmt, 1, verb._id); | ||
| 178 | |||
| 179 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 180 | { | ||
| 181 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
| 182 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
| 183 | |||
| 184 | verb.pronunciations.push_back(phonemes); | ||
| 185 | } | ||
| 186 | |||
| 187 | sqlite3_finalize(ppstmt); | ||
| 188 | } | ||
| 189 | |||
| 190 | return output; | ||
| 191 | } | ||
| 192 | |||
| 193 | }; | 64 | }; |
| diff --git a/lib/verb.h b/lib/verb.h index 7cc87e2..7a2486e 100644 --- a/lib/verb.h +++ b/lib/verb.h | |||
| @@ -3,26 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | namespace verbly { | 4 | namespace verbly { |
| 5 | 5 | ||
| 6 | /*class frame_part { | 6 | class frame_query; |
| 7 | |||
| 8 | }; | ||
| 9 | |||
| 10 | class frame { | ||
| 11 | private: | ||
| 12 | std::list<frame_part> content; | ||
| 13 | std::map<std::string, std::vector<std::list<frame_part>::iterator>> predicates; | ||
| 14 | |||
| 15 | public: | ||
| 16 | frame(std::list<frame_part> content) : content(content) | ||
| 17 | { | ||
| 18 | |||
| 19 | } | ||
| 20 | |||
| 21 | std::unique_ptr<token> make_utterance() const | ||
| 22 | { | ||
| 23 | |||
| 24 | } | ||
| 25 | };*/ | ||
| 26 | 7 | ||
| 27 | class verb : public word { | 8 | class verb : public word { |
| 28 | private: | 9 | private: |
| @@ -35,6 +16,7 @@ namespace verbly { | |||
| 35 | friend class verb_query; | 16 | friend class verb_query; |
| 36 | 17 | ||
| 37 | public: | 18 | public: |
| 19 | verb(); | ||
| 38 | verb(const data& _data, int _id); | 20 | verb(const data& _data, int _id); |
| 39 | 21 | ||
| 40 | std::string base_form() const; | 22 | std::string base_form() const; |
| @@ -43,29 +25,8 @@ namespace verbly { | |||
| 43 | std::string past_participle_form() const; | 25 | std::string past_participle_form() const; |
| 44 | std::string ing_form() const; | 26 | std::string ing_form() const; |
| 45 | std::string s_form() const; | 27 | std::string s_form() const; |
| 46 | }; | ||
| 47 | |||
| 48 | class verb_query { | ||
| 49 | public: | ||
| 50 | verb_query(const data& _data); | ||
| 51 | |||
| 52 | verb_query& limit(int _limit); | ||
| 53 | verb_query& random(bool _random); | ||
| 54 | verb_query& except(const verb& _word); | ||
| 55 | verb_query& rhymes_with(const word& _word); | ||
| 56 | verb_query& has_pronunciation(bool _has_prn); | ||
| 57 | 28 | ||
| 58 | std::list<verb> run() const; | 29 | frame_query frames() const; |
| 59 | |||
| 60 | const static int unlimited = -1; | ||
| 61 | |||
| 62 | private: | ||
| 63 | const data& _data; | ||
| 64 | int _limit = unlimited; | ||
| 65 | bool _random = false; | ||
| 66 | std::list<std::string> _rhymes; | ||
| 67 | std::list<verb> _except; | ||
| 68 | bool _has_prn = false; | ||
| 69 | }; | 30 | }; |
| 70 | 31 | ||
| 71 | }; | 32 | }; |
| diff --git a/lib/verb_query.cpp b/lib/verb_query.cpp new file mode 100644 index 0000000..173a04e --- /dev/null +++ b/lib/verb_query.cpp | |||
| @@ -0,0 +1,170 @@ | |||
| 1 | #include "verbly.h" | ||
| 2 | |||
| 3 | namespace verbly { | ||
| 4 | |||
| 5 | verb_query::verb_query(const data& _data) : _data(_data) | ||
| 6 | { | ||
| 7 | |||
| 8 | } | ||
| 9 | |||
| 10 | verb_query& verb_query::limit(int _limit) | ||
| 11 | { | ||
| 12 | if ((_limit > 0) || (_limit == unlimited)) | ||
| 13 | { | ||
| 14 | this->_limit = _limit; | ||
| 15 | } | ||
| 16 | |||
| 17 | return *this; | ||
| 18 | } | ||
| 19 | |||
| 20 | verb_query& verb_query::random() | ||
| 21 | { | ||
| 22 | this->_random = true; | ||
| 23 | |||
| 24 | return *this; | ||
| 25 | } | ||
| 26 | |||
| 27 | verb_query& verb_query::except(const verb& _word) | ||
| 28 | { | ||
| 29 | _except.push_back(_word); | ||
| 30 | |||
| 31 | return *this; | ||
| 32 | } | ||
| 33 | |||
| 34 | verb_query& verb_query::rhymes_with(const word& _word) | ||
| 35 | { | ||
| 36 | for (auto rhyme : _word.rhyme_phonemes()) | ||
| 37 | { | ||
| 38 | _rhymes.push_back(rhyme); | ||
| 39 | } | ||
| 40 | |||
| 41 | if (dynamic_cast<const verb*>(&_word) != nullptr) | ||
| 42 | { | ||
| 43 | _except.push_back(dynamic_cast<const verb&>(_word)); | ||
| 44 | } | ||
| 45 | |||
| 46 | return *this; | ||
| 47 | } | ||
| 48 | |||
| 49 | verb_query& verb_query::has_pronunciation() | ||
| 50 | { | ||
| 51 | this->_has_prn = true; | ||
| 52 | |||
| 53 | return *this; | ||
| 54 | } | ||
| 55 | |||
| 56 | verb_query& verb_query::has_frames() | ||
| 57 | { | ||
| 58 | this->_has_frames = true; | ||
| 59 | |||
| 60 | return *this; | ||
| 61 | } | ||
| 62 | |||
| 63 | std::list<verb> verb_query::run() const | ||
| 64 | { | ||
| 65 | std::stringstream construct; | ||
| 66 | construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs"; | ||
| 67 | std::list<std::string> conditions; | ||
| 68 | |||
| 69 | if (_has_prn) | ||
| 70 | { | ||
| 71 | conditions.push_back("verb_id IN (SELECT verb_id FROM verb_pronunciations)"); | ||
| 72 | } | ||
| 73 | |||
| 74 | if (!_rhymes.empty()) | ||
| 75 | { | ||
| 76 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
| 77 | std::string cond = "verb_id IN (SELECT verb_id FROM verb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 78 | conditions.push_back(cond); | ||
| 79 | } | ||
| 80 | |||
| 81 | for (auto except : _except) | ||
| 82 | { | ||
| 83 | conditions.push_back("verb_id != @EXCID"); | ||
| 84 | } | ||
| 85 | |||
| 86 | if (!_has_frames) | ||
| 87 | { | ||
| 88 | conditions.push_back("verb_id IN (SELECT verb_id FROM verb_groups)"); | ||
| 89 | } | ||
| 90 | |||
| 91 | if (!conditions.empty()) | ||
| 92 | { | ||
| 93 | construct << " WHERE "; | ||
| 94 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
| 95 | } | ||
| 96 | |||
| 97 | if (_random) | ||
| 98 | { | ||
| 99 | construct << " ORDER BY RANDOM()"; | ||
| 100 | } | ||
| 101 | |||
| 102 | if (_limit != unlimited) | ||
| 103 | { | ||
| 104 | construct << " LIMIT " << _limit; | ||
| 105 | } | ||
| 106 | |||
| 107 | sqlite3_stmt* ppstmt; | ||
| 108 | std::string query = construct.str(); | ||
| 109 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 110 | { | ||
| 111 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 112 | } | ||
| 113 | |||
| 114 | if (!_rhymes.empty()) | ||
| 115 | { | ||
| 116 | int i = 0; | ||
| 117 | for (auto rhyme : _rhymes) | ||
| 118 | { | ||
| 119 | std::string rhymer = "%" + rhyme; | ||
| 120 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
| 121 | |||
| 122 | i++; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | for (auto except : _except) | ||
| 127 | { | ||
| 128 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
| 129 | } | ||
| 130 | |||
| 131 | std::list<verb> output; | ||
| 132 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 133 | { | ||
| 134 | verb tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
| 135 | tnc._infinitive = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
| 136 | tnc._past_tense = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
| 137 | tnc._past_participle = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
| 138 | tnc._ing_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 4))); | ||
| 139 | tnc._s_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 5))); | ||
| 140 | |||
| 141 | output.push_back(tnc); | ||
| 142 | } | ||
| 143 | |||
| 144 | sqlite3_finalize(ppstmt); | ||
| 145 | |||
| 146 | for (auto& verb : output) | ||
| 147 | { | ||
| 148 | query = "SELECT pronunciation FROM verb_pronunciations WHERE verb_id = ?"; | ||
| 149 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 150 | { | ||
| 151 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 152 | } | ||
| 153 | |||
| 154 | sqlite3_bind_int(ppstmt, 1, verb._id); | ||
| 155 | |||
| 156 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 157 | { | ||
| 158 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
| 159 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
| 160 | |||
| 161 | verb.pronunciations.push_back(phonemes); | ||
| 162 | } | ||
| 163 | |||
| 164 | sqlite3_finalize(ppstmt); | ||
| 165 | } | ||
| 166 | |||
| 167 | return output; | ||
| 168 | } | ||
| 169 | |||
| 170 | }; | ||
| diff --git a/lib/verb_query.h b/lib/verb_query.h new file mode 100644 index 0000000..24f5732 --- /dev/null +++ b/lib/verb_query.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | #ifndef VERB_QUERY_H_34E5A679 | ||
| 2 | #define VERB_QUERY_H_34E5A679 | ||
| 3 | |||
| 4 | namespace verbly { | ||
| 5 | |||
| 6 | class verb_query { | ||
| 7 | public: | ||
| 8 | verb_query(const data& _data); | ||
| 9 | |||
| 10 | verb_query& limit(int _limit); | ||
| 11 | verb_query& random(); | ||
| 12 | verb_query& except(const verb& _word); | ||
| 13 | verb_query& rhymes_with(const word& _word); | ||
| 14 | verb_query& has_pronunciation(); | ||
| 15 | |||
| 16 | verb_query& has_frames(); | ||
| 17 | |||
| 18 | std::list<verb> run() const; | ||
| 19 | |||
| 20 | const static int unlimited = -1; | ||
| 21 | |||
| 22 | private: | ||
| 23 | const data& _data; | ||
| 24 | int _limit = unlimited; | ||
| 25 | bool _random = false; | ||
| 26 | std::list<std::string> _rhymes; | ||
| 27 | std::list<verb> _except; | ||
| 28 | bool _has_prn = false; | ||
| 29 | bool _has_frames = false; | ||
| 30 | }; | ||
| 31 | |||
| 32 | }; | ||
| 33 | |||
| 34 | #endif /* end of include guard: VERB_QUERY_H_34E5A679 */ | ||
| diff --git a/lib/verbly.h b/lib/verbly.h index b9f5367..cfaf5bc 100644 --- a/lib/verbly.h +++ b/lib/verbly.h | |||
| @@ -1,14 +1,35 @@ | |||
| 1 | #ifndef VERBLY_H_5B39CE50 | 1 | #ifndef VERBLY_H_5B39CE50 |
| 2 | #define VERBLY_H_5B39CE50 | 2 | #define VERBLY_H_5B39CE50 |
| 3 | 3 | ||
| 4 | #include "c++14.h" | 4 | #include <string> |
| 5 | #include <list> | ||
| 6 | #include <sstream> | ||
| 7 | #include <algorithm> | ||
| 8 | #include <cassert> | ||
| 9 | #include <set> | ||
| 10 | #include <stdexcept> | ||
| 11 | #include <vector> | ||
| 12 | #include <map> | ||
| 13 | #include <iterator> | ||
| 14 | #include <sstream> | ||
| 15 | #include <functional> | ||
| 16 | #include <iostream> | ||
| 17 | #include <new> | ||
| 18 | |||
| 5 | #include "util.h" | 19 | #include "util.h" |
| 6 | #include "token.h" | ||
| 7 | #include "data.h" | 20 | #include "data.h" |
| 8 | #include "word.h" | 21 | #include "word.h" |
| 9 | #include "verb.h" | 22 | #include "verb.h" |
| 10 | #include "adverb.h" | 23 | #include "adverb.h" |
| 11 | #include "adjective.h" | 24 | #include "adjective.h" |
| 12 | #include "noun.h" | 25 | #include "noun.h" |
| 26 | #include "frame.h" | ||
| 27 | #include "preposition.h" | ||
| 28 | #include "token.h" | ||
| 29 | #include "noun_query.h" | ||
| 30 | #include "adverb_query.h" | ||
| 31 | #include "adjective_query.h" | ||
| 32 | #include "verb_query.h" | ||
| 33 | #include "frame_query.h" | ||
| 13 | 34 | ||
| 14 | #endif /* end of include guard: VERBLY_H_5B39CE50 */ | 35 | #endif /* end of include guard: VERBLY_H_5B39CE50 */ |
| diff --git a/lib/word.cpp b/lib/word.cpp index 15af150..13c611f 100644 --- a/lib/word.cpp +++ b/lib/word.cpp | |||
| @@ -3,13 +3,20 @@ | |||
| 3 | 3 | ||
| 4 | namespace verbly { | 4 | namespace verbly { |
| 5 | 5 | ||
| 6 | word::word(const data& _data, int _id) : _data(_data), _id(_id) | 6 | word::word() |
| 7 | { | ||
| 8 | |||
| 9 | } | ||
| 10 | |||
| 11 | word::word(const data& _data, int _id) : _data(&_data), _id(_id), _valid(true) | ||
| 7 | { | 12 | { |
| 8 | 13 | ||
| 9 | } | 14 | } |
| 10 | 15 | ||
| 11 | std::list<std::string> word::rhyme_phonemes() const | 16 | std::list<std::string> word::rhyme_phonemes() const |
| 12 | { | 17 | { |
| 18 | assert(_valid == true); | ||
| 19 | |||
| 13 | std::list<std::string> result; | 20 | std::list<std::string> result; |
| 14 | 21 | ||
| 15 | for (auto pronunciation : pronunciations) | 22 | for (auto pronunciation : pronunciations) |
| @@ -32,6 +39,8 @@ namespace verbly { | |||
| 32 | 39 | ||
| 33 | bool word::starts_with_vowel_sound() const | 40 | bool word::starts_with_vowel_sound() const |
| 34 | { | 41 | { |
| 42 | assert(_valid == true); | ||
| 43 | |||
| 35 | if (pronunciations.size() > 0) | 44 | if (pronunciations.size() > 0) |
| 36 | { | 45 | { |
| 37 | return std::any_of(std::begin(pronunciations), std::end(pronunciations), [] (std::list<std::string> phonemes) { | 46 | return std::any_of(std::begin(pronunciations), std::end(pronunciations), [] (std::list<std::string> phonemes) { |
| diff --git a/lib/word.h b/lib/word.h index db3242a..dc6fac8 100644 --- a/lib/word.h +++ b/lib/word.h | |||
| @@ -3,26 +3,23 @@ | |||
| 3 | 3 | ||
| 4 | namespace verbly { | 4 | namespace verbly { |
| 5 | 5 | ||
| 6 | class adjective_query; | ||
| 7 | class verb_query; | ||
| 8 | class adverb_query; | ||
| 9 | |||
| 10 | template <class T> | ||
| 11 | class query; | ||
| 12 | |||
| 13 | class word { | 6 | class word { |
| 14 | protected: | 7 | protected: |
| 15 | const data& _data; | 8 | const data* _data; |
| 16 | int _id; | 9 | int _id; |
| 10 | bool _valid = false; | ||
| 17 | 11 | ||
| 18 | std::list<std::list<std::string>> pronunciations; | 12 | std::list<std::list<std::string>> pronunciations; |
| 19 | 13 | ||
| 14 | word(); | ||
| 20 | word(const data& _data, int _id); | 15 | word(const data& _data, int _id); |
| 21 | 16 | ||
| 22 | friend class adjective_query; | 17 | friend class adjective_query; |
| 23 | friend class verb_query; | 18 | friend class verb_query; |
| 24 | friend class noun_query; | 19 | friend class noun_query; |
| 25 | friend class adverb_query; | 20 | friend class adverb_query; |
| 21 | friend class frame_query; | ||
| 22 | friend class preposition_query; | ||
| 26 | 23 | ||
| 27 | public: | 24 | public: |
| 28 | virtual std::string base_form() const = 0; | 25 | virtual std::string base_form() const = 0; |
