diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2016-03-16 11:27:16 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2016-03-16 11:27:16 -0400 |
commit | 3aceae8ab1eb5992110ea57a9479bbc3177feb21 (patch) | |
tree | 13167a266805344efb7bb1d900486f782c23285e /verbly/adverb.cpp | |
parent | e1be2716746e75cf6ed37e86461a7f580a964564 (diff) | |
download | furries-3aceae8ab1eb5992110ea57a9479bbc3177feb21.tar.gz furries-3aceae8ab1eb5992110ea57a9479bbc3177feb21.tar.bz2 furries-3aceae8ab1eb5992110ea57a9479bbc3177feb21.zip |
Added more inflections, word relationships, and pronunciations
Nouns, adjectives, and adverbs now have inflected forms. A large number of WordNet word relationships (all noun-noun relationships, plus synonymy and antonymy for all word types except verbs) have been added. Additionally, CMUDICT is now being used to store word pronunciations for rhyming purposes. Verbly is now also a compiled library rather than being header-only due to the complexity of the query interface.
Diffstat (limited to 'verbly/adverb.cpp')
-rw-r--r-- | verbly/adverb.cpp | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/verbly/adverb.cpp b/verbly/adverb.cpp new file mode 100644 index 0000000..9bb5a0d --- /dev/null +++ b/verbly/adverb.cpp | |||
@@ -0,0 +1,364 @@ | |||
1 | #include "verbly.h" | ||
2 | |||
3 | namespace 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 | std::list<adverb> adverb_query::run() const | ||
172 | { | ||
173 | std::stringstream construct; | ||
174 | construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs"; | ||
175 | std::list<std::string> conditions; | ||
176 | |||
177 | if (_has_prn) | ||
178 | { | ||
179 | conditions.push_back("adverb_id IN (SELECT adverb_id FROM adverb_pronunciations)"); | ||
180 | } | ||
181 | |||
182 | if (!_rhymes.empty()) | ||
183 | { | ||
184 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
185 | std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
186 | conditions.push_back(cond); | ||
187 | } | ||
188 | |||
189 | for (auto except : _except) | ||
190 | { | ||
191 | conditions.push_back("adverb_id != @EXCID"); | ||
192 | } | ||
193 | |||
194 | if (_requires_comparative_form) | ||
195 | { | ||
196 | conditions.push_back("comparative IS NOT NULL"); | ||
197 | } | ||
198 | |||
199 | if (_requires_superlative_form) | ||
200 | { | ||
201 | conditions.push_back("superlative IS NOT NULL"); | ||
202 | } | ||
203 | |||
204 | if (_has_antonyms) | ||
205 | { | ||
206 | conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)"); | ||
207 | } | ||
208 | |||
209 | if (!_antonym_of.empty()) | ||
210 | { | ||
211 | std::list<std::string> clauses(_antonym_of.size(), "adverb_1_id = @ANTID"); | ||
212 | std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
213 | conditions.push_back(cond); | ||
214 | } | ||
215 | |||
216 | if (!_not_antonym_of.empty()) | ||
217 | { | ||
218 | std::list<std::string> clauses(_not_antonym_of.size(), "adverb_1_id = @NANTID"); | ||
219 | std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
220 | conditions.push_back(cond); | ||
221 | } | ||
222 | |||
223 | if (_has_synonyms) | ||
224 | { | ||
225 | conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy)"); | ||
226 | } | ||
227 | |||
228 | if (!_synonym_of.empty()) | ||
229 | { | ||
230 | std::list<std::string> clauses(_synonym_of.size(), "adverb_1_id = @SYNID"); | ||
231 | std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
232 | conditions.push_back(cond); | ||
233 | } | ||
234 | |||
235 | if (!_not_synonym_of.empty()) | ||
236 | { | ||
237 | std::list<std::string> clauses(_not_synonym_of.size(), "adverb_1_id = @NSYNID"); | ||
238 | std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
239 | conditions.push_back(cond); | ||
240 | } | ||
241 | |||
242 | if (_is_mannernymic) | ||
243 | { | ||
244 | conditions.push_back("adverb_id IN (SELECT mannernym_id FROM mannernymy)"); | ||
245 | } | ||
246 | |||
247 | if (!_mannernym_of.empty()) | ||
248 | { | ||
249 | std::list<std::string> clauses(_mannernym_of.size(), "adjective_id = @AMANID"); | ||
250 | std::string cond = "adverb_id IN (SELECT mannernym_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
251 | conditions.push_back(cond); | ||
252 | } | ||
253 | |||
254 | if (!conditions.empty()) | ||
255 | { | ||
256 | construct << " WHERE "; | ||
257 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
258 | } | ||
259 | |||
260 | if (_random) | ||
261 | { | ||
262 | construct << " ORDER BY RANDOM()"; | ||
263 | } | ||
264 | |||
265 | if (_limit != unlimited) | ||
266 | { | ||
267 | construct << " LIMIT " << _limit; | ||
268 | } | ||
269 | |||
270 | sqlite3_stmt* ppstmt; | ||
271 | std::string query = construct.str(); | ||
272 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
273 | { | ||
274 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
275 | } | ||
276 | |||
277 | if (!_rhymes.empty()) | ||
278 | { | ||
279 | int i = 0; | ||
280 | for (auto rhyme : _rhymes) | ||
281 | { | ||
282 | std::string rhymer = "%" + rhyme; | ||
283 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
284 | |||
285 | i++; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | for (auto except : _except) | ||
290 | { | ||
291 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
292 | } | ||
293 | |||
294 | for (auto antonym : _antonym_of) | ||
295 | { | ||
296 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
297 | } | ||
298 | |||
299 | for (auto antonym : _not_antonym_of) | ||
300 | { | ||
301 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); | ||
302 | } | ||
303 | |||
304 | for (auto synonym : _synonym_of) | ||
305 | { | ||
306 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
307 | } | ||
308 | |||
309 | for (auto synonym : _not_synonym_of) | ||
310 | { | ||
311 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); | ||
312 | } | ||
313 | |||
314 | for (auto adj : _mannernym_of) | ||
315 | { | ||
316 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id); | ||
317 | } | ||
318 | |||
319 | std::list<adverb> output; | ||
320 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
321 | { | ||
322 | adverb tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
323 | tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
324 | |||
325 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
326 | { | ||
327 | tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
328 | } | ||
329 | |||
330 | if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) | ||
331 | { | ||
332 | tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
333 | } | ||
334 | |||
335 | output.push_back(tnc); | ||
336 | } | ||
337 | |||
338 | sqlite3_finalize(ppstmt); | ||
339 | |||
340 | for (auto& adverb : output) | ||
341 | { | ||
342 | query = "SELECT pronunciation FROM adverb_pronunciations WHERE adverb_id = ?"; | ||
343 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
344 | { | ||
345 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
346 | } | ||
347 | |||
348 | sqlite3_bind_int(ppstmt, 1, adverb._id); | ||
349 | |||
350 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
351 | { | ||
352 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
353 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
354 | |||
355 | adverb.pronunciations.push_back(phonemes); | ||
356 | } | ||
357 | |||
358 | sqlite3_finalize(ppstmt); | ||
359 | } | ||
360 | |||
361 | return output; | ||
362 | } | ||
363 | |||
364 | }; | ||