summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2016-03-16 21:35:35 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2016-03-16 21:35:35 -0400
commitdc210ee6eba3b1d173808bd858113f6abd90bff1 (patch)
treea28d2fce73455eecb87449fc1964c883aef61cd5 /lib
parentae5f75965f8202c8478622763a27ef1848a8ed1a (diff)
downloadverbly-dc210ee6eba3b1d173808bd858113f6abd90bff1.tar.gz
verbly-dc210ee6eba3b1d173808bd858113f6abd90bff1.tar.bz2
verbly-dc210ee6eba3b1d173808bd858113f6abd90bff1.zip
Added word derivational relationships (kind of eh at the moment) and moved verbly into its own directory
Diffstat (limited to 'lib')
-rw-r--r--lib/adjective.cpp690
-rw-r--r--lib/adjective.h143
-rw-r--r--lib/adverb.cpp468
-rw-r--r--lib/adverb.h95
-rw-r--r--lib/c++14.h35
-rw-r--r--lib/data.cpp50
-rw-r--r--lib/data.h49
-rw-r--r--lib/noun.cpp1032
-rw-r--r--lib/noun.h183
-rw-r--r--lib/token.cpp53
-rw-r--r--lib/token.h313
-rw-r--r--lib/util.h53
-rw-r--r--lib/verb.cpp193
-rw-r--r--lib/verb.h73
-rw-r--r--lib/verbly.h14
-rw-r--r--lib/word.cpp32
-rw-r--r--lib/word.h35
17 files changed, 3511 insertions, 0 deletions
diff --git a/lib/adjective.cpp b/lib/adjective.cpp new file mode 100644 index 0000000..b2b53e4 --- /dev/null +++ b/lib/adjective.cpp
@@ -0,0 +1,690 @@
1#include "verbly.h"
2
3namespace 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 adjective_query& adjective_query::derived_from(const word& _w)
265 {
266 if (dynamic_cast<const adjective*>(&_w) != nullptr)
267 {
268 _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
269 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
270 {
271 _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
272 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
273 {
274 _derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
275 }
276
277 return *this;
278 }
279
280 adjective_query& adjective_query::not_derived_from(const word& _w)
281 {
282 if (dynamic_cast<const adjective*>(&_w) != nullptr)
283 {
284 _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
285 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
286 {
287 _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
288 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
289 {
290 _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
291 }
292
293 return *this;
294 }
295
296 std::list<adjective> adjective_query::run() const
297 {
298 std::stringstream construct;
299 construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives";
300 std::list<std::string> conditions;
301
302 if (_has_prn)
303 {
304 conditions.push_back("adjective_id IN (SELECT adjective_id FROM adjective_pronunciations)");
305 }
306
307 if (!_rhymes.empty())
308 {
309 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN");
310 std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
311 conditions.push_back(cond);
312 }
313
314 for (auto except : _except)
315 {
316 conditions.push_back("adjective_id != @EXCID");
317 }
318
319 if (_requires_comparative_form)
320 {
321 conditions.push_back("comparative IS NOT NULL");
322 }
323
324 if (_requires_superlative_form)
325 {
326 conditions.push_back("superlative IS NOT NULL");
327 }
328
329 if (_position != adjective::positioning::undefined)
330 {
331 switch (_position)
332 {
333 case adjective::positioning::predicate: conditions.push_back("position = 'p'"); break;
334 case adjective::positioning::attributive: conditions.push_back("position = 'a'"); break;
335 case adjective::positioning::postnominal: conditions.push_back("position = 'i'"); break;
336 }
337 }
338
339 if (_is_variant)
340 {
341 conditions.push_back("adjective_id IN (SELECT adjective_id FROM variation)");
342 }
343
344 if (!_variant_of.empty())
345 {
346 std::list<std::string> clauses(_variant_of.size(), "noun_id = @ATTRID");
347 std::string cond = "adjective_id IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
348 conditions.push_back(cond);
349 }
350
351 if (!_not_variant_of.empty())
352 {
353 std::list<std::string> clauses(_not_variant_of.size(), "noun_id = @NATTRID");
354 std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
355 conditions.push_back(cond);
356 }
357
358 if (_is_antonymic)
359 {
360 conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy)");
361 }
362
363 if (!_antonym_of.empty())
364 {
365 std::list<std::string> clauses(_antonym_of.size(), "adjective_1_id = @ANTID");
366 std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
367 conditions.push_back(cond);
368 }
369
370 if (!_not_antonym_of.empty())
371 {
372 std::list<std::string> clauses(_not_antonym_of.size(), "adjective_1_id = @NANTID");
373 std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
374 conditions.push_back(cond);
375 }
376
377 if (_is_synonymic)
378 {
379 conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy)");
380 }
381
382 if (!_synonym_of.empty())
383 {
384 std::list<std::string> clauses(_synonym_of.size(), "adjective_1_id = @SYNID");
385 std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
386 conditions.push_back(cond);
387 }
388
389 if (!_not_synonym_of.empty())
390 {
391 std::list<std::string> clauses(_not_synonym_of.size(), "adjective_1_id = @NSYNID");
392 std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
393 conditions.push_back(cond);
394 }
395
396 if (_is_generalization)
397 {
398 conditions.push_back("adjective_id IN (SELECT general_id FROM specification)");
399 }
400
401 if (!_generalization_of.empty())
402 {
403 std::list<std::string> clauses(_generalization_of.size(), "specific_id = @SPECID");
404 std::string cond = "adjective_id IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
405 conditions.push_back(cond);
406 }
407
408 if (!_not_generalization_of.empty())
409 {
410 std::list<std::string> clauses(_not_generalization_of.size(), "specific_id = @NSPECID");
411 std::string cond = "adjective_id NOT IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
412 conditions.push_back(cond);
413 }
414
415 if (_is_specification)
416 {
417 conditions.push_back("adjective_id IN (SELECT specific_id FROM specification)");
418 }
419
420 if (!_specification_of.empty())
421 {
422 std::list<std::string> clauses(_specification_of.size(), "general_id = @GENID");
423 std::string cond = "adjective_id IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
424 conditions.push_back(cond);
425 }
426
427 if (!_not_specification_of.empty())
428 {
429 std::list<std::string> clauses(_not_specification_of.size(), "general_id = @NGENID");
430 std::string cond = "adjective_id NOT IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
431 conditions.push_back(cond);
432 }
433
434 if (_is_pertainymic)
435 {
436 conditions.push_back("adjective_id IN (SELECT pertainym_id FROM pertainymy)");
437 }
438
439 if (!_pertainym_of.empty())
440 {
441 std::list<std::string> clauses(_pertainym_of.size(), "noun_id = @APERID");
442 std::string cond = "adjective_id IN (SELECT pertainym_id FROM pertainymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
443 conditions.push_back(cond);
444 }
445
446 if (_is_mannernymic)
447 {
448 conditions.push_back("adjective_id IN (SELECT adjective_id FROM mannernymy)");
449 }
450
451 if (!_anti_mannernym_of.empty())
452 {
453 std::list<std::string> clauses(_anti_mannernym_of.size(), "mannernym_id = @MANID");
454 std::string cond = "adjective_id IN (SELECT adjective_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
455 conditions.push_back(cond);
456 }
457
458 if (!_derived_from_adjective.empty())
459 {
460 std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_2_id = @DERADJ");
461 std::string cond = "adjective_id IN (SELECT adjective_1_id FROM adjective_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
462 conditions.push_back(cond);
463 }
464
465 if (!_not_derived_from_adjective.empty())
466 {
467 std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_2_id = @NDERADJ");
468 std::string cond = "adjective_id NOT IN (SELECT adjective_1_id FROM adjective_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
469 conditions.push_back(cond);
470 }
471
472 if (!_derived_from_adverb.empty())
473 {
474 std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_id = @DERADV");
475 std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
476 conditions.push_back(cond);
477 }
478
479 if (!_not_derived_from_adverb.empty())
480 {
481 std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_id = @NDERADV");
482 std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
483 conditions.push_back(cond);
484 }
485
486 if (!_derived_from_noun.empty())
487 {
488 std::list<std::string> clauses(_derived_from_noun.size(), "noun_id = @DERN");
489 std::string cond = "adjective_id IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
490 conditions.push_back(cond);
491 }
492
493 if (!_not_derived_from_noun.empty())
494 {
495 std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_id = @NDERN");
496 std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
497 conditions.push_back(cond);
498 }
499
500 if (!conditions.empty())
501 {
502 construct << " WHERE ";
503 construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND ");
504 }
505
506 if (_random)
507 {
508 construct << " ORDER BY RANDOM()";
509 }
510
511 if (_limit != unlimited)
512 {
513 construct << " LIMIT " << _limit;
514 }
515
516 sqlite3_stmt* ppstmt;
517 std::string query = construct.str();
518 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
519 {
520 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
521 }
522
523 if (!_rhymes.empty())
524 {
525 int i = 0;
526 for (auto rhyme : _rhymes)
527 {
528 std::string rhymer = "%" + rhyme;
529 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC);
530
531 i++;
532 }
533 }
534
535 for (auto except : _except)
536 {
537 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
538 }
539
540 for (auto attribute : _variant_of)
541 {
542 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id);
543 }
544
545 for (auto attribute : _not_variant_of)
546 {
547 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NATTRID"), attribute._id);
548 }
549
550 for (auto antonym : _antonym_of)
551 {
552 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id);
553 }
554
555 for (auto antonym : _not_antonym_of)
556 {
557 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id);
558 }
559
560 for (auto synonym : _synonym_of)
561 {
562 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id);
563 }
564
565 for (auto synonym : _not_synonym_of)
566 {
567 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id);
568 }
569
570 for (auto specific : _generalization_of)
571 {
572 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SPECID"), specific._id);
573 }
574
575 for (auto specific : _not_generalization_of)
576 {
577 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSPECID"), specific._id);
578 }
579
580 for (auto general : _specification_of)
581 {
582 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GENID"), general._id);
583 }
584
585 for (auto general : _not_specification_of)
586 {
587 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NGENID"), general._id);
588 }
589
590 for (auto n : _pertainym_of)
591 {
592 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@APERID"), n._id);
593 }
594
595 for (auto mannernym : _anti_mannernym_of)
596 {
597 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MANID"), mannernym._id);
598 }
599
600 for (auto adj : _derived_from_adjective)
601 {
602 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id);
603 }
604
605 for (auto adj : _not_derived_from_adjective)
606 {
607 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id);
608 }
609
610 for (auto adv : _derived_from_adverb)
611 {
612 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id);
613 }
614
615 for (auto adv : _not_derived_from_adverb)
616 {
617 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id);
618 }
619
620 for (auto n : _derived_from_noun)
621 {
622 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id);
623 }
624
625 for (auto n : _not_derived_from_noun)
626 {
627 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id);
628 }
629
630 std::list<adjective> output;
631 while (sqlite3_step(ppstmt) == SQLITE_ROW)
632 {
633 adjective tnc {_data, sqlite3_column_int(ppstmt, 0)};
634 tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1)));
635
636 if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)
637 {
638 tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2)));
639 }
640
641 if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL)
642 {
643 tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3)));
644 }
645
646 if (sqlite3_column_type(ppstmt, 4) != SQLITE_NULL)
647 {
648 std::string adjpos(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 4)));
649 if (adjpos == "p")
650 {
651 tnc._position = adjective::positioning::predicate;
652 } else if (adjpos == "a")
653 {
654 tnc._position = adjective::positioning::attributive;
655 } else if (adjpos == "i")
656 {
657 tnc._position = adjective::positioning::postnominal;
658 }
659 }
660
661 output.push_back(tnc);
662 }
663
664 sqlite3_finalize(ppstmt);
665
666 for (auto& adjective : output)
667 {
668 query = "SELECT pronunciation FROM adjective_pronunciations WHERE adjective_id = ?";
669 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
670 {
671 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
672 }
673
674 sqlite3_bind_int(ppstmt, 1, adjective._id);
675
676 while (sqlite3_step(ppstmt) == SQLITE_ROW)
677 {
678 std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0)));
679 auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " ");
680
681 adjective.pronunciations.push_back(phonemes);
682 }
683
684 sqlite3_finalize(ppstmt);
685 }
686
687 return output;
688 }
689
690};
diff --git a/lib/adjective.h b/lib/adjective.h new file mode 100644 index 0000000..3dcab9b --- /dev/null +++ b/lib/adjective.h
@@ -0,0 +1,143 @@
1#ifndef ADJECTIVE_H_87B3FB75
2#define ADJECTIVE_H_87B3FB75
3
4namespace verbly {
5
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
19 private:
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;
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 {
49 public:
50 adjective_query(const data& _data);
51
52 adjective_query& limit(int _limit);
53 adjective_query& random(bool _random);
54 adjective_query& except(const adjective& _word);
55 adjective_query& rhymes_with(const word& _word);
56 adjective_query& has_pronunciation(bool _has_prn);
57
58 adjective_query& requires_comparative_form(bool req);
59 adjective_query& requires_superlative_form(bool req);
60 adjective_query& position(adjective::positioning pos);
61
62 adjective_query& is_variant(bool _is_variant);
63 adjective_query& variant_of(const noun& _noun);
64 adjective_query& not_variant_of(const noun& _noun);
65
66 adjective_query& has_antonyms(bool _is_antonymic);
67 adjective_query& antonym_of(const adjective& _adj);
68 adjective_query& not_antonym_of(const adjective& _adj);
69
70 adjective_query& has_synonyms(bool _is_synonymic);
71 adjective_query& synonym_of(const adjective& _adj);
72 adjective_query& not_synonym_of(const adjective& _adj);
73
74 adjective_query& is_generalization(bool _is_generalization);
75 adjective_query& generalization_of(const adjective& _adj);
76 adjective_query& not_generalization_of(const adjective& _adj);
77
78 adjective_query& is_specification(bool _is_specification);
79 adjective_query& specification_of(const adjective& _adj);
80 adjective_query& not_specification_of(const adjective& _adj);
81
82 adjective_query& is_pertainymic(bool _is_pertainymic);
83 adjective_query& pertainym_of(const noun& _noun);
84
85 adjective_query& is_mannernymic(bool _is_mannernymic);
86 adjective_query& anti_mannernym_of(const adverb& _adv);
87
88 adjective_query& derived_from(const word& _w);
89 adjective_query& not_derived_from(const word& _w);
90
91 std::list<adjective> run() const;
92
93 const static int unlimited = -1;
94
95 protected:
96 const data& _data;
97 int _limit = unlimited;
98 bool _random = false;
99 std::list<std::string> _rhymes;
100 std::list<adjective> _except;
101 bool _has_prn = false;
102
103 bool _requires_comparative_form = false;
104 bool _requires_superlative_form = false;
105 adjective::positioning _position = adjective::positioning::undefined;
106
107 bool _is_variant = false;
108 std::list<noun> _variant_of;
109 std::list<noun> _not_variant_of;
110
111 bool _is_antonymic = false;
112 std::list<adjective> _antonym_of;
113 std::list<adjective> _not_antonym_of;
114
115 bool _is_synonymic = false;
116 std::list<adjective> _synonym_of;
117 std::list<adjective> _not_synonym_of;
118
119 bool _is_generalization = false;
120 std::list<adjective> _generalization_of;
121 std::list<adjective> _not_generalization_of;
122
123 bool _is_specification = false;
124 std::list<adjective> _specification_of;
125 std::list<adjective> _not_specification_of;
126
127 bool _is_pertainymic = false;
128 std::list<noun> _pertainym_of;
129
130 bool _is_mannernymic = false;
131 std::list<adverb> _anti_mannernym_of;
132
133 std::list<adjective> _derived_from_adjective;
134 std::list<adjective> _not_derived_from_adjective;
135 std::list<adverb> _derived_from_adverb;
136 std::list<adverb> _not_derived_from_adverb;
137 std::list<noun> _derived_from_noun;
138 std::list<noun> _not_derived_from_noun;
139 };
140
141};
142
143#endif /* end of include guard: ADJECTIVE_H_87B3FB75 */
diff --git a/lib/adverb.cpp b/lib/adverb.cpp new file mode 100644 index 0000000..8fcddad --- /dev/null +++ b/lib/adverb.cpp
@@ -0,0 +1,468 @@
1#include "verbly.h"
2
3namespace 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 adverb_query& adverb_query::derived_from(const word& _w)
172 {
173 if (dynamic_cast<const adjective*>(&_w) != nullptr)
174 {
175 _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
176 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
177 {
178 _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
179 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
180 {
181 _derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
182 }
183
184 return *this;
185 }
186
187 adverb_query& adverb_query::not_derived_from(const word& _w)
188 {
189 if (dynamic_cast<const adjective*>(&_w) != nullptr)
190 {
191 _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
192 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
193 {
194 _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
195 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
196 {
197 _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
198 }
199
200 return *this;
201 }
202
203 std::list<adverb> adverb_query::run() const
204 {
205 std::stringstream construct;
206 construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs";
207 std::list<std::string> conditions;
208
209 if (_has_prn)
210 {
211 conditions.push_back("adverb_id IN (SELECT adverb_id FROM adverb_pronunciations)");
212 }
213
214 if (!_rhymes.empty())
215 {
216 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN");
217 std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
218 conditions.push_back(cond);
219 }
220
221 for (auto except : _except)
222 {
223 conditions.push_back("adverb_id != @EXCID");
224 }
225
226 if (_requires_comparative_form)
227 {
228 conditions.push_back("comparative IS NOT NULL");
229 }
230
231 if (_requires_superlative_form)
232 {
233 conditions.push_back("superlative IS NOT NULL");
234 }
235
236 if (_has_antonyms)
237 {
238 conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)");
239 }
240
241 if (!_antonym_of.empty())
242 {
243 std::list<std::string> clauses(_antonym_of.size(), "adverb_1_id = @ANTID");
244 std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
245 conditions.push_back(cond);
246 }
247
248 if (!_not_antonym_of.empty())
249 {
250 std::list<std::string> clauses(_not_antonym_of.size(), "adverb_1_id = @NANTID");
251 std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
252 conditions.push_back(cond);
253 }
254
255 if (_has_synonyms)
256 {
257 conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy)");
258 }
259
260 if (!_synonym_of.empty())
261 {
262 std::list<std::string> clauses(_synonym_of.size(), "adverb_1_id = @SYNID");
263 std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
264 conditions.push_back(cond);
265 }
266
267 if (!_not_synonym_of.empty())
268 {
269 std::list<std::string> clauses(_not_synonym_of.size(), "adverb_1_id = @NSYNID");
270 std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
271 conditions.push_back(cond);
272 }
273
274 if (_is_mannernymic)
275 {
276 conditions.push_back("adverb_id IN (SELECT mannernym_id FROM mannernymy)");
277 }
278
279 if (!_mannernym_of.empty())
280 {
281 std::list<std::string> clauses(_mannernym_of.size(), "adjective_id = @AMANID");
282 std::string cond = "adverb_id IN (SELECT mannernym_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
283 conditions.push_back(cond);
284 }
285
286 if (!_derived_from_adjective.empty())
287 {
288 std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_id = @DERADJ");
289 std::string cond = "adverb_id IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
290 conditions.push_back(cond);
291 }
292
293 if (!_not_derived_from_adjective.empty())
294 {
295 std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_id = @NDERADJ");
296 std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
297 conditions.push_back(cond);
298 }
299
300 if (!_derived_from_adverb.empty())
301 {
302 std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_2_id = @DERADV");
303 std::string cond = "adverb_id IN (SELECT adverb_1_id FROM adverb_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
304 conditions.push_back(cond);
305 }
306
307 if (!_not_derived_from_adverb.empty())
308 {
309 std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_2_id = @NDERADV");
310 std::string cond = "adverb_id NOT IN (SELECT adverb_1_id FROM adverb_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
311 conditions.push_back(cond);
312 }
313
314 if (!_derived_from_noun.empty())
315 {
316 std::list<std::string> clauses(_derived_from_noun.size(), "noun_id = @DERN");
317 std::string cond = "adverb_id IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
318 conditions.push_back(cond);
319 }
320
321 if (!_not_derived_from_noun.empty())
322 {
323 std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_id = @NDERN");
324 std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
325 conditions.push_back(cond);
326 }
327
328 if (!conditions.empty())
329 {
330 construct << " WHERE ";
331 construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND ");
332 }
333
334 if (_random)
335 {
336 construct << " ORDER BY RANDOM()";
337 }
338
339 if (_limit != unlimited)
340 {
341 construct << " LIMIT " << _limit;
342 }
343
344 sqlite3_stmt* ppstmt;
345 std::string query = construct.str();
346 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
347 {
348 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
349 }
350
351 if (!_rhymes.empty())
352 {
353 int i = 0;
354 for (auto rhyme : _rhymes)
355 {
356 std::string rhymer = "%" + rhyme;
357 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC);
358
359 i++;
360 }
361 }
362
363 for (auto except : _except)
364 {
365 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
366 }
367
368 for (auto antonym : _antonym_of)
369 {
370 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id);
371 }
372
373 for (auto antonym : _not_antonym_of)
374 {
375 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id);
376 }
377
378 for (auto synonym : _synonym_of)
379 {
380 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id);
381 }
382
383 for (auto synonym : _not_synonym_of)
384 {
385 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id);
386 }
387
388 for (auto adj : _mannernym_of)
389 {
390 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id);
391 }
392
393 for (auto adj : _derived_from_adjective)
394 {
395 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id);
396 }
397
398 for (auto adj : _not_derived_from_adjective)
399 {
400 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id);
401 }
402
403 for (auto adv : _derived_from_adverb)
404 {
405 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id);
406 }
407
408 for (auto adv : _not_derived_from_adverb)
409 {
410 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id);
411 }
412
413 for (auto n : _derived_from_noun)
414 {
415 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id);
416 }
417
418 for (auto n : _not_derived_from_noun)
419 {
420 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id);
421 }
422
423 std::list<adverb> output;
424 while (sqlite3_step(ppstmt) == SQLITE_ROW)
425 {
426 adverb tnc {_data, sqlite3_column_int(ppstmt, 0)};
427 tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1)));
428
429 if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)
430 {
431 tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2)));
432 }
433
434 if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL)
435 {
436 tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3)));
437 }
438
439 output.push_back(tnc);
440 }
441
442 sqlite3_finalize(ppstmt);
443
444 for (auto& adverb : output)
445 {
446 query = "SELECT pronunciation FROM adverb_pronunciations WHERE adverb_id = ?";
447 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
448 {
449 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
450 }
451
452 sqlite3_bind_int(ppstmt, 1, adverb._id);
453
454 while (sqlite3_step(ppstmt) == SQLITE_ROW)
455 {
456 std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0)));
457 auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " ");
458
459 adverb.pronunciations.push_back(phonemes);
460 }
461
462 sqlite3_finalize(ppstmt);
463 }
464
465 return output;
466 }
467
468};
diff --git a/lib/adverb.h b/lib/adverb.h new file mode 100644 index 0000000..65e3c5c --- /dev/null +++ b/lib/adverb.h
@@ -0,0 +1,95 @@
1#ifndef ADVERB_H_86F8302F
2#define ADVERB_H_86F8302F
3
4namespace verbly {
5
6 class adverb : public word {
7 private:
8 std::string _base_form;
9 std::string _comparative_form;
10 std::string _superlative_form;
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 adverb_query& derived_from(const word& _w);
29 adverb_query& not_derived_from(const word& _w);
30 };
31
32 class adverb_query {
33 public:
34 adverb_query(const data& _data);
35
36 adverb_query& limit(int _limit);
37 adverb_query& random(bool _random);
38 adverb_query& except(const adverb& _word);
39 adverb_query& rhymes_with(const word& _word);
40 adverb_query& has_pronunciation(bool _has_prn);
41
42 adverb_query& requires_comparative_form(bool _arg);
43 adverb_query& requires_superlative_form(bool _arg);
44
45 adverb_query& has_antonyms(bool _arg);
46 adverb_query& antonym_of(const adverb& _adv);
47 adverb_query& not_antonym_of(const adverb& _adv);
48
49 adverb_query& has_synonyms(bool _arg);
50 adverb_query& synonym_of(const adverb& _adv);
51 adverb_query& not_synonym_of(const adverb& _adv);
52
53 adverb_query& is_mannernymic(bool _arg);
54 adverb_query& mannernym_of(const adjective& _adj);
55
56 adverb_query& derived_from(const word& _w);
57 adverb_query& not_derived_from(const word& _w);
58
59 std::list<adverb> run() const;
60
61 const static int unlimited = -1;
62
63 private:
64 const data& _data;
65 int _limit = unlimited;
66 bool _random = false;
67 std::list<std::string> _rhymes;
68 std::list<adverb> _except;
69 bool _has_prn = false;
70
71 bool _requires_comparative_form = false;
72 bool _requires_superlative_form = false;
73
74 bool _has_antonyms = false;
75 std::list<adverb> _antonym_of;
76 std::list<adverb> _not_antonym_of;
77
78 bool _has_synonyms = false;
79 std::list<adverb> _synonym_of;
80 std::list<adverb> _not_synonym_of;
81
82 bool _is_mannernymic = false;
83 std::list<adjective> _mannernym_of;
84
85 std::list<adjective> _derived_from_adjective;
86 std::list<adjective> _not_derived_from_adjective;
87 std::list<adverb> _derived_from_adverb;
88 std::list<adverb> _not_derived_from_adverb;
89 std::list<noun> _derived_from_noun;
90 std::list<noun> _not_derived_from_noun;
91 };
92
93};
94
95#endif /* end of include guard: ADVERB_H_86F8302F */
diff --git a/lib/c++14.h b/lib/c++14.h new file mode 100644 index 0000000..b3efbe2 --- /dev/null +++ b/lib/c++14.h
@@ -0,0 +1,35 @@
1#include <cstddef>
2#include <memory>
3#include <type_traits>
4#include <utility>
5
6namespace std {
7 template<class T> struct _Unique_if {
8 typedef unique_ptr<T> _Single_object;
9 };
10
11 template<class T> struct _Unique_if<T[]> {
12 typedef unique_ptr<T[]> _Unknown_bound;
13 };
14
15 template<class T, size_t N> struct _Unique_if<T[N]> {
16 typedef void _Known_bound;
17 };
18
19 template<class T, class... Args>
20 typename _Unique_if<T>::_Single_object
21 make_unique(Args&&... args) {
22 return unique_ptr<T>(new T(std::forward<Args>(args)...));
23 }
24
25 template<class T>
26 typename _Unique_if<T>::_Unknown_bound
27 make_unique(size_t n) {
28 typedef typename remove_extent<T>::type U;
29 return unique_ptr<T>(new U[n]());
30 }
31
32 template<class T, class... Args>
33 typename _Unique_if<T>::_Known_bound
34 make_unique(Args&&...) = delete;
35}
diff --git a/lib/data.cpp b/lib/data.cpp new file mode 100644 index 0000000..57a8850 --- /dev/null +++ b/lib/data.cpp
@@ -0,0 +1,50 @@
1#include "verbly.h"
2
3namespace 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/lib/data.h b/lib/data.h new file mode 100644 index 0000000..37092d7 --- /dev/null +++ b/lib/data.h
@@ -0,0 +1,49 @@
1#ifndef DATA_H_C4AEC3DD
2#define DATA_H_C4AEC3DD
3
4#include <sqlite3.h>
5#include <stdexcept>
6
7namespace verbly {
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
20 class data {
21 private:
22 sqlite3* ppdb;
23
24 friend class adjective_query;
25 friend class noun_query;
26 friend class verb_query;
27 friend class adverb_query;
28
29 public:
30 data(std::string datafile);
31
32 data(const data& other) = delete;
33 data& operator=(const data& other) = delete;
34
35 data(data&& other);
36 data& operator=(data&& other);
37
38 ~data();
39
40 verb_query verbs() const;
41 adjective_query adjectives() const;
42 adverb_query adverbs() const;
43 noun_query nouns() const;
44
45 };
46
47};
48
49#endif /* end of include guard: DATA_H_C4AEC3DD */
diff --git a/lib/noun.cpp b/lib/noun.cpp new file mode 100644 index 0000000..43fda2e --- /dev/null +++ b/lib/noun.cpp
@@ -0,0 +1,1032 @@
1#include "verbly.h"
2
3namespace 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::is_not_proper(bool _arg)
327 {
328 _is_not_proper = _arg;
329
330 return *this;
331 }
332
333 noun_query& noun_query::instance_of(const noun& _noun)
334 {
335 _instance_of.push_back(_noun);
336
337 return *this;
338 }
339
340 noun_query& noun_query::not_instance_of(const noun& _noun)
341 {
342 _not_instance_of.push_back(_noun);
343
344 return *this;
345 }
346
347 noun_query& noun_query::is_class(bool _arg)
348 {
349 _is_class = _arg;
350
351 return *this;
352 }
353
354 noun_query& noun_query::class_of(const noun& _noun)
355 {
356 _class_of.push_back(_noun);
357
358 return *this;
359 }
360
361 noun_query& noun_query::not_class_of(const noun& _noun)
362 {
363 _not_class_of.push_back(_noun);
364
365 return *this;
366 }
367
368 noun_query& noun_query::has_synonyms(bool _arg)
369 {
370 _has_synonyms = _arg;
371
372 return *this;
373 }
374
375 noun_query& noun_query::synonym_of(const noun& _noun)
376 {
377 _synonym_of.push_back(_noun);
378
379 return *this;
380 }
381
382 noun_query& noun_query::not_synonym_of(const noun& _noun)
383 {
384 _not_synonym_of.push_back(_noun);
385
386 return *this;
387 }
388
389 noun_query& noun_query::has_antonyms(bool _arg)
390 {
391 _has_antonyms = _arg;
392
393 return *this;
394 }
395
396 noun_query& noun_query::antonym_of(const noun& _noun)
397 {
398 _antonym_of.push_back(_noun);
399
400 return *this;
401 }
402
403 noun_query& noun_query::not_antonym_of(const noun& _noun)
404 {
405 _not_antonym_of.push_back(_noun);
406
407 return *this;
408 }
409
410 noun_query& noun_query::has_pertainym(bool _arg)
411 {
412 _has_pertainym = _arg;
413
414 return *this;
415 }
416
417 noun_query& noun_query::anti_pertainym_of(const adjective& _adj)
418 {
419 _anti_pertainym_of.push_back(_adj);
420
421 return *this;
422 }
423
424 noun_query& noun_query::is_attribute(bool _arg)
425 {
426 _is_attribute = _arg;
427
428 return *this;
429 }
430
431 noun_query& noun_query::attribute_of(const adjective& _adj)
432 {
433 _attribute_of.push_back(_adj);
434
435 return *this;
436 }
437
438 noun_query& noun_query::derived_from(const word& _w)
439 {
440 if (dynamic_cast<const adjective*>(&_w) != nullptr)
441 {
442 _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
443 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
444 {
445 _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
446 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
447 {
448 _derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
449 }
450
451 return *this;
452 }
453
454 noun_query& noun_query::not_derived_from(const word& _w)
455 {
456 if (dynamic_cast<const adjective*>(&_w) != nullptr)
457 {
458 _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
459 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
460 {
461 _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
462 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
463 {
464 _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
465 }
466
467 return *this;
468 }
469
470 std::list<noun> noun_query::run() const
471 {
472 std::stringstream construct;
473 construct << "SELECT noun_id, singular, plural FROM nouns";
474 std::list<std::string> conditions;
475
476 if (_has_prn)
477 {
478 conditions.push_back("noun_id IN (SELECT noun_id FROM noun_pronunciations)");
479 }
480
481 if (!_rhymes.empty())
482 {
483 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN");
484 std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
485 conditions.push_back(cond);
486 }
487
488 for (auto except : _except)
489 {
490 conditions.push_back("noun_id != @EXCID");
491 }
492
493 if (_is_hypernym)
494 {
495 conditions.push_back("noun_id IN (SELECT hypernym_id FROM hypernymy)");
496 }
497
498 if (!_hypernym_of.empty())
499 {
500 std::list<std::string> clauses(_hypernym_of.size(), "hyponym_id = @HYPO");
501 std::string cond = "noun_id IN (SELECT hypernym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
502 conditions.push_back(cond);
503 }
504
505 if (!_not_hypernym_of.empty())
506 {
507 std::list<std::string> clauses(_not_hypernym_of.size(), "hyponym_id = @NHYPO");
508 std::string cond = "noun_id NOT IN (SELECT hypernym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
509 conditions.push_back(cond);
510 }
511
512 if (_is_hyponym)
513 {
514 conditions.push_back("noun_id IN (SELECT hyponym_id FROM hypernymy)");
515 }
516
517 if (!_hyponym_of.empty())
518 {
519 std::list<std::string> clauses(_hyponym_of.size(), "hypernym_id = @HYPER");
520 std::string cond = "noun_id IN (SELECT hyponym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
521 conditions.push_back(cond);
522 }
523
524 if (!_not_hyponym_of.empty())
525 {
526 std::list<std::string> clauses(_not_hyponym_of.size(), "hypernym_id = @NHYPER");
527 std::string cond = "noun_id NOT IN (SELECT hyponym_id FROM hypernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
528 conditions.push_back(cond);
529 }
530
531 if (_is_part_meronym)
532 {
533 conditions.push_back("noun_id IN (SELECT meronym_id FROM part_meronymy)");
534 }
535
536 if (!_part_meronym_of.empty())
537 {
538 std::list<std::string> clauses(_part_meronym_of.size(), "holonym_id = @PHOLO");
539 std::string cond = "noun_id IN (SELECT meronym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
540 conditions.push_back(cond);
541 }
542
543 if (!_not_part_meronym_of.empty())
544 {
545 std::list<std::string> clauses(_not_part_meronym_of.size(), "holonym_id = @NPHOLO");
546 std::string cond = "noun_id NOT IN (SELECT meronym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
547 conditions.push_back(cond);
548 }
549
550 if (_is_part_holonym)
551 {
552 conditions.push_back("noun_id IN (SELECT holonym_id FROM part_meronymy)");
553 }
554
555 if (!_part_holonym_of.empty())
556 {
557 std::list<std::string> clauses(_part_holonym_of.size(), "meronym_id = @PMERO");
558 std::string cond = "noun_id IN (SELECT holonym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
559 conditions.push_back(cond);
560 }
561
562 if (!_not_part_holonym_of.empty())
563 {
564 std::list<std::string> clauses(_not_part_holonym_of.size(), "meronym_id = @NPMERO");
565 std::string cond = "noun_id NOT IN (SELECT holonym_id FROM part_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
566 conditions.push_back(cond);
567 }
568
569 if (_is_substance_meronym)
570 {
571 conditions.push_back("noun_id IN (SELECT meronym_id FROM substance_meronymy)");
572 }
573
574 if (!_substance_meronym_of.empty())
575 {
576 std::list<std::string> clauses(_substance_meronym_of.size(), "holonym_id = @SHOLO");
577 std::string cond = "noun_id IN (SELECT meronym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
578 conditions.push_back(cond);
579 }
580
581 if (!_not_substance_meronym_of.empty())
582 {
583 std::list<std::string> clauses(_not_substance_meronym_of.size(), "holonym_id = @NSHOLO");
584 std::string cond = "noun_id NOT IN (SELECT meronym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
585 conditions.push_back(cond);
586 }
587
588 if (_is_substance_holonym)
589 {
590 conditions.push_back("noun_id IN (SELECT holonym_id FROM substance_meronymy)");
591 }
592
593 if (!_substance_holonym_of.empty())
594 {
595 std::list<std::string> clauses(_substance_holonym_of.size(), "meronym_id = @SMERO");
596 std::string cond = "noun_id IN (SELECT holonym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
597 conditions.push_back(cond);
598 }
599
600 if (!_not_substance_holonym_of.empty())
601 {
602 std::list<std::string> clauses(_not_substance_holonym_of.size(), "meronym_id = @NSMERO");
603 std::string cond = "noun_id NOT IN (SELECT holonym_id FROM substance_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
604 conditions.push_back(cond);
605 }
606
607 if (_is_member_meronym)
608 {
609 conditions.push_back("noun_id IN (SELECT meronym_id FROM member_meronymy)");
610 }
611
612 if (!_member_meronym_of.empty())
613 {
614 std::list<std::string> clauses(_member_meronym_of.size(), "holonym_id = @MHOLO");
615 std::string cond = "noun_id IN (SELECT meronym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
616 conditions.push_back(cond);
617 }
618
619 if (!_not_member_meronym_of.empty())
620 {
621 std::list<std::string> clauses(_not_member_meronym_of.size(), "holonym_id = @NMHOLO");
622 std::string cond = "noun_id NOT IN (SELECT meronym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
623 conditions.push_back(cond);
624 }
625
626 if (_is_member_holonym)
627 {
628 conditions.push_back("noun_id IN (SELECT holonym_id FROM member_meronym)");
629 }
630
631 if (!_member_holonym_of.empty())
632 {
633 std::list<std::string> clauses(_member_holonym_of.size(), "meronym_id = @MMERO");
634 std::string cond = "noun_id IN (SELECT holonym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
635 conditions.push_back(cond);
636 }
637
638 if (!_not_member_holonym_of.empty())
639 {
640 std::list<std::string> clauses(_not_member_holonym_of.size(), "meronym_id = @NMMERO");
641 std::string cond = "noun_id NOT IN (SELECT holonym_id FROM member_meronymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
642 conditions.push_back(cond);
643 }
644
645 if (_is_proper)
646 {
647 conditions.push_back("noun_id IN (SELECT instance_id FROM instantiation)");
648 }
649
650 if (_is_not_proper)
651 {
652 conditions.push_back("noun_id NOT IN (SELECT instance_id FROM instantiation)");
653 }
654
655 if (!_instance_of.empty())
656 {
657 std::list<std::string> clauses(_instance_of.size(), "class_id = @CLSID");
658 std::string cond = "noun_id IN (SELECT instance_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
659 conditions.push_back(cond);
660 }
661
662 if (!_not_instance_of.empty())
663 {
664 std::list<std::string> clauses(_not_instance_of.size(), "class_id = @NCLSID");
665 std::string cond = "noun_id NOT IN (SELECT instance_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
666 conditions.push_back(cond);
667 }
668
669 if (_is_class)
670 {
671 conditions.push_back("noun_id IN (SELECT class_id FROM instantiation)");
672 }
673
674 if (!_class_of.empty())
675 {
676 std::list<std::string> clauses(_class_of.size(), "instance_id = @INSID");
677 std::string cond = "noun_id IN (SELECT class_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
678 conditions.push_back(cond);
679 }
680
681 if (!_not_class_of.empty())
682 {
683 std::list<std::string> clauses(_not_class_of.size(), "instance_id = @NINSID");
684 std::string cond = "noun_id NOT IN (SELECT class_id FROM instantiation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
685 conditions.push_back(cond);
686 }
687
688 if (_has_synonyms)
689 {
690 conditions.push_back("noun_id IN (SELECT adjective_2_id FROM adjective_synonymy)");
691 }
692
693 if (!_synonym_of.empty())
694 {
695 std::list<std::string> clauses(_synonym_of.size(), "adjective_1_id = @SYNID");
696 std::string cond = "noun_id IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
697 conditions.push_back(cond);
698 }
699
700 if (!_not_synonym_of.empty())
701 {
702 std::list<std::string> clauses(_not_synonym_of.size(), "adjective_1_id = @NSYNID");
703 std::string cond = "noun_id NOT IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
704 conditions.push_back(cond);
705 }
706
707 if (_has_antonyms)
708 {
709 conditions.push_back("noun_id IN (SELECT adjective_2_id FROM adjective_antonymy)");
710 }
711
712 if (!_antonym_of.empty())
713 {
714 std::list<std::string> clauses(_antonym_of.size(), "adjective_1_id = @ANTID");
715 std::string cond = "noun_id IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
716 conditions.push_back(cond);
717 }
718
719 if (!_not_antonym_of.empty())
720 {
721 std::list<std::string> clauses(_not_antonym_of.size(), "adjective_1_id = @NANTID");
722 std::string cond = "noun_id NOT IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
723 conditions.push_back(cond);
724 }
725
726 if (_has_pertainym)
727 {
728 conditions.push_back("noun_id IN (SELECT noun_id FROM pertainymy)");
729 }
730
731 if (!_anti_pertainym_of.empty())
732 {
733 std::list<std::string> clauses(_anti_pertainym_of.size(), "pertainym_id = @PERID");
734 std::string cond = "noun_id IN (SELECT noun_id FROM pertainymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
735 conditions.push_back(cond);
736 }
737
738 if (_is_attribute)
739 {
740 conditions.push_back("noun_id IN (SELECT noun_id FROM variation)");
741 }
742
743 if (!_attribute_of.empty())
744 {
745 std::list<std::string> clauses(_attribute_of.size(), "adjective_id = @VALID");
746 std::string cond = "noun_id IN (SELECT noun_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
747 conditions.push_back(cond);
748 }
749
750 if (!_derived_from_adjective.empty())
751 {
752 std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_id = @DERADJ");
753 std::string cond = "noun_id IN (SELECT noun_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
754 conditions.push_back(cond);
755 }
756
757 if (!_not_derived_from_adjective.empty())
758 {
759 std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_id = @NDERADJ");
760 std::string cond = "noun_id NOT IN (SELECT noun_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
761 conditions.push_back(cond);
762 }
763
764 if (!_derived_from_adverb.empty())
765 {
766 std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_id = @DERADV");
767 std::string cond = "noun_id IN (SELECT noun_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
768 conditions.push_back(cond);
769 }
770
771 if (!_not_derived_from_adverb.empty())
772 {
773 std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_id = @NDERADV");
774 std::string cond = "noun_id NOT IN (SELECT noun_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
775 conditions.push_back(cond);
776 }
777
778 if (!_derived_from_noun.empty())
779 {
780 std::list<std::string> clauses(_derived_from_noun.size(), "noun_2_id = @DERN");
781 std::string cond = "noun_id IN (SELECT noun_1_id FROM noun_noun_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
782 conditions.push_back(cond);
783 }
784
785 if (!_not_derived_from_noun.empty())
786 {
787 std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_2_id = @NDERN");
788 std::string cond = "noun_id NOT IN (SELECT noun_1_id FROM noun_noun_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
789 conditions.push_back(cond);
790 }
791
792 if (!conditions.empty())
793 {
794 construct << " WHERE ";
795 construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND ");
796 }
797
798 if (_random)
799 {
800 construct << " ORDER BY RANDOM()";
801 }
802
803 if (_limit != unlimited)
804 {
805 construct << " LIMIT " << _limit;
806 }
807
808 sqlite3_stmt* ppstmt;
809 std::string query = construct.str();
810 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
811 {
812 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
813 }
814
815 if (!_rhymes.empty())
816 {
817 int i = 0;
818 for (auto rhyme : _rhymes)
819 {
820 std::string rhymer = "%" + rhyme;
821 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC);
822
823 i++;
824 }
825 }
826
827 for (auto except : _except)
828 {
829 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
830 }
831
832 for (auto hyponym : _hypernym_of)
833 {
834 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPO"), hyponym._id);
835 }
836
837 for (auto hyponym : _not_hypernym_of)
838 {
839 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NHYPO"), hyponym._id);
840 }
841
842 for (auto hypernym : _hyponym_of)
843 {
844 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPER"), hypernym._id);
845 }
846
847 for (auto hypernym : _not_hyponym_of)
848 {
849 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NHYPER"), hypernym._id);
850 }
851
852 for (auto holonym : _part_meronym_of)
853 {
854 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PHOLO"), holonym._id);
855 }
856
857 for (auto holonym : _not_part_meronym_of)
858 {
859 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NPHOLO"), holonym._id);
860 }
861
862 for (auto meronym : _part_holonym_of)
863 {
864 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PMERO"), meronym._id);
865 }
866
867 for (auto meronym : _not_part_holonym_of)
868 {
869 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NPMERO"), meronym._id);
870 }
871
872 for (auto holonym : _substance_meronym_of)
873 {
874 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SHOLO"), holonym._id);
875 }
876
877 for (auto holonym : _not_substance_meronym_of)
878 {
879 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSHOLO"), holonym._id);
880 }
881
882 for (auto meronym : _substance_holonym_of)
883 {
884 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SMERO"), meronym._id);
885 }
886
887 for (auto meronym : _not_substance_holonym_of)
888 {
889 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSMERO"), meronym._id);
890 }
891
892 for (auto holonym : _member_meronym_of)
893 {
894 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MHOLO"), holonym._id);
895 }
896
897 for (auto holonym : _not_member_meronym_of)
898 {
899 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NMHOLO"), holonym._id);
900 }
901
902 for (auto meronym : _member_holonym_of)
903 {
904 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MMERO"), meronym._id);
905 }
906
907 for (auto meronym : _not_member_holonym_of)
908 {
909 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NMMERO"), meronym._id);
910 }
911
912 for (auto cls : _instance_of)
913 {
914 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@CLSID"), cls._id);
915 }
916
917 for (auto cls : _not_instance_of)
918 {
919 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NCLSID"), cls._id);
920 }
921
922 for (auto inst : _class_of)
923 {
924 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@INSID"), inst._id);
925 }
926
927 for (auto inst : _not_class_of)
928 {
929 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NINSID"), inst._id);
930 }
931
932 for (auto synonym : _synonym_of)
933 {
934 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id);
935 }
936
937 for (auto synonym : _not_synonym_of)
938 {
939 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id);
940 }
941
942 for (auto antonym : _antonym_of)
943 {
944 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id);
945 }
946
947 for (auto antonym : _not_antonym_of)
948 {
949 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id);
950 }
951
952 for (auto pertainym : _anti_pertainym_of)
953 {
954 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PERID"), pertainym._id);
955 }
956
957 for (auto value : _attribute_of)
958 {
959 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VALID"), value._id);
960 }
961
962 for (auto adj : _derived_from_adjective)
963 {
964 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id);
965 }
966
967 for (auto adj : _not_derived_from_adjective)
968 {
969 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id);
970 }
971
972 for (auto adv : _derived_from_adverb)
973 {
974 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id);
975 }
976
977 for (auto adv : _not_derived_from_adverb)
978 {
979 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id);
980 }
981
982 for (auto n : _derived_from_noun)
983 {
984 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id);
985 }
986
987 for (auto n : _not_derived_from_noun)
988 {
989 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id);
990 }
991
992 std::list<noun> output;
993 while (sqlite3_step(ppstmt) == SQLITE_ROW)
994 {
995 noun tnc {_data, sqlite3_column_int(ppstmt, 0)};
996 tnc._singular = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1)));
997
998 if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)
999 {
1000 tnc._plural = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2)));
1001 }
1002
1003 output.push_back(tnc);
1004 }
1005
1006 sqlite3_finalize(ppstmt);
1007
1008 for (auto& noun : output)
1009 {
1010 query = "SELECT pronunciation FROM noun_pronunciations WHERE noun_id = ?";
1011 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
1012 {
1013 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
1014 }
1015
1016 sqlite3_bind_int(ppstmt, 1, noun._id);
1017
1018 while (sqlite3_step(ppstmt) == SQLITE_ROW)
1019 {
1020 std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0)));
1021 auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " ");
1022
1023 noun.pronunciations.push_back(phonemes);
1024 }
1025
1026 sqlite3_finalize(ppstmt);
1027 }
1028
1029 return output;
1030 }
1031
1032};
diff --git a/lib/noun.h b/lib/noun.h new file mode 100644 index 0000000..da76866 --- /dev/null +++ b/lib/noun.h
@@ -0,0 +1,183 @@
1#ifndef NOUN_H_24A03C83
2#define NOUN_H_24A03C83
3
4namespace 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& is_not_proper(bool _arg);
82 noun_query& instance_of(const noun& _noun);
83 noun_query& not_instance_of(const noun& _noun);
84
85 noun_query& is_class(bool _arg);
86 noun_query& class_of(const noun& _noun);
87 noun_query& not_class_of(const noun& _noun);
88
89 noun_query& has_synonyms(bool _arg);
90 noun_query& synonym_of(const noun& _noun);
91 noun_query& not_synonym_of(const noun& _noun);
92
93 noun_query& has_antonyms(bool _arg);
94 noun_query& antonym_of(const noun& _noun);
95 noun_query& not_antonym_of(const noun& _noun);
96
97 noun_query& has_pertainym(bool _arg);
98 noun_query& anti_pertainym_of(const adjective& _adj);
99
100 noun_query& is_attribute(bool _arg);
101 noun_query& attribute_of(const adjective& _adj);
102
103 noun_query& derived_from(const word& _w);
104 noun_query& not_derived_from(const word& _w);
105
106 std::list<noun> run() const;
107
108 const static int unlimited = -1;
109
110 private:
111 const data& _data;
112 int _limit = unlimited;
113 bool _random = false;
114 std::list<std::string> _rhymes;
115 std::list<noun> _except;
116 bool _has_prn = false;
117
118 bool _is_hypernym = false;
119 std::list<noun> _hypernym_of;
120 std::list<noun> _not_hypernym_of;
121
122 bool _is_hyponym = false;
123 std::list<noun> _hyponym_of;
124 std::list<noun> _not_hyponym_of;
125
126 bool _is_part_meronym = false;
127 std::list<noun> _part_meronym_of;
128 std::list<noun> _not_part_meronym_of;
129
130 bool _is_substance_meronym = false;
131 std::list<noun> _substance_meronym_of;
132 std::list<noun> _not_substance_meronym_of;
133
134 bool _is_member_meronym = false;
135 std::list<noun> _member_meronym_of;
136 std::list<noun> _not_member_meronym_of;
137
138 bool _is_part_holonym = false;
139 std::list<noun> _part_holonym_of;
140 std::list<noun> _not_part_holonym_of;
141
142 bool _is_substance_holonym = false;
143 std::list<noun> _substance_holonym_of;
144 std::list<noun> _not_substance_holonym_of;
145
146 bool _is_member_holonym = false;
147 std::list<noun> _member_holonym_of;
148 std::list<noun> _not_member_holonym_of;
149
150 bool _is_proper = false;
151 bool _is_not_proper = false;
152 std::list<noun> _instance_of;
153 std::list<noun> _not_instance_of;
154
155 bool _is_class = false;
156 std::list<noun> _class_of;
157 std::list<noun> _not_class_of;
158
159 bool _has_synonyms = false;
160 std::list<noun> _synonym_of;
161 std::list<noun> _not_synonym_of;
162
163 bool _has_antonyms = false;
164 std::list<noun> _antonym_of;
165 std::list<noun> _not_antonym_of;
166
167 bool _has_pertainym = false;
168 std::list<adjective> _anti_pertainym_of;
169
170 bool _is_attribute = false;
171 std::list<adjective> _attribute_of;
172
173 std::list<adjective> _derived_from_adjective;
174 std::list<adjective> _not_derived_from_adjective;
175 std::list<adverb> _derived_from_adverb;
176 std::list<adverb> _not_derived_from_adverb;
177 std::list<noun> _derived_from_noun;
178 std::list<noun> _not_derived_from_noun;
179 };
180
181};
182
183#endif /* end of include guard: NOUN_H_24A03C83 */
diff --git a/lib/token.cpp b/lib/token.cpp new file mode 100644 index 0000000..aa8f50e --- /dev/null +++ b/lib/token.cpp
@@ -0,0 +1,53 @@
1#include "verbly.h"
2
3namespace 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/lib/token.h b/lib/token.h new file mode 100644 index 0000000..44d99cb --- /dev/null +++ b/lib/token.h
@@ -0,0 +1,313 @@
1#ifndef TOKEN_H_AD62C505
2#define TOKEN_H_AD62C505
3
4#include <string>
5#include <list>
6#include <sstream>
7
8namespace verbly {
9
10 class verb;
11
12 class selrestr {
13 };
14
15 class synrestr {
16 };
17
18 enum class fillin_type {
19 noun_phrase,
20 participle_phrase,
21 adjective,
22 adverb
23 };
24
25 class token {
26 public:
27 enum class type {
28 verb,
29 fillin,
30 string,
31 utterance
32 };
33
34 protected:
35 // General
36 type _type;
37
38 token(type _type);
39
40 public:
41 enum type token_type() const;
42
43 virtual bool complete() const = 0;
44 virtual std::string compile() const = 0;
45 virtual token* copy() const = 0;
46 };
47
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
58 private:
59 // Verb
60 const verb* _verb;
61 inflection _inflection = inflection::infinitive;
62
63 public:
64 verb_token(const class verb& _verb);
65
66 const class verb& verb() const;
67
68 verb_token& inflect(inflection infl);
69
70 bool complete() const;
71
72 std::string compile() const;
73
74 token* copy() const;
75 };
76
77 class utterance_token : public token {
78 private:
79 // Utterance
80 std::list<std::unique_ptr<token>> utterance;
81
82 public:
83 typedef std::list<std::unique_ptr<token>>::iterator iterator;
84 /*class iterator {
85 private:
86 friend class utterance_token;
87
88 std::list<std::unique_ptr<token>>::iterator it;
89
90 public:
91 iterator(std::list<std::unique_ptr<token>>::iterator it) : it(it)
92 {
93
94 }
95
96 iterator& operator++()
97 {
98 ++it;
99 return *this;
100 }
101
102 iterator& operator--()
103 {
104 --it;
105 return *this;
106 }
107
108 bool operator==(const iterator& other) const
109 {
110 return it == other.it;
111 }
112
113 bool operator!=(const iterator& other) const
114 {
115 return it != other.it;
116 }
117
118 token& operator*()
119 {
120 return **it;
121 }
122
123 token& operator->()
124 {
125 return **it;
126 }
127 };*/
128
129 utterance_token(std::initializer_list<token*> tkns) : token(token::type::utterance)
130 {
131 for (auto tkn : tkns)
132 {
133 utterance.push_back(std::unique_ptr<token>(tkn));
134 }
135 }
136
137 utterance_token(const utterance_token& other) : token(token::type::utterance)
138 {
139 for (auto& tkn : other.utterance)
140 {
141 utterance.push_back(std::unique_ptr<token>(tkn->copy()));
142 }
143 }
144
145 utterance_token(utterance_token&& other) : token(token::type::utterance), utterance(std::move(other.utterance))
146 {
147
148 }
149
150 utterance_token& operator=(const utterance_token& other)
151 {
152 utterance.clear();
153
154 for (auto& tkn : other.utterance)
155 {
156 utterance.push_back(std::unique_ptr<token>(tkn->copy()));
157 }
158
159 return *this;
160 }
161
162 utterance_token& operator=(utterance_token&& other)
163 {
164 utterance = std::move(other.utterance);
165
166 return *this;
167 }
168
169 iterator begin()
170 {
171 return std::begin(utterance);
172 }
173
174 iterator end()
175 {
176 return std::end(utterance);
177 }
178
179 void erase(iterator it)
180 {
181 utterance.erase(it);
182 }
183
184 bool complete() const
185 {
186 return std::all_of(std::begin(utterance), std::end(utterance), [] (const std::unique_ptr<token>& tkn) {
187 return tkn->complete();
188 });
189 }
190
191 std::string compile() const
192 {
193 std::stringstream result;
194 for (auto& t : utterance)
195 {
196 if (t->complete())
197 {
198 result << t->compile() << " ";
199 } else {
200 return "Could not compile!";
201 }
202 }
203
204 std::string output = result.str();
205 if (output != "")
206 {
207 output.pop_back();
208 }
209
210 return output;
211 }
212
213 token* copy() const
214 {
215 return new utterance_token(*this);
216 }
217 };
218
219 class fillin_token : public token {
220 private:
221 // Fillin
222 std::string m_theme;
223 fillin_type m_fillin_type;
224
225 public:
226 fillin_token(fillin_type ft) : token(token::type::fillin), m_fillin_type(ft)
227 {
228
229 }
230
231/* void synrestrs(std::initializer_list<synrestr> ins)
232 {
233 m_synrestrs = std::set<synrestr>(ins);
234 }
235
236 std::set<synrestr>& synrestrs()
237 {
238 return m_synrestrs;
239 }
240
241 void selrestrs(std::initializer_list<selrestr> ins)
242 {
243 m_selrestrs = std::set<selrestr>(ins);
244 }
245
246 std::set<selrestr>& selrestrs()
247 {
248 return m_selrestrs;
249 }*/
250
251 fillin_token theme(std::string theme)
252 {
253 m_theme = theme;
254
255 return *this;
256 }
257
258 std::string& theme()
259 {
260 return m_theme;
261 }
262
263 fillin_type fillin_type() const
264 {
265 return m_fillin_type;
266 }
267
268 bool complete() const
269 {
270 return false;
271 }
272
273 std::string compile() const
274 {
275 return "";
276 }
277
278 token* copy() const
279 {
280 return new fillin_token(*this);
281 }
282 };
283
284 class string_token : public token {
285 private:
286 // String
287 std::string str;
288
289 public:
290 string_token(std::string str) : token(token::type::string), str(str)
291 {
292
293 }
294
295 bool complete() const
296 {
297 return true;
298 }
299
300 std::string compile() const
301 {
302 return str;
303 }
304
305 token* copy() const
306 {
307 return new string_token(*this);
308 }
309 };
310
311};
312
313#endif /* end of include guard: TOKEN_H_AD62C505 */
diff --git a/lib/util.h b/lib/util.h new file mode 100644 index 0000000..815b47c --- /dev/null +++ b/lib/util.h
@@ -0,0 +1,53 @@
1#ifndef UTIL_H_15DDCA2D
2#define UTIL_H_15DDCA2D
3
4#include <string>
5#include <iterator>
6#include <sstream>
7
8namespace 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/lib/verb.cpp b/lib/verb.cpp new file mode 100644 index 0000000..23f7c92 --- /dev/null +++ b/lib/verb.cpp
@@ -0,0 +1,193 @@
1#include "verbly.h"
2
3namespace 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/lib/verb.h b/lib/verb.h new file mode 100644 index 0000000..7cc87e2 --- /dev/null +++ b/lib/verb.h
@@ -0,0 +1,73 @@
1#ifndef VERB_H_BCC929AD
2#define VERB_H_BCC929AD
3
4namespace verbly {
5
6 /*class frame_part {
7
8 };
9
10 class frame {
11 private:
12 std::list<frame_part> content;
13 std::map<std::string, std::vector<std::list<frame_part>::iterator>> predicates;
14
15 public:
16 frame(std::list<frame_part> content) : content(content)
17 {
18
19 }
20
21 std::unique_ptr<token> make_utterance() const
22 {
23
24 }
25 };*/
26
27 class verb : public word {
28 private:
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;
36
37 public:
38 verb(const data& _data, int _id);
39
40 std::string base_form() const;
41 std::string infinitive_form() const;
42 std::string past_tense_form() const;
43 std::string past_participle_form() const;
44 std::string ing_form() const;
45 std::string s_form() const;
46 };
47
48 class verb_query {
49 public:
50 verb_query(const data& _data);
51
52 verb_query& limit(int _limit);
53 verb_query& random(bool _random);
54 verb_query& except(const verb& _word);
55 verb_query& rhymes_with(const word& _word);
56 verb_query& has_pronunciation(bool _has_prn);
57
58 std::list<verb> run() const;
59
60 const static int unlimited = -1;
61
62 private:
63 const data& _data;
64 int _limit = unlimited;
65 bool _random = false;
66 std::list<std::string> _rhymes;
67 std::list<verb> _except;
68 bool _has_prn = false;
69 };
70
71};
72
73#endif /* end of include guard: VERB_H_BCC929AD */
diff --git a/lib/verbly.h b/lib/verbly.h new file mode 100644 index 0000000..b9f5367 --- /dev/null +++ b/lib/verbly.h
@@ -0,0 +1,14 @@
1#ifndef VERBLY_H_5B39CE50
2#define VERBLY_H_5B39CE50
3
4#include "c++14.h"
5#include "util.h"
6#include "token.h"
7#include "data.h"
8#include "word.h"
9#include "verb.h"
10#include "adverb.h"
11#include "adjective.h"
12#include "noun.h"
13
14#endif /* end of include guard: VERBLY_H_5B39CE50 */
diff --git a/lib/word.cpp b/lib/word.cpp new file mode 100644 index 0000000..c50e7d3 --- /dev/null +++ b/lib/word.cpp
@@ -0,0 +1,32 @@
1#include "verbly.h"
2
3namespace 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/lib/word.h b/lib/word.h new file mode 100644 index 0000000..23ddb2b --- /dev/null +++ b/lib/word.h
@@ -0,0 +1,35 @@
1#ifndef WORD_H_8FC89498
2#define WORD_H_8FC89498
3
4namespace 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 */