summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--generator/generator.cpp57
-rw-r--r--generator/schema.sql4
-rw-r--r--lib/adjective_query.cpp147
-rw-r--r--lib/adverb_query.cpp103
-rw-r--r--lib/data.cpp117
-rw-r--r--lib/data.h32
-rw-r--r--lib/frame_query.cpp30
-rw-r--r--lib/noun.cpp17
-rw-r--r--lib/noun.h4
-rw-r--r--lib/noun_query.cpp274
-rw-r--r--lib/noun_query.h6
-rw-r--r--lib/preposition.cpp30
-rw-r--r--lib/verb_query.cpp39
13 files changed, 551 insertions, 309 deletions
diff --git a/generator/generator.cpp b/generator/generator.cpp index 6fbbfb8..e67bda7 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp
@@ -81,6 +81,7 @@ std::map<std::string, verb_t> verbs;
81std::map<std::string, adjective_t> adjectives; 81std::map<std::string, adjective_t> adjectives;
82std::map<std::string, noun_t> nouns; 82std::map<std::string, noun_t> nouns;
83std::map<int, std::map<int, int>> wn; 83std::map<int, std::map<int, int>> wn;
84std::map<int, int> images;
84std::map<std::string, std::set<std::string>> pronunciations; 85std::map<std::string, std::set<std::string>> pronunciations;
85 86
86void print_usage() 87void print_usage()
@@ -89,10 +90,10 @@ void print_usage()
89 std::cout << "-------------------------" << std::endl; 90 std::cout << "-------------------------" << std::endl;
90 std::cout << "Requires exactly six arguments." << std::endl; 91 std::cout << "Requires exactly six arguments." << std::endl;
91 std::cout << "1. The path to a VerbNet data directory." << std::endl; 92 std::cout << "1. The path to a VerbNet data directory." << std::endl;
92 std::cout << "2. The path to a SemLink vnpbMappings file." << std::endl; 93 std::cout << "2. The path to an AGID infl.txt file." << std::endl;
93 std::cout << "3. The path to an AGID infl.txt file." << std::endl; 94 std::cout << "3. The path to a WordNet prolog data directory." << std::endl;
94 std::cout << "4. The path to a WordNet prolog data directory." << std::endl; 95 std::cout << "4. The path to a CMUDICT pronunciation file." << std::endl;
95 std::cout << "5. The path to a CMUDICT pronunciation file." << std::endl; 96 std::cout << "5. The path to an ImageNet urls.txt file." << std::endl;
96 std::cout << "6. Datafile output path." << std::endl; 97 std::cout << "6. Datafile output path." << std::endl;
97 98
98 exit(1); 99 exit(1);
@@ -431,10 +432,10 @@ int main(int argc, char** argv)
431 // Get verbs from AGID 432 // Get verbs from AGID
432 std::cout << "Reading inflections..." << std::endl; 433 std::cout << "Reading inflections..." << std::endl;
433 434
434 std::ifstream agidfile(argv[3]); 435 std::ifstream agidfile(argv[2]);
435 if (!agidfile.is_open()) 436 if (!agidfile.is_open())
436 { 437 {
437 std::cout << "Could not open AGID file: " << argv[3] << std::endl; 438 std::cout << "Could not open AGID file: " << argv[2] << std::endl;
438 print_usage(); 439 print_usage();
439 } 440 }
440 441
@@ -562,10 +563,10 @@ int main(int argc, char** argv)
562 // Pronounciations 563 // Pronounciations
563 std::cout << "Reading pronunciations..." << std::endl; 564 std::cout << "Reading pronunciations..." << std::endl;
564 565
565 std::ifstream pronfile(argv[5]); 566 std::ifstream pronfile(argv[4]);
566 if (!pronfile.is_open()) 567 if (!pronfile.is_open())
567 { 568 {
568 std::cout << "Could not open CMUDICT file: " << argv[5] << std::endl; 569 std::cout << "Could not open CMUDICT file: " << argv[4] << std::endl;
569 print_usage(); 570 print_usage();
570 } 571 }
571 572
@@ -593,6 +594,36 @@ int main(int argc, char** argv)
593 } 594 }
594 } 595 }
595 596
597 // Images
598 std::cout << "Reading images..." << std::endl;
599
600 std::ifstream imagefile(argv[5]);
601 if (!imagefile.is_open())
602 {
603 std::cout << "Could not open ImageNet file: " << argv[5] << std::endl;
604 print_usage();
605 }
606
607 for (;;)
608 {
609 std::string line;
610 if (!getline(imagefile, line))
611 {
612 break;
613 }
614
615 if (line.back() == '\r')
616 {
617 line.pop_back();
618 }
619
620 std::string wnid_s = line.substr(1, 8);
621 int wnid = stoi(wnid_s) + 100000000;
622 images[wnid]++;
623 }
624
625 imagefile.close();
626
596 // Start writing output 627 // Start writing output
597 std::cout << "Writing schema..." << std::endl; 628 std::cout << "Writing schema..." << std::endl;
598 629
@@ -972,7 +1003,7 @@ int main(int argc, char** argv)
972 // - sa: specification (e.g. inaccurate (general) can mean imprecise or incorrect (specific)) 1003 // - sa: specification (e.g. inaccurate (general) can mean imprecise or incorrect (specific))
973 // - sim: synonymy (e.g. cheerful/happy, happy/cheerful) 1004 // - sim: synonymy (e.g. cheerful/happy, happy/cheerful)
974 // - syntax: positioning flags for some adjectives 1005 // - syntax: positioning flags for some adjectives
975 std::string wnpref {argv[4]}; 1006 std::string wnpref {argv[3]};
976 if (wnpref.back() != '/') 1007 if (wnpref.back() != '/')
977 { 1008 {
978 wnpref += '/'; 1009 wnpref += '/';
@@ -1027,9 +1058,9 @@ int main(int argc, char** argv)
1027 { 1058 {
1028 if (nouns.count(word) == 1) 1059 if (nouns.count(word) == 1)
1029 { 1060 {
1030 query = "INSERT INTO nouns (singular, proper, complexity, plural) VALUES (?, ?, ?, ?)"; 1061 query = "INSERT INTO nouns (singular, proper, complexity, images, wnid, plural) VALUES (?, ?, ?, ?, ?, ?)";
1031 } else { 1062 } else {
1032 query = "INSERT INTO nouns (singular, proper, complexity) VALUES (?, ?, ?)"; 1063 query = "INSERT INTO nouns (singular, proper, complexity, images, wnid) VALUES (?, ?, ?, ?, ?)";
1033 } 1064 }
1034 1065
1035 break; 1066 break;
@@ -1083,10 +1114,12 @@ int main(int argc, char** argv)
1083 }) ? 1 : 0)); 1114 }) ? 1 : 0));
1084 1115
1085 sqlite3_bind_int(ppstmt, 3, verbly::split<std::list<std::string>>(word, " ").size()); 1116 sqlite3_bind_int(ppstmt, 3, verbly::split<std::list<std::string>>(word, " ").size());
1117 sqlite3_bind_int(ppstmt, 4, images[synset_id]);
1118 sqlite3_bind_int(ppstmt, 5, synset_id);
1086 1119
1087 if (nouns.count(word) == 1) 1120 if (nouns.count(word) == 1)
1088 { 1121 {
1089 sqlite3_bind_text(ppstmt, 4, nouns[word].plural.c_str(), nouns[word].plural.length(), SQLITE_STATIC); 1122 sqlite3_bind_text(ppstmt, 6, nouns[word].plural.c_str(), nouns[word].plural.length(), SQLITE_STATIC);
1090 } 1123 }
1091 1124
1092 break; 1125 break;
diff --git a/generator/schema.sql b/generator/schema.sql index f2445f0..9a39944 100644 --- a/generator/schema.sql +++ b/generator/schema.sql
@@ -55,7 +55,9 @@ CREATE TABLE `nouns` (
55 `singular` VARCHAR(32) NOT NULL, 55 `singular` VARCHAR(32) NOT NULL,
56 `plural` VARCHAR(32), 56 `plural` VARCHAR(32),
57 `proper` INTEGER(1) NOT NULL, 57 `proper` INTEGER(1) NOT NULL,
58 `complexity` INTEGER NOT NULL 58 `complexity` INTEGER NOT NULL,
59 `images` INTEGER NOT NULL,
60 `wnid` INTEGER NOT NULL
59); 61);
60 62
61DROP TABLE IF EXISTS `hypernymy`; 63DROP TABLE IF EXISTS `hypernymy`;
diff --git a/lib/adjective_query.cpp b/lib/adjective_query.cpp index 283fdca..a7f915c 100644 --- a/lib/adjective_query.cpp +++ b/lib/adjective_query.cpp
@@ -218,6 +218,7 @@ namespace verbly {
218 std::stringstream construct; 218 std::stringstream construct;
219 construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives"; 219 construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives";
220 std::list<std::string> conditions; 220 std::list<std::string> conditions;
221 std::list<binding> bindings;
221 222
222 if (_has_prn) 223 if (_has_prn)
223 { 224 {
@@ -226,14 +227,20 @@ namespace verbly {
226 227
227 if (!_rhymes.empty()) 228 if (!_rhymes.empty())
228 { 229 {
229 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); 230 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?");
230 std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; 231 std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
231 conditions.push_back(cond); 232 conditions.push_back(cond);
233
234 for (auto rhyme : _rhymes)
235 {
236 bindings.emplace_back("%" + rhyme);
237 }
232 } 238 }
233 239
234 for (auto except : _except) 240 for (auto except : _except)
235 { 241 {
236 conditions.push_back("adjective_id != @EXCID"); 242 conditions.push_back("adjective_id != ?");
243 bindings.emplace_back(except._id);
237 } 244 }
238 245
239 if (_requires_comparative_form) 246 if (_requires_comparative_form)
@@ -261,11 +268,13 @@ namespace verbly {
261 { 268 {
262 case filter<std::string>::type::singleton: 269 case filter<std::string>::type::singleton:
263 { 270 {
271 bindings.emplace_back(f.get_elem() + "%");
272
264 if (notlogic == f.get_notlogic()) 273 if (notlogic == f.get_notlogic())
265 { 274 {
266 return "base_form LIKE @PREFIX"; 275 return "base_form LIKE ?";
267 } else { 276 } else {
268 return "base_form NOT LIKE @PREFIX"; 277 return "base_form NOT LIKE ?";
269 } 278 }
270 } 279 }
271 280
@@ -298,11 +307,13 @@ namespace verbly {
298 { 307 {
299 case filter<std::string>::type::singleton: 308 case filter<std::string>::type::singleton:
300 { 309 {
310 bindings.emplace_back("%" + f.get_elem());
311
301 if (notlogic == f.get_notlogic()) 312 if (notlogic == f.get_notlogic())
302 { 313 {
303 return "base_form LIKE @SUFFIX"; 314 return "base_form LIKE ?";
304 } else { 315 } else {
305 return "base_form NOT LIKE @SUFFIX"; 316 return "base_form NOT LIKE ?";
306 } 317 }
307 } 318 }
308 319
@@ -330,7 +341,8 @@ namespace verbly {
330 341
331 if (_with_complexity != unlimited) 342 if (_with_complexity != unlimited)
332 { 343 {
333 conditions.push_back("complexity = @COMPLEX"); 344 conditions.push_back("complexity = ?");
345 bindings.emplace_back(_with_complexity);
334 } 346 }
335 347
336 if (_is_variant) 348 if (_is_variant)
@@ -355,11 +367,13 @@ namespace verbly {
355 { 367 {
356 case filter<noun>::type::singleton: 368 case filter<noun>::type::singleton:
357 { 369 {
370 bindings.emplace_back(f.get_elem()._id);
371
358 if (notlogic == f.get_notlogic()) 372 if (notlogic == f.get_notlogic())
359 { 373 {
360 return "noun_id = @ATTRID"; 374 return "noun_id = ?";
361 } else { 375 } else {
362 return "noun_id != @ATTRID"; 376 return "noun_id != ?";
363 } 377 }
364 } 378 }
365 379
@@ -409,11 +423,13 @@ namespace verbly {
409 { 423 {
410 case filter<adjective>::type::singleton: 424 case filter<adjective>::type::singleton:
411 { 425 {
426 bindings.emplace_back(f.get_elem()._id);
427
412 if (notlogic == f.get_notlogic()) 428 if (notlogic == f.get_notlogic())
413 { 429 {
414 return "adjective_1_id = @ANTID"; 430 return "adjective_1_id = ?";
415 } else { 431 } else {
416 return "adjective_1_id != @ANTID"; 432 return "adjective_1_id != ?";
417 } 433 }
418 } 434 }
419 435
@@ -463,11 +479,13 @@ namespace verbly {
463 { 479 {
464 case filter<adjective>::type::singleton: 480 case filter<adjective>::type::singleton:
465 { 481 {
482 bindings.emplace_back(f.get_elem()._id);
483
466 if (notlogic == f.get_notlogic()) 484 if (notlogic == f.get_notlogic())
467 { 485 {
468 return "adjective_1_id = @SYNID"; 486 return "adjective_1_id = ?";
469 } else { 487 } else {
470 return "adjective_1_id != @SYNID"; 488 return "adjective_1_id != ?";
471 } 489 }
472 } 490 }
473 491
@@ -517,11 +535,13 @@ namespace verbly {
517 { 535 {
518 case filter<adjective>::type::singleton: 536 case filter<adjective>::type::singleton:
519 { 537 {
538 bindings.emplace_back(f.get_elem()._id);
539
520 if (notlogic == f.get_notlogic()) 540 if (notlogic == f.get_notlogic())
521 { 541 {
522 return "specific_id = @SPECID"; 542 return "specific_id = ?";
523 } else { 543 } else {
524 return "specific_id != @SPECID"; 544 return "specific_id != ?";
525 } 545 }
526 } 546 }
527 547
@@ -571,11 +591,13 @@ namespace verbly {
571 { 591 {
572 case filter<adjective>::type::singleton: 592 case filter<adjective>::type::singleton:
573 { 593 {
594 bindings.emplace_back(f.get_elem()._id);
595
574 if (notlogic == f.get_notlogic()) 596 if (notlogic == f.get_notlogic())
575 { 597 {
576 return "general_id = @GENID"; 598 return "general_id = ?";
577 } else { 599 } else {
578 return "general_id != @GENID"; 600 return "general_id != ?";
579 } 601 }
580 } 602 }
581 603
@@ -625,11 +647,13 @@ namespace verbly {
625 { 647 {
626 case filter<noun>::type::singleton: 648 case filter<noun>::type::singleton:
627 { 649 {
650 bindings.emplace_back(f.get_elem()._id);
651
628 if (notlogic == f.get_notlogic()) 652 if (notlogic == f.get_notlogic())
629 { 653 {
630 return "noun_id = @APERID"; 654 return "noun_id = ?";
631 } else { 655 } else {
632 return "noun_id != @APERID"; 656 return "noun_id != ?";
633 } 657 }
634 } 658 }
635 659
@@ -679,11 +703,13 @@ namespace verbly {
679 { 703 {
680 case filter<adverb>::type::singleton: 704 case filter<adverb>::type::singleton:
681 { 705 {
706 bindings.emplace_back(f.get_elem()._id);
707
682 if (notlogic == f.get_notlogic()) 708 if (notlogic == f.get_notlogic())
683 { 709 {
684 return "mannernym_id = @MANID"; 710 return "mannernym_id = ?";
685 } else { 711 } else {
686 return "mannernym_id != @MANID"; 712 return "mannernym_id != ?";
687 } 713 }
688 } 714 }
689 715
@@ -776,74 +802,29 @@ namespace verbly {
776 throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); 802 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
777 } 803 }
778 804
779 if (!_rhymes.empty()) 805 int i = 1;
806 for (auto& binding : bindings)
780 { 807 {
781 int i = 0; 808 switch (binding.get_type())
782 for (auto rhyme : _rhymes)
783 { 809 {
784 std::string rhymer = "%" + rhyme; 810 case binding::type::integer:
785 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); 811 {
812 sqlite3_bind_int(ppstmt, i, binding.get_integer());
813
814 break;
815 }
786 816
787 i++; 817 case binding::type::string:
818 {
819 sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC);
820
821 break;
822 }
788 } 823 }
824
825 i++;
789 } 826 }
790 827
791 for (auto except : _except)
792 {
793 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
794 }
795
796 for (auto prefix : _with_prefix.inorder_flatten())
797 {
798 std::string pfat = prefix + "%";
799 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PREFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC);
800 }
801
802 for (auto suffix : _with_suffix.inorder_flatten())
803 {
804 std::string pfat = "%" + suffix;
805 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SUFFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC);
806 }
807
808 if (_with_complexity != unlimited)
809 {
810 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@COMPLEX"), _with_complexity);
811 }
812
813 for (auto attribute : _variant_of.inorder_flatten())
814 {
815 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id);
816 }
817
818 for (auto antonym : _antonym_of.inorder_flatten())
819 {
820 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id);
821 }
822
823 for (auto synonym : _synonym_of.inorder_flatten())
824 {
825 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id);
826 }
827
828 for (auto specific : _generalization_of.inorder_flatten())
829 {
830 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SPECID"), specific._id);
831 }
832
833 for (auto general : _specification_of.inorder_flatten())
834 {
835 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GENID"), general._id);
836 }
837
838 for (auto n : _pertainym_of.inorder_flatten())
839 {
840 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@APERID"), n._id);
841 }
842
843 for (auto mannernym : _anti_mannernym_of.inorder_flatten())
844 {
845 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MANID"), mannernym._id);
846 }
847 /* 828 /*
848 for (auto adj : _derived_from_adjective) 829 for (auto adj : _derived_from_adjective)
849 { 830 {
diff --git a/lib/adverb_query.cpp b/lib/adverb_query.cpp index c9d0d09..30ba92b 100644 --- a/lib/adverb_query.cpp +++ b/lib/adverb_query.cpp
@@ -172,6 +172,7 @@ namespace verbly {
172 std::stringstream construct; 172 std::stringstream construct;
173 construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs"; 173 construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs";
174 std::list<std::string> conditions; 174 std::list<std::string> conditions;
175 std::list<binding> bindings;
175 176
176 if (_has_prn) 177 if (_has_prn)
177 { 178 {
@@ -180,14 +181,20 @@ namespace verbly {
180 181
181 if (!_rhymes.empty()) 182 if (!_rhymes.empty())
182 { 183 {
183 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); 184 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?");
184 std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; 185 std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
185 conditions.push_back(cond); 186 conditions.push_back(cond);
187
188 for (auto rhyme : _rhymes)
189 {
190 bindings.emplace_back("%" + rhyme);
191 }
186 } 192 }
187 193
188 for (auto except : _except) 194 for (auto except : _except)
189 { 195 {
190 conditions.push_back("adverb_id != @EXCID"); 196 conditions.push_back("adverb_id != ?");
197 bindings.emplace_back(except._id);
191 } 198 }
192 199
193 if (_requires_comparative_form) 200 if (_requires_comparative_form)
@@ -207,11 +214,13 @@ namespace verbly {
207 { 214 {
208 case filter<std::string>::type::singleton: 215 case filter<std::string>::type::singleton:
209 { 216 {
217 bindings.emplace_back(f.get_elem() + "%");
218
210 if (notlogic == f.get_notlogic()) 219 if (notlogic == f.get_notlogic())
211 { 220 {
212 return "base_form LIKE @PREFIX"; 221 return "base_form LIKE ?";
213 } else { 222 } else {
214 return "base_form NOT LIKE @PREFIX"; 223 return "base_form NOT LIKE ?";
215 } 224 }
216 } 225 }
217 226
@@ -244,11 +253,13 @@ namespace verbly {
244 { 253 {
245 case filter<std::string>::type::singleton: 254 case filter<std::string>::type::singleton:
246 { 255 {
256 bindings.emplace_back("%" + f.get_elem());
257
247 if (notlogic == f.get_notlogic()) 258 if (notlogic == f.get_notlogic())
248 { 259 {
249 return "base_form LIKE @SUFFIX"; 260 return "base_form LIKE ?";
250 } else { 261 } else {
251 return "base_form NOT LIKE @SUFFIX"; 262 return "base_form NOT LIKE ?";
252 } 263 }
253 } 264 }
254 265
@@ -276,7 +287,8 @@ namespace verbly {
276 287
277 if (_with_complexity != unlimited) 288 if (_with_complexity != unlimited)
278 { 289 {
279 conditions.push_back("complexity = @COMPLEX"); 290 conditions.push_back("complexity = ?");
291 bindings.emplace_back(_with_complexity);
280 } 292 }
281 293
282 if (_has_antonyms) 294 if (_has_antonyms)
@@ -301,11 +313,13 @@ namespace verbly {
301 { 313 {
302 case filter<adverb>::type::singleton: 314 case filter<adverb>::type::singleton:
303 { 315 {
316 bindings.emplace_back(f.get_elem()._id);
317
304 if (notlogic == f.get_notlogic()) 318 if (notlogic == f.get_notlogic())
305 { 319 {
306 return "adverb_1_id = @ANTID"; 320 return "adverb_1_id = ?";
307 } else { 321 } else {
308 return "adverb_1_id != @ANTID"; 322 return "adverb_1_id != ?";
309 } 323 }
310 } 324 }
311 325
@@ -355,11 +369,13 @@ namespace verbly {
355 { 369 {
356 case filter<adverb>::type::singleton: 370 case filter<adverb>::type::singleton:
357 { 371 {
372 bindings.emplace_back(f.get_elem()._id);
373
358 if (notlogic == f.get_notlogic()) 374 if (notlogic == f.get_notlogic())
359 { 375 {
360 return "adverb_1_id = @SYNID"; 376 return "adverb_1_id = ?";
361 } else { 377 } else {
362 return "adverb_1_id != @SYNID"; 378 return "adverb_1_id != ?";
363 } 379 }
364 } 380 }
365 381
@@ -409,11 +425,13 @@ namespace verbly {
409 { 425 {
410 case filter<adjective>::type::singleton: 426 case filter<adjective>::type::singleton:
411 { 427 {
428 bindings.emplace_back(f.get_elem()._id);
429
412 if (notlogic == f.get_notlogic()) 430 if (notlogic == f.get_notlogic())
413 { 431 {
414 return "adjective_id = @AMANID"; 432 return "adjective_id = ?";
415 } else { 433 } else {
416 return "adjective_id != @AMANID"; 434 return "adjective_id != ?";
417 } 435 }
418 } 436 }
419 437
@@ -506,54 +524,29 @@ namespace verbly {
506 throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); 524 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
507 } 525 }
508 526
509 if (!_rhymes.empty()) 527 int i = 1;
528 for (auto& binding : bindings)
510 { 529 {
511 int i = 0; 530 switch (binding.get_type())
512 for (auto rhyme : _rhymes)
513 { 531 {
514 std::string rhymer = "%" + rhyme; 532 case binding::type::integer:
515 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); 533 {
534 sqlite3_bind_int(ppstmt, i, binding.get_integer());
535
536 break;
537 }
516 538
517 i++; 539 case binding::type::string:
540 {
541 sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC);
542
543 break;
544 }
518 } 545 }
546
547 i++;
519 } 548 }
520 549
521 for (auto except : _except)
522 {
523 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
524 }
525
526 for (auto prefix : _with_prefix.inorder_flatten())
527 {
528 std::string pfat = prefix + "%";
529 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PREFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC);
530 }
531
532 for (auto suffix : _with_suffix.inorder_flatten())
533 {
534 std::string pfat = "%" + suffix;
535 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SUFFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC);
536 }
537
538 if (_with_complexity != unlimited)
539 {
540 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@COMPLEX"), _with_complexity);
541 }
542
543 for (auto antonym : _antonym_of.inorder_flatten())
544 {
545 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id);
546 }
547
548 for (auto synonym : _synonym_of.inorder_flatten())
549 {
550 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id);
551 }
552
553 for (auto adj : _mannernym_of.inorder_flatten())
554 {
555 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id);
556 }
557 /* 550 /*
558 for (auto adj : _derived_from_adjective) 551 for (auto adj : _derived_from_adjective)
559 { 552 {
diff --git a/lib/data.cpp b/lib/data.cpp index 5a9397b..c14956f 100644 --- a/lib/data.cpp +++ b/lib/data.cpp
@@ -57,4 +57,121 @@ namespace verbly {
57 return preposition_query(*this); 57 return preposition_query(*this);
58 } 58 }
59 59
60 binding::type binding::get_type() const
61 {
62 return _type;
63 }
64
65 binding::binding(const binding& other)
66 {
67 _type = other._type;
68
69 switch (_type)
70 {
71 case type::integer:
72 {
73 _integer = other._integer;
74
75 break;
76 }
77
78 case type::string:
79 {
80 new(&_string) std::string(other._string);
81
82 break;
83 }
84 }
85 }
86
87 binding::~binding()
88 {
89 switch (_type)
90 {
91 case type::string:
92 {
93 using string_type = std::string;
94 _string.~string_type();
95
96 break;
97 }
98 }
99 }
100
101 binding& binding::operator=(const binding& other)
102 {
103 this->~binding();
104
105 _type = other._type;
106
107 switch (_type)
108 {
109 case type::integer:
110 {
111 _integer = other._integer;
112
113 break;
114 }
115
116 case type::string:
117 {
118 new(&_string) std::string(other._string);
119
120 break;
121 }
122 }
123
124 return *this;
125 }
126
127 binding::binding(int _arg)
128 {
129 _type = type::integer;
130 _integer = _arg;
131 }
132
133 int binding::get_integer() const
134 {
135 assert(_type == type::integer);
136
137 return _integer;
138 }
139
140 void binding::set_integer(int _arg)
141 {
142 *this = binding(_arg);
143 }
144
145 binding& binding::operator=(int _arg)
146 {
147 *this = binding(_arg);
148
149 return *this;
150 }
151
152 binding::binding(std::string _arg)
153 {
154 _type = type::string;
155 new(&_string) std::string(_arg);
156 }
157
158 std::string binding::get_string() const
159 {
160 assert(_type == type::string);
161
162 return _string;
163 }
164
165 void binding::set_string(std::string _arg)
166 {
167 *this = binding(_arg);
168 }
169
170 binding& binding::operator=(std::string _arg)
171 {
172 *this = binding(_arg);
173
174 return *this;
175 }
176
60}; 177};
diff --git a/lib/data.h b/lib/data.h index 0d599c4..b8b12b9 100644 --- a/lib/data.h +++ b/lib/data.h
@@ -343,6 +343,38 @@ namespace verbly {
343 }; 343 };
344 }; 344 };
345 345
346 class binding {
347 public:
348 enum class type {
349 integer,
350 string
351 };
352
353 type get_type() const;
354 binding(const binding& other);
355 ~binding();
356 binding& operator=(const binding& other);
357
358 // Integer
359 binding(int _arg);
360 int get_integer() const;
361 void set_integer(int _arg);
362 binding& operator=(int _arg);
363
364 // String
365 binding(std::string _arg);
366 std::string get_string() const;
367 void set_string(std::string _arg);
368 binding& operator=(std::string _arg);
369
370 private:
371 union {
372 int _integer;
373 std::string _string;
374 };
375 type _type;
376 };
377
346}; 378};
347 379
348#endif /* end of include guard: DATA_H_C4AEC3DD */ 380#endif /* end of include guard: DATA_H_C4AEC3DD */
diff --git a/lib/frame_query.cpp b/lib/frame_query.cpp index 6583da4..3c4a3e8 100644 --- a/lib/frame_query.cpp +++ b/lib/frame_query.cpp
@@ -37,13 +37,19 @@ namespace verbly {
37 { 37 {
38 std::stringstream construct; 38 std::stringstream construct;
39 construct << "SELECT frames.data, groups.data FROM frames INNER JOIN groups ON frames.group_id = groups.group_id"; 39 construct << "SELECT frames.data, groups.data FROM frames INNER JOIN groups ON frames.group_id = groups.group_id";
40 std::list<binding> bindings;
40 41
41 if (!_for_verb.empty()) 42 if (!_for_verb.empty())
42 { 43 {
43 std::list<std::string> clauses(_for_verb.size(), "verb_id = @VERID"); 44 std::list<std::string> clauses(_for_verb.size(), "verb_id = ?");
44 construct << " WHERE frames.group_id IN (SELECT group_id FROM verb_groups WHERE "; 45 construct << " WHERE frames.group_id IN (SELECT group_id FROM verb_groups WHERE ";
45 construct << verbly::implode(std::begin(clauses), std::end(clauses), " OR "); 46 construct << verbly::implode(std::begin(clauses), std::end(clauses), " OR ");
46 construct << ")"; 47 construct << ")";
48
49 for (auto v : _for_verb)
50 {
51 bindings.emplace_back(v._id);
52 }
47 } 53 }
48 54
49 sqlite3_stmt* ppstmt; 55 sqlite3_stmt* ppstmt;
@@ -53,9 +59,27 @@ namespace verbly {
53 throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); 59 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
54 } 60 }
55 61
56 for (auto verb : _for_verb) 62 int i = 1;
63 for (auto& binding : bindings)
57 { 64 {
58 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VERID"), verb._id); 65 switch (binding.get_type())
66 {
67 case binding::type::integer:
68 {
69 sqlite3_bind_int(ppstmt, i, binding.get_integer());
70
71 break;
72 }
73
74 case binding::type::string:
75 {
76 sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC);
77
78 break;
79 }
80 }
81
82 i++;
59 } 83 }
60 84
61 std::list<frame> output; 85 std::list<frame> output;
diff --git a/lib/noun.cpp b/lib/noun.cpp index 71c9af0..d8b34c9 100644 --- a/lib/noun.cpp +++ b/lib/noun.cpp
@@ -34,6 +34,13 @@ namespace verbly {
34 34
35 return _plural; 35 return _plural;
36 } 36 }
37
38 int noun::wnid() const
39 {
40 assert(_valid == true);
41
42 return _wnid;
43 }
37 44
38 bool noun::has_plural_form() const 45 bool noun::has_plural_form() const
39 { 46 {
@@ -196,6 +203,16 @@ namespace verbly {
196 return _data->adjectives().variant_of(*this); 203 return _data->adjectives().variant_of(*this);
197 } 204 }
198 205
206 std::string noun::imagenet_url() const
207 {
208 std::stringstream url;
209 url << "http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=n";
210 url.width(8);
211 url.fill('0');
212 url << (_wnid % 100000000);
213 return url.str();
214 }
215
199 bool noun::operator<(const noun& other) const 216 bool noun::operator<(const noun& other) const
200 { 217 {
201 return _id < other._id; 218 return _id < other._id;
diff --git a/lib/noun.h b/lib/noun.h index 969d2c8..bd71e57 100644 --- a/lib/noun.h +++ b/lib/noun.h
@@ -7,6 +7,7 @@ namespace verbly {
7 private: 7 private:
8 std::string _singular; 8 std::string _singular;
9 std::string _plural; 9 std::string _plural;
10 int _wnid;
10 11
11 friend class noun_query; 12 friend class noun_query;
12 13
@@ -17,6 +18,7 @@ namespace verbly {
17 std::string base_form() const; 18 std::string base_form() const;
18 std::string singular_form() const; 19 std::string singular_form() const;
19 std::string plural_form() const; 20 std::string plural_form() const;
21 int wnid() const;
20 22
21 bool has_plural_form() const; 23 bool has_plural_form() const;
22 24
@@ -43,6 +45,8 @@ namespace verbly {
43 adjective_query pertainyms() const; 45 adjective_query pertainyms() const;
44 adjective_query variations() const; 46 adjective_query variations() const;
45 47
48 std::string imagenet_url() const;
49
46 bool operator<(const noun& other) const; 50 bool operator<(const noun& other) const;
47 }; 51 };
48 52
diff --git a/lib/noun_query.cpp b/lib/noun_query.cpp index 83bb47d..19a1297 100644 --- a/lib/noun_query.cpp +++ b/lib/noun_query.cpp
@@ -370,6 +370,21 @@ namespace verbly {
370 370
371 return *this; 371 return *this;
372 } 372 }
373
374 noun_query& noun_query::at_least_n_images(int _arg)
375 {
376 _at_least_n_images = _arg;
377
378 return *this;
379 }
380
381 noun_query& noun_query::with_wnid(int _arg)
382 {
383 _with_wnid.insert(_arg);
384
385 return *this;
386 }
387
373 /* 388 /*
374 noun_query& noun_query::derived_from(const word& _w) 389 noun_query& noun_query::derived_from(const word& _w)
375 { 390 {
@@ -457,8 +472,9 @@ namespace verbly {
457 construct << " "; 472 construct << " ";
458 } 473 }
459 474
460 construct << "SELECT noun_id, singular, plural FROM nouns"; 475 construct << "SELECT noun_id, singular, plural, wnid FROM nouns";
461 std::list<std::string> conditions; 476 std::list<std::string> conditions;
477 std::list<binding> bindings;
462 478
463 if (_has_prn) 479 if (_has_prn)
464 { 480 {
@@ -467,21 +483,32 @@ namespace verbly {
467 483
468 if (!_rhymes.empty()) 484 if (!_rhymes.empty())
469 { 485 {
470 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); 486 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?");
471 std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; 487 std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
472 conditions.push_back(cond); 488 conditions.push_back(cond);
489
490 for (auto rhyme : _rhymes)
491 {
492 bindings.emplace_back("%" + rhyme);
493 }
473 } 494 }
474 495
475 for (auto except : _except) 496 for (auto except : _except)
476 { 497 {
477 conditions.push_back("noun_id != @EXCID"); 498 conditions.push_back("noun_id != ?");
499 bindings.emplace_back(except._id);
478 } 500 }
479 501
480 if (!_with_singular_form.empty()) 502 if (!_with_singular_form.empty())
481 { 503 {
482 std::list<std::string> clauses(_with_singular_form.size(), "singular = @SFORM"); 504 std::list<std::string> clauses(_with_singular_form.size(), "singular = ?");
483 std::string cond = "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; 505 std::string cond = "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
484 conditions.push_back(cond); 506 conditions.push_back(cond);
507
508 for (auto form : _with_singular_form)
509 {
510 bindings.emplace_back(form);
511 }
485 } 512 }
486 513
487 if (!_with_prefix.empty()) 514 if (!_with_prefix.empty())
@@ -491,11 +518,13 @@ namespace verbly {
491 { 518 {
492 case filter<std::string>::type::singleton: 519 case filter<std::string>::type::singleton:
493 { 520 {
521 bindings.emplace_back(f.get_elem() + "%");
522
494 if (notlogic == f.get_notlogic()) 523 if (notlogic == f.get_notlogic())
495 { 524 {
496 return "singular LIKE @PREFIX"; 525 return "singular LIKE ?";
497 } else { 526 } else {
498 return "singular NOT LIKE @PREFIX"; 527 return "singular NOT LIKE ?";
499 } 528 }
500 } 529 }
501 530
@@ -528,11 +557,13 @@ namespace verbly {
528 { 557 {
529 case filter<std::string>::type::singleton: 558 case filter<std::string>::type::singleton:
530 { 559 {
560 bindings.emplace_back("%" + f.get_elem());
561
531 if (notlogic == f.get_notlogic()) 562 if (notlogic == f.get_notlogic())
532 { 563 {
533 return "singular LIKE @SUFFIX"; 564 return "singular LIKE ?";
534 } else { 565 } else {
535 return "singular NOT LIKE @SUFFIX"; 566 return "singular NOT LIKE ?";
536 } 567 }
537 } 568 }
538 569
@@ -560,7 +591,8 @@ namespace verbly {
560 591
561 if (_with_complexity != unlimited) 592 if (_with_complexity != unlimited)
562 { 593 {
563 conditions.push_back("complexity = @COMPLEX"); 594 conditions.push_back("complexity = ?");
595 bindings.emplace_back(_with_complexity);
564 } 596 }
565 597
566 if (_is_hypernym) 598 if (_is_hypernym)
@@ -585,11 +617,13 @@ namespace verbly {
585 { 617 {
586 case filter<noun>::type::singleton: 618 case filter<noun>::type::singleton:
587 { 619 {
620 bindings.emplace_back(f.get_elem()._id);
621
588 if (notlogic == f.get_notlogic()) 622 if (notlogic == f.get_notlogic())
589 { 623 {
590 return "hyponym_id = @HYPO"; 624 return "hyponym_id = ?";
591 } else { 625 } else {
592 return "hyponym_id != @HYPO"; 626 return "hyponym_id != ?";
593 } 627 }
594 } 628 }
595 629
@@ -713,11 +747,13 @@ namespace verbly {
713 { 747 {
714 case filter<noun>::type::singleton: 748 case filter<noun>::type::singleton:
715 { 749 {
750 bindings.emplace_back(f.get_elem()._id);
751
716 if (notlogic == f.get_notlogic()) 752 if (notlogic == f.get_notlogic())
717 { 753 {
718 return "hypernym_id = @HYPER"; 754 return "hypernym_id = ?";
719 } else { 755 } else {
720 return "hypernym_id != @HYPER"; 756 return "hypernym_id != ?";
721 } 757 }
722 } 758 }
723 759
@@ -767,11 +803,13 @@ namespace verbly {
767 { 803 {
768 case filter<noun>::type::singleton: 804 case filter<noun>::type::singleton:
769 { 805 {
806 bindings.emplace_back(f.get_elem()._id);
807
770 if (notlogic == f.get_notlogic()) 808 if (notlogic == f.get_notlogic())
771 { 809 {
772 return "holonym_id = @PHOLO"; 810 return "holonym_id = ?";
773 } else { 811 } else {
774 return "holonym_id != @PHOLO"; 812 return "holonym_id != ?";
775 } 813 }
776 } 814 }
777 815
@@ -858,11 +896,13 @@ namespace verbly {
858 { 896 {
859 case filter<noun>::type::singleton: 897 case filter<noun>::type::singleton:
860 { 898 {
899 bindings.emplace_back(f.get_elem()._id);
900
861 if (notlogic == f.get_notlogic()) 901 if (notlogic == f.get_notlogic())
862 { 902 {
863 return "meronym_id = @PMERO"; 903 return "meronym_id = ?";
864 } else { 904 } else {
865 return "meronym_id != @PMERO"; 905 return "meronym_id != ?";
866 } 906 }
867 } 907 }
868 908
@@ -949,11 +989,13 @@ namespace verbly {
949 { 989 {
950 case filter<noun>::type::singleton: 990 case filter<noun>::type::singleton:
951 { 991 {
992 bindings.emplace_back(f.get_elem()._id);
993
952 if (notlogic == f.get_notlogic()) 994 if (notlogic == f.get_notlogic())
953 { 995 {
954 return "holonym_id = @SHOLO"; 996 return "holonym_id = ?";
955 } else { 997 } else {
956 return "holonym_id != @SHOLO"; 998 return "holonym_id != ?";
957 } 999 }
958 } 1000 }
959 1001
@@ -1040,11 +1082,13 @@ namespace verbly {
1040 { 1082 {
1041 case filter<noun>::type::singleton: 1083 case filter<noun>::type::singleton:
1042 { 1084 {
1085 bindings.emplace_back(f.get_elem()._id);
1086
1043 if (notlogic == f.get_notlogic()) 1087 if (notlogic == f.get_notlogic())
1044 { 1088 {
1045 return "meronym_id = @SMERO"; 1089 return "meronym_id = ?";
1046 } else { 1090 } else {
1047 return "meronym_id != @SMERO"; 1091 return "meronym_id != ?";
1048 } 1092 }
1049 } 1093 }
1050 1094
@@ -1131,11 +1175,13 @@ namespace verbly {
1131 { 1175 {
1132 case filter<noun>::type::singleton: 1176 case filter<noun>::type::singleton:
1133 { 1177 {
1178 bindings.emplace_back(f.get_elem()._id);
1179
1134 if (notlogic == f.get_notlogic()) 1180 if (notlogic == f.get_notlogic())
1135 { 1181 {
1136 return "holonym_id = @MHOLO"; 1182 return "holonym_id = ?";
1137 } else { 1183 } else {
1138 return "holonym_id != @MHOLO"; 1184 return "holonym_id != ?";
1139 } 1185 }
1140 } 1186 }
1141 1187
@@ -1222,11 +1268,13 @@ namespace verbly {
1222 { 1268 {
1223 case filter<noun>::type::singleton: 1269 case filter<noun>::type::singleton:
1224 { 1270 {
1271 bindings.emplace_back(f.get_elem()._id);
1272
1225 if (notlogic == f.get_notlogic()) 1273 if (notlogic == f.get_notlogic())
1226 { 1274 {
1227 return "meronym_id = @MMERO"; 1275 return "meronym_id = ?";
1228 } else { 1276 } else {
1229 return "meronym_id != @MMERO"; 1277 return "meronym_id != ?";
1230 } 1278 }
1231 } 1279 }
1232 1280
@@ -1323,11 +1371,13 @@ namespace verbly {
1323 { 1371 {
1324 case filter<noun>::type::singleton: 1372 case filter<noun>::type::singleton:
1325 { 1373 {
1374 bindings.emplace_back(f.get_elem()._id);
1375
1326 if (notlogic == f.get_notlogic()) 1376 if (notlogic == f.get_notlogic())
1327 { 1377 {
1328 return "class_id = @CLSID"; 1378 return "class_id = ?";
1329 } else { 1379 } else {
1330 return "class_id != @CLSID"; 1380 return "class_id != ?";
1331 } 1381 }
1332 } 1382 }
1333 1383
@@ -1377,11 +1427,13 @@ namespace verbly {
1377 { 1427 {
1378 case filter<noun>::type::singleton: 1428 case filter<noun>::type::singleton:
1379 { 1429 {
1430 bindings.emplace_back(f.get_elem()._id);
1431
1380 if (notlogic == f.get_notlogic()) 1432 if (notlogic == f.get_notlogic())
1381 { 1433 {
1382 return "instance_id = @INSID"; 1434 return "instance_id = ?";
1383 } else { 1435 } else {
1384 return "instance_id != @INSID"; 1436 return "instance_id != ?";
1385 } 1437 }
1386 } 1438 }
1387 1439
@@ -1431,11 +1483,13 @@ namespace verbly {
1431 { 1483 {
1432 case filter<noun>::type::singleton: 1484 case filter<noun>::type::singleton:
1433 { 1485 {
1486 bindings.emplace_back(f.get_elem()._id);
1487
1434 if (notlogic == f.get_notlogic()) 1488 if (notlogic == f.get_notlogic())
1435 { 1489 {
1436 return "noun_1_id = @SYNID"; 1490 return "noun_1_id = ?";
1437 } else { 1491 } else {
1438 return "noun_1_id != @SYNID"; 1492 return "noun_1_id != ?";
1439 } 1493 }
1440 } 1494 }
1441 1495
@@ -1485,11 +1539,13 @@ namespace verbly {
1485 { 1539 {
1486 case filter<noun>::type::singleton: 1540 case filter<noun>::type::singleton:
1487 { 1541 {
1542 bindings.emplace_back(f.get_elem()._id);
1543
1488 if (notlogic == f.get_notlogic()) 1544 if (notlogic == f.get_notlogic())
1489 { 1545 {
1490 return "noun_1_id = @ANTID"; 1546 return "noun_1_id = ?";
1491 } else { 1547 } else {
1492 return "noun_1_id != @ANTID"; 1548 return "noun_1_id != ?";
1493 } 1549 }
1494 } 1550 }
1495 1551
@@ -1539,11 +1595,13 @@ namespace verbly {
1539 { 1595 {
1540 case filter<adjective>::type::singleton: 1596 case filter<adjective>::type::singleton:
1541 { 1597 {
1598 bindings.emplace_back(f.get_elem()._id);
1599
1542 if (notlogic == f.get_notlogic()) 1600 if (notlogic == f.get_notlogic())
1543 { 1601 {
1544 return "pertainym_id = @PERID"; 1602 return "pertainym_id = ?";
1545 } else { 1603 } else {
1546 return "pertainym_id != @PERID"; 1604 return "pertainym_id != ?";
1547 } 1605 }
1548 } 1606 }
1549 1607
@@ -1593,11 +1651,13 @@ namespace verbly {
1593 { 1651 {
1594 case filter<adjective>::type::singleton: 1652 case filter<adjective>::type::singleton:
1595 { 1653 {
1654 bindings.emplace_back(f.get_elem()._id);
1655
1596 if (notlogic == f.get_notlogic()) 1656 if (notlogic == f.get_notlogic())
1597 { 1657 {
1598 return "adjective_id = @VALID"; 1658 return "adjective_id = ?";
1599 } else { 1659 } else {
1600 return "adjective_id != @VALID"; 1660 return "adjective_id != ?";
1601 } 1661 }
1602 } 1662 }
1603 1663
@@ -1624,6 +1684,25 @@ namespace verbly {
1624 cond << ")"; 1684 cond << ")";
1625 conditions.push_back(cond.str()); 1685 conditions.push_back(cond.str());
1626 } 1686 }
1687
1688 if (_at_least_n_images != unlimited)
1689 {
1690 conditions.push_back("images >= ?");
1691 bindings.emplace_back(_at_least_n_images);
1692 }
1693
1694 if (!_with_wnid.empty())
1695 {
1696 std::vector<std::string> clauses(_with_wnid.size(), "wnid = ?");
1697 std::string cond = verbly::implode(std::begin(clauses), std::end(clauses), " OR ");
1698 conditions.push_back("(" + cond + ")");
1699
1700 for (auto wnid : _with_wnid)
1701 {
1702 bindings.emplace_back(wnid);
1703 }
1704 }
1705
1627 /* 1706 /*
1628 if (!_derived_from_adjective.empty()) 1707 if (!_derived_from_adjective.empty())
1629 { 1708 {
@@ -1690,114 +1769,29 @@ namespace verbly {
1690 throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); 1769 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
1691 } 1770 }
1692 1771
1693 if (!_rhymes.empty()) 1772 int i = 1;
1773 for (auto& binding : bindings)
1694 { 1774 {
1695 int i = 0; 1775 switch (binding.get_type())
1696 for (auto rhyme : _rhymes)
1697 { 1776 {
1698 std::string rhymer = "%" + rhyme; 1777 case binding::type::integer:
1699 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); 1778 {
1779 sqlite3_bind_int(ppstmt, i, binding.get_integer());
1780
1781 break;
1782 }
1700 1783
1701 i++; 1784 case binding::type::string:
1785 {
1786 sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC);
1787
1788 break;
1789 }
1702 } 1790 }
1791
1792 i++;
1703 } 1793 }
1704 1794
1705 for (auto except : _except)
1706 {
1707 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
1708 }
1709
1710 for (auto sform : _with_singular_form)
1711 {
1712 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SFORM"), sform.c_str(), sform.size(), SQLITE_STATIC);
1713 }
1714
1715 for (auto prefix : _with_prefix.inorder_flatten())
1716 {
1717 std::string pfat = prefix + "%";
1718 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PREFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC);
1719 }
1720
1721 for (auto suffix : _with_suffix.inorder_flatten())
1722 {
1723 std::string pfat = "%" + suffix;
1724 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SUFFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC);
1725 }
1726
1727 if (_with_complexity != unlimited)
1728 {
1729 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@COMPLEX"), _with_complexity);
1730 }
1731
1732 for (auto hyponym : _hypernym_of.inorder_flatten())
1733 {
1734 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPO"), hyponym._id);
1735 }
1736
1737 for (auto hypernym : _hyponym_of.inorder_flatten())
1738 {
1739 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPER"), hypernym._id);
1740 }
1741
1742 for (auto holonym : _part_meronym_of.inorder_flatten())
1743 {
1744 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PHOLO"), holonym._id);
1745 }
1746
1747 for (auto meronym : _part_holonym_of.inorder_flatten())
1748 {
1749 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PMERO"), meronym._id);
1750 }
1751
1752 for (auto holonym : _substance_meronym_of.inorder_flatten())
1753 {
1754 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SHOLO"), holonym._id);
1755 }
1756
1757 for (auto meronym : _substance_holonym_of.inorder_flatten())
1758 {
1759 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SMERO"), meronym._id);
1760 }
1761
1762 for (auto holonym : _member_meronym_of.inorder_flatten())
1763 {
1764 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MHOLO"), holonym._id);
1765 }
1766
1767 for (auto meronym : _member_holonym_of.inorder_flatten())
1768 {
1769 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MMERO"), meronym._id);
1770 }
1771
1772 for (auto cls : _instance_of.inorder_flatten())
1773 {
1774 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@CLSID"), cls._id);
1775 }
1776
1777 for (auto inst : _class_of.inorder_flatten())
1778 {
1779 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@INSID"), inst._id);
1780 }
1781
1782 for (auto synonym : _synonym_of.inorder_flatten())
1783 {
1784 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id);
1785 }
1786
1787 for (auto antonym : _antonym_of.inorder_flatten())
1788 {
1789 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id);
1790 }
1791
1792 for (auto pertainym : _anti_pertainym_of.inorder_flatten())
1793 {
1794 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PERID"), pertainym._id);
1795 }
1796
1797 for (auto value : _attribute_of.inorder_flatten())
1798 {
1799 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VALID"), value._id);
1800 }
1801 /* 1795 /*
1802 for (auto adj : _derived_from_adjective) 1796 for (auto adj : _derived_from_adjective)
1803 { 1797 {
@@ -1839,6 +1833,8 @@ namespace verbly {
1839 { 1833 {
1840 tnc._plural = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); 1834 tnc._plural = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2)));
1841 } 1835 }
1836
1837 tnc._wnid = sqlite3_column_int(ppstmt, 3);
1842 1838
1843 output.push_back(tnc); 1839 output.push_back(tnc);
1844 } 1840 }
diff --git a/lib/noun_query.h b/lib/noun_query.h index 5b73f8d..8768f5d 100644 --- a/lib/noun_query.h +++ b/lib/noun_query.h
@@ -72,6 +72,9 @@ namespace verbly {
72 noun_query& is_attribute(); 72 noun_query& is_attribute();
73 noun_query& attribute_of(filter<adjective> _f); 73 noun_query& attribute_of(filter<adjective> _f);
74 74
75 noun_query& at_least_n_images(int _arg);
76 noun_query& with_wnid(int _arg);
77
75/* noun_query& derived_from(const word& _w); 78/* noun_query& derived_from(const word& _w);
76 noun_query& not_derived_from(const word& _w);*/ 79 noun_query& not_derived_from(const word& _w);*/
77 80
@@ -146,6 +149,9 @@ namespace verbly {
146 bool _is_attribute = false; 149 bool _is_attribute = false;
147 filter<adjective> _attribute_of; 150 filter<adjective> _attribute_of;
148 151
152 int _at_least_n_images = unlimited;
153 std::set<int> _with_wnid;
154
149/* std::list<adjective> _derived_from_adjective; 155/* std::list<adjective> _derived_from_adjective;
150 std::list<adjective> _not_derived_from_adjective; 156 std::list<adjective> _not_derived_from_adjective;
151 std::list<adverb> _derived_from_adverb; 157 std::list<adverb> _derived_from_adverb;
diff --git a/lib/preposition.cpp b/lib/preposition.cpp index c619bbf..8df13aa 100644 --- a/lib/preposition.cpp +++ b/lib/preposition.cpp
@@ -37,13 +37,19 @@ namespace verbly {
37 { 37 {
38 std::stringstream construct; 38 std::stringstream construct;
39 construct << "SELECT form FROM prepositions"; 39 construct << "SELECT form FROM prepositions";
40 std::list<binding> bindings;
40 41
41 if (!_in_group.empty()) 42 if (!_in_group.empty())
42 { 43 {
43 std::list<std::string> clauses(_in_group.size(), "groupname = @GNAME"); 44 std::list<std::string> clauses(_in_group.size(), "groupname = ?");
44 construct << " WHERE preposition_id IN (SELECT preposition_id FROM preposition_groups WHERE "; 45 construct << " WHERE preposition_id IN (SELECT preposition_id FROM preposition_groups WHERE ";
45 construct << verbly::implode(std::begin(clauses), std::end(clauses), " OR "); 46 construct << verbly::implode(std::begin(clauses), std::end(clauses), " OR ");
46 construct << ")"; 47 construct << ")";
48
49 for (auto g : _in_group)
50 {
51 bindings.emplace_back(g);
52 }
47 } 53 }
48 54
49 if (_random) 55 if (_random)
@@ -63,9 +69,27 @@ namespace verbly {
63 throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); 69 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
64 } 70 }
65 71
66 for (auto& group : _in_group) 72 int i = 1;
73 for (auto& binding : bindings)
67 { 74 {
68 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GNAME"), group.c_str(), group.length(), SQLITE_STATIC); 75 switch (binding.get_type())
76 {
77 case binding::type::integer:
78 {
79 sqlite3_bind_int(ppstmt, i, binding.get_integer());
80
81 break;
82 }
83
84 case binding::type::string:
85 {
86 sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC);
87
88 break;
89 }
90 }
91
92 i++;
69 } 93 }
70 94
71 std::list<preposition> output; 95 std::list<preposition> output;
diff --git a/lib/verb_query.cpp b/lib/verb_query.cpp index 173a04e..929ecc7 100644 --- a/lib/verb_query.cpp +++ b/lib/verb_query.cpp
@@ -65,6 +65,7 @@ namespace verbly {
65 std::stringstream construct; 65 std::stringstream construct;
66 construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs"; 66 construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs";
67 std::list<std::string> conditions; 67 std::list<std::string> conditions;
68 std::list<binding> bindings;
68 69
69 if (_has_prn) 70 if (_has_prn)
70 { 71 {
@@ -73,14 +74,20 @@ namespace verbly {
73 74
74 if (!_rhymes.empty()) 75 if (!_rhymes.empty())
75 { 76 {
76 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); 77 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?");
77 std::string cond = "verb_id IN (SELECT verb_id FROM verb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; 78 std::string cond = "verb_id IN (SELECT verb_id FROM verb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
78 conditions.push_back(cond); 79 conditions.push_back(cond);
80
81 for (auto rhyme : _rhymes)
82 {
83 bindings.emplace_back("%" + rhyme);
84 }
79 } 85 }
80 86
81 for (auto except : _except) 87 for (auto except : _except)
82 { 88 {
83 conditions.push_back("verb_id != @EXCID"); 89 conditions.push_back("verb_id != ?");
90 bindings.emplace_back(except._id);
84 } 91 }
85 92
86 if (!_has_frames) 93 if (!_has_frames)
@@ -111,21 +118,27 @@ namespace verbly {
111 throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); 118 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
112 } 119 }
113 120
114 if (!_rhymes.empty()) 121 int i = 1;
122 for (auto& binding : bindings)
115 { 123 {
116 int i = 0; 124 switch (binding.get_type())
117 for (auto rhyme : _rhymes)
118 { 125 {
119 std::string rhymer = "%" + rhyme; 126 case binding::type::integer:
120 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); 127 {
128 sqlite3_bind_int(ppstmt, i, binding.get_integer());
129
130 break;
131 }
121 132
122 i++; 133 case binding::type::string:
134 {
135 sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC);
136
137 break;
138 }
123 } 139 }
124 } 140
125 141 i++;
126 for (auto except : _except)
127 {
128 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
129 } 142 }
130 143
131 std::list<verb> output; 144 std::list<verb> output;