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