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