about summary refs log tree commit diff stats
path: root/verbly/adjective.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'verbly/adjective.cpp')
-rw-r--r--verbly/adjective.cpp586
1 files changed, 586 insertions, 0 deletions
diff --git a/verbly/adjective.cpp b/verbly/adjective.cpp new file mode 100644 index 0000000..0f4087f --- /dev/null +++ b/verbly/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};