summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2016-03-27 14:28:54 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2016-03-27 14:28:54 -0400
commit4c94e100e87a09284f0e0a5bc0df688672492a1e (patch)
treef94611f057268dbc1000fb66cd89a8d3ad809d7a
parent429f6195f6a4410ae45ef3f560b0745ac60184c1 (diff)
downloadverbly-4c94e100e87a09284f0e0a5bc0df688672492a1e.tar.gz
verbly-4c94e100e87a09284f0e0a5bc0df688672492a1e.tar.bz2
verbly-4c94e100e87a09284f0e0a5bc0df688672492a1e.zip
Added prefix/suffix search, and word complexity search for nouns, adjectives, and adverbs
Word complexity refers to the number of words in a noun, adjective, or adverb.
-rw-r--r--generator/generator.cpp22
-rw-r--r--generator/schema.sql9
-rw-r--r--lib/adjective_query.cpp119
-rw-r--r--lib/adjective_query.h10
-rw-r--r--lib/adverb_query.cpp119
-rw-r--r--lib/adverb_query.h10
-rw-r--r--lib/noun.cpp42
-rw-r--r--lib/noun.h6
-rw-r--r--lib/noun_query.cpp119
-rw-r--r--lib/noun_query.h8
10 files changed, 452 insertions, 12 deletions
diff --git a/generator/generator.cpp b/generator/generator.cpp index aea750c..6fbbfb8 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp
@@ -1027,9 +1027,9 @@ int main(int argc, char** argv)
1027 { 1027 {
1028 if (nouns.count(word) == 1) 1028 if (nouns.count(word) == 1)
1029 { 1029 {
1030 query = "INSERT INTO nouns (singular, proper, plural) VALUES (?, ?, ?)"; 1030 query = "INSERT INTO nouns (singular, proper, complexity, plural) VALUES (?, ?, ?, ?)";
1031 } else { 1031 } else {
1032 query = "INSERT INTO nouns (singular, proper) VALUES (?, ?)"; 1032 query = "INSERT INTO nouns (singular, proper, complexity) VALUES (?, ?, ?)";
1033 } 1033 }
1034 1034
1035 break; 1035 break;
@@ -1046,9 +1046,9 @@ int main(int argc, char** argv)
1046 { 1046 {
1047 if (adjectives.count(word) == 1) 1047 if (adjectives.count(word) == 1)
1048 { 1048 {
1049 query = "INSERT INTO adjectives (base_form, comparative, superlative) VALUES (?, ?, ?)"; 1049 query = "INSERT INTO adjectives (base_form, complexity, comparative, superlative) VALUES (?, ?, ?, ?)";
1050 } else { 1050 } else {
1051 query = "INSERT INTO adjectives (base_form) VALUES (?)"; 1051 query = "INSERT INTO adjectives (base_form, complexity) VALUES (?, ?)";
1052 } 1052 }
1053 1053
1054 break; 1054 break;
@@ -1058,9 +1058,9 @@ int main(int argc, char** argv)
1058 { 1058 {
1059 if (adjectives.count(word) == 1) 1059 if (adjectives.count(word) == 1)
1060 { 1060 {
1061 query = "INSERT INTO adverbs (base_form, comparative, superlative) VALUES (?, ?, ?)"; 1061 query = "INSERT INTO adverbs (base_form, complexity, comparative, superlative) VALUES (?, ?, ?, ?)";
1062 } else { 1062 } else {
1063 query = "INSERT INTO adverbs (base_form) VALUES (?)"; 1063 query = "INSERT INTO adverbs (base_form, complexity) VALUES (?, ?)";
1064 } 1064 }
1065 1065
1066 break; 1066 break;
@@ -1082,9 +1082,11 @@ int main(int argc, char** argv)
1082 return isupper(ch); 1082 return isupper(ch);
1083 }) ? 1 : 0)); 1083 }) ? 1 : 0));
1084 1084
1085 sqlite3_bind_int(ppstmt, 3, verbly::split<std::list<std::string>>(word, " ").size());
1086
1085 if (nouns.count(word) == 1) 1087 if (nouns.count(word) == 1)
1086 { 1088 {
1087 sqlite3_bind_text(ppstmt, 3, nouns[word].plural.c_str(), nouns[word].plural.length(), SQLITE_STATIC); 1089 sqlite3_bind_text(ppstmt, 4, nouns[word].plural.c_str(), nouns[word].plural.length(), SQLITE_STATIC);
1088 } 1090 }
1089 1091
1090 break; 1092 break;
@@ -1093,10 +1095,12 @@ int main(int argc, char** argv)
1093 case 3: // Adjective 1095 case 3: // Adjective
1094 case 4: // Adverb 1096 case 4: // Adverb
1095 { 1097 {
1098 sqlite3_bind_int(ppstmt, 2, verbly::split<std::list<std::string>>(word, " ").size());
1099
1096 if (adjectives.count(word) == 1) 1100 if (adjectives.count(word) == 1)
1097 { 1101 {
1098 sqlite3_bind_text(ppstmt, 2, adjectives[word].comparative.c_str(), adjectives[word].comparative.length(), SQLITE_STATIC); 1102 sqlite3_bind_text(ppstmt, 3, adjectives[word].comparative.c_str(), adjectives[word].comparative.length(), SQLITE_STATIC);
1099 sqlite3_bind_text(ppstmt, 3, adjectives[word].superlative.c_str(), adjectives[word].superlative.length(), SQLITE_STATIC); 1103 sqlite3_bind_text(ppstmt, 4, adjectives[word].superlative.c_str(), adjectives[word].superlative.length(), SQLITE_STATIC);
1100 } 1104 }
1101 1105
1102 break; 1106 break;
diff --git a/generator/schema.sql b/generator/schema.sql index 2295444..f2445f0 100644 --- a/generator/schema.sql +++ b/generator/schema.sql
@@ -36,7 +36,8 @@ CREATE TABLE `adjectives` (
36 `base_form` VARCHAR(32) NOT NULL, 36 `base_form` VARCHAR(32) NOT NULL,
37 `comparative` VARCHAR(32), 37 `comparative` VARCHAR(32),
38 `superlative` VARCHAR(32), 38 `superlative` VARCHAR(32),
39 `position` CHAR(1) 39 `position` CHAR(1),
40 `complexity` INTEGER NOT NULL
40); 41);
41 42
42DROP TABLE IF EXISTS `adverbs`; 43DROP TABLE IF EXISTS `adverbs`;
@@ -44,7 +45,8 @@ CREATE TABLE `adverbs` (
44 `adverb_id` INTEGER PRIMARY KEY, 45 `adverb_id` INTEGER PRIMARY KEY,
45 `base_form` VARCHAR(32) NOT NULL, 46 `base_form` VARCHAR(32) NOT NULL,
46 `comparative` VARCHAR(32), 47 `comparative` VARCHAR(32),
47 `superlative` VARCHAR(32) 48 `superlative` VARCHAR(32),
49 `complexity` INTEGER NOT NULL
48); 50);
49 51
50DROP TABLE IF EXISTS `nouns`; 52DROP TABLE IF EXISTS `nouns`;
@@ -52,7 +54,8 @@ CREATE TABLE `nouns` (
52 `noun_id` INTEGER PRIMARY KEY, 54 `noun_id` INTEGER PRIMARY KEY,
53 `singular` VARCHAR(32) NOT NULL, 55 `singular` VARCHAR(32) NOT NULL,
54 `plural` VARCHAR(32), 56 `plural` VARCHAR(32),
55 `proper` INTEGER(1) NOT NULL 57 `proper` INTEGER(1) NOT NULL,
58 `complexity` INTEGER NOT NULL
56); 59);
57 60
58DROP TABLE IF EXISTS `hypernymy`; 61DROP TABLE IF EXISTS `hypernymy`;
diff --git a/lib/adjective_query.cpp b/lib/adjective_query.cpp index ec100e3..283fdca 100644 --- a/lib/adjective_query.cpp +++ b/lib/adjective_query.cpp
@@ -53,6 +53,29 @@ namespace verbly {
53 return *this; 53 return *this;
54 } 54 }
55 55
56 adjective_query& adjective_query::with_prefix(filter<std::string> _f)
57 {
58 _f.clean();
59 _with_prefix = _f;
60
61 return *this;
62 }
63
64 adjective_query& adjective_query::with_suffix(filter<std::string> _f)
65 {
66 _f.clean();
67 _with_suffix = _f;
68
69 return *this;
70 }
71
72 adjective_query& adjective_query::with_complexity(int _arg)
73 {
74 _with_complexity = _arg;
75
76 return *this;
77 }
78
56 adjective_query& adjective_query::is_variant() 79 adjective_query& adjective_query::is_variant()
57 { 80 {
58 this->_is_variant = true; 81 this->_is_variant = true;
@@ -231,6 +254,85 @@ namespace verbly {
231 case adjective::positioning::undefined: break; 254 case adjective::positioning::undefined: break;
232 } 255 }
233 256
257 if (!_with_prefix.empty())
258 {
259 std::function<std::string (filter<std::string>, bool)> recur = [&] (filter<std::string> f, bool notlogic) -> std::string {
260 switch (f.get_type())
261 {
262 case filter<std::string>::type::singleton:
263 {
264 if (notlogic == f.get_notlogic())
265 {
266 return "base_form LIKE @PREFIX";
267 } else {
268 return "base_form NOT LIKE @PREFIX";
269 }
270 }
271
272 case filter<std::string>::type::group:
273 {
274 bool truelogic = notlogic != f.get_notlogic();
275
276 std::list<std::string> clauses;
277 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<std::string> f2) {
278 return recur(f2, truelogic);
279 });
280
281 if (truelogic == f.get_orlogic())
282 {
283 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
284 } else {
285 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
286 }
287 }
288 }
289 };
290
291 conditions.push_back(recur(_with_prefix, false));
292 }
293
294 if (!_with_suffix.empty())
295 {
296 std::function<std::string (filter<std::string>, bool)> recur = [&] (filter<std::string> f, bool notlogic) -> std::string {
297 switch (f.get_type())
298 {
299 case filter<std::string>::type::singleton:
300 {
301 if (notlogic == f.get_notlogic())
302 {
303 return "base_form LIKE @SUFFIX";
304 } else {
305 return "base_form NOT LIKE @SUFFIX";
306 }
307 }
308
309 case filter<std::string>::type::group:
310 {
311 bool truelogic = notlogic != f.get_notlogic();
312
313 std::list<std::string> clauses;
314 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<std::string> f2) {
315 return recur(f2, truelogic);
316 });
317
318 if (truelogic == f.get_orlogic())
319 {
320 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
321 } else {
322 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
323 }
324 }
325 }
326 };
327
328 conditions.push_back(recur(_with_suffix, false));
329 }
330
331 if (_with_complexity != unlimited)
332 {
333 conditions.push_back("complexity = @COMPLEX");
334 }
335
234 if (_is_variant) 336 if (_is_variant)
235 { 337 {
236 conditions.push_back("adjective_id IN (SELECT adjective_id FROM variation)"); 338 conditions.push_back("adjective_id IN (SELECT adjective_id FROM variation)");
@@ -691,6 +793,23 @@ namespace verbly {
691 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); 793 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
692 } 794 }
693 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
694 for (auto attribute : _variant_of.inorder_flatten()) 813 for (auto attribute : _variant_of.inorder_flatten())
695 { 814 {
696 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id); 815 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id);
diff --git a/lib/adjective_query.h b/lib/adjective_query.h index e7755cb..b2859dc 100644 --- a/lib/adjective_query.h +++ b/lib/adjective_query.h
@@ -17,6 +17,11 @@ namespace verbly {
17 adjective_query& requires_superlative_form(); 17 adjective_query& requires_superlative_form();
18 adjective_query& position(adjective::positioning pos); 18 adjective_query& position(adjective::positioning pos);
19 19
20 adjective_query& with_prefix(filter<std::string> _f);
21 adjective_query& with_suffix(filter<std::string> _f);
22
23 adjective_query& with_complexity(int _arg);
24
20 adjective_query& is_variant(); 25 adjective_query& is_variant();
21 adjective_query& variant_of(filter<noun> _f); 26 adjective_query& variant_of(filter<noun> _f);
22 27
@@ -57,6 +62,11 @@ namespace verbly {
57 bool _requires_superlative_form = false; 62 bool _requires_superlative_form = false;
58 adjective::positioning _position = adjective::positioning::undefined; 63 adjective::positioning _position = adjective::positioning::undefined;
59 64
65 filter<std::string> _with_prefix;
66 filter<std::string> _with_suffix;
67
68 int _with_complexity = unlimited;
69
60 bool _is_variant = false; 70 bool _is_variant = false;
61 filter<noun> _variant_of; 71 filter<noun> _variant_of;
62 72
diff --git a/lib/adverb_query.cpp b/lib/adverb_query.cpp index 639f16f..c9d0d09 100644 --- a/lib/adverb_query.cpp +++ b/lib/adverb_query.cpp
@@ -67,6 +67,29 @@ namespace verbly {
67 return *this; 67 return *this;
68 } 68 }
69 69
70 adverb_query& adverb_query::with_prefix(filter<std::string> _f)
71 {
72 _f.clean();
73 _with_prefix = _f;
74
75 return *this;
76 }
77
78 adverb_query& adverb_query::with_suffix(filter<std::string> _f)
79 {
80 _f.clean();
81 _with_suffix = _f;
82
83 return *this;
84 }
85
86 adverb_query& adverb_query::with_complexity(int _arg)
87 {
88 _with_complexity = _arg;
89
90 return *this;
91 }
92
70 adverb_query& adverb_query::has_antonyms() 93 adverb_query& adverb_query::has_antonyms()
71 { 94 {
72 _has_antonyms = true; 95 _has_antonyms = true;
@@ -177,6 +200,85 @@ namespace verbly {
177 conditions.push_back("superlative IS NOT NULL"); 200 conditions.push_back("superlative IS NOT NULL");
178 } 201 }
179 202
203 if (!_with_prefix.empty())
204 {
205 std::function<std::string (filter<std::string>, bool)> recur = [&] (filter<std::string> f, bool notlogic) -> std::string {
206 switch (f.get_type())
207 {
208 case filter<std::string>::type::singleton:
209 {
210 if (notlogic == f.get_notlogic())
211 {
212 return "base_form LIKE @PREFIX";
213 } else {
214 return "base_form NOT LIKE @PREFIX";
215 }
216 }
217
218 case filter<std::string>::type::group:
219 {
220 bool truelogic = notlogic != f.get_notlogic();
221
222 std::list<std::string> clauses;
223 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<std::string> f2) {
224 return recur(f2, truelogic);
225 });
226
227 if (truelogic == f.get_orlogic())
228 {
229 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
230 } else {
231 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
232 }
233 }
234 }
235 };
236
237 conditions.push_back(recur(_with_prefix, false));
238 }
239
240 if (!_with_suffix.empty())
241 {
242 std::function<std::string (filter<std::string>, bool)> recur = [&] (filter<std::string> f, bool notlogic) -> std::string {
243 switch (f.get_type())
244 {
245 case filter<std::string>::type::singleton:
246 {
247 if (notlogic == f.get_notlogic())
248 {
249 return "base_form LIKE @SUFFIX";
250 } else {
251 return "base_form NOT LIKE @SUFFIX";
252 }
253 }
254
255 case filter<std::string>::type::group:
256 {
257 bool truelogic = notlogic != f.get_notlogic();
258
259 std::list<std::string> clauses;
260 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<std::string> f2) {
261 return recur(f2, truelogic);
262 });
263
264 if (truelogic == f.get_orlogic())
265 {
266 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
267 } else {
268 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
269 }
270 }
271 }
272 };
273
274 conditions.push_back(recur(_with_suffix, false));
275 }
276
277 if (_with_complexity != unlimited)
278 {
279 conditions.push_back("complexity = @COMPLEX");
280 }
281
180 if (_has_antonyms) 282 if (_has_antonyms)
181 { 283 {
182 conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)"); 284 conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)");
@@ -421,6 +523,23 @@ namespace verbly {
421 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); 523 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
422 } 524 }
423 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
424 for (auto antonym : _antonym_of.inorder_flatten()) 543 for (auto antonym : _antonym_of.inorder_flatten())
425 { 544 {
426 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); 545 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id);
diff --git a/lib/adverb_query.h b/lib/adverb_query.h index 20f9ce5..e9354bb 100644 --- a/lib/adverb_query.h +++ b/lib/adverb_query.h
@@ -16,6 +16,11 @@ namespace verbly {
16 adverb_query& requires_comparative_form(); 16 adverb_query& requires_comparative_form();
17 adverb_query& requires_superlative_form(); 17 adverb_query& requires_superlative_form();
18 18
19 adverb_query& with_prefix(filter<std::string> _f);
20 adverb_query& with_suffix(filter<std::string> _f);
21
22 adverb_query& with_complexity(int _arg);
23
19 adverb_query& has_antonyms(); 24 adverb_query& has_antonyms();
20 adverb_query& antonym_of(filter<adverb> _f); 25 adverb_query& antonym_of(filter<adverb> _f);
21 26
@@ -43,6 +48,11 @@ namespace verbly {
43 bool _requires_comparative_form = false; 48 bool _requires_comparative_form = false;
44 bool _requires_superlative_form = false; 49 bool _requires_superlative_form = false;
45 50
51 filter<std::string> _with_prefix;
52 filter<std::string> _with_suffix;
53
54 int _with_complexity = unlimited;
55
46 bool _has_antonyms = false; 56 bool _has_antonyms = false;
47 filter<adverb> _antonym_of; 57 filter<adverb> _antonym_of;
48 58
diff --git a/lib/noun.cpp b/lib/noun.cpp index f575117..71c9af0 100644 --- a/lib/noun.cpp +++ b/lib/noun.cpp
@@ -77,6 +77,13 @@ namespace verbly {
77 return _data->nouns().part_meronym_of(*this); 77 return _data->nouns().part_meronym_of(*this);
78 } 78 }
79 79
80 noun_query noun::full_part_meronyms() const
81 {
82 assert(_valid == true);
83
84 return _data->nouns().full_part_meronym_of(*this);
85 }
86
80 noun_query noun::part_holonyms() const 87 noun_query noun::part_holonyms() const
81 { 88 {
82 assert(_valid == true); 89 assert(_valid == true);
@@ -84,6 +91,13 @@ namespace verbly {
84 return _data->nouns().part_holonym_of(*this); 91 return _data->nouns().part_holonym_of(*this);
85 } 92 }
86 93
94 noun_query noun::full_part_holonyms() const
95 {
96 assert(_valid == true);
97
98 return _data->nouns().full_part_holonym_of(*this);
99 }
100
87 noun_query noun::substance_meronyms() const 101 noun_query noun::substance_meronyms() const
88 { 102 {
89 assert(_valid == true); 103 assert(_valid == true);
@@ -91,6 +105,13 @@ namespace verbly {
91 return _data->nouns().substance_meronym_of(*this); 105 return _data->nouns().substance_meronym_of(*this);
92 } 106 }
93 107
108 noun_query noun::full_substance_meronyms() const
109 {
110 assert(_valid == true);
111
112 return _data->nouns().full_substance_meronym_of(*this);
113 }
114
94 noun_query noun::substance_holonyms() const 115 noun_query noun::substance_holonyms() const
95 { 116 {
96 assert(_valid == true); 117 assert(_valid == true);
@@ -98,6 +119,13 @@ namespace verbly {
98 return _data->nouns().substance_holonym_of(*this); 119 return _data->nouns().substance_holonym_of(*this);
99 } 120 }
100 121
122 noun_query noun::full_substance_holonyms() const
123 {
124 assert(_valid == true);
125
126 return _data->nouns().full_substance_holonym_of(*this);
127 }
128
101 noun_query noun::member_meronyms() const 129 noun_query noun::member_meronyms() const
102 { 130 {
103 assert(_valid == true); 131 assert(_valid == true);
@@ -105,6 +133,13 @@ namespace verbly {
105 return _data->nouns().member_meronym_of(*this); 133 return _data->nouns().member_meronym_of(*this);
106 } 134 }
107 135
136 noun_query noun::full_member_meronyms() const
137 {
138 assert(_valid == true);
139
140 return _data->nouns().full_member_meronym_of(*this);
141 }
142
108 noun_query noun::member_holonyms() const 143 noun_query noun::member_holonyms() const
109 { 144 {
110 assert(_valid == true); 145 assert(_valid == true);
@@ -112,6 +147,13 @@ namespace verbly {
112 return _data->nouns().member_holonym_of(*this); 147 return _data->nouns().member_holonym_of(*this);
113 } 148 }
114 149
150 noun_query noun::full_member_holonyms() const
151 {
152 assert(_valid == true);
153
154 return _data->nouns().full_member_holonym_of(*this);
155 }
156
115 noun_query noun::classes() const 157 noun_query noun::classes() const
116 { 158 {
117 assert(_valid == true); 159 assert(_valid == true);
diff --git a/lib/noun.h b/lib/noun.h index 77601d0..969d2c8 100644 --- a/lib/noun.h +++ b/lib/noun.h
@@ -25,11 +25,17 @@ namespace verbly {
25 noun_query hyponyms() const; 25 noun_query hyponyms() const;
26 noun_query full_hyponyms() const; 26 noun_query full_hyponyms() const;
27 noun_query part_meronyms() const; 27 noun_query part_meronyms() const;
28 noun_query full_part_meronyms() const;
28 noun_query part_holonyms() const; 29 noun_query part_holonyms() const;
30 noun_query full_part_holonyms() const;
29 noun_query substance_meronyms() const; 31 noun_query substance_meronyms() const;
32 noun_query full_substance_meronyms() const;
30 noun_query substance_holonyms() const; 33 noun_query substance_holonyms() const;
34 noun_query full_substance_holonyms() const;
31 noun_query member_meronyms() const; 35 noun_query member_meronyms() const;
36 noun_query full_member_meronyms() const;
32 noun_query member_holonyms() const; 37 noun_query member_holonyms() const;
38 noun_query full_member_holonyms() const;
33 noun_query classes() const; 39 noun_query classes() const;
34 noun_query instances() const; 40 noun_query instances() const;
35 noun_query synonyms() const; 41 noun_query synonyms() const;
diff --git a/lib/noun_query.cpp b/lib/noun_query.cpp index 2c3f57c..83bb47d 100644 --- a/lib/noun_query.cpp +++ b/lib/noun_query.cpp
@@ -60,6 +60,29 @@ namespace verbly {
60 return *this; 60 return *this;
61 } 61 }
62 62
63 noun_query& noun_query::with_prefix(filter<std::string> _f)
64 {
65 _f.clean();
66 _with_prefix = _f;
67
68 return *this;
69 }
70
71 noun_query& noun_query::with_suffix(filter<std::string> _f)
72 {
73 _f.clean();
74 _with_suffix = _f;
75
76 return *this;
77 }
78
79 noun_query& noun_query::with_complexity(int _arg)
80 {
81 _with_complexity = _arg;
82
83 return *this;
84 }
85
63 noun_query& noun_query::is_hypernym() 86 noun_query& noun_query::is_hypernym()
64 { 87 {
65 _is_hypernym = true; 88 _is_hypernym = true;
@@ -461,6 +484,85 @@ namespace verbly {
461 conditions.push_back(cond); 484 conditions.push_back(cond);
462 } 485 }
463 486
487 if (!_with_prefix.empty())
488 {
489 std::function<std::string (filter<std::string>, bool)> recur = [&] (filter<std::string> f, bool notlogic) -> std::string {
490 switch (f.get_type())
491 {
492 case filter<std::string>::type::singleton:
493 {
494 if (notlogic == f.get_notlogic())
495 {
496 return "singular LIKE @PREFIX";
497 } else {
498 return "singular NOT LIKE @PREFIX";
499 }
500 }
501
502 case filter<std::string>::type::group:
503 {
504 bool truelogic = notlogic != f.get_notlogic();
505
506 std::list<std::string> clauses;
507 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<std::string> f2) {
508 return recur(f2, truelogic);
509 });
510
511 if (truelogic == f.get_orlogic())
512 {
513 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
514 } else {
515 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
516 }
517 }
518 }
519 };
520
521 conditions.push_back(recur(_with_prefix, false));
522 }
523
524 if (!_with_suffix.empty())
525 {
526 std::function<std::string (filter<std::string>, bool)> recur = [&] (filter<std::string> f, bool notlogic) -> std::string {
527 switch (f.get_type())
528 {
529 case filter<std::string>::type::singleton:
530 {
531 if (notlogic == f.get_notlogic())
532 {
533 return "singular LIKE @SUFFIX";
534 } else {
535 return "singular NOT LIKE @SUFFIX";
536 }
537 }
538
539 case filter<std::string>::type::group:
540 {
541 bool truelogic = notlogic != f.get_notlogic();
542
543 std::list<std::string> clauses;
544 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<std::string> f2) {
545 return recur(f2, truelogic);
546 });
547
548 if (truelogic == f.get_orlogic())
549 {
550 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
551 } else {
552 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
553 }
554 }
555 }
556 };
557
558 conditions.push_back(recur(_with_suffix, false));
559 }
560
561 if (_with_complexity != unlimited)
562 {
563 conditions.push_back("complexity = @COMPLEX");
564 }
565
464 if (_is_hypernym) 566 if (_is_hypernym)
465 { 567 {
466 conditions.push_back("noun_id IN (SELECT hypernym_id FROM hypernymy)"); 568 conditions.push_back("noun_id IN (SELECT hypernym_id FROM hypernymy)");
@@ -1610,6 +1712,23 @@ namespace verbly {
1610 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SFORM"), sform.c_str(), sform.size(), SQLITE_STATIC); 1712 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SFORM"), sform.c_str(), sform.size(), SQLITE_STATIC);
1611 } 1713 }
1612 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
1613 for (auto hyponym : _hypernym_of.inorder_flatten()) 1732 for (auto hyponym : _hypernym_of.inorder_flatten())
1614 { 1733 {
1615 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPO"), hyponym._id); 1734 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPO"), hyponym._id);
diff --git a/lib/noun_query.h b/lib/noun_query.h index e95e0c0..5b73f8d 100644 --- a/lib/noun_query.h +++ b/lib/noun_query.h
@@ -14,6 +14,10 @@ namespace verbly {
14 noun_query& has_pronunciation(); 14 noun_query& has_pronunciation();
15 15
16 noun_query& with_singular_form(std::string _arg); 16 noun_query& with_singular_form(std::string _arg);
17 noun_query& with_prefix(filter<std::string> _f);
18 noun_query& with_suffix(filter<std::string> _f);
19
20 noun_query& with_complexity(int _arg);
17 21
18 noun_query& is_hypernym(); 22 noun_query& is_hypernym();
19 noun_query& hypernym_of(filter<noun> _f); 23 noun_query& hypernym_of(filter<noun> _f);
@@ -84,6 +88,10 @@ namespace verbly {
84 bool _has_prn = false; 88 bool _has_prn = false;
85 89
86 std::list<std::string> _with_singular_form; 90 std::list<std::string> _with_singular_form;
91 filter<std::string> _with_prefix;
92 filter<std::string> _with_suffix;
93
94 int _with_complexity = unlimited;
87 95
88 bool _is_hypernym = false; 96 bool _is_hypernym = false;
89 filter<noun> _hypernym_of; 97 filter<noun> _hypernym_of;