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