summary refs log tree commit diff stats
diff options
context:
space:
mode:
-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 */