diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2016-03-16 11:27:16 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2016-03-16 11:27:16 -0400 |
commit | ae5f75965f8202c8478622763a27ef1848a8ed1a (patch) | |
tree | fcbe1a05eeec628118bcf32db9135e101e038cd5 | |
parent | e5f284e6cf676fb0e712f568e560b5b8661506f4 (diff) | |
download | verbly-ae5f75965f8202c8478622763a27ef1848a8ed1a.tar.gz verbly-ae5f75965f8202c8478622763a27ef1848a8ed1a.tar.bz2 verbly-ae5f75965f8202c8478622763a27ef1848a8ed1a.zip |
Added more inflections, word relationships, and pronunciations
Nouns, adjectives, and adverbs now have inflected forms. A large number of WordNet word relationships (all noun-noun relationships, plus synonymy and antonymy for all word types except verbs) have been added. Additionally, CMUDICT is now being used to store word pronunciations for rhyming purposes. Verbly is now also a compiled library rather than being header-only due to the complexity of the query interface.
-rw-r--r-- | adjective.cpp | 586 | ||||
-rw-r--r-- | adjective.h | 126 | ||||
-rw-r--r-- | adverb.cpp | 364 | ||||
-rw-r--r-- | adverb.h | 75 | ||||
-rw-r--r-- | data.cpp | 50 | ||||
-rw-r--r-- | data.h | 275 | ||||
-rw-r--r-- | noun.cpp | 916 | ||||
-rw-r--r-- | noun.h | 171 | ||||
-rw-r--r-- | token.cpp | 53 | ||||
-rw-r--r-- | token.h | 82 | ||||
-rw-r--r-- | util.h | 53 | ||||
-rw-r--r-- | verb.cpp | 193 | ||||
-rw-r--r-- | verb.h | 68 | ||||
-rw-r--r-- | verbly.h | 7 | ||||
-rw-r--r-- | word.cpp | 32 | ||||
-rw-r--r-- | word.h | 35 |
16 files changed, 2740 insertions, 346 deletions
diff --git a/adjective.cpp b/adjective.cpp new file mode 100644 index 0000000..0f4087f --- /dev/null +++ b/adjective.cpp | |||
@@ -0,0 +1,586 @@ | |||
1 | #include "verbly.h" | ||
2 | |||
3 | namespace verbly { | ||
4 | |||
5 | adjective::adjective(const data& _data, int _id) : word(_data, _id) | ||
6 | { | ||
7 | |||
8 | } | ||
9 | |||
10 | std::string adjective::base_form() const | ||
11 | { | ||
12 | return _base_form; | ||
13 | } | ||
14 | |||
15 | std::string adjective::comparative_form() const | ||
16 | { | ||
17 | return _comparative_form; | ||
18 | } | ||
19 | |||
20 | std::string adjective::superlative_form() const | ||
21 | { | ||
22 | return _superlative_form; | ||
23 | } | ||
24 | |||
25 | adjective::positioning adjective::position() const | ||
26 | { | ||
27 | return _position; | ||
28 | } | ||
29 | |||
30 | bool adjective::has_comparative_form() const | ||
31 | { | ||
32 | return !_comparative_form.empty(); | ||
33 | } | ||
34 | |||
35 | bool adjective::has_superlative_form() const | ||
36 | { | ||
37 | return !_superlative_form.empty(); | ||
38 | } | ||
39 | |||
40 | bool adjective::has_position() const | ||
41 | { | ||
42 | return _position != adjective::positioning::undefined; | ||
43 | } | ||
44 | |||
45 | adjective_query adjective::antonyms() const | ||
46 | { | ||
47 | return _data.adjectives().antonym_of(*this); | ||
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 | |||
226 | return *this; | ||
227 | } | ||
228 | |||
229 | adjective_query& adjective_query::not_specification_of(const adjective& _adj) | ||
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 | { | ||
245 | _pertainym_of.push_back(_noun); | ||
246 | |||
247 | return *this; | ||
248 | } | ||
249 | |||
250 | adjective_query& adjective_query::is_mannernymic(bool _is_mannernymic) | ||
251 | { | ||
252 | this->_is_mannernymic = _is_mannernymic; | ||
253 | |||
254 | return *this; | ||
255 | } | ||
256 | |||
257 | adjective_query& adjective_query::anti_mannernym_of(const adverb& _adv) | ||
258 | { | ||
259 | _anti_mannernym_of.push_back(_adv); | ||
260 | |||
261 | return *this; | ||
262 | } | ||
263 | |||
264 | std::list<adjective> adjective_query::run() const | ||
265 | { | ||
266 | std::stringstream construct; | ||
267 | construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives"; | ||
268 | std::list<std::string> conditions; | ||
269 | |||
270 | if (_has_prn) | ||
271 | { | ||
272 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM adjective_pronunciations)"); | ||
273 | } | ||
274 | |||
275 | if (!_rhymes.empty()) | ||
276 | { | ||
277 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
278 | std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
279 | conditions.push_back(cond); | ||
280 | } | ||
281 | |||
282 | for (auto except : _except) | ||
283 | { | ||
284 | conditions.push_back("adjective_id != @EXCID"); | ||
285 | } | ||
286 | |||
287 | if (_requires_comparative_form) | ||
288 | { | ||
289 | conditions.push_back("comparative IS NOT NULL"); | ||
290 | } | ||
291 | |||
292 | if (_requires_superlative_form) | ||
293 | { | ||
294 | conditions.push_back("superlative IS NOT NULL"); | ||
295 | } | ||
296 | |||
297 | if (_position != adjective::positioning::undefined) | ||
298 | { | ||
299 | switch (_position) | ||
300 | { | ||
301 | case adjective::positioning::predicate: conditions.push_back("position = 'p'"); break; | ||
302 | case adjective::positioning::attributive: conditions.push_back("position = 'a'"); break; | ||
303 | case adjective::positioning::postnominal: conditions.push_back("position = 'i'"); break; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | if (_is_variant) | ||
308 | { | ||
309 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM variation)"); | ||
310 | } | ||
311 | |||
312 | if (!_variant_of.empty()) | ||
313 | { | ||
314 | std::list<std::string> clauses(_variant_of.size(), "noun_id = @ATTRID"); | ||
315 | std::string cond = "adjective_id IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
316 | conditions.push_back(cond); | ||
317 | } | ||
318 | |||
319 | if (!_not_variant_of.empty()) | ||
320 | { | ||
321 | std::list<std::string> clauses(_not_variant_of.size(), "noun_id = @NATTRID"); | ||
322 | std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
323 | conditions.push_back(cond); | ||
324 | } | ||
325 | |||
326 | if (_is_antonymic) | ||
327 | { | ||
328 | conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy)"); | ||
329 | } | ||
330 | |||
331 | if (!_antonym_of.empty()) | ||
332 | { | ||
333 | std::list<std::string> clauses(_antonym_of.size(), "adjective_1_id = @ANTID"); | ||
334 | std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
335 | conditions.push_back(cond); | ||
336 | } | ||
337 | |||
338 | if (!_not_antonym_of.empty()) | ||
339 | { | ||
340 | std::list<std::string> clauses(_not_antonym_of.size(), "adjective_1_id = @NANTID"); | ||
341 | std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
342 | conditions.push_back(cond); | ||
343 | } | ||
344 | |||
345 | if (_is_synonymic) | ||
346 | { | ||
347 | conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy)"); | ||
348 | } | ||
349 | |||
350 | if (!_synonym_of.empty()) | ||
351 | { | ||
352 | std::list<std::string> clauses(_synonym_of.size(), "adjective_1_id = @SYNID"); | ||
353 | std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
354 | conditions.push_back(cond); | ||
355 | } | ||
356 | |||
357 | if (!_not_synonym_of.empty()) | ||
358 | { | ||
359 | std::list<std::string> clauses(_not_synonym_of.size(), "adjective_1_id = @NSYNID"); | ||
360 | std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
361 | conditions.push_back(cond); | ||
362 | } | ||
363 | |||
364 | if (_is_generalization) | ||
365 | { | ||
366 | conditions.push_back("adjective_id IN (SELECT general_id FROM specification)"); | ||
367 | } | ||
368 | |||
369 | if (!_generalization_of.empty()) | ||
370 | { | ||
371 | std::list<std::string> clauses(_generalization_of.size(), "specific_id = @SPECID"); | ||
372 | std::string cond = "adjective_id IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
373 | conditions.push_back(cond); | ||
374 | } | ||
375 | |||
376 | if (!_not_generalization_of.empty()) | ||
377 | { | ||
378 | std::list<std::string> clauses(_not_generalization_of.size(), "specific_id = @NSPECID"); | ||
379 | std::string cond = "adjective_id NOT IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
380 | conditions.push_back(cond); | ||
381 | } | ||
382 | |||
383 | if (_is_specification) | ||
384 | { | ||
385 | conditions.push_back("adjective_id IN (SELECT specific_id FROM specification)"); | ||
386 | } | ||
387 | |||
388 | if (!_specification_of.empty()) | ||
389 | { | ||
390 | std::list<std::string> clauses(_specification_of.size(), "general_id = @GENID"); | ||
391 | std::string cond = "adjective_id IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
392 | conditions.push_back(cond); | ||
393 | } | ||
394 | |||
395 | if (!_not_specification_of.empty()) | ||
396 | { | ||
397 | std::list<std::string> clauses(_not_specification_of.size(), "general_id = @NGENID"); | ||
398 | std::string cond = "adjective_id NOT IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
399 | conditions.push_back(cond); | ||
400 | } | ||
401 | |||
402 | if (_is_pertainymic) | ||
403 | { | ||
404 | conditions.push_back("adjective_id IN (SELECT pertainym_id FROM pertainymy)"); | ||
405 | } | ||
406 | |||
407 | if (!_pertainym_of.empty()) | ||
408 | { | ||
409 | std::list<std::string> clauses(_pertainym_of.size(), "noun_id = @APERID"); | ||
410 | std::string cond = "adjective_id IN (SELECT pertainym_id FROM pertainymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
411 | conditions.push_back(cond); | ||
412 | } | ||
413 | |||
414 | if (_is_mannernymic) | ||
415 | { | ||
416 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM mannernymy)"); | ||
417 | } | ||
418 | |||
419 | if (!_anti_mannernym_of.empty()) | ||
420 | { | ||
421 | std::list<std::string> clauses(_anti_mannernym_of.size(), "mannernym_id = @MANID"); | ||
422 | std::string cond = "adjective_id IN (SELECT adjective_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
423 | conditions.push_back(cond); | ||
424 | } | ||
425 | |||
426 | if (!conditions.empty()) | ||
427 | { | ||
428 | construct << " WHERE "; | ||
429 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
430 | } | ||
431 | |||
432 | if (_random) | ||
433 | { | ||
434 | construct << " ORDER BY RANDOM()"; | ||
435 | } | ||
436 | |||
437 | if (_limit != unlimited) | ||
438 | { | ||
439 | construct << " LIMIT " << _limit; | ||
440 | } | ||
441 | |||
442 | sqlite3_stmt* ppstmt; | ||
443 | std::string query = construct.str(); | ||
444 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
445 | { | ||
446 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
447 | } | ||
448 | |||
449 | if (!_rhymes.empty()) | ||
450 | { | ||
451 | int i = 0; | ||
452 | for (auto rhyme : _rhymes) | ||
453 | { | ||
454 | std::string rhymer = "%" + rhyme; | ||
455 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
456 | |||
457 | i++; | ||
458 | } | ||
459 | } | ||
460 | |||
461 | for (auto except : _except) | ||
462 | { | ||
463 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
464 | } | ||
465 | |||
466 | for (auto attribute : _variant_of) | ||
467 | { | ||
468 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id); | ||
469 | } | ||
470 | |||
471 | for (auto attribute : _not_variant_of) | ||
472 | { | ||
473 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NATTRID"), attribute._id); | ||
474 | } | ||
475 | |||
476 | for (auto antonym : _antonym_of) | ||
477 | { | ||
478 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
479 | } | ||
480 | |||
481 | for (auto antonym : _not_antonym_of) | ||
482 | { | ||
483 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); | ||
484 | } | ||
485 | |||
486 | for (auto synonym : _synonym_of) | ||
487 | { | ||
488 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
489 | } | ||
490 | |||
491 | for (auto synonym : _not_synonym_of) | ||
492 | { | ||
493 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); | ||
494 | } | ||
495 | |||
496 | for (auto specific : _generalization_of) | ||
497 | { | ||
498 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SPECID"), specific._id); | ||
499 | } | ||
500 | |||
501 | for (auto specific : _not_generalization_of) | ||
502 | { | ||
503 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSPECID"), specific._id); | ||
504 | } | ||
505 | |||
506 | for (auto general : _specification_of) | ||
507 | { | ||
508 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GENID"), general._id); | ||
509 | } | ||
510 | |||
511 | for (auto general : _not_specification_of) | ||
512 | { | ||
513 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NGENID"), general._id); | ||
514 | } | ||
515 | |||
516 | for (auto n : _pertainym_of) | ||
517 | { | ||
518 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@APERID"), n._id); | ||
519 | } | ||
520 | |||
521 | for (auto mannernym : _anti_mannernym_of) | ||
522 | { | ||
523 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MANID"), mannernym._id); | ||
524 | } | ||
525 | |||
526 | std::list<adjective> output; | ||
527 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
528 | { | ||
529 | adjective tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
530 | tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
531 | |||
532 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
533 | { | ||
534 | tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
535 | } | ||
536 | |||
537 | if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) | ||
538 | { | ||
539 | tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
540 | } | ||
541 | |||
542 | if (sqlite3_column_type(ppstmt, 4) != SQLITE_NULL) | ||
543 | { | ||
544 | std::string adjpos(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 4))); | ||
545 | if (adjpos == "p") | ||
546 | { | ||
547 | tnc._position = adjective::positioning::predicate; | ||
548 | } else if (adjpos == "a") | ||
549 | { | ||
550 | tnc._position = adjective::positioning::attributive; | ||
551 | } else if (adjpos == "i") | ||
552 | { | ||
553 | tnc._position = adjective::positioning::postnominal; | ||
554 | } | ||
555 | } | ||
556 | |||
557 | output.push_back(tnc); | ||
558 | } | ||
559 | |||
560 | sqlite3_finalize(ppstmt); | ||
561 | |||
562 | for (auto& adjective : output) | ||
563 | { | ||
564 | query = "SELECT pronunciation FROM adjective_pronunciations WHERE adjective_id = ?"; | ||
565 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
566 | { | ||
567 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
568 | } | ||
569 | |||
570 | sqlite3_bind_int(ppstmt, 1, adjective._id); | ||
571 | |||
572 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
573 | { | ||
574 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
575 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
576 | |||
577 | adjective.pronunciations.push_back(phonemes); | ||
578 | } | ||
579 | |||
580 | sqlite3_finalize(ppstmt); | ||
581 | } | ||
582 | |||
583 | return output; | ||
584 | } | ||
585 | |||
586 | }; | ||
diff --git a/adjective.h b/adjective.h index 9d7883f..4927d59 100644 --- a/adjective.h +++ b/adjective.h | |||
@@ -3,17 +3,129 @@ | |||
3 | 3 | ||
4 | namespace verbly { | 4 | namespace verbly { |
5 | 5 | ||
6 | class adjective { | 6 | class adjective_query; |
7 | class adverb_query; | ||
8 | class noun_query; | ||
9 | |||
10 | class adjective : public word { | ||
11 | public: | ||
12 | enum class positioning { | ||
13 | undefined, | ||
14 | predicate, | ||
15 | attributive, | ||
16 | postnominal | ||
17 | }; | ||
18 | |||
7 | private: | 19 | private: |
8 | int id; | 20 | std::string _base_form; |
21 | std::string _comparative_form; | ||
22 | std::string _superlative_form; | ||
23 | positioning _position = positioning::undefined; | ||
24 | |||
25 | friend class adjective_query; | ||
26 | |||
27 | public: | ||
28 | adjective(const data& _data, int _id); | ||
29 | |||
30 | std::string base_form() const; | ||
31 | std::string comparative_form() const; | ||
32 | std::string superlative_form() const; | ||
33 | positioning position() const; | ||
34 | |||
35 | bool has_comparative_form() const; | ||
36 | bool has_superlative_form() const; | ||
37 | bool has_position() const; | ||
9 | 38 | ||
39 | adjective_query antonyms() const; | ||
40 | adjective_query synonyms() const; | ||
41 | adjective_query generalizations() const; | ||
42 | adjective_query specifications() const; | ||
43 | noun_query anti_pertainyms() const; | ||
44 | adverb_query mannernyms() const; | ||
45 | noun_query attributes() const; | ||
46 | }; | ||
47 | |||
48 | class adjective_query { | ||
10 | public: | 49 | public: |
11 | std::string form; | 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 | std::list<adjective> run() const; | ||
89 | |||
90 | const static int unlimited = -1; | ||
91 | |||
92 | protected: | ||
93 | const data& _data; | ||
94 | int _limit = unlimited; | ||
95 | bool _random = false; | ||
96 | std::list<std::string> _rhymes; | ||
97 | std::list<adjective> _except; | ||
98 | bool _has_prn = false; | ||
99 | |||
100 | bool _requires_comparative_form = false; | ||
101 | bool _requires_superlative_form = false; | ||
102 | adjective::positioning _position = adjective::positioning::undefined; | ||
103 | |||
104 | bool _is_variant = false; | ||
105 | std::list<noun> _variant_of; | ||
106 | std::list<noun> _not_variant_of; | ||
107 | |||
108 | bool _is_antonymic = false; | ||
109 | std::list<adjective> _antonym_of; | ||
110 | std::list<adjective> _not_antonym_of; | ||
111 | |||
112 | bool _is_synonymic = false; | ||
113 | std::list<adjective> _synonym_of; | ||
114 | std::list<adjective> _not_synonym_of; | ||
115 | |||
116 | bool _is_generalization = false; | ||
117 | std::list<adjective> _generalization_of; | ||
118 | std::list<adjective> _not_generalization_of; | ||
119 | |||
120 | bool _is_specification = false; | ||
121 | std::list<adjective> _specification_of; | ||
122 | std::list<adjective> _not_specification_of; | ||
123 | |||
124 | bool _is_pertainymic = false; | ||
125 | std::list<noun> _pertainym_of; | ||
12 | 126 | ||
13 | adjective(int id) : id(id) | 127 | bool _is_mannernymic = false; |
14 | { | 128 | std::list<adverb> _anti_mannernym_of; |
15 | |||
16 | } | ||
17 | }; | 129 | }; |
18 | 130 | ||
19 | }; | 131 | }; |
diff --git a/adverb.cpp b/adverb.cpp new file mode 100644 index 0000000..9bb5a0d --- /dev/null +++ b/adverb.cpp | |||
@@ -0,0 +1,364 @@ | |||
1 | #include "verbly.h" | ||
2 | |||
3 | namespace verbly { | ||
4 | |||
5 | adverb::adverb(const data& _data, int _id) : word(_data, _id) | ||
6 | { | ||
7 | |||
8 | } | ||
9 | |||
10 | std::string adverb::base_form() const | ||
11 | { | ||
12 | return _base_form; | ||
13 | } | ||
14 | |||
15 | std::string adverb::comparative_form() const | ||
16 | { | ||
17 | return _comparative_form; | ||
18 | } | ||
19 | |||
20 | std::string adverb::superlative_form() const | ||
21 | { | ||
22 | return _superlative_form; | ||
23 | } | ||
24 | |||
25 | bool adverb::has_comparative_form() const | ||
26 | { | ||
27 | return !_comparative_form.empty(); | ||
28 | } | ||
29 | |||
30 | bool adverb::has_superlative_form() const | ||
31 | { | ||
32 | return !_superlative_form.empty(); | ||
33 | } | ||
34 | |||
35 | adverb_query adverb::antonyms() const | ||
36 | { | ||
37 | return _data.adverbs().antonym_of(*this); | ||
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 | |||
76 | return *this; | ||
77 | } | ||
78 | |||
79 | adverb_query& adverb_query::rhymes_with(const word& _word) | ||
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 | std::list<adverb> adverb_query::run() const | ||
172 | { | ||
173 | std::stringstream construct; | ||
174 | construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs"; | ||
175 | std::list<std::string> conditions; | ||
176 | |||
177 | if (_has_prn) | ||
178 | { | ||
179 | conditions.push_back("adverb_id IN (SELECT adverb_id FROM adverb_pronunciations)"); | ||
180 | } | ||
181 | |||
182 | if (!_rhymes.empty()) | ||
183 | { | ||
184 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
185 | std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
186 | conditions.push_back(cond); | ||
187 | } | ||
188 | |||
189 | for (auto except : _except) | ||
190 | { | ||
191 | conditions.push_back("adverb_id != @EXCID"); | ||
192 | } | ||
193 | |||
194 | if (_requires_comparative_form) | ||
195 | { | ||
196 | conditions.push_back("comparative IS NOT NULL"); | ||
197 | } | ||
198 | |||
199 | if (_requires_superlative_form) | ||
200 | { | ||
201 | conditions.push_back("superlative IS NOT NULL"); | ||
202 | } | ||
203 | |||
204 | if (_has_antonyms) | ||
205 | { | ||
206 | conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)"); | ||
207 | } | ||
208 | |||
209 | if (!_antonym_of.empty()) | ||
210 | { | ||
211 | std::list<std::string> clauses(_antonym_of.size(), "adverb_1_id = @ANTID"); | ||
212 | std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
213 | conditions.push_back(cond); | ||
214 | } | ||
215 | |||
216 | if (!_not_antonym_of.empty()) | ||
217 | { | ||
218 | std::list<std::string> clauses(_not_antonym_of.size(), "adverb_1_id = @NANTID"); | ||
219 | std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
220 | conditions.push_back(cond); | ||
221 | } | ||
222 | |||
223 | if (_has_synonyms) | ||
224 | { | ||
225 | conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy)"); | ||
226 | } | ||
227 | |||
228 | if (!_synonym_of.empty()) | ||
229 | { | ||
230 | std::list<std::string> clauses(_synonym_of.size(), "adverb_1_id = @SYNID"); | ||
231 | std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
232 | conditions.push_back(cond); | ||
233 | } | ||
234 | |||
235 | if (!_not_synonym_of.empty()) | ||
236 | { | ||
237 | std::list<std::string> clauses(_not_synonym_of.size(), "adverb_1_id = @NSYNID"); | ||
238 | std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
239 | conditions.push_back(cond); | ||
240 | } | ||
241 | |||
242 | if (_is_mannernymic) | ||
243 | { | ||
244 | conditions.push_back("adverb_id IN (SELECT mannernym_id FROM mannernymy)"); | ||
245 | } | ||
246 | |||
247 | if (!_mannernym_of.empty()) | ||
248 | { | ||
249 | std::list<std::string> clauses(_mannernym_of.size(), "adjective_id = @AMANID"); | ||
250 | std::string cond = "adverb_id IN (SELECT mannernym_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
251 | conditions.push_back(cond); | ||
252 | } | ||
253 | |||
254 | if (!conditions.empty()) | ||
255 | { | ||
256 | construct << " WHERE "; | ||
257 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
258 | } | ||
259 | |||
260 | if (_random) | ||
261 | { | ||
262 | construct << " ORDER BY RANDOM()"; | ||
263 | } | ||
264 | |||
265 | if (_limit != unlimited) | ||
266 | { | ||
267 | construct << " LIMIT " << _limit; | ||
268 | } | ||
269 | |||
270 | sqlite3_stmt* ppstmt; | ||
271 | std::string query = construct.str(); | ||
272 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
273 | { | ||
274 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
275 | } | ||
276 | |||
277 | if (!_rhymes.empty()) | ||
278 | { | ||
279 | int i = 0; | ||
280 | for (auto rhyme : _rhymes) | ||
281 | { | ||
282 | std::string rhymer = "%" + rhyme; | ||
283 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
284 | |||
285 | i++; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | for (auto except : _except) | ||
290 | { | ||
291 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
292 | } | ||
293 | |||
294 | for (auto antonym : _antonym_of) | ||
295 | { | ||
296 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
297 | } | ||
298 | |||
299 | for (auto antonym : _not_antonym_of) | ||
300 | { | ||
301 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); | ||
302 | } | ||
303 | |||
304 | for (auto synonym : _synonym_of) | ||
305 | { | ||
306 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
307 | } | ||
308 | |||
309 | for (auto synonym : _not_synonym_of) | ||
310 | { | ||
311 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); | ||
312 | } | ||
313 | |||
314 | for (auto adj : _mannernym_of) | ||
315 | { | ||
316 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id); | ||
317 | } | ||
318 | |||
319 | std::list<adverb> output; | ||
320 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
321 | { | ||
322 | adverb tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
323 | tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
324 | |||
325 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
326 | { | ||
327 | tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
328 | } | ||
329 | |||
330 | if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) | ||
331 | { | ||
332 | tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
333 | } | ||
334 | |||
335 | output.push_back(tnc); | ||
336 | } | ||
337 | |||
338 | sqlite3_finalize(ppstmt); | ||
339 | |||
340 | for (auto& adverb : output) | ||
341 | { | ||
342 | query = "SELECT pronunciation FROM adverb_pronunciations WHERE adverb_id = ?"; | ||
343 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
344 | { | ||
345 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
346 | } | ||
347 | |||
348 | sqlite3_bind_int(ppstmt, 1, adverb._id); | ||
349 | |||
350 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
351 | { | ||
352 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
353 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
354 | |||
355 | adverb.pronunciations.push_back(phonemes); | ||
356 | } | ||
357 | |||
358 | sqlite3_finalize(ppstmt); | ||
359 | } | ||
360 | |||
361 | return output; | ||
362 | } | ||
363 | |||
364 | }; | ||
diff --git a/adverb.h b/adverb.h index 6d2466e..42c3492 100644 --- a/adverb.h +++ b/adverb.h | |||
@@ -3,17 +3,78 @@ | |||
3 | 3 | ||
4 | namespace verbly { | 4 | namespace verbly { |
5 | 5 | ||
6 | class adverb { | 6 | class adverb : public word { |
7 | private: | 7 | private: |
8 | int id; | 8 | std::string _base_form; |
9 | std::string _comparative_form; | ||
10 | std::string _superlative_form; | ||
9 | 11 | ||
12 | friend class adverb_query; | ||
13 | |||
14 | public: | ||
15 | adverb(const data& _data, int _id); | ||
16 | |||
17 | std::string base_form() const; | ||
18 | std::string comparative_form() const; | ||
19 | std::string superlative_form() const; | ||
20 | |||
21 | bool has_comparative_form() const; | ||
22 | bool has_superlative_form() const; | ||
23 | |||
24 | adverb_query antonyms() const; | ||
25 | adverb_query synonyms() const; | ||
26 | adjective_query anti_mannernyms() const; | ||
27 | }; | ||
28 | |||
29 | class adverb_query { | ||
10 | public: | 30 | public: |
11 | std::string form; | 31 | adverb_query(const data& _data); |
32 | |||
33 | adverb_query& limit(int _limit); | ||
34 | adverb_query& random(bool _random); | ||
35 | adverb_query& except(const adverb& _word); | ||
36 | adverb_query& rhymes_with(const word& _word); | ||
37 | adverb_query& has_pronunciation(bool _has_prn); | ||
38 | |||
39 | adverb_query& requires_comparative_form(bool _arg); | ||
40 | adverb_query& requires_superlative_form(bool _arg); | ||
41 | |||
42 | adverb_query& has_antonyms(bool _arg); | ||
43 | adverb_query& antonym_of(const adverb& _adv); | ||
44 | adverb_query& not_antonym_of(const adverb& _adv); | ||
45 | |||
46 | adverb_query& has_synonyms(bool _arg); | ||
47 | adverb_query& synonym_of(const adverb& _adv); | ||
48 | adverb_query& not_synonym_of(const adverb& _adv); | ||
49 | |||
50 | adverb_query& is_mannernymic(bool _arg); | ||
51 | adverb_query& mannernym_of(const adjective& _adj); | ||
52 | |||
53 | std::list<adverb> run() const; | ||
54 | |||
55 | const static int unlimited = -1; | ||
56 | |||
57 | private: | ||
58 | const data& _data; | ||
59 | int _limit = unlimited; | ||
60 | bool _random = false; | ||
61 | std::list<std::string> _rhymes; | ||
62 | std::list<adverb> _except; | ||
63 | bool _has_prn = false; | ||
64 | |||
65 | bool _requires_comparative_form = false; | ||
66 | bool _requires_superlative_form = false; | ||
67 | |||
68 | bool _has_antonyms = false; | ||
69 | std::list<adverb> _antonym_of; | ||
70 | std::list<adverb> _not_antonym_of; | ||
71 | |||
72 | bool _has_synonyms = false; | ||
73 | std::list<adverb> _synonym_of; | ||
74 | std::list<adverb> _not_synonym_of; | ||
12 | 75 | ||
13 | adverb(int id) : id(id) | 76 | bool _is_mannernymic = false; |
14 | { | 77 | std::list<adjective> _mannernym_of; |
15 | |||
16 | } | ||
17 | }; | 78 | }; |
18 | 79 | ||
19 | }; | 80 | }; |
diff --git a/data.cpp b/data.cpp new file mode 100644 index 0000000..57a8850 --- /dev/null +++ b/data.cpp | |||
@@ -0,0 +1,50 @@ | |||
1 | #include "verbly.h" | ||
2 | |||
3 | namespace verbly { | ||
4 | |||
5 | data::data(std::string datafile) | ||
6 | { | ||
7 | if (sqlite3_open_v2(datafile.c_str(), &ppdb, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) | ||
8 | { | ||
9 | throw std::invalid_argument(sqlite3_errmsg(ppdb)); | ||
10 | } | ||
11 | } | ||
12 | |||
13 | data::data(data&& other) | ||
14 | { | ||
15 | ppdb = other.ppdb; | ||
16 | } | ||
17 | |||
18 | data& data::operator=(data&& other) | ||
19 | { | ||
20 | ppdb = other.ppdb; | ||
21 | |||
22 | return *this; | ||
23 | } | ||
24 | |||
25 | data::~data() | ||
26 | { | ||
27 | sqlite3_close_v2(ppdb); | ||
28 | } | ||
29 | |||
30 | verb_query data::verbs() const | ||
31 | { | ||
32 | return verb_query(*this); | ||
33 | } | ||
34 | |||
35 | adjective_query data::adjectives() const | ||
36 | { | ||
37 | return adjective_query(*this); | ||
38 | } | ||
39 | |||
40 | adverb_query data::adverbs() const | ||
41 | { | ||
42 | return adverb_query(*this); | ||
43 | } | ||
44 | |||
45 | noun_query data::nouns() const | ||
46 | { | ||
47 | return noun_query(*this); | ||
48 | } | ||
49 | |||
50 | }; | ||
diff --git a/data.h b/data.h index e901cba..37092d7 100644 --- a/data.h +++ b/data.h | |||
@@ -1,273 +1,46 @@ | |||
1 | #ifndef DATA_H_C4AEC3DD | 1 | #ifndef DATA_H_C4AEC3DD |
2 | #define DATA_H_C4AEC3DD | 2 | #define DATA_H_C4AEC3DD |
3 | 3 | ||
4 | #include "verb.h" | ||
5 | #include <sqlite3.h> | 4 | #include <sqlite3.h> |
6 | #include <stdexcept> | 5 | #include <stdexcept> |
7 | 6 | ||
8 | namespace verbly { | 7 | namespace verbly { |
9 | 8 | ||
9 | class data; | ||
10 | class word; | ||
11 | class adjective; | ||
12 | class noun; | ||
13 | class verb; | ||
14 | class adverb; | ||
15 | class adjective_query; | ||
16 | class adverb_query; | ||
17 | class noun_query; | ||
18 | class verb_query; | ||
19 | |||
10 | class data { | 20 | class data { |
11 | private: | 21 | private: |
12 | sqlite3* ppdb; | 22 | sqlite3* ppdb; |
13 | 23 | ||
14 | public: | 24 | friend class adjective_query; |
15 | class verb_query { | 25 | friend class noun_query; |
16 | public: | 26 | friend class verb_query; |
17 | const static int unlimited = -1; | 27 | friend class adverb_query; |
18 | |||
19 | private: | ||
20 | const data& database; | ||
21 | int m_limit = unlimited; | ||
22 | bool m_random = false; | ||
23 | |||
24 | public: | ||
25 | verb_query(const data& database) : database(database) | ||
26 | { | ||
27 | |||
28 | } | ||
29 | |||
30 | verb_query& limit(int m_limit) | ||
31 | { | ||
32 | if ((m_limit > 0) || (m_limit == unlimited)) | ||
33 | { | ||
34 | this->m_limit = m_limit; | ||
35 | } | ||
36 | |||
37 | return *this; | ||
38 | } | ||
39 | |||
40 | verb_query& random(bool m_random) | ||
41 | { | ||
42 | this->m_random = m_random; | ||
43 | |||
44 | return *this; | ||
45 | } | ||
46 | |||
47 | std::list<verb> run() const | ||
48 | { | ||
49 | std::stringstream construct; | ||
50 | construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs"; | ||
51 | |||
52 | if (m_random) | ||
53 | { | ||
54 | construct << " ORDER BY RANDOM()"; | ||
55 | } | ||
56 | |||
57 | if (m_limit != unlimited) | ||
58 | { | ||
59 | construct << " LIMIT " << m_limit; | ||
60 | } | ||
61 | |||
62 | sqlite3_stmt* ppstmt; | ||
63 | std::string query = construct.str(); | ||
64 | if (sqlite3_prepare_v2(database.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
65 | { | ||
66 | throw std::runtime_error(sqlite3_errmsg(database.ppdb)); | ||
67 | } | ||
68 | |||
69 | std::list<verb> output; | ||
70 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
71 | { | ||
72 | verb tnc {sqlite3_column_int(ppstmt, 0)}; | ||
73 | tnc.infinitive = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
74 | tnc.past_tense = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
75 | tnc.past_participle = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
76 | tnc.ing_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 4))); | ||
77 | tnc.s_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 5))); | ||
78 | |||
79 | output.push_back(tnc); | ||
80 | } | ||
81 | |||
82 | sqlite3_finalize(ppstmt); | ||
83 | |||
84 | return output; | ||
85 | } | ||
86 | |||
87 | }; | ||
88 | |||
89 | class adjective_query { | ||
90 | public: | ||
91 | const static int unlimited = -1; | ||
92 | |||
93 | private: | ||
94 | const data& database; | ||
95 | int m_limit = unlimited; | ||
96 | bool m_random = false; | ||
97 | |||
98 | public: | ||
99 | adjective_query(const data& database) : database(database) | ||
100 | { | ||
101 | |||
102 | } | ||
103 | |||
104 | adjective_query& limit(int m_limit) | ||
105 | { | ||
106 | if ((m_limit > 0) || (m_limit == unlimited)) | ||
107 | { | ||
108 | this->m_limit = m_limit; | ||
109 | } | ||
110 | |||
111 | return *this; | ||
112 | } | ||
113 | |||
114 | adjective_query& random(bool m_random) | ||
115 | { | ||
116 | this->m_random = m_random; | ||
117 | |||
118 | return *this; | ||
119 | } | ||
120 | |||
121 | std::list<adjective> run() const | ||
122 | { | ||
123 | std::stringstream construct; | ||
124 | construct << "SELECT adjective_id, form FROM adjectives"; | ||
125 | |||
126 | if (m_random) | ||
127 | { | ||
128 | construct << " ORDER BY RANDOM()"; | ||
129 | } | ||
130 | |||
131 | if (m_limit != unlimited) | ||
132 | { | ||
133 | construct << " LIMIT " << m_limit; | ||
134 | } | ||
135 | |||
136 | sqlite3_stmt* ppstmt; | ||
137 | std::string query = construct.str(); | ||
138 | if (sqlite3_prepare_v2(database.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
139 | { | ||
140 | throw std::runtime_error(sqlite3_errmsg(database.ppdb)); | ||
141 | } | ||
142 | |||
143 | std::list<adjective> output; | ||
144 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
145 | { | ||
146 | adjective tnc {sqlite3_column_int(ppstmt, 0)}; | ||
147 | tnc.form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
148 | |||
149 | output.push_back(tnc); | ||
150 | } | ||
151 | |||
152 | sqlite3_finalize(ppstmt); | ||
153 | |||
154 | return output; | ||
155 | } | ||
156 | |||
157 | }; | ||
158 | |||
159 | class adverb_query { | ||
160 | public: | ||
161 | const static int unlimited = -1; | ||
162 | |||
163 | private: | ||
164 | const data& database; | ||
165 | int m_limit = unlimited; | ||
166 | bool m_random = false; | ||
167 | |||
168 | public: | ||
169 | adverb_query(const data& database) : database(database) | ||
170 | { | ||
171 | |||
172 | } | ||
173 | |||
174 | adverb_query& limit(int m_limit) | ||
175 | { | ||
176 | if ((m_limit > 0) || (m_limit == unlimited)) | ||
177 | { | ||
178 | this->m_limit = m_limit; | ||
179 | } | ||
180 | |||
181 | return *this; | ||
182 | } | ||
183 | |||
184 | adverb_query& random(bool m_random) | ||
185 | { | ||
186 | this->m_random = m_random; | ||
187 | |||
188 | return *this; | ||
189 | } | ||
190 | |||
191 | std::list<adverb> run() const | ||
192 | { | ||
193 | std::stringstream construct; | ||
194 | construct << "SELECT adverb_id, form FROM adverbs"; | ||
195 | |||
196 | if (m_random) | ||
197 | { | ||
198 | construct << " ORDER BY RANDOM()"; | ||
199 | } | ||
200 | |||
201 | if (m_limit != unlimited) | ||
202 | { | ||
203 | construct << " LIMIT " << m_limit; | ||
204 | } | ||
205 | |||
206 | sqlite3_stmt* ppstmt; | ||
207 | std::string query = construct.str(); | ||
208 | if (sqlite3_prepare_v2(database.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
209 | { | ||
210 | throw std::runtime_error(sqlite3_errmsg(database.ppdb)); | ||
211 | } | ||
212 | |||
213 | std::list<adverb> output; | ||
214 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
215 | { | ||
216 | adverb tnc {sqlite3_column_int(ppstmt, 0)}; | ||
217 | tnc.form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
218 | |||
219 | output.push_back(tnc); | ||
220 | } | ||
221 | |||
222 | sqlite3_finalize(ppstmt); | ||
223 | |||
224 | return output; | ||
225 | } | ||
226 | |||
227 | }; | ||
228 | 28 | ||
229 | data(std::string datafile) | 29 | public: |
230 | { | 30 | data(std::string datafile); |
231 | if (sqlite3_open_v2(datafile.c_str(), &ppdb, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) | ||
232 | { | ||
233 | throw std::invalid_argument(sqlite3_errmsg(ppdb)); | ||
234 | } | ||
235 | } | ||
236 | 31 | ||
237 | data(const data& other) = delete; | 32 | data(const data& other) = delete; |
238 | data& operator=(const data& other) = delete; | 33 | data& operator=(const data& other) = delete; |
239 | 34 | ||
240 | data(data&& other) | 35 | data(data&& other); |
241 | { | 36 | data& operator=(data&& other); |
242 | ppdb = other.ppdb; | ||
243 | } | ||
244 | |||
245 | data& operator=(data&& other) | ||
246 | { | ||
247 | ppdb = other.ppdb; | ||
248 | |||
249 | return *this; | ||
250 | } | ||
251 | |||
252 | ~data() | ||
253 | { | ||
254 | sqlite3_close_v2(ppdb); | ||
255 | } | ||
256 | |||
257 | verb_query verbs() const | ||
258 | { | ||
259 | return verb_query(*this); | ||
260 | } | ||
261 | 37 | ||
262 | adjective_query adjectives() const | 38 | ~data(); |
263 | { | ||
264 | return adjective_query(*this); | ||
265 | } | ||
266 | 39 | ||
267 | adverb_query adverbs() const | 40 | verb_query verbs() const; |
268 | { | 41 | adjective_query adjectives() const; |
269 | return adverb_query(*this); | 42 | adverb_query adverbs() const; |
270 | } | 43 | noun_query nouns() const; |
271 | 44 | ||
272 | }; | 45 | }; |
273 | 46 | ||
diff --git a/noun.cpp b/noun.cpp new file mode 100644 index 0000000..9336a1c --- /dev/null +++ b/noun.cpp | |||
@@ -0,0 +1,916 @@ | |||
1 | #include "verbly.h" | ||
2 | |||
3 | namespace verbly { | ||
4 | |||
5 | noun::noun(const data& _data, int _id) : word(_data, _id) | ||
6 | { | ||
7 | |||
8 | } | ||
9 | |||
10 | std::string noun::base_form() const | ||
11 | { | ||
12 | return _singular; | ||
13 | } | ||
14 | |||
15 | std::string noun::singular_form() const | ||
16 | { | ||
17 | return _singular; | ||
18 | } | ||
19 | |||
20 | std::string noun::plural_form() const | ||
21 | { | ||
22 | return _plural; | ||
23 | } | ||
24 | |||
25 | bool noun::has_plural_form() const | ||
26 | { | ||
27 | return !_plural.empty(); | ||
28 | } | ||
29 | |||
30 | noun_query noun::hypernyms() const | ||
31 | { | ||
32 | return _data.nouns().hypernym_of(*this); | ||
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 | |||
204 | return *this; | ||
205 | } | ||
206 | |||
207 | noun_query& noun_query::not_part_meronym_of(const noun& _noun) | ||
208 | { | ||
209 | _not_part_meronym_of.push_back(_noun); | ||
210 | |||
211 | return *this; | ||
212 | } | ||
213 | |||
214 | noun_query& noun_query::is_part_holonym(bool _arg) | ||
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::instance_of(const noun& _noun) | ||
327 | { | ||
328 | _instance_of.push_back(_noun); | ||
329 | |||
330 | return *this; | ||
331 | } | ||
332 | |||
333 | noun_query& noun_query::not_instance_of(const noun& _noun) | ||
334 | { | ||
335 | _not_instance_of.push_back(_noun); | ||
336 | |||
337 | return *this; | ||
338 | } | ||
339 | |||
340 | noun_query& noun_query::is_class(bool _arg) | ||
341 | { | ||
342 | _is_class = _arg; | ||
343 | |||
344 | return *this; | ||
345 | } | ||
346 | |||
347 | noun_query& noun_query::class_of(const noun& _noun) | ||
348 | { | ||
349 | _class_of.push_back(_noun); | ||
350 | |||
351 | return *this; | ||
352 | } | ||
353 | |||
354 | noun_query& noun_query::not_class_of(const noun& _noun) | ||
355 | { | ||
356 | _not_class_of.push_back(_noun); | ||
357 | |||
358 | return *this; | ||
359 | } | ||
360 | |||
361 | noun_query& noun_query::has_synonyms(bool _arg) | ||
362 | { | ||
363 | _has_synonyms = _arg; | ||
364 | |||
365 | return *this; | ||
366 | } | ||
367 | |||
368 | noun_query& noun_query::synonym_of(const noun& _noun) | ||
369 | { | ||
370 | _synonym_of.push_back(_noun); | ||
371 | |||
372 | return *this; | ||
373 | } | ||
374 | |||
375 | noun_query& noun_query::not_synonym_of(const noun& _noun) | ||
376 | { | ||
377 | _not_synonym_of.push_back(_noun); | ||
378 | |||
379 | return *this; | ||
380 | } | ||
381 | |||
382 | noun_query& noun_query::has_antonyms(bool _arg) | ||
383 | { | ||
384 | _has_antonyms = _arg; | ||
385 | |||
386 | return *this; | ||
387 | } | ||
388 | |||
389 | noun_query& noun_query::antonym_of(const noun& _noun) | ||
390 | { | ||
391 | _antonym_of.push_back(_noun); | ||
392 | |||
393 | return *this; | ||
394 | } | ||
395 | |||
396 | noun_query& noun_query::not_antonym_of(const noun& _noun) | ||
397 | { | ||
398 | _not_antonym_of.push_back(_noun); | ||
399 | |||
400 | return *this; | ||
401 | } | ||
402 | |||
403 | noun_query& noun_query::has_pertainym(bool _arg) | ||
404 | { | ||
405 | _has_pertainym = _arg; | ||
406 | |||
407 | return *this; | ||
408 | } | ||
409 | |||
410 | noun_query& noun_query::anti_pertainym_of(const adjective& _adj) | ||
411 | { | ||
412 | _anti_pertainym_of.push_back(_adj); | ||
413 | |||
414 | return *this; | ||
415 | } | ||
416 | |||
417 | noun_query& noun_query::is_attribute(bool _arg) | ||
418 | { | ||
419 | _is_attribute = _arg; | ||
420 | |||
421 | return *this; | ||
422 | } | ||
423 | |||
424 | noun_query& noun_query::attribute_of(const adjective& _adj) | ||
425 | { | ||
426 | _attribute_of.push_back(_adj); | ||
427 | |||
428 | return *this; | ||
429 | } | ||
430 | |||
431 | std::list<noun> noun_query::run() const | ||
432 | { | ||
433 | std::stringstream construct; | ||
434 | construct << "SELECT noun_id, singular, plural FROM nouns"; | ||
435 | std::list<std::string> conditions; | ||
436 | |||
437 | if (_has_prn) | ||
438 | { | ||
439 | conditions.push_back("noun_id IN (SELECT noun_id FROM noun_pronunciations)"); | ||
440 | } | ||
441 | |||
442 | if (!_rhymes.empty()) | ||
443 | { | ||
444 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
445 | std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
446 | conditions.push_back(cond); | ||
447 | } | ||
448 | |||
449 | for (auto except : _except) | ||
450 | { | ||
451 | conditions.push_back("noun_id != @EXCID"); | ||
452 | } | ||
453 | |||
454 | if (_is_hypernym) | ||
455 | { | ||
456 | conditions.push_back("noun_id IN (SELECT hypernym_id FROM hypernymy)"); | ||
457 | } | ||
458 | |||
459 | if (!_hypernym_of.empty()) | ||
460 | { | ||
461 | std::list<std::string> clauses(_hypernym_of.size(), "hyponym_id = @HYPO"); | ||
462 | std::string cond = "noun_id IN (SELECT hypernym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
463 | conditions.push_back(cond); | ||
464 | } | ||
465 | |||
466 | if (!_not_hypernym_of.empty()) | ||
467 | { | ||
468 | std::list<std::string> clauses(_not_hypernym_of.size(), "hyponym_id = @NHYPO"); | ||
469 | std::string cond = "noun_id NOT IN (SELECT hypernym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
470 | conditions.push_back(cond); | ||
471 | } | ||
472 | |||
473 | if (_is_hyponym) | ||
474 | { | ||
475 | conditions.push_back("noun_id IN (SELECT hyponym_id FROM hypernymy)"); | ||
476 | } | ||
477 | |||
478 | if (!_hyponym_of.empty()) | ||
479 | { | ||
480 | std::list<std::string> clauses(_hyponym_of.size(), "hypernym_id = @HYPER"); | ||
481 | std::string cond = "noun_id IN (SELECT hyponym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
482 | conditions.push_back(cond); | ||
483 | } | ||
484 | |||
485 | if (!_not_hyponym_of.empty()) | ||
486 | { | ||
487 | std::list<std::string> clauses(_not_hyponym_of.size(), "hypernym_id = @NHYPER"); | ||
488 | std::string cond = "noun_id NOT IN (SELECT hyponym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
489 | conditions.push_back(cond); | ||
490 | } | ||
491 | |||
492 | if (_is_part_meronym) | ||
493 | { | ||
494 | conditions.push_back("noun_id IN (SELECT meronym_id FROM part_meronymy)"); | ||
495 | } | ||
496 | |||
497 | if (!_part_meronym_of.empty()) | ||
498 | { | ||
499 | std::list<std::string> clauses(_part_meronym_of.size(), "holonym_id = @PHOLO"); | ||
500 | std::string cond = "noun_id IN (SELECT meronym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
501 | conditions.push_back(cond); | ||
502 | } | ||
503 | |||
504 | if (!_not_part_meronym_of.empty()) | ||
505 | { | ||
506 | std::list<std::string> clauses(_not_part_meronym_of.size(), "holonym_id = @NPHOLO"); | ||
507 | std::string cond = "noun_id NOT IN (SELECT meronym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
508 | conditions.push_back(cond); | ||
509 | } | ||
510 | |||
511 | if (_is_part_holonym) | ||
512 | { | ||
513 | conditions.push_back("noun_id IN (SELECT holonym_id FROM part_meronymy)"); | ||
514 | } | ||
515 | |||
516 | if (!_part_holonym_of.empty()) | ||
517 | { | ||
518 | std::list<std::string> clauses(_part_holonym_of.size(), "meronym_id = @PMERO"); | ||
519 | std::string cond = "noun_id IN (SELECT holonym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
520 | conditions.push_back(cond); | ||
521 | } | ||
522 | |||
523 | if (!_not_part_holonym_of.empty()) | ||
524 | { | ||
525 | std::list<std::string> clauses(_not_part_holonym_of.size(), "meronym_id = @NPMERO"); | ||
526 | std::string cond = "noun_id NOT IN (SELECT holonym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
527 | conditions.push_back(cond); | ||
528 | } | ||
529 | |||
530 | if (_is_substance_meronym) | ||
531 | { | ||
532 | conditions.push_back("noun_id IN (SELECT meronym_id FROM substance_meronymy)"); | ||
533 | } | ||
534 | |||
535 | if (!_substance_meronym_of.empty()) | ||
536 | { | ||
537 | std::list<std::string> clauses(_substance_meronym_of.size(), "holonym_id = @SHOLO"); | ||
538 | std::string cond = "noun_id IN (SELECT meronym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
539 | conditions.push_back(cond); | ||
540 | } | ||
541 | |||
542 | if (!_not_substance_meronym_of.empty()) | ||
543 | { | ||
544 | std::list<std::string> clauses(_not_substance_meronym_of.size(), "holonym_id = @NSHOLO"); | ||
545 | std::string cond = "noun_id NOT IN (SELECT meronym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
546 | conditions.push_back(cond); | ||
547 | } | ||
548 | |||
549 | if (_is_substance_holonym) | ||
550 | { | ||
551 | conditions.push_back("noun_id IN (SELECT holonym_id FROM substance_meronymy)"); | ||
552 | } | ||
553 | |||
554 | if (!_substance_holonym_of.empty()) | ||
555 | { | ||
556 | std::list<std::string> clauses(_substance_holonym_of.size(), "meronym_id = @SMERO"); | ||
557 | std::string cond = "noun_id IN (SELECT holonym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
558 | conditions.push_back(cond); | ||
559 | } | ||
560 | |||
561 | if (!_not_substance_holonym_of.empty()) | ||
562 | { | ||
563 | std::list<std::string> clauses(_not_substance_holonym_of.size(), "meronym_id = @NSMERO"); | ||
564 | std::string cond = "noun_id NOT IN (SELECT holonym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
565 | conditions.push_back(cond); | ||
566 | } | ||
567 | |||
568 | if (_is_member_meronym) | ||
569 | { | ||
570 | conditions.push_back("noun_id IN (SELECT meronym_id FROM member_meronymy)"); | ||
571 | } | ||
572 | |||
573 | if (!_member_meronym_of.empty()) | ||
574 | { | ||
575 | std::list<std::string> clauses(_member_meronym_of.size(), "holonym_id = @MHOLO"); | ||
576 | std::string cond = "noun_id IN (SELECT meronym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
577 | conditions.push_back(cond); | ||
578 | } | ||
579 | |||
580 | if (!_not_member_meronym_of.empty()) | ||
581 | { | ||
582 | std::list<std::string> clauses(_not_member_meronym_of.size(), "holonym_id = @NMHOLO"); | ||
583 | std::string cond = "noun_id NOT IN (SELECT meronym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
584 | conditions.push_back(cond); | ||
585 | } | ||
586 | |||
587 | if (_is_member_holonym) | ||
588 | { | ||
589 | conditions.push_back("noun_id IN (SELECT holonym_id FROM member_meronym)"); | ||
590 | } | ||
591 | |||
592 | if (!_member_holonym_of.empty()) | ||
593 | { | ||
594 | std::list<std::string> clauses(_member_holonym_of.size(), "meronym_id = @MMERO"); | ||
595 | std::string cond = "noun_id IN (SELECT holonym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
596 | conditions.push_back(cond); | ||
597 | } | ||
598 | |||
599 | if (!_not_member_holonym_of.empty()) | ||
600 | { | ||
601 | std::list<std::string> clauses(_not_member_holonym_of.size(), "meronym_id = @NMMERO"); | ||
602 | std::string cond = "noun_id NOT IN (SELECT holonym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
603 | conditions.push_back(cond); | ||
604 | } | ||
605 | |||
606 | if (_is_proper) | ||
607 | { | ||
608 | conditions.push_back("noun_id IN (SELECT instance_id FROM instantiation)"); | ||
609 | } | ||
610 | |||
611 | if (!_instance_of.empty()) | ||
612 | { | ||
613 | std::list<std::string> clauses(_instance_of.size(), "class_id = @CLSID"); | ||
614 | std::string cond = "noun_id IN (SELECT instance_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
615 | conditions.push_back(cond); | ||
616 | } | ||
617 | |||
618 | if (!_not_instance_of.empty()) | ||
619 | { | ||
620 | std::list<std::string> clauses(_not_instance_of.size(), "class_id = @NCLSID"); | ||
621 | std::string cond = "noun_id NOT IN (SELECT instance_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
622 | conditions.push_back(cond); | ||
623 | } | ||
624 | |||
625 | if (_is_class) | ||
626 | { | ||
627 | conditions.push_back("noun_id IN (SELECT class_id FROM instantiation)"); | ||
628 | } | ||
629 | |||
630 | if (!_class_of.empty()) | ||
631 | { | ||
632 | std::list<std::string> clauses(_class_of.size(), "instance_id = @INSID"); | ||
633 | std::string cond = "noun_id IN (SELECT class_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
634 | conditions.push_back(cond); | ||
635 | } | ||
636 | |||
637 | if (!_not_class_of.empty()) | ||
638 | { | ||
639 | std::list<std::string> clauses(_not_class_of.size(), "instance_id = @NINSID"); | ||
640 | std::string cond = "noun_id NOT IN (SELECT class_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
641 | conditions.push_back(cond); | ||
642 | } | ||
643 | |||
644 | if (_has_synonyms) | ||
645 | { | ||
646 | conditions.push_back("noun_id IN (SELECT adjective_2_id FROM adjective_synonymy)"); | ||
647 | } | ||
648 | |||
649 | if (!_synonym_of.empty()) | ||
650 | { | ||
651 | std::list<std::string> clauses(_synonym_of.size(), "adjective_1_id = @SYNID"); | ||
652 | std::string cond = "noun_id IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
653 | conditions.push_back(cond); | ||
654 | } | ||
655 | |||
656 | if (!_not_synonym_of.empty()) | ||
657 | { | ||
658 | std::list<std::string> clauses(_not_synonym_of.size(), "adjective_1_id = @NSYNID"); | ||
659 | std::string cond = "noun_id NOT IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
660 | conditions.push_back(cond); | ||
661 | } | ||
662 | |||
663 | if (_has_antonyms) | ||
664 | { | ||
665 | conditions.push_back("noun_id IN (SELECT adjective_2_id FROM adjective_antonymy)"); | ||
666 | } | ||
667 | |||
668 | if (!_antonym_of.empty()) | ||
669 | { | ||
670 | std::list<std::string> clauses(_antonym_of.size(), "adjective_1_id = @ANTID"); | ||
671 | std::string cond = "noun_id IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
672 | conditions.push_back(cond); | ||
673 | } | ||
674 | |||
675 | if (!_not_antonym_of.empty()) | ||
676 | { | ||
677 | std::list<std::string> clauses(_not_antonym_of.size(), "adjective_1_id = @NANTID"); | ||
678 | std::string cond = "noun_id NOT IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
679 | conditions.push_back(cond); | ||
680 | } | ||
681 | |||
682 | if (_has_pertainym) | ||
683 | { | ||
684 | conditions.push_back("noun_id IN (SELECT noun_id FROM pertainymy)"); | ||
685 | } | ||
686 | |||
687 | if (!_anti_pertainym_of.empty()) | ||
688 | { | ||
689 | std::list<std::string> clauses(_anti_pertainym_of.size(), "pertainym_id = @PERID"); | ||
690 | std::string cond = "noun_id IN (SELECT noun_id FROM pertainymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
691 | conditions.push_back(cond); | ||
692 | } | ||
693 | |||
694 | if (_is_attribute) | ||
695 | { | ||
696 | conditions.push_back("noun_id IN (SELECT noun_id FROM variation)"); | ||
697 | } | ||
698 | |||
699 | if (!_attribute_of.empty()) | ||
700 | { | ||
701 | std::list<std::string> clauses(_attribute_of.size(), "adjective_id = @VALID"); | ||
702 | std::string cond = "noun_id IN (SELECT noun_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
703 | conditions.push_back(cond); | ||
704 | } | ||
705 | |||
706 | if (!conditions.empty()) | ||
707 | { | ||
708 | construct << " WHERE "; | ||
709 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
710 | } | ||
711 | |||
712 | if (_random) | ||
713 | { | ||
714 | construct << " ORDER BY RANDOM()"; | ||
715 | } | ||
716 | |||
717 | if (_limit != unlimited) | ||
718 | { | ||
719 | construct << " LIMIT " << _limit; | ||
720 | } | ||
721 | |||
722 | sqlite3_stmt* ppstmt; | ||
723 | std::string query = construct.str(); | ||
724 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
725 | { | ||
726 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
727 | } | ||
728 | |||
729 | if (!_rhymes.empty()) | ||
730 | { | ||
731 | int i = 0; | ||
732 | for (auto rhyme : _rhymes) | ||
733 | { | ||
734 | std::string rhymer = "%" + rhyme; | ||
735 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
736 | |||
737 | i++; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | for (auto except : _except) | ||
742 | { | ||
743 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
744 | } | ||
745 | |||
746 | for (auto hyponym : _hypernym_of) | ||
747 | { | ||
748 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPO"), hyponym._id); | ||
749 | } | ||
750 | |||
751 | for (auto hyponym : _not_hypernym_of) | ||
752 | { | ||
753 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NHYPO"), hyponym._id); | ||
754 | } | ||
755 | |||
756 | for (auto hypernym : _hyponym_of) | ||
757 | { | ||
758 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPER"), hypernym._id); | ||
759 | } | ||
760 | |||
761 | for (auto hypernym : _not_hyponym_of) | ||
762 | { | ||
763 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NHYPER"), hypernym._id); | ||
764 | } | ||
765 | |||
766 | for (auto holonym : _part_meronym_of) | ||
767 | { | ||
768 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PHOLO"), holonym._id); | ||
769 | } | ||
770 | |||
771 | for (auto holonym : _not_part_meronym_of) | ||
772 | { | ||
773 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NPHOLO"), holonym._id); | ||
774 | } | ||
775 | |||
776 | for (auto meronym : _part_holonym_of) | ||
777 | { | ||
778 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PMERO"), meronym._id); | ||
779 | } | ||
780 | |||
781 | for (auto meronym : _not_part_holonym_of) | ||
782 | { | ||
783 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NPMERO"), meronym._id); | ||
784 | } | ||
785 | |||
786 | for (auto holonym : _substance_meronym_of) | ||
787 | { | ||
788 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SHOLO"), holonym._id); | ||
789 | } | ||
790 | |||
791 | for (auto holonym : _not_substance_meronym_of) | ||
792 | { | ||
793 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSHOLO"), holonym._id); | ||
794 | } | ||
795 | |||
796 | for (auto meronym : _substance_holonym_of) | ||
797 | { | ||
798 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SMERO"), meronym._id); | ||
799 | } | ||
800 | |||
801 | for (auto meronym : _not_substance_holonym_of) | ||
802 | { | ||
803 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSMERO"), meronym._id); | ||
804 | } | ||
805 | |||
806 | for (auto holonym : _member_meronym_of) | ||
807 | { | ||
808 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MHOLO"), holonym._id); | ||
809 | } | ||
810 | |||
811 | for (auto holonym : _not_member_meronym_of) | ||
812 | { | ||
813 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NMHOLO"), holonym._id); | ||
814 | } | ||
815 | |||
816 | for (auto meronym : _member_holonym_of) | ||
817 | { | ||
818 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MMERO"), meronym._id); | ||
819 | } | ||
820 | |||
821 | for (auto meronym : _not_member_holonym_of) | ||
822 | { | ||
823 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NMMERO"), meronym._id); | ||
824 | } | ||
825 | |||
826 | for (auto cls : _instance_of) | ||
827 | { | ||
828 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@CLSID"), cls._id); | ||
829 | } | ||
830 | |||
831 | for (auto cls : _not_instance_of) | ||
832 | { | ||
833 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NCLSID"), cls._id); | ||
834 | } | ||
835 | |||
836 | for (auto inst : _class_of) | ||
837 | { | ||
838 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@INSID"), inst._id); | ||
839 | } | ||
840 | |||
841 | for (auto inst : _not_class_of) | ||
842 | { | ||
843 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NINSID"), inst._id); | ||
844 | } | ||
845 | |||
846 | for (auto synonym : _synonym_of) | ||
847 | { | ||
848 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
849 | } | ||
850 | |||
851 | for (auto synonym : _not_synonym_of) | ||
852 | { | ||
853 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); | ||
854 | } | ||
855 | |||
856 | for (auto antonym : _antonym_of) | ||
857 | { | ||
858 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
859 | } | ||
860 | |||
861 | for (auto antonym : _not_antonym_of) | ||
862 | { | ||
863 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); | ||
864 | } | ||
865 | |||
866 | for (auto pertainym : _anti_pertainym_of) | ||
867 | { | ||
868 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PERID"), pertainym._id); | ||
869 | } | ||
870 | |||
871 | for (auto value : _attribute_of) | ||
872 | { | ||
873 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VALID"), value._id); | ||
874 | } | ||
875 | |||
876 | std::list<noun> output; | ||
877 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
878 | { | ||
879 | noun tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
880 | tnc._singular = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
881 | |||
882 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
883 | { | ||
884 | tnc._plural = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
885 | } | ||
886 | |||
887 | output.push_back(tnc); | ||
888 | } | ||
889 | |||
890 | sqlite3_finalize(ppstmt); | ||
891 | |||
892 | for (auto& noun : output) | ||
893 | { | ||
894 | query = "SELECT pronunciation FROM noun_pronunciations WHERE noun_id = ?"; | ||
895 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
896 | { | ||
897 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
898 | } | ||
899 | |||
900 | sqlite3_bind_int(ppstmt, 1, noun._id); | ||
901 | |||
902 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
903 | { | ||
904 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
905 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
906 | |||
907 | noun.pronunciations.push_back(phonemes); | ||
908 | } | ||
909 | |||
910 | sqlite3_finalize(ppstmt); | ||
911 | } | ||
912 | |||
913 | return output; | ||
914 | } | ||
915 | |||
916 | }; | ||
diff --git a/noun.h b/noun.h new file mode 100644 index 0000000..f5ba256 --- /dev/null +++ b/noun.h | |||
@@ -0,0 +1,171 @@ | |||
1 | #ifndef NOUN_H_24A03C83 | ||
2 | #define NOUN_H_24A03C83 | ||
3 | |||
4 | namespace verbly { | ||
5 | |||
6 | class noun : public word { | ||
7 | private: | ||
8 | std::string _singular; | ||
9 | std::string _plural; | ||
10 | |||
11 | friend class noun_query; | ||
12 | |||
13 | public: | ||
14 | noun(const data& _data, int _id); | ||
15 | |||
16 | std::string base_form() const; | ||
17 | std::string singular_form() const; | ||
18 | std::string plural_form() const; | ||
19 | |||
20 | bool has_plural_form() const; | ||
21 | |||
22 | noun_query hypernyms() const; | ||
23 | noun_query hyponyms() const; | ||
24 | noun_query part_meronyms() const; | ||
25 | noun_query part_holonyms() const; | ||
26 | noun_query substance_meronyms() const; | ||
27 | noun_query substance_holonyms() const; | ||
28 | noun_query member_meronyms() const; | ||
29 | noun_query member_holonyms() const; | ||
30 | noun_query classes() const; | ||
31 | noun_query instances() const; | ||
32 | noun_query synonyms() const; | ||
33 | noun_query antonyms() const; | ||
34 | adjective_query pertainyms() const; | ||
35 | 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& instance_of(const noun& _noun); | ||
82 | noun_query& not_instance_of(const noun& _noun); | ||
83 | |||
84 | noun_query& is_class(bool _arg); | ||
85 | noun_query& class_of(const noun& _noun); | ||
86 | noun_query& not_class_of(const noun& _noun); | ||
87 | |||
88 | noun_query& has_synonyms(bool _arg); | ||
89 | noun_query& synonym_of(const noun& _noun); | ||
90 | noun_query& not_synonym_of(const noun& _noun); | ||
91 | |||
92 | noun_query& has_antonyms(bool _arg); | ||
93 | noun_query& antonym_of(const noun& _noun); | ||
94 | noun_query& not_antonym_of(const noun& _noun); | ||
95 | |||
96 | noun_query& has_pertainym(bool _arg); | ||
97 | noun_query& anti_pertainym_of(const adjective& _adj); | ||
98 | |||
99 | noun_query& is_attribute(bool _arg); | ||
100 | noun_query& attribute_of(const adjective& _adj); | ||
101 | |||
102 | std::list<noun> run() const; | ||
103 | |||
104 | const static int unlimited = -1; | ||
105 | |||
106 | private: | ||
107 | const data& _data; | ||
108 | int _limit = unlimited; | ||
109 | bool _random = false; | ||
110 | std::list<std::string> _rhymes; | ||
111 | std::list<noun> _except; | ||
112 | bool _has_prn = false; | ||
113 | |||
114 | bool _is_hypernym = false; | ||
115 | std::list<noun> _hypernym_of; | ||
116 | std::list<noun> _not_hypernym_of; | ||
117 | |||
118 | bool _is_hyponym = false; | ||
119 | std::list<noun> _hyponym_of; | ||
120 | std::list<noun> _not_hyponym_of; | ||
121 | |||
122 | bool _is_part_meronym = false; | ||
123 | std::list<noun> _part_meronym_of; | ||
124 | std::list<noun> _not_part_meronym_of; | ||
125 | |||
126 | bool _is_substance_meronym = false; | ||
127 | std::list<noun> _substance_meronym_of; | ||
128 | std::list<noun> _not_substance_meronym_of; | ||
129 | |||
130 | bool _is_member_meronym = false; | ||
131 | std::list<noun> _member_meronym_of; | ||
132 | std::list<noun> _not_member_meronym_of; | ||
133 | |||
134 | bool _is_part_holonym = false; | ||
135 | std::list<noun> _part_holonym_of; | ||
136 | std::list<noun> _not_part_holonym_of; | ||
137 | |||
138 | bool _is_substance_holonym = false; | ||
139 | std::list<noun> _substance_holonym_of; | ||
140 | std::list<noun> _not_substance_holonym_of; | ||
141 | |||
142 | bool _is_member_holonym = false; | ||
143 | std::list<noun> _member_holonym_of; | ||
144 | std::list<noun> _not_member_holonym_of; | ||
145 | |||
146 | bool _is_proper = false; | ||
147 | std::list<noun> _instance_of; | ||
148 | std::list<noun> _not_instance_of; | ||
149 | |||
150 | bool _is_class = false; | ||
151 | std::list<noun> _class_of; | ||
152 | std::list<noun> _not_class_of; | ||
153 | |||
154 | bool _has_synonyms = false; | ||
155 | std::list<noun> _synonym_of; | ||
156 | std::list<noun> _not_synonym_of; | ||
157 | |||
158 | bool _has_antonyms = false; | ||
159 | std::list<noun> _antonym_of; | ||
160 | std::list<noun> _not_antonym_of; | ||
161 | |||
162 | bool _has_pertainym = false; | ||
163 | std::list<adjective> _anti_pertainym_of; | ||
164 | |||
165 | bool _is_attribute = false; | ||
166 | std::list<adjective> _attribute_of; | ||
167 | }; | ||
168 | |||
169 | }; | ||
170 | |||
171 | #endif /* end of include guard: NOUN_H_24A03C83 */ | ||
diff --git a/token.cpp b/token.cpp new file mode 100644 index 0000000..aa8f50e --- /dev/null +++ b/token.cpp | |||
@@ -0,0 +1,53 @@ | |||
1 | #include "verbly.h" | ||
2 | |||
3 | namespace verbly { | ||
4 | |||
5 | token::token(token::type _type) : _type(_type) | ||
6 | { | ||
7 | |||
8 | } | ||
9 | |||
10 | token::type token::token_type() const | ||
11 | { | ||
12 | return _type; | ||
13 | } | ||
14 | |||
15 | verb_token::verb_token(const class verb& _verb) : token(token::type::verb), _verb(&_verb) | ||
16 | { | ||
17 | |||
18 | } | ||
19 | |||
20 | const class verb& verb_token::verb() const | ||
21 | { | ||
22 | return *_verb; | ||
23 | } | ||
24 | |||
25 | verb_token& verb_token::inflect(verb_token::inflection infl) | ||
26 | { | ||
27 | _inflection = infl; | ||
28 | return *this; | ||
29 | } | ||
30 | |||
31 | bool verb_token::complete() const | ||
32 | { | ||
33 | return true; | ||
34 | } | ||
35 | |||
36 | std::string verb_token::compile() const | ||
37 | { | ||
38 | switch (_inflection) | ||
39 | { | ||
40 | case inflection::infinitive: return _verb->infinitive_form(); | ||
41 | case inflection::past_tense: return _verb->past_tense_form(); | ||
42 | case inflection::past_participle: return _verb->past_participle_form(); | ||
43 | case inflection::ing_form: return _verb->ing_form(); | ||
44 | case inflection::s_form: return _verb->s_form(); | ||
45 | } | ||
46 | } | ||
47 | |||
48 | token* verb_token::copy() const | ||
49 | { | ||
50 | return new verb_token(*this); | ||
51 | } | ||
52 | |||
53 | }; | ||
diff --git a/token.h b/token.h index 2848fd0..44d99cb 100644 --- a/token.h +++ b/token.h | |||
@@ -4,16 +4,10 @@ | |||
4 | #include <string> | 4 | #include <string> |
5 | #include <list> | 5 | #include <list> |
6 | #include <sstream> | 6 | #include <sstream> |
7 | #include "verb.h" | ||
8 | 7 | ||
9 | namespace verbly { | 8 | namespace verbly { |
10 | 9 | ||
11 | enum class type { | 10 | class verb; |
12 | verb, | ||
13 | fillin, | ||
14 | string, | ||
15 | utterance | ||
16 | }; | ||
17 | 11 | ||
18 | class selrestr { | 12 | class selrestr { |
19 | }; | 13 | }; |
@@ -29,20 +23,22 @@ namespace verbly { | |||
29 | }; | 23 | }; |
30 | 24 | ||
31 | class token { | 25 | class token { |
26 | public: | ||
27 | enum class type { | ||
28 | verb, | ||
29 | fillin, | ||
30 | string, | ||
31 | utterance | ||
32 | }; | ||
33 | |||
32 | protected: | 34 | protected: |
33 | // General | 35 | // General |
34 | type type; | 36 | type _type; |
35 | 37 | ||
36 | token(enum type type) : type(type) | 38 | token(type _type); |
37 | { | ||
38 | |||
39 | } | ||
40 | 39 | ||
41 | public: | 40 | public: |
42 | enum type token_type() const | 41 | enum type token_type() const; |
43 | { | ||
44 | return type; | ||
45 | } | ||
46 | 42 | ||
47 | virtual bool complete() const = 0; | 43 | virtual bool complete() const = 0; |
48 | virtual std::string compile() const = 0; | 44 | virtual std::string compile() const = 0; |
@@ -50,42 +46,32 @@ namespace verbly { | |||
50 | }; | 46 | }; |
51 | 47 | ||
52 | class verb_token : public token { | 48 | class verb_token : public token { |
49 | public: | ||
50 | enum class inflection { | ||
51 | infinitive, | ||
52 | past_tense, | ||
53 | past_participle, | ||
54 | ing_form, | ||
55 | s_form | ||
56 | }; | ||
57 | |||
53 | private: | 58 | private: |
54 | // Verb | 59 | // Verb |
55 | const verb* m_verb; | 60 | const verb* _verb; |
56 | conjugation verb_infl = conjugation::infinitive; | 61 | inflection _inflection = inflection::infinitive; |
57 | 62 | ||
58 | public: | 63 | public: |
59 | verb_token(const class verb& verb) : token(type::verb), m_verb(&verb) | 64 | verb_token(const class verb& _verb); |
60 | { | ||
61 | |||
62 | } | ||
63 | 65 | ||
64 | const class verb& verb() const | 66 | const class verb& verb() const; |
65 | { | ||
66 | return *m_verb; | ||
67 | } | ||
68 | 67 | ||
69 | verb_token& conjugate(conjugation infl) | 68 | verb_token& inflect(inflection infl); |
70 | { | ||
71 | verb_infl = infl; | ||
72 | return *this; | ||
73 | } | ||
74 | 69 | ||
75 | bool complete() const | 70 | bool complete() const; |
76 | { | ||
77 | return true; | ||
78 | } | ||
79 | 71 | ||
80 | std::string compile() const | 72 | std::string compile() const; |
81 | { | ||
82 | return m_verb->conjugate(verb_infl); | ||
83 | } | ||
84 | 73 | ||
85 | token* copy() const | 74 | token* copy() const; |
86 | { | ||
87 | return new verb_token(*this); | ||
88 | } | ||
89 | }; | 75 | }; |
90 | 76 | ||
91 | class utterance_token : public token { | 77 | class utterance_token : public token { |
@@ -140,7 +126,7 @@ namespace verbly { | |||
140 | } | 126 | } |
141 | };*/ | 127 | };*/ |
142 | 128 | ||
143 | utterance_token(std::initializer_list<token*> tkns) : token(type::utterance) | 129 | utterance_token(std::initializer_list<token*> tkns) : token(token::type::utterance) |
144 | { | 130 | { |
145 | for (auto tkn : tkns) | 131 | for (auto tkn : tkns) |
146 | { | 132 | { |
@@ -148,7 +134,7 @@ namespace verbly { | |||
148 | } | 134 | } |
149 | } | 135 | } |
150 | 136 | ||
151 | utterance_token(const utterance_token& other) : token(type::utterance) | 137 | utterance_token(const utterance_token& other) : token(token::type::utterance) |
152 | { | 138 | { |
153 | for (auto& tkn : other.utterance) | 139 | for (auto& tkn : other.utterance) |
154 | { | 140 | { |
@@ -156,7 +142,7 @@ namespace verbly { | |||
156 | } | 142 | } |
157 | } | 143 | } |
158 | 144 | ||
159 | utterance_token(utterance_token&& other) : token(type::utterance), utterance(std::move(other.utterance)) | 145 | utterance_token(utterance_token&& other) : token(token::type::utterance), utterance(std::move(other.utterance)) |
160 | { | 146 | { |
161 | 147 | ||
162 | } | 148 | } |
@@ -237,7 +223,7 @@ namespace verbly { | |||
237 | fillin_type m_fillin_type; | 223 | fillin_type m_fillin_type; |
238 | 224 | ||
239 | public: | 225 | public: |
240 | fillin_token(fillin_type ft) : token(type::fillin), m_fillin_type(ft) | 226 | fillin_token(fillin_type ft) : token(token::type::fillin), m_fillin_type(ft) |
241 | { | 227 | { |
242 | 228 | ||
243 | } | 229 | } |
@@ -301,7 +287,7 @@ namespace verbly { | |||
301 | std::string str; | 287 | std::string str; |
302 | 288 | ||
303 | public: | 289 | public: |
304 | string_token(std::string str) : token(type::string), str(str) | 290 | string_token(std::string str) : token(token::type::string), str(str) |
305 | { | 291 | { |
306 | 292 | ||
307 | } | 293 | } |
diff --git a/util.h b/util.h new file mode 100644 index 0000000..815b47c --- /dev/null +++ b/util.h | |||
@@ -0,0 +1,53 @@ | |||
1 | #ifndef UTIL_H_15DDCA2D | ||
2 | #define UTIL_H_15DDCA2D | ||
3 | |||
4 | #include <string> | ||
5 | #include <iterator> | ||
6 | #include <sstream> | ||
7 | |||
8 | namespace verbly { | ||
9 | |||
10 | template <class InputIterator> | ||
11 | std::string implode(InputIterator first, InputIterator last, std::string delimiter) | ||
12 | { | ||
13 | std::stringstream result; | ||
14 | |||
15 | for (InputIterator it = first; it != last; it++) | ||
16 | { | ||
17 | if (it != first) | ||
18 | { | ||
19 | result << delimiter; | ||
20 | } | ||
21 | |||
22 | result << *it; | ||
23 | } | ||
24 | |||
25 | return result.str(); | ||
26 | } | ||
27 | |||
28 | template <class Container> | ||
29 | Container split(std::string input, std::string delimiter) | ||
30 | { | ||
31 | Container result; | ||
32 | |||
33 | while (!input.empty()) | ||
34 | { | ||
35 | int divider = input.find(" "); | ||
36 | if (divider == std::string::npos) | ||
37 | { | ||
38 | result.push_back(input); | ||
39 | |||
40 | input = ""; | ||
41 | } else { | ||
42 | result.push_back(input.substr(0, divider)); | ||
43 | |||
44 | input = input.substr(divider+1); | ||
45 | } | ||
46 | } | ||
47 | |||
48 | return result; | ||
49 | } | ||
50 | |||
51 | }; | ||
52 | |||
53 | #endif /* end of include guard: UTIL_H_15DDCA2D */ | ||
diff --git a/verb.cpp b/verb.cpp new file mode 100644 index 0000000..23f7c92 --- /dev/null +++ b/verb.cpp | |||
@@ -0,0 +1,193 @@ | |||
1 | #include "verbly.h" | ||
2 | |||
3 | namespace verbly { | ||
4 | |||
5 | verb::verb(const data& _data, int _id) : word(_data, _id) | ||
6 | { | ||
7 | |||
8 | } | ||
9 | |||
10 | std::string verb::base_form() const | ||
11 | { | ||
12 | return _infinitive; | ||
13 | } | ||
14 | |||
15 | std::string verb::infinitive_form() const | ||
16 | { | ||
17 | return _infinitive; | ||
18 | } | ||
19 | |||
20 | std::string verb::past_tense_form() const | ||
21 | { | ||
22 | return _past_tense; | ||
23 | } | ||
24 | |||
25 | std::string verb::past_participle_form() const | ||
26 | { | ||
27 | return _past_participle; | ||
28 | } | ||
29 | |||
30 | std::string verb::ing_form() const | ||
31 | { | ||
32 | return _ing_form; | ||
33 | } | ||
34 | |||
35 | std::string verb::s_form() const | ||
36 | { | ||
37 | return _s_form; | ||
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 | |||
81 | return *this; | ||
82 | } | ||
83 | |||
84 | verb_query& verb_query::has_pronunciation(bool _has_prn) | ||
85 | { | ||
86 | this->_has_prn = _has_prn; | ||
87 | |||
88 | return *this; | ||
89 | } | ||
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 | |||
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 | }; | ||
diff --git a/verb.h b/verb.h index 42c8dc2..7cc87e2 100644 --- a/verb.h +++ b/verb.h | |||
@@ -1,8 +1,6 @@ | |||
1 | #ifndef VERB_H_BCC929AD | 1 | #ifndef VERB_H_BCC929AD |
2 | #define VERB_H_BCC929AD | 2 | #define VERB_H_BCC929AD |
3 | 3 | ||
4 | #include <vector> | ||
5 | |||
6 | namespace verbly { | 4 | namespace verbly { |
7 | 5 | ||
8 | /*class frame_part { | 6 | /*class frame_part { |
@@ -26,42 +24,50 @@ namespace verbly { | |||
26 | } | 24 | } |
27 | };*/ | 25 | };*/ |
28 | 26 | ||
29 | enum class conjugation { | 27 | class verb : public word { |
30 | present_participle, | ||
31 | past_participle, | ||
32 | infinitive | ||
33 | }; | ||
34 | |||
35 | class verb { | ||
36 | private: | 28 | private: |
37 | int id; | 29 | std::string _infinitive; |
30 | std::string _past_tense; | ||
31 | std::string _past_participle; | ||
32 | std::string _ing_form; | ||
33 | std::string _s_form; | ||
34 | |||
35 | friend class verb_query; | ||
38 | 36 | ||
39 | public: | 37 | public: |
40 | verb(int id) : id(id) | 38 | verb(const data& _data, int _id); |
41 | { | ||
42 | |||
43 | } | ||
44 | 39 | ||
45 | std::string infinitive; | 40 | std::string base_form() const; |
46 | std::string past_tense; | 41 | std::string infinitive_form() const; |
47 | std::string past_participle; | 42 | std::string past_tense_form() const; |
48 | std::string ing_form; | 43 | std::string past_participle_form() const; |
49 | std::string s_form; | 44 | std::string ing_form() const; |
50 | //std::vector<frame> frames; | 45 | std::string s_form() const; |
46 | }; | ||
47 | |||
48 | class verb_query { | ||
49 | public: | ||
50 | verb_query(const data& _data); | ||
51 | 51 | ||
52 | std::string conjugate(conjugation infl) const | 52 | verb_query& limit(int _limit); |
53 | { | 53 | verb_query& random(bool _random); |
54 | switch (infl) | 54 | verb_query& except(const verb& _word); |
55 | { | 55 | verb_query& rhymes_with(const word& _word); |
56 | case conjugation::infinitive: return infinitive; | 56 | verb_query& has_pronunciation(bool _has_prn); |
57 | case conjugation::past_participle: return past_participle; | 57 | |
58 | case conjugation::present_participle: return ing_form; | 58 | std::list<verb> run() const; |
59 | } | 59 | |
60 | } | 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; | ||
61 | }; | 69 | }; |
62 | 70 | ||
63 | }; | 71 | }; |
64 | 72 | ||
65 | #include "token.h" | ||
66 | |||
67 | #endif /* end of include guard: VERB_H_BCC929AD */ | 73 | #endif /* end of include guard: VERB_H_BCC929AD */ |
diff --git a/verbly.h b/verbly.h index 44fd3a8..b9f5367 100644 --- a/verbly.h +++ b/verbly.h | |||
@@ -2,10 +2,13 @@ | |||
2 | #define VERBLY_H_5B39CE50 | 2 | #define VERBLY_H_5B39CE50 |
3 | 3 | ||
4 | #include "c++14.h" | 4 | #include "c++14.h" |
5 | #include "util.h" | ||
5 | #include "token.h" | 6 | #include "token.h" |
7 | #include "data.h" | ||
8 | #include "word.h" | ||
6 | #include "verb.h" | 9 | #include "verb.h" |
7 | #include "adjective.h" | ||
8 | #include "adverb.h" | 10 | #include "adverb.h" |
9 | #include "data.h" | 11 | #include "adjective.h" |
12 | #include "noun.h" | ||
10 | 13 | ||
11 | #endif /* end of include guard: VERBLY_H_5B39CE50 */ | 14 | #endif /* end of include guard: VERBLY_H_5B39CE50 */ |
diff --git a/word.cpp b/word.cpp new file mode 100644 index 0000000..c50e7d3 --- /dev/null +++ b/word.cpp | |||
@@ -0,0 +1,32 @@ | |||
1 | #include "verbly.h" | ||
2 | |||
3 | namespace verbly { | ||
4 | |||
5 | word::word(const data& _data, int _id) : _data(_data), _id(_id) | ||
6 | { | ||
7 | |||
8 | } | ||
9 | |||
10 | std::list<std::string> word::rhyme_phonemes() const | ||
11 | { | ||
12 | std::list<std::string> result; | ||
13 | |||
14 | for (auto pronunciation : pronunciations) | ||
15 | { | ||
16 | auto phemstrt = std::find_if(std::begin(pronunciation), std::end(pronunciation), [] (std::string phoneme) { | ||
17 | return phoneme.find("1") != std::string::npos; | ||
18 | }); | ||
19 | |||
20 | std::stringstream rhymer; | ||
21 | for (auto it = phemstrt; it != std::end(pronunciation); it++) | ||
22 | { | ||
23 | rhymer << " " << *it; | ||
24 | } | ||
25 | |||
26 | result.push_back(rhymer.str()); | ||
27 | } | ||
28 | |||
29 | return result; | ||
30 | } | ||
31 | |||
32 | }; | ||
diff --git a/word.h b/word.h new file mode 100644 index 0000000..23ddb2b --- /dev/null +++ b/word.h | |||
@@ -0,0 +1,35 @@ | |||
1 | #ifndef WORD_H_8FC89498 | ||
2 | #define WORD_H_8FC89498 | ||
3 | |||
4 | namespace verbly { | ||
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 { | ||
14 | protected: | ||
15 | const data& _data; | ||
16 | int _id; | ||
17 | |||
18 | std::list<std::list<std::string>> pronunciations; | ||
19 | |||
20 | word(const data& _data, int _id); | ||
21 | |||
22 | friend class adjective_query; | ||
23 | friend class verb_query; | ||
24 | friend class noun_query; | ||
25 | friend class adverb_query; | ||
26 | |||
27 | public: | ||
28 | virtual std::string base_form() const = 0; | ||
29 | |||
30 | std::list<std::string> rhyme_phonemes() const; | ||
31 | }; | ||
32 | |||
33 | }; | ||
34 | |||
35 | #endif /* end of include guard: WORD_H_8FC89498 */ | ||