about summary refs log tree commit diff stats
path: root/verbly
diff options
context:
space:
mode:
Diffstat (limited to 'verbly')
-rw-r--r--verbly/CMakeLists.txt9
-rw-r--r--verbly/LICENSE3
-rw-r--r--verbly/generator/CMakeLists.txt12
-rw-r--r--verbly/generator/generator.cpp1663
-rw-r--r--verbly/generator/progress.h50
-rw-r--r--verbly/generator/schema.sql252
-rw-r--r--verbly/lib/adjective.cpp690
-rw-r--r--verbly/lib/adjective.h143
-rw-r--r--verbly/lib/adverb.cpp468
-rw-r--r--verbly/lib/adverb.h95
-rw-r--r--verbly/lib/c++14.h35
-rw-r--r--verbly/lib/data.cpp50
-rw-r--r--verbly/lib/data.h49
-rw-r--r--verbly/lib/noun.cpp1032
-rw-r--r--verbly/lib/noun.h183
-rw-r--r--verbly/lib/token.cpp53
-rw-r--r--verbly/lib/token.h313
-rw-r--r--verbly/lib/util.h53
-rw-r--r--verbly/lib/verb.cpp193
-rw-r--r--verbly/lib/verb.h73
-rw-r--r--verbly/lib/verbly.h14
-rw-r--r--verbly/lib/word.cpp32
-rw-r--r--verbly/lib/word.h35
23 files changed, 0 insertions, 5500 deletions
diff --git a/verbly/CMakeLists.txt b/verbly/CMakeLists.txt deleted file mode 100644 index 5a3e526..0000000 --- a/verbly/CMakeLists.txt +++ /dev/null
@@ -1,9 +0,0 @@
1cmake_minimum_required (VERSION 2.6)
2project (verbly)
3
4find_package(PkgConfig)
5pkg_check_modules(sqlite3 sqlite3 REQUIRED)
6
7add_library(verbly lib/data.cpp lib/adjective.cpp lib/noun.cpp lib/verb.cpp lib/adverb.cpp lib/token.cpp lib/word.cpp)
8set_property(TARGET verbly PROPERTY CXX_STANDARD 11)
9set_property(TARGET verbly PROPERTY CXX_STANDARD_REQUIRED ON)
diff --git a/verbly/LICENSE b/verbly/LICENSE deleted file mode 100644 index 4c4b690..0000000 --- a/verbly/LICENSE +++ /dev/null
@@ -1,3 +0,0 @@
1WordNet Release 3.0
2
3This software and database is being provided to you, the LICENSEE, by Princeton University under the following license. By obtaining, using and/or copying this software and database, you agree that you have read, understood, and will comply with these terms and conditions.: Permission to use, copy, modify and distribute this software and database and its documentation for any purpose and without fee or royalty is hereby granted, provided that you agree to comply with the following copyright notice and statements, including the disclaimer, and that the same appear on ALL copies of the software, database and documentation, including modifications that you make for internal use or for distribution. WordNet 3.0 Copyright 2006 by Princeton University. All rights reserved. THIS SOFTWARE AND DATABASE IS PROVIDED "AS IS" AND PRINCETON UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PRINCETON UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANT- ABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE, DATABASE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. The name of Princeton University or Princeton may not be used in advertising or publicity pertaining to distribution of the software and/or database. Title to copyright in this software, database and any associated documentation shall at all times remain with Princeton University and LICENSEE agrees to preserve same. \ No newline at end of file
diff --git a/verbly/generator/CMakeLists.txt b/verbly/generator/CMakeLists.txt deleted file mode 100644 index bbc3c4f..0000000 --- a/verbly/generator/CMakeLists.txt +++ /dev/null
@@ -1,12 +0,0 @@
1cmake_minimum_required (VERSION 2.6)
2project (generator)
3
4find_package(PkgConfig)
5pkg_check_modules(sqlite3 sqlite3 REQUIRED)
6find_package(libxml2 REQUIRED)
7
8include_directories(${sqlite3_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
9add_executable(generator generator.cpp)
10set_property(TARGET generator PROPERTY CXX_STANDARD 11)
11set_property(TARGET generator PROPERTY CXX_STANDARD_REQUIRED ON)
12target_link_libraries(generator ${sqlite3_LIBRARIES} ${LIBXML2_LIBRARIES})
diff --git a/verbly/generator/generator.cpp b/verbly/generator/generator.cpp deleted file mode 100644 index faef5f7..0000000 --- a/verbly/generator/generator.cpp +++ /dev/null
@@ -1,1663 +0,0 @@
1#include <libxml/parser.h>
2#include <iostream>
3#include <dirent.h>
4#include <set>
5#include <map>
6#include <string>
7#include <vector>
8#include <fstream>
9#include <sqlite3.h>
10#include <sstream>
11#include <regex>
12#include <list>
13#include "progress.h"
14
15struct verb {
16 std::string infinitive;
17 std::string past_tense;
18 std::string past_participle;
19 std::string ing_form;
20 std::string s_form;
21};
22
23struct adjective {
24 std::string base;
25 std::string comparative;
26 std::string superlative;
27};
28
29struct noun {
30 std::string singular;
31 std::string plural;
32};
33
34struct group {
35 std::string id;
36 std::set<std::string> members;
37};
38
39std::map<std::string, group> groups;
40std::map<std::string, verb> verbs;
41std::map<std::string, adjective> adjectives;
42std::map<std::string, noun> nouns;
43std::map<int, std::map<int, int>> wn;
44std::map<std::string, std::set<std::string>> pronunciations;
45
46void print_usage()
47{
48 std::cout << "Verbly Datafile Generator" << std::endl;
49 std::cout << "-------------------------" << std::endl;
50 std::cout << "Requires exactly six arguments." << std::endl;
51 std::cout << "1. The path to a VerbNet data directory." << std::endl;
52 std::cout << "2. The path to a SemLink vnpbMappings file." << std::endl;
53 std::cout << "3. The path to an AGID infl.txt file." << std::endl;
54 std::cout << "4. The path to a WordNet prolog data directory." << std::endl;
55 std::cout << "5. The path to a CMUDICT pronunciation file." << std::endl;
56 std::cout << "6. Datafile output path." << std::endl;
57
58 exit(1);
59}
60
61void db_error(sqlite3* ppdb, std::string)
62{
63 std::cout << "Error writing to output database: " << sqlite3_errmsg(ppdb) << std::endl;
64 sqlite3_close_v2(ppdb);
65 print_usage();
66}
67
68/*
69void parse_group(xmlNodePtr top, std::string filename)
70{
71 xmlChar* key = xmlGetProp(top, (xmlChar*) "ID");
72 if (key == 0)
73 {
74 std::cout << "Bad VerbNet file format: " << filename << std::endl;
75 print_usage();
76 }
77 std::string vnid = key;
78 vnid = vnid.substr(vnid.find_first_of("-")+1);
79 xmlFree(key);
80
81 group g;
82 g.id = vnid;
83
84 for (xmlNodePtr node = top->xmlChildrenNode; node != nullptr; node = node->next)
85 {
86 if (!xmlStrcmp(node->name, (const xmlChar*) "MEMBERS"))
87 {
88 for (xmlNodePtr member = node->xmlChildrenNode; member != nullptr; member = member->next)
89 {
90 if (!xmlStrcmp(member->name, (const xmlChar*) "MEMBER"))
91 {
92 key = xmlGetProp(member, (xmlChar*) "name");
93 g.members.insert(key);
94 xmlFree(key);
95 }
96 }
97 } else if (!xmlStrcmp(node->name, (const xmlChar*) "FRAMES"))
98 {
99 for (xmlNodePtr frame = node->xmlChildrenNode; frame != nullptr; frame = frame->next)
100 {
101 if (!xmlStrcmp(frame->name, (const xmlChar*) "FRAME"))
102 {
103 for (xmlNodePtr framenode = frame->xmlChildrenNode; framenode != nullptr; framenode = framenode->next)
104 {
105
106 }
107 }
108 }
109 }
110 }
111}*/
112
113int main(int argc, char** argv)
114{
115 if (argc != 7)
116 {
117 print_usage();
118 }
119
120 /*DIR* dir;
121 if ((dir = opendir(argv[1])) == nullptr)
122 {
123 std::cout << "Invalid VerbNet data directory." << std::endl;
124
125 print_usage();
126 }
127
128 struct dirent* ent;
129 while ((ent = readdir(dir)) != nullptr)
130 {
131 std::string filename(argv[1]);
132 if (filename.back() != '/')
133 {
134 filename += '/';
135 }
136
137 filename += ent->d_name;
138 //std::cout << ent->d_name << std::endl;
139
140 if (filename.rfind(".xml") != filename.size() - 4)
141 {
142 continue;
143 }
144
145 xmlDocPtr doc = xmlParseFile(filename.c_str());
146 if (doc == nullptr)
147 {
148 std::cout << "Error opening " << filename << std::endl;
149 print_usage();
150 }
151
152 xmlNodePtr top = xmlDocGetRootElement(doc);
153 if ((top == nullptr) || (xmlStrcmp(top->name, (xmlChar*) "VNCLASS")))
154 {
155 std::cout << "Bad VerbNet file format: " << filename << std::endl;
156 print_usage();
157 }
158
159 parse_group(top, filename);
160 }
161
162 closedir(dir);*/
163
164 // Get verbs from AGID
165 std::cout << "Reading inflections..." << std::endl;
166
167 std::ifstream agidfile(argv[3]);
168 if (!agidfile.is_open())
169 {
170 std::cout << "Could not open AGID file: " << argv[3] << std::endl;
171 print_usage();
172 }
173
174 for (;;)
175 {
176 std::string line;
177 if (!getline(agidfile, line))
178 {
179 break;
180 }
181
182 if (line.back() == '\r')
183 {
184 line.pop_back();
185 }
186
187 int divider = line.find_first_of(" ");
188 std::string word = line.substr(0, divider);
189 line = line.substr(divider+1);
190 char type = line[0];
191
192 if (line[1] == '?')
193 {
194 line.erase(0, 4);
195 } else {
196 line.erase(0, 3);
197 }
198
199 std::vector<std::string> forms;
200 while (!line.empty())
201 {
202 std::string inflection;
203 if ((divider = line.find(" | ")) != std::string::npos)
204 {
205 inflection = line.substr(0, divider);
206 line = line.substr(divider + 3);
207 } else {
208 inflection = line;
209 line = "";
210 }
211
212 if ((divider = inflection.find_first_of(",?")) != std::string::npos)
213 {
214 inflection = inflection.substr(0, divider);
215 }
216
217 forms.push_back(inflection);
218 }
219
220 switch (type)
221 {
222 case 'V':
223 {
224 verb v;
225 v.infinitive = word;
226 if (forms.size() == 4)
227 {
228 v.past_tense = forms[0];
229 v.past_participle = forms[1];
230 v.ing_form = forms[2];
231 v.s_form = forms[3];
232 } else if (forms.size() == 3)
233 {
234 v.past_tense = forms[0];
235 v.past_participle = forms[0];
236 v.ing_form = forms[1];
237 v.s_form = forms[2];
238 } else if (forms.size() == 8)
239 {
240 // As of AGID 2014.08.11, this is only "to be"
241 v.past_tense = forms[0];
242 v.past_participle = forms[2];
243 v.ing_form = forms[3];
244 v.s_form = forms[4];
245 } else {
246 // Words that don't fit the cases above as of AGID 2014.08.11:
247 // - may and shall do not conjugate the way we want them to
248 // - methinks only has a past tense and is an outlier
249 // - wit has five forms, and is archaic/obscure enough that we can ignore it for now
250 std::cout << "Ignoring verb \"" << word << "\" due to non-standard number of forms." << std::endl;
251 }
252
253 verbs[word] = v;
254
255 break;
256 }
257
258 case 'A':
259 {
260 adjective adj;
261 adj.base = word;
262 if (forms.size() == 2)
263 {
264 adj.comparative = forms[0];
265 adj.superlative = forms[1];
266 } else {
267 // As of AGID 2014.08.11, this is only "only", which has only the form "onliest"
268 std::cout << "Ignoring adjective/adverb \"" << word << "\" due to non-standard number of forms." << std::endl;
269 }
270
271 adjectives[word] = adj;
272
273 break;
274 }
275
276 case 'N':
277 {
278 noun n;
279 n.singular = word;
280 if (forms.size() == 1)
281 {
282 n.plural = forms[0];
283 } else {
284 // As of AGID 2014.08.11, this is non-existent.
285 std::cout << "Ignoring noun \"" << word << "\" due to non-standard number of forms." << std::endl;
286 }
287
288 nouns[word] = n;
289
290 break;
291 }
292 }
293 }
294
295 // Pronounciations
296 std::cout << "Reading pronunciations..." << std::endl;
297
298 std::ifstream pronfile(argv[5]);
299 if (!pronfile.is_open())
300 {
301 std::cout << "Could not open CMUDICT file: " << argv[5] << std::endl;
302 print_usage();
303 }
304
305 for (;;)
306 {
307 std::string line;
308 if (!getline(pronfile, line))
309 {
310 break;
311 }
312
313 if (line.back() == '\r')
314 {
315 line.pop_back();
316 }
317
318 std::regex phoneme("([A-Z][^ \\(]*)(?:\\(\\d+\\))? ([A-Z 0-9]+)");
319 std::smatch phoneme_data;
320 if (std::regex_search(line, phoneme_data, phoneme))
321 {
322 std::string canonical(phoneme_data[1]);
323 std::transform(std::begin(canonical), std::end(canonical), std::begin(canonical), ::tolower);
324
325 pronunciations[canonical].insert(phoneme_data[2]);
326 }
327 }
328
329 // Start writing output
330 std::cout << "Writing schema..." << std::endl;
331
332 sqlite3* ppdb;
333 if (sqlite3_open_v2(argv[6], &ppdb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) != SQLITE_OK)
334 {
335 std::cout << "Error opening output datafile: " << sqlite3_errmsg(ppdb) << std::endl;
336 print_usage();
337 }
338
339 std::ifstream schemafile("schema.sql");
340 if (!schemafile.is_open())
341 {
342 std::cout << "Could not find schema file" << std::endl;
343 print_usage();
344 }
345
346 std::stringstream schemabuilder;
347 for (;;)
348 {
349 std::string line;
350 if (!getline(schemafile, line))
351 {
352 break;
353 }
354
355 if (line.back() == '\r')
356 {
357 line.pop_back();
358 }
359
360 schemabuilder << line << std::endl;
361 }
362
363 std::string schema = schemabuilder.str();
364 while (!schema.empty())
365 {
366 std::string query;
367 int divider = schema.find(";");
368 if (divider != std::string::npos)
369 {
370 query = schema.substr(0, divider+1);
371 schema = schema.substr(divider+2);
372 } else {
373 break;
374 }
375
376 sqlite3_stmt* schmstmt;
377 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &schmstmt, NULL) != SQLITE_OK)
378 {
379 db_error(ppdb, query);
380 }
381
382 if (sqlite3_step(schmstmt) != SQLITE_DONE)
383 {
384 db_error(ppdb, query);
385 }
386
387 sqlite3_finalize(schmstmt);
388 }
389
390 {
391 progress ppgs("Writing verbs...", verbs.size());
392 for (auto& mapping : verbs)
393 {
394 sqlite3_stmt* ppstmt;
395 std::string query("INSERT INTO verbs (infinitive, past_tense, past_participle, ing_form, s_form) VALUES (?, ?, ?, ?, ?)");
396 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
397 {
398 db_error(ppdb, query);
399 }
400
401 sqlite3_bind_text(ppstmt, 1, mapping.second.infinitive.c_str(), mapping.second.infinitive.length(), SQLITE_STATIC);
402 sqlite3_bind_text(ppstmt, 2, mapping.second.past_tense.c_str(), mapping.second.past_tense.length(), SQLITE_STATIC);
403 sqlite3_bind_text(ppstmt, 3, mapping.second.past_participle.c_str(), mapping.second.past_participle.length(), SQLITE_STATIC);
404 sqlite3_bind_text(ppstmt, 4, mapping.second.ing_form.c_str(), mapping.second.ing_form.length(), SQLITE_STATIC);
405 sqlite3_bind_text(ppstmt, 5, mapping.second.s_form.c_str(), mapping.second.s_form.length(), SQLITE_STATIC);
406
407 if (sqlite3_step(ppstmt) != SQLITE_DONE)
408 {
409 db_error(ppdb, query);
410 }
411
412 sqlite3_finalize(ppstmt);
413
414 std::string canonical(mapping.second.infinitive);
415 std::transform(std::begin(canonical), std::end(canonical), std::begin(canonical), ::tolower);
416 if (pronunciations.count(canonical) == 1)
417 {
418 query = "SELECT last_insert_rowid()";
419 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
420 {
421 db_error(ppdb, query);
422 }
423
424 if (sqlite3_step(ppstmt) != SQLITE_ROW)
425 {
426 db_error(ppdb, query);
427 }
428
429 int rowid = sqlite3_column_int(ppstmt, 0);
430
431 sqlite3_finalize(ppstmt);
432
433 for (auto pronunciation : pronunciations[canonical])
434 {
435 query = "INSERT INTO verb_pronunciations (verb_id, pronunciation) VALUES (?, ?)";
436 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
437 {
438 db_error(ppdb, query);
439 }
440
441 sqlite3_bind_int(ppstmt, 1, rowid);
442 sqlite3_bind_text(ppstmt, 2, pronunciation.c_str(), pronunciation.length(), SQLITE_STATIC);
443
444 if (sqlite3_step(ppstmt) != SQLITE_DONE)
445 {
446 db_error(ppdb, query);
447 }
448
449 sqlite3_finalize(ppstmt);
450 }
451 }
452
453 ppgs.update();
454 }
455 }
456
457 // Get nouns/adjectives/adverbs from WordNet
458 // Useful relations:
459 // - s: master list
460 // - ant: antonymy (e.g. happy/sad, sad/happy, happiness/sadness)
461 // - at: variation (e.g. a measurement can be standard or nonstandard)
462 // - der: derivation (e.g. happy/happily, happily/happy)
463 // - hyp: hypernymy/hyponymy (e.g. color/red, color/blue)
464 // - ins: instantiation (do we need this? let's see)
465 // - mm: member meronymy/holonymy (e.g. family/mother, family/child)
466 // - mp: part meronymy/holonymy (e.g. wheel/spoke, wheel/tire)
467 // - ms: substance meronymy/holonymy (e.g. tire/rubber, doorstop/rubber)
468 // - per: pertainymy (e.g. something that is Alaskan pertains to Alaska)
469 // mannernymy (e.g. something done quickly is done in a manner that is quick)
470 // - sa: specification (e.g. inaccurate (general) can mean imprecise or incorrect (specific))
471 // - sim: synonymy (e.g. cheerful/happy, happy/cheerful)
472 // - syntax: positioning flags for some adjectives
473 std::string wnpref {argv[4]};
474 if (wnpref.back() != '/')
475 {
476 wnpref += '/';
477 }
478
479 // s table
480 {
481 std::ifstream wnsfile(wnpref + "wn_s.pl");
482 if (!wnsfile.is_open())
483 {
484 std::cout << "Invalid WordNet data directory." << std::endl;
485 print_usage();
486 }
487
488 std::list<std::string> lines;
489 for (;;)
490 {
491 std::string line;
492 if (!getline(wnsfile, line))
493 {
494 break;
495 }
496
497 if (line.back() == '\r')
498 {
499 line.pop_back();
500 }
501
502 lines.push_back(line);
503 }
504
505 progress ppgs("Writing nouns, adjectives, and adverbs...", lines.size());
506 for (auto line : lines)
507 {
508 ppgs.update();
509
510 std::regex relation("^s\\(([134]\\d{8}),(\\d+),'([\\w ]+)',");
511 std::smatch relation_data;
512 if (!std::regex_search(line, relation_data, relation))
513 {
514 continue;
515 }
516
517 int synset_id = stoi(relation_data[1]);
518 int wnum = stoi(relation_data[2]);
519 std::string word = relation_data[3];
520
521 std::string query;
522 switch (synset_id / 100000000)
523 {
524 case 1: // Noun
525 {
526 if (nouns.count(word) == 1)
527 {
528 query = "INSERT INTO nouns (singular, plural) VALUES (?, ?)";
529 } else {
530 query = "INSERT INTO nouns (singular) VALUES (?)";
531 }
532
533 break;
534 }
535
536 case 2: // Verb
537 {
538 // Ignore
539
540 break;
541 }
542
543 case 3: // Adjective
544 {
545 if (adjectives.count(word) == 1)
546 {
547 query = "INSERT INTO adjectives (base_form, comparative, superlative) VALUES (?, ?, ?)";
548 } else {
549 query = "INSERT INTO adjectives (base_form) VALUES (?)";
550 }
551
552 break;
553 }
554
555 case 4: // Adverb
556 {
557 if (adjectives.count(word) == 1)
558 {
559 query = "INSERT INTO adverbs (base_form, comparative, superlative) VALUES (?, ?, ?)";
560 } else {
561 query = "INSERT INTO adverbs (base_form) VALUES (?)";
562 }
563
564 break;
565 }
566 }
567
568 sqlite3_stmt* ppstmt;
569 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
570 {
571 db_error(ppdb, query);
572 }
573
574 sqlite3_bind_text(ppstmt, 1, word.c_str(), word.length(), SQLITE_STATIC);
575 switch (synset_id / 100000000)
576 {
577 case 1: // Noun
578 {
579 if (nouns.count(word) == 1)
580 {
581 sqlite3_bind_text(ppstmt, 2, nouns[word].plural.c_str(), nouns[word].plural.length(), SQLITE_STATIC);
582 }
583
584 break;
585 }
586
587 case 3: // Adjective
588 case 4: // Adverb
589 {
590 if (adjectives.count(word) == 1)
591 {
592 sqlite3_bind_text(ppstmt, 2, adjectives[word].comparative.c_str(), adjectives[word].comparative.length(), SQLITE_STATIC);
593 sqlite3_bind_text(ppstmt, 3, adjectives[word].superlative.c_str(), adjectives[word].superlative.length(), SQLITE_STATIC);
594 }
595
596 break;
597 }
598 }
599
600 if (sqlite3_step(ppstmt) != SQLITE_DONE)
601 {
602 db_error(ppdb, query);
603 }
604
605 sqlite3_finalize(ppstmt);
606
607 query = "SELECT last_insert_rowid()";
608 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
609 {
610 db_error(ppdb, query);
611 }
612
613 if (sqlite3_step(ppstmt) != SQLITE_ROW)
614 {
615 db_error(ppdb, query);
616 }
617
618 int rowid = sqlite3_column_int(ppstmt, 0);
619 wn[synset_id][wnum] = rowid;
620
621 sqlite3_finalize(ppstmt);
622
623 std::string canonical(word);
624 std::transform(std::begin(canonical), std::end(canonical), std::begin(canonical), ::tolower);
625 if (pronunciations.count(canonical) == 1)
626 {
627 for (auto pronunciation : pronunciations[canonical])
628 {
629 switch (synset_id / 100000000)
630 {
631 case 1: // Noun
632 {
633 query = "INSERT INTO noun_pronunciations (noun_id, pronunciation) VALUES (?, ?)";
634
635 break;
636 }
637
638 case 3: // Adjective
639 {
640 query = "INSERT INTO adjective_pronunciations (adjective_id, pronunciation) VALUES (?, ?)";
641
642 break;
643 }
644
645 case 4: // Adverb
646 {
647 query = "INSERT INTO adverb_pronunciations (adverb_id, pronunciation) VALUES (?, ?)";
648
649 break;
650 }
651 }
652
653 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
654 {
655 db_error(ppdb, query);
656 }
657
658 sqlite3_bind_int(ppstmt, 1, rowid);
659 sqlite3_bind_text(ppstmt, 2, pronunciation.c_str(), pronunciation.length(), SQLITE_STATIC);
660
661 if (sqlite3_step(ppstmt) != SQLITE_DONE)
662 {
663 db_error(ppdb, query);
664 }
665
666 sqlite3_finalize(ppstmt);
667 }
668 }
669 }
670 }
671
672 // While we're working on s
673 {
674 progress ppgs("Writing word synonyms...", wn.size());
675 for (auto sense : wn)
676 {
677 ppgs.update();
678
679 for (auto word1 : sense.second)
680 {
681 for (auto word2 : sense.second)
682 {
683 if (word1 != word2)
684 {
685 std::string query;
686 switch (sense.first / 100000000)
687 {
688 case 1: // Noun
689 {
690 query = "INSERT INTO noun_synonymy (noun_1_id, noun_2_id) VALUES (?, ?)";
691
692 break;
693 }
694
695 case 2: // Verb
696 {
697 // Ignore
698
699 break;
700 }
701
702 case 3: // Adjective
703 {
704 query = "INSERT INTO adjective_synonymy (adjective_1_id, adjective_2_id) VALUES (?, ?)";
705
706 break;
707 }
708
709 case 4: // Adverb
710 {
711 query = "INSERT INTO adverb_synonymy (adverb_1_id, adverb_2_id) VALUES (?, ?)";
712
713 break;
714 }
715 }
716
717 sqlite3_stmt* ppstmt;
718 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
719 {
720 db_error(ppdb, query);
721 }
722
723 sqlite3_bind_int(ppstmt, 1, word1.second);
724 sqlite3_bind_int(ppstmt, 2, word2.second);
725
726 if (sqlite3_step(ppstmt) != SQLITE_DONE)
727 {
728 db_error(ppdb, query);
729 }
730
731 sqlite3_finalize(ppstmt);
732 }
733 }
734 }
735 }
736 }
737
738 // ant table
739 {
740 std::ifstream wnantfile(wnpref + "wn_ant.pl");
741 if (!wnantfile.is_open())
742 {
743 std::cout << "Invalid WordNet data directory." << std::endl;
744 print_usage();
745 }
746
747 std::list<std::string> lines;
748 for (;;)
749 {
750 std::string line;
751 if (!getline(wnantfile, line))
752 {
753 break;
754 }
755
756 if (line.back() == '\r')
757 {
758 line.pop_back();
759 }
760
761 lines.push_back(line);
762 }
763
764 progress ppgs("Writing antonyms...", lines.size());
765 for (auto line : lines)
766 {
767 ppgs.update();
768
769 std::regex relation("^ant\\(([134]\\d{8}),(\\d+),([134]\\d{8}),(\\d+)\\)\\.");
770 std::smatch relation_data;
771 if (!std::regex_search(line, relation_data, relation))
772 {
773 continue;
774 }
775
776 int synset_id_1 = stoi(relation_data[1]);
777 int wnum_1 = stoi(relation_data[2]);
778 int synset_id_2 = stoi(relation_data[3]);
779 int wnum_2 = stoi(relation_data[4]);
780
781 std::string query;
782 switch (synset_id_1 / 100000000)
783 {
784 case 1: // Noun
785 {
786 query = "INSERT INTO noun_antonymy (noun_1_id, noun_2_id) VALUES (?, ?)";
787
788 break;
789 }
790
791 case 2: // Verb
792 {
793 // Ignore
794
795 break;
796 }
797
798 case 3: // Adjective
799 {
800 query = "INSERT INTO adjective_antonymy (adjective_1_id, adjective_2_id) VALUES (?, ?)";
801
802 break;
803 }
804
805 case 4: // Adverb
806 {
807 query = "INSERT INTO adverb_antonymy (adverb_1_id, adverb_2_id) VALUES (?, ?)";
808
809 break;
810 }
811 }
812
813 sqlite3_stmt* ppstmt;
814 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
815 {
816 db_error(ppdb, query);
817 }
818
819 sqlite3_bind_int(ppstmt, 1, wn[synset_id_1][wnum_1]);
820 sqlite3_bind_int(ppstmt, 2, wn[synset_id_2][wnum_2]);
821
822 if (sqlite3_step(ppstmt) != SQLITE_DONE)
823 {
824 db_error(ppdb, query);
825 }
826
827 sqlite3_finalize(ppstmt);
828 }
829 }
830
831 // at table
832 {
833 std::ifstream wnatfile(wnpref + "wn_at.pl");
834 if (!wnatfile.is_open())
835 {
836 std::cout << "Invalid WordNet data directory." << std::endl;
837 print_usage();
838 }
839
840 std::list<std::string> lines;
841 for (;;)
842 {
843 std::string line;
844 if (!getline(wnatfile, line))
845 {
846 break;
847 }
848
849 if (line.back() == '\r')
850 {
851 line.pop_back();
852 }
853
854 lines.push_back(line);
855 }
856
857 progress ppgs("Writing variations...", lines.size());
858 for (auto line : lines)
859 {
860 ppgs.update();
861
862 std::regex relation("^at\\((1\\d{8}),(3\\d{8})\\)\\.");
863 std::smatch relation_data;
864 if (!std::regex_search(line, relation_data, relation))
865 {
866 continue;
867 }
868
869 int synset_id_1 = stoi(relation_data[1]);
870 int synset_id_2 = stoi(relation_data[2]);
871 std::string query("INSERT INTO variation (noun_id, adjective_id) VALUES (?, ?)");
872
873 for (auto mapping1 : wn[synset_id_1])
874 {
875 for (auto mapping2 : wn[synset_id_2])
876 {
877 sqlite3_stmt* ppstmt;
878 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK)
879 {
880 db_error(ppdb, query);
881 }
882
883 sqlite3_bind_int(ppstmt, 1, mapping1.second);
884 sqlite3_bind_int(ppstmt, 2, mapping2.second);
885
886 if (sqlite3_step(ppstmt) != SQLITE_DONE)
887 {
888 db_error(ppdb, query);
889 }
890
891 sqlite3_finalize(ppstmt);
892 }
893 }
894 }
895 }
896
897 // der table
898 {
899 std::ifstream wnderfile(wnpref + "wn_der.pl");
900 if (!wnderfile.is_open())
901 {
902 std::cout << "Invalid WordNet data directory." << std::endl;
903 print_usage();
904 }
905
906 std::list<std::string> lines;
907 for (;;)
908 {
909 std::string line;
910 if (!getline(wnderfile, line))
911 {
912 break;
913 }
914
915 if (line.back() == '\r')
916 {
917 line.pop_back();
918 }
919
920 lines.push_back(line);
921 }
922
923 progress ppgs("Writing morphological derivation...", lines.size());
924 for (auto line : lines)
925 {
926 ppgs.update();
927
928 std::regex relation("^der\\(([134]\\d{8}),(\\d+),([134]\\d{8}),(\\d+)\\)\\.");
929 std::smatch relation_data;
930 if (!std::regex_search(line, relation_data, relation))
931 {
932 continue;
933 }
934
935 int synset_id_1 = stoi(relation_data[1]);
936 int wnum_1 = stoi(relation_data[2]);
937 int synset_id_2 = stoi(relation_data[3]);
938 int wnum_2 = stoi(relation_data[4]);
939 std::string query;
940 switch (synset_id_1 / 100000000)
941 {
942 case 1: // Noun
943 {
944 switch (synset_id_2 / 100000000)
945 {
946 case 1: // Noun
947 {
948 query = "INSERT INTO noun_noun_derivation (noun_1_id, noun_2_id) VALUES (?, ?)";
949 break;
950 }
951
952 case 3: // Adjective
953 {
954 query = "INSERT INTO noun_adjective_derivation (noun_id, adjective_id) VALUES (?, ?)";
955 break;
956 }
957
958 case 4: // Adverb
959 {
960 query = "INSERT INTO noun_adverb_derivation (noun_id, adverb_id) VALUES (?, ?)";
961 break;
962 }
963 }
964
965 break;
966 }
967
968 case 3: // Adjective
969 {
970 switch (synset_id_2 / 100000000)
971 {
972 case 1: // Noun
973 {
974 query = "INSERT INTO noun_adjective_derivation (adjective_id, noun_id) VALUES (?, ?)";
975 break;
976 }
977
978 case 3: // Adjective
979 {
980 query = "INSERT INTO adjective_adjective_derivation (adjective_id, adjective_id) VALUES (?, ?)";
981 break;
982 }
983
984 case 4: // Adverb
985 {
986 query = "INSERT INTO adjective_adverb_derivation (adjective_id, adverb_id) VALUES (?, ?)";
987 break;
988 }
989 }
990
991 break;
992 }
993
994 case 4: // Adverb
995 {
996 switch (synset_id_2 / 100000000)
997 {
998 case 1: // Noun
999 {
1000 query = "INSERT INTO noun_adverb_derivation (adverb_id, noun_id) VALUES (?, ?)";
1001 break;
1002 }
1003
1004 case 3: // Adjective
1005 {
1006 query = "INSERT INTO adjective_adverb_derivation (adverb_id, adjective_id) VALUES (?, ?)";
1007 break;
1008 }
1009
1010 case 4: // Adverb
1011 {
1012 query = "INSERT INTO adverb_adverb_derivation (adverb_1_id, adverb_2_id) VALUES (?, ?)";
1013 break;
1014 }
1015 }
1016
1017 break;
1018 }
1019 }
1020
1021 sqlite3_stmt* ppstmt;
1022 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK)
1023 {
1024 db_error(ppdb, query);
1025 }
1026
1027 sqlite3_bind_int(ppstmt, 1, wn[synset_id_1][wnum_1]);
1028 sqlite3_bind_int(ppstmt, 2, wn[synset_id_2][wnum_2]);
1029
1030 if (sqlite3_step(ppstmt) != SQLITE_DONE)
1031 {
1032 db_error(ppdb, query);
1033 }
1034
1035 sqlite3_finalize(ppstmt);
1036 }
1037 }
1038
1039 // hyp table
1040 {
1041 std::ifstream wnhypfile(wnpref + "wn_hyp.pl");
1042 if (!wnhypfile.is_open())
1043 {
1044 std::cout << "Invalid WordNet data directory." << std::endl;
1045 print_usage();
1046 }
1047
1048 std::list<std::string> lines;
1049 for (;;)
1050 {
1051 std::string line;
1052 if (!getline(wnhypfile, line))
1053 {
1054 break;
1055 }
1056
1057 if (line.back() == '\r')
1058 {
1059 line.pop_back();
1060 }
1061
1062 lines.push_back(line);
1063 }
1064
1065 progress ppgs("Writing hypernyms...", lines.size());
1066 for (auto line : lines)
1067 {
1068 ppgs.update();
1069
1070 std::regex relation("^hyp\\((1\\d{8}),(1\\d{8})\\)\\.");
1071 std::smatch relation_data;
1072 if (!std::regex_search(line, relation_data, relation))
1073 {
1074 continue;
1075 }
1076
1077 int synset_id_1 = stoi(relation_data[1]);
1078 int synset_id_2 = stoi(relation_data[2]);
1079 std::string query("INSERT INTO hypernymy (hyponym_id, hypernym_id) VALUES (?, ?)");
1080
1081 for (auto mapping1 : wn[synset_id_1])
1082 {
1083 for (auto mapping2 : wn[synset_id_2])
1084 {
1085 sqlite3_stmt* ppstmt;
1086 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK)
1087 {
1088 db_error(ppdb, query);
1089 }
1090
1091 sqlite3_bind_int(ppstmt, 1, mapping1.second);
1092 sqlite3_bind_int(ppstmt, 2, mapping2.second);
1093
1094 if (sqlite3_step(ppstmt) != SQLITE_DONE)
1095 {
1096 db_error(ppdb, query);
1097 }
1098
1099 sqlite3_finalize(ppstmt);
1100 }
1101 }
1102 }
1103 }
1104
1105 // ins table
1106 {
1107 std::ifstream wninsfile(wnpref + "wn_ins.pl");
1108 if (!wninsfile.is_open())
1109 {
1110 std::cout << "Invalid WordNet data directory." << std::endl;
1111 print_usage();
1112 }
1113
1114 std::list<std::string> lines;
1115 for (;;)
1116 {
1117 std::string line;
1118 if (!getline(wninsfile, line))
1119 {
1120 break;
1121 }
1122
1123 if (line.back() == '\r')
1124 {
1125 line.pop_back();
1126 }
1127
1128 lines.push_back(line);
1129 }
1130
1131 progress ppgs("Writing instantiations...", lines.size());
1132 for (auto line : lines)
1133 {
1134 ppgs.update();
1135
1136 std::regex relation("^ins\\((1\\d{8}),(1\\d{8})\\)\\.");
1137 std::smatch relation_data;
1138 if (!std::regex_search(line, relation_data, relation))
1139 {
1140 continue;
1141 }
1142
1143 int synset_id_1 = stoi(relation_data[1]);
1144 int synset_id_2 = stoi(relation_data[2]);
1145 std::string query("INSERT INTO instantiation (instance_id, class_id) VALUES (?, ?)");
1146
1147 for (auto mapping1 : wn[synset_id_1])
1148 {
1149 for (auto mapping2 : wn[synset_id_2])
1150 {
1151 sqlite3_stmt* ppstmt;
1152 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK)
1153 {
1154 db_error(ppdb, query);
1155 }
1156
1157 sqlite3_bind_int(ppstmt, 1, mapping1.second);
1158 sqlite3_bind_int(ppstmt, 2, mapping2.second);
1159
1160 if (sqlite3_step(ppstmt) != SQLITE_DONE)
1161 {
1162 db_error(ppdb, query);
1163 }
1164
1165 sqlite3_finalize(ppstmt);
1166 }
1167 }
1168 }
1169 }
1170
1171 // mm table
1172 {
1173 std::ifstream wnmmfile(wnpref + "wn_mm.pl");
1174 if (!wnmmfile.is_open())
1175 {
1176 std::cout << "Invalid WordNet data directory." << std::endl;
1177 print_usage();
1178 }
1179
1180 std::list<std::string> lines;
1181 for (;;)
1182 {
1183 std::string line;
1184 if (!getline(wnmmfile, line))
1185 {
1186 break;
1187 }
1188
1189 if (line.back() == '\r')
1190 {
1191 line.pop_back();
1192 }
1193
1194 lines.push_back(line);
1195 }
1196
1197 progress ppgs("Writing member meronyms...", lines.size());
1198 for (auto line : lines)
1199 {
1200 ppgs.update();
1201
1202 std::regex relation("^mm\\((1\\d{8}),(1\\d{8})\\)\\.");
1203 std::smatch relation_data;
1204 if (!std::regex_search(line, relation_data, relation))
1205 {
1206 continue;
1207 }
1208
1209 int synset_id_1 = stoi(relation_data[1]);
1210 int synset_id_2 = stoi(relation_data[2]);
1211 std::string query("INSERT INTO member_meronymy (holonym_id, meronym_id) VALUES (?, ?)");
1212
1213 for (auto mapping1 : wn[synset_id_1])
1214 {
1215 for (auto mapping2 : wn[synset_id_2])
1216 {
1217 sqlite3_stmt* ppstmt;
1218 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK)
1219 {
1220 db_error(ppdb, query);
1221 }
1222
1223 sqlite3_bind_int(ppstmt, 1, mapping1.second);
1224 sqlite3_bind_int(ppstmt, 2, mapping2.second);
1225
1226 if (sqlite3_step(ppstmt) != SQLITE_DONE)
1227 {
1228 db_error(ppdb, query);
1229 }
1230
1231 sqlite3_finalize(ppstmt);
1232 }
1233 }
1234 }
1235 }
1236
1237 // ms table
1238 {
1239 std::ifstream wnmsfile(wnpref + "wn_ms.pl");
1240 if (!wnmsfile.is_open())
1241 {
1242 std::cout << "Invalid WordNet data directory." << std::endl;
1243 print_usage();
1244 }
1245
1246 std::list<std::string> lines;
1247 for (;;)
1248 {
1249 std::string line;
1250 if (!getline(wnmsfile, line))
1251 {
1252 break;
1253 }
1254
1255 if (line.back() == '\r')
1256 {
1257 line.pop_back();
1258 }
1259
1260 lines.push_back(line);
1261 }
1262
1263 progress ppgs("Writing substance meronyms...", lines.size());
1264 for (auto line : lines)
1265 {
1266 ppgs.update();
1267
1268 std::regex relation("^ms\\((1\\d{8}),(1\\d{8})\\)\\.");
1269 std::smatch relation_data;
1270 if (!std::regex_search(line, relation_data, relation))
1271 {
1272 continue;
1273 }
1274
1275 int synset_id_1 = stoi(relation_data[1]);
1276 int synset_id_2 = stoi(relation_data[2]);
1277 std::string query("INSERT INTO substance_meronymy (holonym_id, meronym_id) VALUES (?, ?)");
1278
1279 for (auto mapping1 : wn[synset_id_1])
1280 {
1281 for (auto mapping2 : wn[synset_id_2])
1282 {
1283 sqlite3_stmt* ppstmt;
1284 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK)
1285 {
1286 db_error(ppdb, query);
1287 }
1288
1289 sqlite3_bind_int(ppstmt, 1, mapping1.second);
1290 sqlite3_bind_int(ppstmt, 2, mapping2.second);
1291
1292 if (sqlite3_step(ppstmt) != SQLITE_DONE)
1293 {
1294 db_error(ppdb, query);
1295 }
1296
1297 sqlite3_finalize(ppstmt);
1298 }
1299 }
1300 }
1301 }
1302
1303 // mm table
1304 {
1305 std::ifstream wnmpfile(wnpref + "wn_mp.pl");
1306 if (!wnmpfile.is_open())
1307 {
1308 std::cout << "Invalid WordNet data directory." << std::endl;
1309 print_usage();
1310 }
1311
1312 std::list<std::string> lines;
1313 for (;;)
1314 {
1315 std::string line;
1316 if (!getline(wnmpfile, line))
1317 {
1318 break;
1319 }
1320
1321 if (line.back() == '\r')
1322 {
1323 line.pop_back();
1324 }
1325
1326 lines.push_back(line);
1327 }
1328
1329 progress ppgs("Writing part meronyms...", lines.size());
1330 for (auto line : lines)
1331 {
1332 ppgs.update();
1333
1334 std::regex relation("^mp\\((1\\d{8}),(1\\d{8})\\)\\.");
1335 std::smatch relation_data;
1336 if (!std::regex_search(line, relation_data, relation))
1337 {
1338 continue;
1339 }
1340
1341 int synset_id_1 = stoi(relation_data[1]);
1342 int synset_id_2 = stoi(relation_data[2]);
1343 std::string query("INSERT INTO part_meronymy (holonym_id, meronym_id) VALUES (?, ?)");
1344
1345 for (auto mapping1 : wn[synset_id_1])
1346 {
1347 for (auto mapping2 : wn[synset_id_2])
1348 {
1349 sqlite3_stmt* ppstmt;
1350 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK)
1351 {
1352 db_error(ppdb, query);
1353 }
1354
1355 sqlite3_bind_int(ppstmt, 1, mapping1.second);
1356 sqlite3_bind_int(ppstmt, 2, mapping2.second);
1357
1358 if (sqlite3_step(ppstmt) != SQLITE_DONE)
1359 {
1360 db_error(ppdb, query);
1361 }
1362
1363 sqlite3_finalize(ppstmt);
1364 }
1365 }
1366 }
1367 }
1368
1369 // per table
1370 {
1371 std::ifstream wnperfile(wnpref + "wn_per.pl");
1372 if (!wnperfile.is_open())
1373 {
1374 std::cout << "Invalid WordNet data directory." << std::endl;
1375 print_usage();
1376 }
1377
1378 std::list<std::string> lines;
1379 for (;;)
1380 {
1381 std::string line;
1382 if (!getline(wnperfile, line))
1383 {
1384 break;
1385 }
1386
1387 if (line.back() == '\r')
1388 {
1389 line.pop_back();
1390 }
1391
1392 lines.push_back(line);
1393 }
1394
1395 progress ppgs("Writing pertainyms and mannernyms...", lines.size());
1396 for (auto line : lines)
1397 {
1398 ppgs.update();
1399
1400 std::regex relation("^per\\(([34]\\d{8}),(\\d+),([13]\\d{8}),(\\d+)\\)\\.");
1401 std::smatch relation_data;
1402 if (!std::regex_search(line, relation_data, relation))
1403 {
1404 continue;
1405 }
1406
1407 int synset_id_1 = stoi(relation_data[1]);
1408 int wnum_1 = stoi(relation_data[2]);
1409 int synset_id_2 = stoi(relation_data[3]);
1410 int wnum_2 = stoi(relation_data[4]);
1411 std::string query;
1412 switch (synset_id_1 / 100000000)
1413 {
1414 case 3: // Adjective
1415 {
1416 // This is a pertainym, the second word should be a noun
1417 // Technically it can be an adjective but we're ignoring that
1418 if (synset_id_2 / 100000000 != 1)
1419 {
1420 continue;
1421 }
1422
1423 query = "INSERT INTO pertainymy (pertainym_id, noun_id) VALUES (?, ?)";
1424
1425 break;
1426 }
1427
1428 case 4: // Adverb
1429 {
1430 // This is a mannernym, the second word should be an adjective
1431 if (synset_id_2 / 100000000 != 3)
1432 {
1433 continue;
1434 }
1435
1436 query = "INSERT INTO mannernymy (mannernym_id, adjective_id) VALUES (?, ?)";
1437
1438 break;
1439 }
1440 }
1441
1442 sqlite3_stmt* ppstmt;
1443 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
1444 {
1445 db_error(ppdb, query);
1446 }
1447
1448 sqlite3_bind_int(ppstmt, 1, wn[synset_id_1][wnum_1]);
1449 sqlite3_bind_int(ppstmt, 2, wn[synset_id_2][wnum_2]);
1450
1451 if (sqlite3_step(ppstmt) != SQLITE_DONE)
1452 {
1453 db_error(ppdb, query);
1454 }
1455
1456 sqlite3_finalize(ppstmt);
1457 }
1458 }
1459
1460 // sa table
1461 {
1462 std::ifstream wnsafile(wnpref + "wn_sa.pl");
1463 if (!wnsafile.is_open())
1464 {
1465 std::cout << "Invalid WordNet data directory." << std::endl;
1466 print_usage();
1467 }
1468
1469 std::list<std::string> lines;
1470 for (;;)
1471 {
1472 std::string line;
1473 if (!getline(wnsafile, line))
1474 {
1475 break;
1476 }
1477
1478 if (line.back() == '\r')
1479 {
1480 line.pop_back();
1481 }
1482
1483 lines.push_back(line);
1484 }
1485
1486 progress ppgs("Writing specifications...", lines.size());
1487 for (auto line : lines)
1488 {
1489 ppgs.update();
1490
1491 std::regex relation("^per\\((3\\d{8}),(\\d+),(3\\d{8}),(\\d+)\\)\\.");
1492 std::smatch relation_data;
1493 if (!std::regex_search(line, relation_data, relation))
1494 {
1495 continue;
1496 }
1497
1498 int synset_id_1 = stoi(relation_data[1]);
1499 int wnum_1 = stoi(relation_data[2]);
1500 int synset_id_2 = stoi(relation_data[3]);
1501 int wnum_2 = stoi(relation_data[4]);
1502 std::string query("INSERT INTO specification (general_id, specific_id) VALUES (?, ?)");
1503
1504 sqlite3_stmt* ppstmt;
1505 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
1506 {
1507 db_error(ppdb, query);
1508 }
1509
1510 sqlite3_bind_int(ppstmt, 1, wn[synset_id_1][wnum_1]);
1511 sqlite3_bind_int(ppstmt, 2, wn[synset_id_2][wnum_2]);
1512
1513 if (sqlite3_step(ppstmt) != SQLITE_DONE)
1514 {
1515 db_error(ppdb, query);
1516 }
1517
1518 sqlite3_finalize(ppstmt);
1519 }
1520 }
1521
1522 // sim table
1523 {
1524 std::ifstream wnsimfile(wnpref + "wn_sim.pl");
1525 if (!wnsimfile.is_open())
1526 {
1527 std::cout << "Invalid WordNet data directory." << std::endl;
1528 print_usage();
1529 }
1530
1531 std::list<std::string> lines;
1532 for (;;)
1533 {
1534 std::string line;
1535 if (!getline(wnsimfile, line))
1536 {
1537 break;
1538 }
1539
1540 if (line.back() == '\r')
1541 {
1542 line.pop_back();
1543 }
1544
1545 lines.push_back(line);
1546 }
1547
1548 progress ppgs("Writing sense synonyms...", lines.size());
1549 for (auto line : lines)
1550 {
1551 ppgs.update();
1552
1553 std::regex relation("^sim\\((3\\d{8}),(3\\d{8})\\)\\.");
1554 std::smatch relation_data;
1555 if (!std::regex_search(line, relation_data, relation))
1556 {
1557 continue;
1558 }
1559
1560 int synset_id_1 = stoi(relation_data[1]);
1561 int synset_id_2 = stoi(relation_data[2]);
1562 std::string query("INSERT INTO adjective_synonymy (adjective_1_id, adjective_2_id) VALUES (?, ?)");
1563
1564 for (auto mapping1 : wn[synset_id_1])
1565 {
1566 for (auto mapping2 : wn[synset_id_2])
1567 {
1568 sqlite3_stmt* ppstmt;
1569 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK)
1570 {
1571 db_error(ppdb, query);
1572 }
1573
1574 sqlite3_bind_int(ppstmt, 1, mapping1.second);
1575 sqlite3_bind_int(ppstmt, 2, mapping2.second);
1576
1577 if (sqlite3_step(ppstmt) != SQLITE_DONE)
1578 {
1579 db_error(ppdb, query);
1580 }
1581
1582 sqlite3_reset(ppstmt);
1583 sqlite3_clear_bindings(ppstmt);
1584
1585 sqlite3_bind_int(ppstmt, 1, mapping2.second);
1586 sqlite3_bind_int(ppstmt, 2, mapping1.second);
1587
1588 if (sqlite3_step(ppstmt) != SQLITE_DONE)
1589 {
1590 db_error(ppdb, query);
1591 }
1592
1593 sqlite3_finalize(ppstmt);
1594 }
1595 }
1596 }
1597 }
1598
1599 // syntax table
1600 {
1601 std::ifstream wnsyntaxfile(wnpref + "wn_syntax.pl");
1602 if (!wnsyntaxfile.is_open())
1603 {
1604 std::cout << "Invalid WordNet data directory." << std::endl;
1605 print_usage();
1606 }
1607
1608 std::list<std::string> lines;
1609 for (;;)
1610 {
1611 std::string line;
1612 if (!getline(wnsyntaxfile, line))
1613 {
1614 break;
1615 }
1616
1617 if (line.back() == '\r')
1618 {
1619 line.pop_back();
1620 }
1621
1622 lines.push_back(line);
1623 }
1624
1625 progress ppgs("Writing adjective syntax markers...", lines.size());
1626 for (auto line : lines)
1627 {
1628 ppgs.update();
1629
1630 std::regex relation("^syntax\\((3\\d{8}),(\\d+),([ipa])p?\\)\\.");
1631 std::smatch relation_data;
1632 if (!std::regex_search(line, relation_data, relation))
1633 {
1634 continue;
1635 }
1636
1637 int synset_id = stoi(relation_data[1]);
1638 int wnum = stoi(relation_data[2]);
1639 std::string syn = relation_data[3];
1640 std::string query("UPDATE adjectives SET position = ? WHERE adjective_id = ?");
1641
1642 sqlite3_stmt* ppstmt;
1643 if (sqlite3_prepare_v2(ppdb, query.c_str(), query.size(), &ppstmt, NULL) != SQLITE_OK)
1644 {
1645 db_error(ppdb, query);
1646 }
1647
1648 sqlite3_bind_text(ppstmt, 1, syn.c_str(), 1, SQLITE_STATIC);
1649 sqlite3_bind_int(ppstmt, 2, wn[synset_id][wnum]);
1650
1651 if (sqlite3_step(ppstmt) != SQLITE_DONE)
1652 {
1653 db_error(ppdb, query);
1654 }
1655
1656 sqlite3_finalize(ppstmt);
1657 }
1658 }
1659
1660 sqlite3_close_v2(ppdb);
1661
1662 std::cout << "Done." << std::endl;
1663}
diff --git a/verbly/generator/progress.h b/verbly/generator/progress.h deleted file mode 100644 index 81f07a3..0000000 --- a/verbly/generator/progress.h +++ /dev/null
@@ -1,50 +0,0 @@
1#ifndef PROGRESS_H_A34EF856
2#define PROGRESS_H_A34EF856
3
4#include <string>
5
6class progress {
7 private:
8 std::string message;
9 int total;
10 int cur = 0;
11 int lprint = 0;
12
13 public:
14 progress(std::string message, int total) : message(message), total(total)
15 {
16 std::cout << message << " 0%" << std::flush;
17 }
18
19 void update(int val)
20 {
21 if (val <= total)
22 {
23 cur = val;
24 } else {
25 cur = total;
26 }
27
28 int pp = cur * 100 / total;
29 if (pp != lprint)
30 {
31 lprint = pp;
32
33 std::cout << "\b\b\b\b" << std::right;
34 std::cout.width(3);
35 std::cout << pp << "%" << std::flush;
36 }
37 }
38
39 void update()
40 {
41 update(cur+1);
42 }
43
44 ~progress()
45 {
46 std::cout << "\b\b\b\b100%" << std::endl;
47 }
48};
49
50#endif /* end of include guard: PROGRESS_H_A34EF856 */
diff --git a/verbly/generator/schema.sql b/verbly/generator/schema.sql deleted file mode 100644 index b4efe0a..0000000 --- a/verbly/generator/schema.sql +++ /dev/null
@@ -1,252 +0,0 @@
1DROP TABLE IF EXISTS `verbs`;
2CREATE TABLE `verbs` (
3 `verb_id` INTEGER PRIMARY KEY,
4 `infinitive` VARCHAR(32) NOT NULL,
5 `past_tense` VARCHAR(32) NOT NULL,
6 `past_participle` VARCHAR(32) NOT NULL,
7 `ing_form` VARCHAR(32) NOT NULL,
8 `s_form` VARCHAR(32) NOT NULL
9);
10
11DROP TABLE IF EXISTS `groups`;
12CREATE TABLE `groups` (
13 `group_id` INTEGER PRIMARY KEY,
14 `parent_id` INTEGER,
15 FOREIGN KEY (`parent_id`) REFERENCES `groups`(`group_id`)
16);
17
18DROP TABLE IF EXISTS `frames`;
19CREATE TABLE `frames` (
20 `frame_id` INTEGER PRIMARY KEY,
21 `group_id` INTEGER NOT NULL,
22 `data` BLOB NOT NULL,
23 FOREIGN KEY (`group_id`) REFERENCES `groups`(`group_id`)
24);
25
26DROP TABLE IF EXISTS `verb_groups`;
27CREATE TABLE `verb_groups` (
28 `verb_id` INTEGER NOT NULL,
29 `group_id` INTEGER NOT NULL,
30 FOREIGN KEY (`verb_id`) REFERENCES `verbs`(`verb_id`),
31 FOREIGN KEY (`group_id`) REFERENCES `groups`(`group_id`)
32);
33
34DROP TABLE IF EXISTS `adjectives`;
35CREATE TABLE `adjectives` (
36 `adjective_id` INTEGER PRIMARY KEY,
37 `base_form` VARCHAR(32) NOT NULL,
38 `comparative` VARCHAR(32),
39 `superlative` VARCHAR(32),
40 `position` CHAR(1)
41);
42
43DROP TABLE IF EXISTS `adverbs`;
44CREATE TABLE `adverbs` (
45 `adverb_id` INTEGER PRIMARY KEY,
46 `base_form` VARCHAR(32) NOT NULL,
47 `comparative` VARCHAR(32),
48 `superlative` VARCHAR(32)
49);
50
51DROP TABLE IF EXISTS `nouns`;
52CREATE TABLE `nouns` (
53 `noun_id` INTEGER PRIMARY KEY,
54 `singular` VARCHAR(32) NOT NULL,
55 `plural` VARCHAR(32)
56);
57
58DROP TABLE IF EXISTS `hypernymy`;
59CREATE TABLE `hypernymy` (
60 `hypernym_id` INTEGER NOT NULL,
61 `hyponym_id` INTEGER NOT NULL,
62 FOREIGN KEY (`hypernym_id`) REFERENCES `nouns`(`noun_id`),
63 FOREIGN KEY (`hyponym_id`) REFERENCES `nouns`(`noun_id`)
64);
65
66DROP TABLE IF EXISTS `instantiation`;
67CREATE TABLE `instantiation` (
68 `class_id` INTEGER NOT NULL,
69 `instance_id` INTEGER NOT NULL,
70 FOREIGN KEY (`class_id`) REFERENCES `nouns`(`noun_id`),
71 FOREIGN KEY (`instance_id`) REFERENCES `nouns`(`noun_id`)
72);
73
74DROP TABLE IF EXISTS `member_meronymy`;
75CREATE TABLE `member_meronymy` (
76 `meronym_id` INTEGER NOT NULL,
77 `holonym_id` INTEGER NOT NULL,
78 FOREIGN KEY (`meronym_id`) REFERENCES `nouns`(`noun_id`),
79 FOREIGN KEY (`holonym_id`) REFERENCES `nouns`(`noun_id`)
80);
81
82DROP TABLE IF EXISTS `part_meronymy`;
83CREATE TABLE `part_meronymy` (
84 `meronym_id` INTEGER NOT NULL,
85 `holonym_id` INTEGER NOT NULL,
86 FOREIGN KEY (`meronym_id`) REFERENCES `nouns`(`noun_id`),
87 FOREIGN KEY (`holonym_id`) REFERENCES `nouns`(`noun_id`)
88);
89
90DROP TABLE IF EXISTS `substance_meronymy`;
91CREATE TABLE `substance_meronymy` (
92 `meronym_id` INTEGER NOT NULL,
93 `holonym_id` INTEGER NOT NULL,
94 FOREIGN KEY (`meronym_id`) REFERENCES `nouns`(`noun_id`),
95 FOREIGN KEY (`holonym_id`) REFERENCES `nouns`(`noun_id`)
96);
97
98DROP TABLE IF EXISTS `variation`;
99CREATE TABLE `variation` (
100 `noun_id` INTEGER NOT NULL,
101 `adjective_id` INTEGER NOT NULL,
102 FOREIGN KEY (`noun_id`) REFERENCES `nouns`(`noun_id`),
103 FOREIGN KEY (`adjective_id`) REFERENCES `adjectives`(`adjective_id`)
104);
105
106DROP TABLE IF EXISTS `noun_antonymy`;
107CREATE TABLE `noun_antonymy` (
108 `noun_1_id` INTEGER NOT NULL,
109 `noun_2_id` INTEGER NOT NULL,
110 FOREIGN KEY (`noun_1_id`) REFERENCES `nouns`(`noun_id`),
111 FOREIGN KEY (`noun_2_id`) REFERENCES `nouns`(`noun_id`)
112);
113
114DROP TABLE IF EXISTS `adjective_antonymy`;
115CREATE TABLE `adjective_antonymy` (
116 `adjective_1_id` INTEGER NOT NULL,
117 `adjective_2_id` INTEGER NOT NULL,
118 FOREIGN KEY (`adjective_1_id`) REFERENCES `adjectives`(`adjective_id`),
119 FOREIGN KEY (`adjective_2_id`) REFERENCES `adjectives`(`adjective_id`)
120);
121
122DROP TABLE IF EXISTS `adverb_antonymy`;
123CREATE TABLE `adverb_antonymy` (
124 `adverb_1_id` INTEGER NOT NULL,
125 `adverb_2_id` INTEGER NOT NULL,
126 FOREIGN KEY (`adverb_1_id`) REFERENCES `adverbs`(`adverb_id`),
127 FOREIGN KEY (`adverb_2_id`) REFERENCES `adverbs`(`adverb_id`)
128);
129
130DROP TABLE IF EXISTS `specification`;
131CREATE TABLE `specification` (
132 `general_id` INTEGER NOT NULL,
133 `specific_id` INTEGER NOT NULL,
134 FOREIGN KEY (`general_id`) REFERENCES `adjectives`(`adjective_id`),
135 FOREIGN KEY (`specific_id`) REFERENCES `adjectives`(`adjective_id`)
136);
137
138DROP TABLE IF EXISTS `pertainymy`;
139CREATE TABLE `pertainymy` (
140 `noun_id` INTEGER NOT NULL,
141 `pertainym_id` INTEGER NOT NULL,
142 FOREIGN KEY (`noun_id`) REFERENCES `nouns`(`noun_id`),
143 FOREIGN KEY (`pertainym_id`) REFERENCES `adjectives`(`adjective_id`)
144);
145
146DROP TABLE IF EXISTS `mannernymy`;
147CREATE TABLE `mannernymy` (
148 `adjective_id` INTEGER NOT NULL,
149 `mannernym_id` INTEGER NOT NULL,
150 FOREIGN KEY (`adjective_id`) REFERENCES `adjectives`(`adjective_id`),
151 FOREIGN KEY (`mannernym_id`) REFERENCES `adverbs`(`adverb_id`)
152);
153
154DROP TABLE IF EXISTS `noun_synonymy`;
155CREATE TABLE `noun_synonymy` (
156 `noun_1_id` INTEGER NOT NULL,
157 `noun_2_id` INTEGER NOT NULL,
158 FOREIGN KEY (`noun_1_id`) REFERENCES `nouns`(`nouns_id`),
159 FOREIGN KEY (`noun_2_id`) REFERENCES `nouns`(`nouns_id`)
160);
161
162DROP TABLE IF EXISTS `adjective_synonymy`;
163CREATE TABLE `adjective_synonymy` (
164 `adjective_1_id` INTEGER NOT NULL,
165 `adjective_2_id` INTEGER NOT NULL,
166 FOREIGN KEY (`adjective_1_id`) REFERENCES `adjectives`(`adjective_id`),
167 FOREIGN KEY (`adjective_2_id`) REFERENCES `adjectives`(`adjective_id`)
168);
169
170DROP TABLE IF EXISTS `adverb_synonymy`;
171CREATE TABLE `adverb_synonymy` (
172 `adverb_1_id` INTEGER NOT NULL,
173 `adverb_2_id` INTEGER NOT NULL,
174 FOREIGN KEY (`adverb_1_id`) REFERENCES `adverbs`(`adverb_id`),
175 FOREIGN KEY (`adverb_2_id`) REFERENCES `adverbs`(`adverb_id`)
176);
177
178DROP TABLE IF EXISTS `noun_pronunciations`;
179CREATE TABLE `noun_pronunciations` (
180 `noun_id` INTEGER NOT NULL,
181 `pronunciation` VARCHAR(64) NOT NULL,
182 FOREIGN KEY (`noun_id`) REFERENCES `nouns`(`noun_id`)
183);
184
185DROP TABLE IF EXISTS `verb_pronunciations`;
186CREATE TABLE `verb_pronunciations` (
187 `verb_id` INTEGER NOT NULL,
188 `pronunciation` VARCHAR(64) NOT NULL,
189 FOREIGN KEY (`verb_id`) REFERENCES `verbs`(`verb_id`)
190);
191
192DROP TABLE IF EXISTS `adjective_pronunciations`;
193CREATE TABLE `adjective_pronunciations` (
194 `adjective_id` INTEGER NOT NULL,
195 `pronunciation` VARCHAR(64) NOT NULL,
196 FOREIGN KEY (`adjective_id`) REFERENCES `adjectives`(`adjective_id`)
197);
198
199DROP TABLE IF EXISTS `adverb_pronunciations`;
200CREATE TABLE `adverb_pronunciations` (
201 `adverb_id` INTEGER NOT NULL,
202 `pronunciation` VARCHAR(64) NOT NULL,
203 FOREIGN KEY (`adverb_id`) REFERENCES `adverbs`(`adverb_id`)
204);
205
206DROP TABLE IF EXISTS `noun_noun_derivation`;
207CREATE TABLE `noun_noun_derivation` (
208 `noun_1_id` INTEGER NOT NULL,
209 `noun_2_id` INTEGER NOT NULL,
210 FOREIGN KEY (`noun_1_id`) REFERENCES `nouns`(`noun_id`),
211 FOREIGN KEY (`noun_2_id`) REFERENCES `nouns`(`noun_id`)
212);
213
214DROP TABLE IF EXISTS `noun_adjective_derivation`;
215CREATE TABLE `noun_adjective_derivation` (
216 `noun_id` INTEGER NOT NULL,
217 `adjective_id` INTEGER NOT NULL,
218 FOREIGN KEY (`noun_id`) REFERENCES `nouns`(`noun_id`),
219 FOREIGN KEY (`adjective_id`) REFERENCES `adjectives`(`adjective_id`)
220);
221
222DROP TABLE IF EXISTS `noun_adverb_derivation`;
223CREATE TABLE `noun_adverb_derivation` (
224 `noun_id` INTEGER NOT NULL,
225 `adverb_id` INTEGER NOT NULL,
226 FOREIGN KEY (`noun_id`) REFERENCES `nouns`(`noun_id`),
227 FOREIGN KEY (`adverb_id`) REFERENCES `adverbs`(`adverb_id`)
228);
229
230DROP TABLE IF EXISTS `adjective_adjective_derivation`;
231CREATE TABLE `adjective_adjective_derivation` (
232 `adjective_1_id` INTEGER NOT NULL,
233 `adjective_2_id` INTEGER NOT NULL,
234 FOREIGN KEY (`adjective_1_id`) REFERENCES `adjectives`(`adjective_id`),
235 FOREIGN KEY (`adjective_2_id`) REFERENCES `adjectives`(`adjective_id`)
236);
237
238DROP TABLE IF EXISTS `adjective_adverb_derivation`;
239CREATE TABLE `adjective_adverb_derivation` (
240 `adjective_id` INTEGER NOT NULL,
241 `adverb_id` INTEGER NOT NULL,
242 FOREIGN KEY (`adjective_id`) REFERENCES `adjectives`(`adjective_id`),
243 FOREIGN KEY (`adverb_id`) REFERENCES `adverbs`(`adjective_id`)
244);
245
246DROP TABLE IF EXISTS `adverb_adverb_derivation`;
247CREATE TABLE `adverb_adverb_derivation` (
248 `adverb_1_id` INTEGER NOT NULL,
249 `adverb_2_id` INTEGER NOT NULL,
250 FOREIGN KEY (`adverb_1_id`) REFERENCES `adverbs`(`adverb_id`),
251 FOREIGN KEY (`adverb_2_id`) REFERENCES `adverbs`(`adverb_id`)
252);
diff --git a/verbly/lib/adjective.cpp b/verbly/lib/adjective.cpp deleted file mode 100644 index b2b53e4..0000000 --- a/verbly/lib/adjective.cpp +++ /dev/null
@@ -1,690 +0,0 @@
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 adjective_query& adjective_query::derived_from(const word& _w)
265 {
266 if (dynamic_cast<const adjective*>(&_w) != nullptr)
267 {
268 _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
269 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
270 {
271 _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
272 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
273 {
274 _derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
275 }
276
277 return *this;
278 }
279
280 adjective_query& adjective_query::not_derived_from(const word& _w)
281 {
282 if (dynamic_cast<const adjective*>(&_w) != nullptr)
283 {
284 _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
285 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
286 {
287 _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
288 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
289 {
290 _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
291 }
292
293 return *this;
294 }
295
296 std::list<adjective> adjective_query::run() const
297 {
298 std::stringstream construct;
299 construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives";
300 std::list<std::string> conditions;
301
302 if (_has_prn)
303 {
304 conditions.push_back("adjective_id IN (SELECT adjective_id FROM adjective_pronunciations)");
305 }
306
307 if (!_rhymes.empty())
308 {
309 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN");
310 std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
311 conditions.push_back(cond);
312 }
313
314 for (auto except : _except)
315 {
316 conditions.push_back("adjective_id != @EXCID");
317 }
318
319 if (_requires_comparative_form)
320 {
321 conditions.push_back("comparative IS NOT NULL");
322 }
323
324 if (_requires_superlative_form)
325 {
326 conditions.push_back("superlative IS NOT NULL");
327 }
328
329 if (_position != adjective::positioning::undefined)
330 {
331 switch (_position)
332 {
333 case adjective::positioning::predicate: conditions.push_back("position = 'p'"); break;
334 case adjective::positioning::attributive: conditions.push_back("position = 'a'"); break;
335 case adjective::positioning::postnominal: conditions.push_back("position = 'i'"); break;
336 }
337 }
338
339 if (_is_variant)
340 {
341 conditions.push_back("adjective_id IN (SELECT adjective_id FROM variation)");
342 }
343
344 if (!_variant_of.empty())
345 {
346 std::list<std::string> clauses(_variant_of.size(), "noun_id = @ATTRID");
347 std::string cond = "adjective_id IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
348 conditions.push_back(cond);
349 }
350
351 if (!_not_variant_of.empty())
352 {
353 std::list<std::string> clauses(_not_variant_of.size(), "noun_id = @NATTRID");
354 std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM variation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
355 conditions.push_back(cond);
356 }
357
358 if (_is_antonymic)
359 {
360 conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy)");
361 }
362
363 if (!_antonym_of.empty())
364 {
365 std::list<std::string> clauses(_antonym_of.size(), "adjective_1_id = @ANTID");
366 std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
367 conditions.push_back(cond);
368 }
369
370 if (!_not_antonym_of.empty())
371 {
372 std::list<std::string> clauses(_not_antonym_of.size(), "adjective_1_id = @NANTID");
373 std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
374 conditions.push_back(cond);
375 }
376
377 if (_is_synonymic)
378 {
379 conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy)");
380 }
381
382 if (!_synonym_of.empty())
383 {
384 std::list<std::string> clauses(_synonym_of.size(), "adjective_1_id = @SYNID");
385 std::string cond = "adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
386 conditions.push_back(cond);
387 }
388
389 if (!_not_synonym_of.empty())
390 {
391 std::list<std::string> clauses(_not_synonym_of.size(), "adjective_1_id = @NSYNID");
392 std::string cond = "adjective_id NOT IN (SELECT adjective_2_id FROM adjective_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
393 conditions.push_back(cond);
394 }
395
396 if (_is_generalization)
397 {
398 conditions.push_back("adjective_id IN (SELECT general_id FROM specification)");
399 }
400
401 if (!_generalization_of.empty())
402 {
403 std::list<std::string> clauses(_generalization_of.size(), "specific_id = @SPECID");
404 std::string cond = "adjective_id IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
405 conditions.push_back(cond);
406 }
407
408 if (!_not_generalization_of.empty())
409 {
410 std::list<std::string> clauses(_not_generalization_of.size(), "specific_id = @NSPECID");
411 std::string cond = "adjective_id NOT IN (SELECT general_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
412 conditions.push_back(cond);
413 }
414
415 if (_is_specification)
416 {
417 conditions.push_back("adjective_id IN (SELECT specific_id FROM specification)");
418 }
419
420 if (!_specification_of.empty())
421 {
422 std::list<std::string> clauses(_specification_of.size(), "general_id = @GENID");
423 std::string cond = "adjective_id IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
424 conditions.push_back(cond);
425 }
426
427 if (!_not_specification_of.empty())
428 {
429 std::list<std::string> clauses(_not_specification_of.size(), "general_id = @NGENID");
430 std::string cond = "adjective_id NOT IN (SELECT specific_id FROM specification WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
431 conditions.push_back(cond);
432 }
433
434 if (_is_pertainymic)
435 {
436 conditions.push_back("adjective_id IN (SELECT pertainym_id FROM pertainymy)");
437 }
438
439 if (!_pertainym_of.empty())
440 {
441 std::list<std::string> clauses(_pertainym_of.size(), "noun_id = @APERID");
442 std::string cond = "adjective_id IN (SELECT pertainym_id FROM pertainymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
443 conditions.push_back(cond);
444 }
445
446 if (_is_mannernymic)
447 {
448 conditions.push_back("adjective_id IN (SELECT adjective_id FROM mannernymy)");
449 }
450
451 if (!_anti_mannernym_of.empty())
452 {
453 std::list<std::string> clauses(_anti_mannernym_of.size(), "mannernym_id = @MANID");
454 std::string cond = "adjective_id IN (SELECT adjective_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
455 conditions.push_back(cond);
456 }
457
458 if (!_derived_from_adjective.empty())
459 {
460 std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_2_id = @DERADJ");
461 std::string cond = "adjective_id IN (SELECT adjective_1_id FROM adjective_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
462 conditions.push_back(cond);
463 }
464
465 if (!_not_derived_from_adjective.empty())
466 {
467 std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_2_id = @NDERADJ");
468 std::string cond = "adjective_id NOT IN (SELECT adjective_1_id FROM adjective_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
469 conditions.push_back(cond);
470 }
471
472 if (!_derived_from_adverb.empty())
473 {
474 std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_id = @DERADV");
475 std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
476 conditions.push_back(cond);
477 }
478
479 if (!_not_derived_from_adverb.empty())
480 {
481 std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_id = @NDERADV");
482 std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
483 conditions.push_back(cond);
484 }
485
486 if (!_derived_from_noun.empty())
487 {
488 std::list<std::string> clauses(_derived_from_noun.size(), "noun_id = @DERN");
489 std::string cond = "adjective_id IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
490 conditions.push_back(cond);
491 }
492
493 if (!_not_derived_from_noun.empty())
494 {
495 std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_id = @NDERN");
496 std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
497 conditions.push_back(cond);
498 }
499
500 if (!conditions.empty())
501 {
502 construct << " WHERE ";
503 construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND ");
504 }
505
506 if (_random)
507 {
508 construct << " ORDER BY RANDOM()";
509 }
510
511 if (_limit != unlimited)
512 {
513 construct << " LIMIT " << _limit;
514 }
515
516 sqlite3_stmt* ppstmt;
517 std::string query = construct.str();
518 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
519 {
520 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
521 }
522
523 if (!_rhymes.empty())
524 {
525 int i = 0;
526 for (auto rhyme : _rhymes)
527 {
528 std::string rhymer = "%" + rhyme;
529 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC);
530
531 i++;
532 }
533 }
534
535 for (auto except : _except)
536 {
537 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
538 }
539
540 for (auto attribute : _variant_of)
541 {
542 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id);
543 }
544
545 for (auto attribute : _not_variant_of)
546 {
547 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NATTRID"), attribute._id);
548 }
549
550 for (auto antonym : _antonym_of)
551 {
552 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id);
553 }
554
555 for (auto antonym : _not_antonym_of)
556 {
557 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id);
558 }
559
560 for (auto synonym : _synonym_of)
561 {
562 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id);
563 }
564
565 for (auto synonym : _not_synonym_of)
566 {
567 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id);
568 }
569
570 for (auto specific : _generalization_of)
571 {
572 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SPECID"), specific._id);
573 }
574
575 for (auto specific : _not_generalization_of)
576 {
577 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSPECID"), specific._id);
578 }
579
580 for (auto general : _specification_of)
581 {
582 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GENID"), general._id);
583 }
584
585 for (auto general : _not_specification_of)
586 {
587 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NGENID"), general._id);
588 }
589
590 for (auto n : _pertainym_of)
591 {
592 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@APERID"), n._id);
593 }
594
595 for (auto mannernym : _anti_mannernym_of)
596 {
597 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MANID"), mannernym._id);
598 }
599
600 for (auto adj : _derived_from_adjective)
601 {
602 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id);
603 }
604
605 for (auto adj : _not_derived_from_adjective)
606 {
607 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id);
608 }
609
610 for (auto adv : _derived_from_adverb)
611 {
612 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id);
613 }
614
615 for (auto adv : _not_derived_from_adverb)
616 {
617 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id);
618 }
619
620 for (auto n : _derived_from_noun)
621 {
622 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id);
623 }
624
625 for (auto n : _not_derived_from_noun)
626 {
627 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id);
628 }
629
630 std::list<adjective> output;
631 while (sqlite3_step(ppstmt) == SQLITE_ROW)
632 {
633 adjective tnc {_data, sqlite3_column_int(ppstmt, 0)};
634 tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1)));
635
636 if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)
637 {
638 tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2)));
639 }
640
641 if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL)
642 {
643 tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3)));
644 }
645
646 if (sqlite3_column_type(ppstmt, 4) != SQLITE_NULL)
647 {
648 std::string adjpos(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 4)));
649 if (adjpos == "p")
650 {
651 tnc._position = adjective::positioning::predicate;
652 } else if (adjpos == "a")
653 {
654 tnc._position = adjective::positioning::attributive;
655 } else if (adjpos == "i")
656 {
657 tnc._position = adjective::positioning::postnominal;
658 }
659 }
660
661 output.push_back(tnc);
662 }
663
664 sqlite3_finalize(ppstmt);
665
666 for (auto& adjective : output)
667 {
668 query = "SELECT pronunciation FROM adjective_pronunciations WHERE adjective_id = ?";
669 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
670 {
671 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
672 }
673
674 sqlite3_bind_int(ppstmt, 1, adjective._id);
675
676 while (sqlite3_step(ppstmt) == SQLITE_ROW)
677 {
678 std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0)));
679 auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " ");
680
681 adjective.pronunciations.push_back(phonemes);
682 }
683
684 sqlite3_finalize(ppstmt);
685 }
686
687 return output;
688 }
689
690};
diff --git a/verbly/lib/adjective.h b/verbly/lib/adjective.h deleted file mode 100644 index 3dcab9b..0000000 --- a/verbly/lib/adjective.h +++ /dev/null
@@ -1,143 +0,0 @@
1#ifndef ADJECTIVE_H_87B3FB75
2#define ADJECTIVE_H_87B3FB75
3
4namespace verbly {
5
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
19 private:
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;
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 {
49 public:
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 adjective_query& derived_from(const word& _w);
89 adjective_query& not_derived_from(const word& _w);
90
91 std::list<adjective> run() const;
92
93 const static int unlimited = -1;
94
95 protected:
96 const data& _data;
97 int _limit = unlimited;
98 bool _random = false;
99 std::list<std::string> _rhymes;
100 std::list<adjective> _except;
101 bool _has_prn = false;
102
103 bool _requires_comparative_form = false;
104 bool _requires_superlative_form = false;
105 adjective::positioning _position = adjective::positioning::undefined;
106
107 bool _is_variant = false;
108 std::list<noun> _variant_of;
109 std::list<noun> _not_variant_of;
110
111 bool _is_antonymic = false;
112 std::list<adjective> _antonym_of;
113 std::list<adjective> _not_antonym_of;
114
115 bool _is_synonymic = false;
116 std::list<adjective> _synonym_of;
117 std::list<adjective> _not_synonym_of;
118
119 bool _is_generalization = false;
120 std::list<adjective> _generalization_of;
121 std::list<adjective> _not_generalization_of;
122
123 bool _is_specification = false;
124 std::list<adjective> _specification_of;
125 std::list<adjective> _not_specification_of;
126
127 bool _is_pertainymic = false;
128 std::list<noun> _pertainym_of;
129
130 bool _is_mannernymic = false;
131 std::list<adverb> _anti_mannernym_of;
132
133 std::list<adjective> _derived_from_adjective;
134 std::list<adjective> _not_derived_from_adjective;
135 std::list<adverb> _derived_from_adverb;
136 std::list<adverb> _not_derived_from_adverb;
137 std::list<noun> _derived_from_noun;
138 std::list<noun> _not_derived_from_noun;
139 };
140
141};
142
143#endif /* end of include guard: ADJECTIVE_H_87B3FB75 */
diff --git a/verbly/lib/adverb.cpp b/verbly/lib/adverb.cpp deleted file mode 100644 index 8fcddad..0000000 --- a/verbly/lib/adverb.cpp +++ /dev/null
@@ -1,468 +0,0 @@
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 adverb_query& adverb_query::derived_from(const word& _w)
172 {
173 if (dynamic_cast<const adjective*>(&_w) != nullptr)
174 {
175 _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
176 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
177 {
178 _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
179 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
180 {
181 _derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
182 }
183
184 return *this;
185 }
186
187 adverb_query& adverb_query::not_derived_from(const word& _w)
188 {
189 if (dynamic_cast<const adjective*>(&_w) != nullptr)
190 {
191 _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
192 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
193 {
194 _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
195 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
196 {
197 _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
198 }
199
200 return *this;
201 }
202
203 std::list<adverb> adverb_query::run() const
204 {
205 std::stringstream construct;
206 construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs";
207 std::list<std::string> conditions;
208
209 if (_has_prn)
210 {
211 conditions.push_back("adverb_id IN (SELECT adverb_id FROM adverb_pronunciations)");
212 }
213
214 if (!_rhymes.empty())
215 {
216 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN");
217 std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
218 conditions.push_back(cond);
219 }
220
221 for (auto except : _except)
222 {
223 conditions.push_back("adverb_id != @EXCID");
224 }
225
226 if (_requires_comparative_form)
227 {
228 conditions.push_back("comparative IS NOT NULL");
229 }
230
231 if (_requires_superlative_form)
232 {
233 conditions.push_back("superlative IS NOT NULL");
234 }
235
236 if (_has_antonyms)
237 {
238 conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)");
239 }
240
241 if (!_antonym_of.empty())
242 {
243 std::list<std::string> clauses(_antonym_of.size(), "adverb_1_id = @ANTID");
244 std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
245 conditions.push_back(cond);
246 }
247
248 if (!_not_antonym_of.empty())
249 {
250 std::list<std::string> clauses(_not_antonym_of.size(), "adverb_1_id = @NANTID");
251 std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
252 conditions.push_back(cond);
253 }
254
255 if (_has_synonyms)
256 {
257 conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy)");
258 }
259
260 if (!_synonym_of.empty())
261 {
262 std::list<std::string> clauses(_synonym_of.size(), "adverb_1_id = @SYNID");
263 std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
264 conditions.push_back(cond);
265 }
266
267 if (!_not_synonym_of.empty())
268 {
269 std::list<std::string> clauses(_not_synonym_of.size(), "adverb_1_id = @NSYNID");
270 std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
271 conditions.push_back(cond);
272 }
273
274 if (_is_mannernymic)
275 {
276 conditions.push_back("adverb_id IN (SELECT mannernym_id FROM mannernymy)");
277 }
278
279 if (!_mannernym_of.empty())
280 {
281 std::list<std::string> clauses(_mannernym_of.size(), "adjective_id = @AMANID");
282 std::string cond = "adverb_id IN (SELECT mannernym_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
283 conditions.push_back(cond);
284 }
285
286 if (!_derived_from_adjective.empty())
287 {
288 std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_id = @DERADJ");
289 std::string cond = "adverb_id IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
290 conditions.push_back(cond);
291 }
292
293 if (!_not_derived_from_adjective.empty())
294 {
295 std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_id = @NDERADJ");
296 std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
297 conditions.push_back(cond);
298 }
299
300 if (!_derived_from_adverb.empty())
301 {
302 std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_2_id = @DERADV");
303 std::string cond = "adverb_id IN (SELECT adverb_1_id FROM adverb_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
304 conditions.push_back(cond);
305 }
306
307 if (!_not_derived_from_adverb.empty())
308 {
309 std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_2_id = @NDERADV");
310 std::string cond = "adverb_id NOT IN (SELECT adverb_1_id FROM adverb_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
311 conditions.push_back(cond);
312 }
313
314 if (!_derived_from_noun.empty())
315 {
316 std::list<std::string> clauses(_derived_from_noun.size(), "noun_id = @DERN");
317 std::string cond = "adverb_id IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
318 conditions.push_back(cond);
319 }
320
321 if (!_not_derived_from_noun.empty())
322 {
323 std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_id = @NDERN");
324 std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
325 conditions.push_back(cond);
326 }
327
328 if (!conditions.empty())
329 {
330 construct << " WHERE ";
331 construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND ");
332 }
333
334 if (_random)
335 {
336 construct << " ORDER BY RANDOM()";
337 }
338
339 if (_limit != unlimited)
340 {
341 construct << " LIMIT " << _limit;
342 }
343
344 sqlite3_stmt* ppstmt;
345 std::string query = construct.str();
346 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
347 {
348 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
349 }
350
351 if (!_rhymes.empty())
352 {
353 int i = 0;
354 for (auto rhyme : _rhymes)
355 {
356 std::string rhymer = "%" + rhyme;
357 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC);
358
359 i++;
360 }
361 }
362
363 for (auto except : _except)
364 {
365 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
366 }
367
368 for (auto antonym : _antonym_of)
369 {
370 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id);
371 }
372
373 for (auto antonym : _not_antonym_of)
374 {
375 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id);
376 }
377
378 for (auto synonym : _synonym_of)
379 {
380 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id);
381 }
382
383 for (auto synonym : _not_synonym_of)
384 {
385 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id);
386 }
387
388 for (auto adj : _mannernym_of)
389 {
390 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id);
391 }
392
393 for (auto adj : _derived_from_adjective)
394 {
395 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id);
396 }
397
398 for (auto adj : _not_derived_from_adjective)
399 {
400 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id);
401 }
402
403 for (auto adv : _derived_from_adverb)
404 {
405 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id);
406 }
407
408 for (auto adv : _not_derived_from_adverb)
409 {
410 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id);
411 }
412
413 for (auto n : _derived_from_noun)
414 {
415 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id);
416 }
417
418 for (auto n : _not_derived_from_noun)
419 {
420 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id);
421 }
422
423 std::list<adverb> output;
424 while (sqlite3_step(ppstmt) == SQLITE_ROW)
425 {
426 adverb tnc {_data, sqlite3_column_int(ppstmt, 0)};
427 tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1)));
428
429 if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)
430 {
431 tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2)));
432 }
433
434 if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL)
435 {
436 tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3)));
437 }
438
439 output.push_back(tnc);
440 }
441
442 sqlite3_finalize(ppstmt);
443
444 for (auto& adverb : output)
445 {
446 query = "SELECT pronunciation FROM adverb_pronunciations WHERE adverb_id = ?";
447 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
448 {
449 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
450 }
451
452 sqlite3_bind_int(ppstmt, 1, adverb._id);
453
454 while (sqlite3_step(ppstmt) == SQLITE_ROW)
455 {
456 std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0)));
457 auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " ");
458
459 adverb.pronunciations.push_back(phonemes);
460 }
461
462 sqlite3_finalize(ppstmt);
463 }
464
465 return output;
466 }
467
468};
diff --git a/verbly/lib/adverb.h b/verbly/lib/adverb.h deleted file mode 100644 index 65e3c5c..0000000 --- a/verbly/lib/adverb.h +++ /dev/null
@@ -1,95 +0,0 @@
1#ifndef ADVERB_H_86F8302F
2#define ADVERB_H_86F8302F
3
4namespace verbly {
5
6 class adverb : public word {
7 private:
8 std::string _base_form;
9 std::string _comparative_form;
10 std::string _superlative_form;
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 adverb_query& derived_from(const word& _w);
29 adverb_query& not_derived_from(const word& _w);
30 };
31
32 class adverb_query {
33 public:
34 adverb_query(const data& _data);
35
36 adverb_query& limit(int _limit);
37 adverb_query& random(bool _random);
38 adverb_query& except(const adverb& _word);
39 adverb_query& rhymes_with(const word& _word);
40 adverb_query& has_pronunciation(bool _has_prn);
41
42 adverb_query& requires_comparative_form(bool _arg);
43 adverb_query& requires_superlative_form(bool _arg);
44
45 adverb_query& has_antonyms(bool _arg);
46 adverb_query& antonym_of(const adverb& _adv);
47 adverb_query& not_antonym_of(const adverb& _adv);
48
49 adverb_query& has_synonyms(bool _arg);
50 adverb_query& synonym_of(const adverb& _adv);
51 adverb_query& not_synonym_of(const adverb& _adv);
52
53 adverb_query& is_mannernymic(bool _arg);
54 adverb_query& mannernym_of(const adjective& _adj);
55
56 adverb_query& derived_from(const word& _w);
57 adverb_query& not_derived_from(const word& _w);
58
59 std::list<adverb> run() const;
60
61 const static int unlimited = -1;
62
63 private:
64 const data& _data;
65 int _limit = unlimited;
66 bool _random = false;
67 std::list<std::string> _rhymes;
68 std::list<adverb> _except;
69 bool _has_prn = false;
70
71 bool _requires_comparative_form = false;
72 bool _requires_superlative_form = false;
73
74 bool _has_antonyms = false;
75 std::list<adverb> _antonym_of;
76 std::list<adverb> _not_antonym_of;
77
78 bool _has_synonyms = false;
79 std::list<adverb> _synonym_of;
80 std::list<adverb> _not_synonym_of;
81
82 bool _is_mannernymic = false;
83 std::list<adjective> _mannernym_of;
84
85 std::list<adjective> _derived_from_adjective;
86 std::list<adjective> _not_derived_from_adjective;
87 std::list<adverb> _derived_from_adverb;
88 std::list<adverb> _not_derived_from_adverb;
89 std::list<noun> _derived_from_noun;
90 std::list<noun> _not_derived_from_noun;
91 };
92
93};
94
95#endif /* end of include guard: ADVERB_H_86F8302F */
diff --git a/verbly/lib/c++14.h b/verbly/lib/c++14.h deleted file mode 100644 index b3efbe2..0000000 --- a/verbly/lib/c++14.h +++ /dev/null
@@ -1,35 +0,0 @@
1#include <cstddef>
2#include <memory>
3#include <type_traits>
4#include <utility>
5
6namespace std {
7 template<class T> struct _Unique_if {
8 typedef unique_ptr<T> _Single_object;
9 };
10
11 template<class T> struct _Unique_if<T[]> {
12 typedef unique_ptr<T[]> _Unknown_bound;
13 };
14
15 template<class T, size_t N> struct _Unique_if<T[N]> {
16 typedef void _Known_bound;
17 };
18
19 template<class T, class... Args>
20 typename _Unique_if<T>::_Single_object
21 make_unique(Args&&... args) {
22 return unique_ptr<T>(new T(std::forward<Args>(args)...));
23 }
24
25 template<class T>
26 typename _Unique_if<T>::_Unknown_bound
27 make_unique(size_t n) {
28 typedef typename remove_extent<T>::type U;
29 return unique_ptr<T>(new U[n]());
30 }
31
32 template<class T, class... Args>
33 typename _Unique_if<T>::_Known_bound
34 make_unique(Args&&...) = delete;
35}
diff --git a/verbly/lib/data.cpp b/verbly/lib/data.cpp deleted file mode 100644 index 57a8850..0000000 --- a/verbly/lib/data.cpp +++ /dev/null
@@ -1,50 +0,0 @@
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/verbly/lib/data.h b/verbly/lib/data.h deleted file mode 100644 index 37092d7..0000000 --- a/verbly/lib/data.h +++ /dev/null
@@ -1,49 +0,0 @@
1#ifndef DATA_H_C4AEC3DD
2#define DATA_H_C4AEC3DD
3
4#include <sqlite3.h>
5#include <stdexcept>
6
7namespace verbly {
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
20 class data {
21 private:
22 sqlite3* ppdb;
23
24 friend class adjective_query;
25 friend class noun_query;
26 friend class verb_query;
27 friend class adverb_query;
28
29 public:
30 data(std::string datafile);
31
32 data(const data& other) = delete;
33 data& operator=(const data& other) = delete;
34
35 data(data&& other);
36 data& operator=(data&& other);
37
38 ~data();
39
40 verb_query verbs() const;
41 adjective_query adjectives() const;
42 adverb_query adverbs() const;
43 noun_query nouns() const;
44
45 };
46
47};
48
49#endif /* end of include guard: DATA_H_C4AEC3DD */
diff --git a/verbly/lib/noun.cpp b/verbly/lib/noun.cpp deleted file mode 100644 index 43fda2e..0000000 --- a/verbly/lib/noun.cpp +++ /dev/null
@@ -1,1032 +0,0 @@
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};
diff --git a/verbly/lib/noun.h b/verbly/lib/noun.h deleted file mode 100644 index da76866..0000000 --- a/verbly/lib/noun.h +++ /dev/null
@@ -1,183 +0,0 @@
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& is_not_proper(bool _arg);
82 noun_query& instance_of(const noun& _noun);
83 noun_query& not_instance_of(const noun& _noun);
84
85 noun_query& is_class(bool _arg);
86 noun_query& class_of(const noun& _noun);
87 noun_query& not_class_of(const noun& _noun);
88
89 noun_query& has_synonyms(bool _arg);
90 noun_query& synonym_of(const noun& _noun);
91 noun_query& not_synonym_of(const noun& _noun);
92
93 noun_query& has_antonyms(bool _arg);
94 noun_query& antonym_of(const noun& _noun);
95 noun_query& not_antonym_of(const noun& _noun);
96
97 noun_query& has_pertainym(bool _arg);
98 noun_query& anti_pertainym_of(const adjective& _adj);
99
100 noun_query& is_attribute(bool _arg);
101 noun_query& attribute_of(const adjective& _adj);
102
103 noun_query& derived_from(const word& _w);
104 noun_query& not_derived_from(const word& _w);
105
106 std::list<noun> run() const;
107
108 const static int unlimited = -1;
109
110 private:
111 const data& _data;
112 int _limit = unlimited;
113 bool _random = false;
114 std::list<std::string> _rhymes;
115 std::list<noun> _except;
116 bool _has_prn = false;
117
118 bool _is_hypernym = false;
119 std::list<noun> _hypernym_of;
120 std::list<noun> _not_hypernym_of;
121
122 bool _is_hyponym = false;
123 std::list<noun> _hyponym_of;
124 std::list<noun> _not_hyponym_of;
125
126 bool _is_part_meronym = false;
127 std::list<noun> _part_meronym_of;
128 std::list<noun> _not_part_meronym_of;
129
130 bool _is_substance_meronym = false;
131 std::list<noun> _substance_meronym_of;
132 std::list<noun> _not_substance_meronym_of;
133
134 bool _is_member_meronym = false;
135 std::list<noun> _member_meronym_of;
136 std::list<noun> _not_member_meronym_of;
137
138 bool _is_part_holonym = false;
139 std::list<noun> _part_holonym_of;
140 std::list<noun> _not_part_holonym_of;
141
142 bool _is_substance_holonym = false;
143 std::list<noun> _substance_holonym_of;
144 std::list<noun> _not_substance_holonym_of;
145
146 bool _is_member_holonym = false;
147 std::list<noun> _member_holonym_of;
148 std::list<noun> _not_member_holonym_of;
149
150 bool _is_proper = false;
151 bool _is_not_proper = false;
152 std::list<noun> _instance_of;
153 std::list<noun> _not_instance_of;
154
155 bool _is_class = false;
156 std::list<noun> _class_of;
157 std::list<noun> _not_class_of;
158
159 bool _has_synonyms = false;
160 std::list<noun> _synonym_of;
161 std::list<noun> _not_synonym_of;
162
163 bool _has_antonyms = false;
164 std::list<noun> _antonym_of;
165 std::list<noun> _not_antonym_of;
166
167 bool _has_pertainym = false;
168 std::list<adjective> _anti_pertainym_of;
169
170 bool _is_attribute = false;
171 std::list<adjective> _attribute_of;
172
173 std::list<adjective> _derived_from_adjective;
174 std::list<adjective> _not_derived_from_adjective;
175 std::list<adverb> _derived_from_adverb;
176 std::list<adverb> _not_derived_from_adverb;
177 std::list<noun> _derived_from_noun;
178 std::list<noun> _not_derived_from_noun;
179 };
180
181};
182
183#endif /* end of include guard: NOUN_H_24A03C83 */
diff --git a/verbly/lib/token.cpp b/verbly/lib/token.cpp deleted file mode 100644 index aa8f50e..0000000 --- a/verbly/lib/token.cpp +++ /dev/null
@@ -1,53 +0,0 @@
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/verbly/lib/token.h b/verbly/lib/token.h deleted file mode 100644 index 44d99cb..0000000 --- a/verbly/lib/token.h +++ /dev/null
@@ -1,313 +0,0 @@
1#ifndef TOKEN_H_AD62C505
2#define TOKEN_H_AD62C505
3
4#include <string>
5#include <list>
6#include <sstream>
7
8namespace verbly {
9
10 class verb;
11
12 class selrestr {
13 };
14
15 class synrestr {
16 };
17
18 enum class fillin_type {
19 noun_phrase,
20 participle_phrase,
21 adjective,
22 adverb
23 };
24
25 class token {
26 public:
27 enum class type {
28 verb,
29 fillin,
30 string,
31 utterance
32 };
33
34 protected:
35 // General
36 type _type;
37
38 token(type _type);
39
40 public:
41 enum type token_type() const;
42
43 virtual bool complete() const = 0;
44 virtual std::string compile() const = 0;
45 virtual token* copy() const = 0;
46 };
47
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
58 private:
59 // Verb
60 const verb* _verb;
61 inflection _inflection = inflection::infinitive;
62
63 public:
64 verb_token(const class verb& _verb);
65
66 const class verb& verb() const;
67
68 verb_token& inflect(inflection infl);
69
70 bool complete() const;
71
72 std::string compile() const;
73
74 token* copy() const;
75 };
76
77 class utterance_token : public token {
78 private:
79 // Utterance
80 std::list<std::unique_ptr<token>> utterance;
81
82 public:
83 typedef std::list<std::unique_ptr<token>>::iterator iterator;
84 /*class iterator {
85 private:
86 friend class utterance_token;
87
88 std::list<std::unique_ptr<token>>::iterator it;
89
90 public:
91 iterator(std::list<std::unique_ptr<token>>::iterator it) : it(it)
92 {
93
94 }
95
96 iterator& operator++()
97 {
98 ++it;
99 return *this;
100 }
101
102 iterator& operator--()
103 {
104 --it;
105 return *this;
106 }
107
108 bool operator==(const iterator& other) const
109 {
110 return it == other.it;
111 }
112
113 bool operator!=(const iterator& other) const
114 {
115 return it != other.it;
116 }
117
118 token& operator*()
119 {
120 return **it;
121 }
122
123 token& operator->()
124 {
125 return **it;
126 }
127 };*/
128
129 utterance_token(std::initializer_list<token*> tkns) : token(token::type::utterance)
130 {
131 for (auto tkn : tkns)
132 {
133 utterance.push_back(std::unique_ptr<token>(tkn));
134 }
135 }
136
137 utterance_token(const utterance_token& other) : token(token::type::utterance)
138 {
139 for (auto& tkn : other.utterance)
140 {
141 utterance.push_back(std::unique_ptr<token>(tkn->copy()));
142 }
143 }
144
145 utterance_token(utterance_token&& other) : token(token::type::utterance), utterance(std::move(other.utterance))
146 {
147
148 }
149
150 utterance_token& operator=(const utterance_token& other)
151 {
152 utterance.clear();
153
154 for (auto& tkn : other.utterance)
155 {
156 utterance.push_back(std::unique_ptr<token>(tkn->copy()));
157 }
158
159 return *this;
160 }
161
162 utterance_token& operator=(utterance_token&& other)
163 {
164 utterance = std::move(other.utterance);
165
166 return *this;
167 }
168
169 iterator begin()
170 {
171 return std::begin(utterance);
172 }
173
174 iterator end()
175 {
176 return std::end(utterance);
177 }
178
179 void erase(iterator it)
180 {
181 utterance.erase(it);
182 }
183
184 bool complete() const
185 {
186 return std::all_of(std::begin(utterance), std::end(utterance), [] (const std::unique_ptr<token>& tkn) {
187 return tkn->complete();
188 });
189 }
190
191 std::string compile() const
192 {
193 std::stringstream result;
194 for (auto& t : utterance)
195 {
196 if (t->complete())
197 {
198 result << t->compile() << " ";
199 } else {
200 return "Could not compile!";
201 }
202 }
203
204 std::string output = result.str();
205 if (output != "")
206 {
207 output.pop_back();
208 }
209
210 return output;
211 }
212
213 token* copy() const
214 {
215 return new utterance_token(*this);
216 }
217 };
218
219 class fillin_token : public token {
220 private:
221 // Fillin
222 std::string m_theme;
223 fillin_type m_fillin_type;
224
225 public:
226 fillin_token(fillin_type ft) : token(token::type::fillin), m_fillin_type(ft)
227 {
228
229 }
230
231/* void synrestrs(std::initializer_list<synrestr> ins)
232 {
233 m_synrestrs = std::set<synrestr>(ins);
234 }
235
236 std::set<synrestr>& synrestrs()
237 {
238 return m_synrestrs;
239 }
240
241 void selrestrs(std::initializer_list<selrestr> ins)
242 {
243 m_selrestrs = std::set<selrestr>(ins);
244 }
245
246 std::set<selrestr>& selrestrs()
247 {
248 return m_selrestrs;
249 }*/
250
251 fillin_token theme(std::string theme)
252 {
253 m_theme = theme;
254
255 return *this;
256 }
257
258 std::string& theme()
259 {
260 return m_theme;
261 }
262
263 fillin_type fillin_type() const
264 {
265 return m_fillin_type;
266 }
267
268 bool complete() const
269 {
270 return false;
271 }
272
273 std::string compile() const
274 {
275 return "";
276 }
277
278 token* copy() const
279 {
280 return new fillin_token(*this);
281 }
282 };
283
284 class string_token : public token {
285 private:
286 // String
287 std::string str;
288
289 public:
290 string_token(std::string str) : token(token::type::string), str(str)
291 {
292
293 }
294
295 bool complete() const
296 {
297 return true;
298 }
299
300 std::string compile() const
301 {
302 return str;
303 }
304
305 token* copy() const
306 {
307 return new string_token(*this);
308 }
309 };
310
311};
312
313#endif /* end of include guard: TOKEN_H_AD62C505 */
diff --git a/verbly/lib/util.h b/verbly/lib/util.h deleted file mode 100644 index 815b47c..0000000 --- a/verbly/lib/util.h +++ /dev/null
@@ -1,53 +0,0 @@
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/verbly/lib/verb.cpp b/verbly/lib/verb.cpp deleted file mode 100644 index 23f7c92..0000000 --- a/verbly/lib/verb.cpp +++ /dev/null
@@ -1,193 +0,0 @@
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/verbly/lib/verb.h b/verbly/lib/verb.h deleted file mode 100644 index 7cc87e2..0000000 --- a/verbly/lib/verb.h +++ /dev/null
@@ -1,73 +0,0 @@
1#ifndef VERB_H_BCC929AD
2#define VERB_H_BCC929AD
3
4namespace verbly {
5
6 /*class frame_part {
7
8 };
9
10 class frame {
11 private:
12 std::list<frame_part> content;
13 std::map<std::string, std::vector<std::list<frame_part>::iterator>> predicates;
14
15 public:
16 frame(std::list<frame_part> content) : content(content)
17 {
18
19 }
20
21 std::unique_ptr<token> make_utterance() const
22 {
23
24 }
25 };*/
26
27 class verb : public word {
28 private:
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;
36
37 public:
38 verb(const data& _data, int _id);
39
40 std::string base_form() const;
41 std::string infinitive_form() const;
42 std::string past_tense_form() const;
43 std::string past_participle_form() const;
44 std::string ing_form() const;
45 std::string s_form() const;
46 };
47
48 class verb_query {
49 public:
50 verb_query(const data& _data);
51
52 verb_query& limit(int _limit);
53 verb_query& random(bool _random);
54 verb_query& except(const verb& _word);
55 verb_query& rhymes_with(const word& _word);
56 verb_query& has_pronunciation(bool _has_prn);
57
58 std::list<verb> run() const;
59
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;
69 };
70
71};
72
73#endif /* end of include guard: VERB_H_BCC929AD */
diff --git a/verbly/lib/verbly.h b/verbly/lib/verbly.h deleted file mode 100644 index b9f5367..0000000 --- a/verbly/lib/verbly.h +++ /dev/null
@@ -1,14 +0,0 @@
1#ifndef VERBLY_H_5B39CE50
2#define VERBLY_H_5B39CE50
3
4#include "c++14.h"
5#include "util.h"
6#include "token.h"
7#include "data.h"
8#include "word.h"
9#include "verb.h"
10#include "adverb.h"
11#include "adjective.h"
12#include "noun.h"
13
14#endif /* end of include guard: VERBLY_H_5B39CE50 */
diff --git a/verbly/lib/word.cpp b/verbly/lib/word.cpp deleted file mode 100644 index c50e7d3..0000000 --- a/verbly/lib/word.cpp +++ /dev/null
@@ -1,32 +0,0 @@
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/verbly/lib/word.h b/verbly/lib/word.h deleted file mode 100644 index 23ddb2b..0000000 --- a/verbly/lib/word.h +++ /dev/null
@@ -1,35 +0,0 @@
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 */