summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2016-03-09 23:30:14 -0500
committerKelly Rauchenberger <fefferburbia@gmail.com>2016-03-09 23:30:14 -0500
commit8455e8badc80aa018a982102ffff71d5a6b1940c (patch)
tree24f92ed6afd227d38d4c4755be16d5ea0125aef6
downloadverbly-8455e8badc80aa018a982102ffff71d5a6b1940c.tar.gz
verbly-8455e8badc80aa018a982102ffff71d5a6b1940c.tar.bz2
verbly-8455e8badc80aa018a982102ffff71d5a6b1940c.zip
Started verbly rewrite
verbly is intended to be a general use natural language generation library. Here, I'm using it to simply generate random verbs or adjectives. A schema for the sqlite database is provided, and for testing I manually added data. A generator program is being written that will generate a database from WordNet, VerbNet, PropBank, and AGID data.
-rw-r--r--adjective.h21
-rw-r--r--c++14.h35
-rw-r--r--data.h201
-rw-r--r--token.h336
-rw-r--r--verb.h67
-rw-r--r--verbly.h10
6 files changed, 670 insertions, 0 deletions
diff --git a/adjective.h b/adjective.h new file mode 100644 index 0000000..58c490e --- /dev/null +++ b/adjective.h
@@ -0,0 +1,21 @@
1#ifndef ADJECTIVE_H_87B3FB75
2#define ADJECTIVE_H_87B3FB75
3
4namespace verbly {
5
6 class adjective {
7 private:
8 int id;
9
10 public:
11 std::string value;
12
13 adjective(int id) : id(id)
14 {
15
16 }
17 };
18
19};
20
21#endif /* end of include guard: ADJECTIVE_H_87B3FB75 */
diff --git a/c++14.h b/c++14.h new file mode 100644 index 0000000..b3efbe2 --- /dev/null +++ b/c++14.h
@@ -0,0 +1,35 @@
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/data.h b/data.h new file mode 100644 index 0000000..2c23c15 --- /dev/null +++ b/data.h
@@ -0,0 +1,201 @@
1#ifndef DATA_H_C4AEC3DD
2#define DATA_H_C4AEC3DD
3
4#include "verb.h"
5#include <sqlite3.h>
6#include <stdexcept>
7
8namespace verbly {
9
10 class data {
11 private:
12 sqlite3* ppdb;
13
14 public:
15 class verb_query {
16 public:
17 const static int unlimited = -1;
18
19 private:
20 const data& database;
21 int m_limit = unlimited;
22 bool m_random = false;
23
24 public:
25 verb_query(const data& database) : database(database)
26 {
27
28 }
29
30 verb_query& limit(int m_limit)
31 {
32 if ((m_limit > 0) || (m_limit == unlimited))
33 {
34 this->m_limit = m_limit;
35 }
36
37 return *this;
38 }
39
40 verb_query& random(bool m_random)
41 {
42 this->m_random = m_random;
43
44 return *this;
45 }
46
47 std::list<verb> run() const
48 {
49 std::stringstream construct;
50 construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs";
51
52 if (m_random)
53 {
54 construct << " ORDER BY RANDOM()";
55 }
56
57 if (m_limit != unlimited)
58 {
59 construct << " LIMIT " << m_limit;
60 }
61
62 sqlite3_stmt* ppstmt;
63 std::string query = construct.str();
64 if (sqlite3_prepare_v2(database.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
65 {
66 throw std::runtime_error(sqlite3_errmsg(database.ppdb));
67 }
68
69 std::list<verb> output;
70 while (sqlite3_step(ppstmt) == SQLITE_ROW)
71 {
72 verb tnc {sqlite3_column_int(ppstmt, 0)};
73 tnc.infinitive = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1)));
74 tnc.past_tense = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2)));
75 tnc.past_participle = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3)));
76 tnc.ing_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 4)));
77 tnc.s_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 5)));
78
79 output.push_back(tnc);
80 }
81
82 sqlite3_finalize(ppstmt);
83
84 return output;
85 }
86
87 };
88
89 class adjective_query {
90 public:
91 const static int unlimited = -1;
92
93 private:
94 const data& database;
95 int m_limit = unlimited;
96 bool m_random = false;
97
98 public:
99 adjective_query(const data& database) : database(database)
100 {
101
102 }
103
104 adjective_query& limit(int m_limit)
105 {
106 if ((m_limit > 0) || (m_limit == unlimited))
107 {
108 this->m_limit = m_limit;
109 }
110
111 return *this;
112 }
113
114 adjective_query& random(bool m_random)
115 {
116 this->m_random = m_random;
117
118 return *this;
119 }
120
121 std::list<adjective> run() const
122 {
123 std::stringstream construct;
124 construct << "SELECT adjective_id, adjective FROM adjectives";
125
126 if (m_random)
127 {
128 construct << " ORDER BY RANDOM()";
129 }
130
131 if (m_limit != unlimited)
132 {
133 construct << " LIMIT " << m_limit;
134 }
135
136 sqlite3_stmt* ppstmt;
137 std::string query = construct.str();
138 if (sqlite3_prepare_v2(database.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
139 {
140 throw std::runtime_error(sqlite3_errmsg(database.ppdb));
141 }
142
143 std::list<adjective> output;
144 while (sqlite3_step(ppstmt) == SQLITE_ROW)
145 {
146 adjective tnc {sqlite3_column_int(ppstmt, 0)};
147 tnc.value = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1)));
148
149 output.push_back(tnc);
150 }
151
152 sqlite3_finalize(ppstmt);
153
154 return output;
155 }
156
157 };
158
159 data(std::string datafile)
160 {
161 if (sqlite3_open_v2(datafile.c_str(), &ppdb, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK)
162 {
163 throw std::invalid_argument(sqlite3_errmsg(ppdb));
164 }
165 }
166
167 data(const data& other) = delete;
168 data& operator=(const data& other) = delete;
169
170 data(data&& other)
171 {
172 ppdb = other.ppdb;
173 }
174
175 data& operator=(data&& other)
176 {
177 ppdb = other.ppdb;
178
179 return *this;
180 }
181
182 ~data()
183 {
184 sqlite3_close_v2(ppdb);
185 }
186
187 verb_query verbs() const
188 {
189 return verb_query(*this);
190 }
191
192 adjective_query adjectives() const
193 {
194 return adjective_query(*this);
195 }
196
197 };
198
199};
200
201#endif /* end of include guard: DATA_H_C4AEC3DD */
diff --git a/token.h b/token.h new file mode 100644 index 0000000..bbe7c2d --- /dev/null +++ b/token.h
@@ -0,0 +1,336 @@
1#ifndef TOKEN_H_AD62C505
2#define TOKEN_H_AD62C505
3
4#include <string>
5#include <list>
6#include <sstream>
7#include "verb.h"
8
9namespace verbly {
10
11 enum class type {
12 verb,
13 fillin,
14 string,
15 utterance
16 };
17
18 class selrestr {
19 };
20
21 class synrestr {
22 };
23
24 enum class fillin_type {
25 noun_phrase,
26 participle_phrase,
27 adjective
28 };
29
30 class token {
31 protected:
32 // General
33 type type;
34
35 token(enum type type) : type(type)
36 {
37
38 }
39
40 public:
41 enum type token_type() const
42 {
43 return type;
44 }
45
46 virtual bool complete() const = 0;
47 virtual std::string compile() const = 0;
48 virtual token* copy() const = 0;
49 };
50
51 class verb_token : public token {
52 private:
53 // Verb
54 const verb* m_verb;
55 conjugation verb_infl = conjugation::infinitive;
56
57 public:
58 verb_token(const class verb& verb) : token(type::verb), m_verb(&verb)
59 {
60
61 }
62
63 const class verb& verb() const
64 {
65 return *m_verb;
66 }
67
68 verb_token& conjugate(conjugation infl)
69 {
70 verb_infl = infl;
71 return *this;
72 }
73
74 bool complete() const
75 {
76 return true;
77 }
78
79 std::string compile() const
80 {
81 return m_verb->conjugate(verb_infl);
82 }
83
84 token* copy() const
85 {
86 return new verb_token(*this);
87 }
88 };
89
90 class utterance_token : public token {
91 private:
92 // Utterance
93 std::list<std::unique_ptr<token>> utterance;
94
95 public:
96 typedef std::list<std::unique_ptr<token>>::iterator iterator;
97 /*class iterator {
98 private:
99 friend class utterance_token;
100
101 std::list<std::unique_ptr<token>>::iterator it;
102
103 public:
104 iterator(std::list<std::unique_ptr<token>>::iterator it) : it(it)
105 {
106
107 }
108
109 iterator& operator++()
110 {
111 ++it;
112 return *this;
113 }
114
115 iterator& operator--()
116 {
117 --it;
118 return *this;
119 }
120
121 bool operator==(const iterator& other) const
122 {
123 return it == other.it;
124 }
125
126 bool operator!=(const iterator& other) const
127 {
128 return it != other.it;
129 }
130
131 token* operator*()
132 {
133 return *it->get();
134 }
135
136 token* operator->()
137 {
138 return *it->get();
139 }
140 };*/
141
142 utterance_token(std::initializer_list<token*> tkns) : token(type::utterance)
143 {
144 for (auto tkn : tkns)
145 {
146 utterance.push_back(std::unique_ptr<token>(tkn));
147 }
148 }
149
150 utterance_token(const utterance_token& other) : token(type::utterance)
151 {
152 for (auto& tkn : other.utterance)
153 {
154 utterance.push_back(std::unique_ptr<token>(tkn->copy()));
155 }
156 }
157
158 utterance_token(utterance_token&& other) : token(type::utterance), utterance(std::move(other.utterance))
159 {
160
161 }
162
163 utterance_token& operator=(const utterance_token& other)
164 {
165 utterance.clear();
166
167 for (auto& tkn : other.utterance)
168 {
169 utterance.push_back(std::unique_ptr<token>(tkn->copy()));
170 }
171
172 return *this;
173 }
174
175 utterance_token& operator=(utterance_token&& other)
176 {
177 utterance = std::move(other.utterance);
178
179 return *this;
180 }
181
182 iterator begin()
183 {
184 return std::begin(utterance);
185 }
186
187 iterator end()
188 {
189 return std::end(utterance);
190 }
191
192 const iterator begin() const
193 {
194 return std::begin(utterance);
195 }
196
197 const iterator end() const
198 {
199 return std::end(utterance);
200 }
201
202 void erase(iterator it)
203 {
204 utterance.erase(it);
205 }
206
207 bool complete() const
208 {
209 return std::all_of(std::begin(utterance), std::end(utterance), [] (const std::unique_ptr<token>& tkn) {
210 return tkn->complete();
211 });
212 }
213
214 std::string compile() const
215 {
216 std::stringstream result;
217 for (auto& t : utterance)
218 {
219 if (t->complete())
220 {
221 result << t->compile() << " ";
222 } else {
223 return "Could not compile!";
224 }
225 }
226
227 std::string output = result.str();
228 if (output != "")
229 {
230 output.pop_back();
231 }
232
233 return output;
234 }
235
236 token* copy() const
237 {
238 return new utterance_token(*this);
239 }
240 };
241
242 class fillin_token : public token {
243 private:
244 // Fillin
245 std::string m_theme;
246 fillin_type m_fillin_type;
247
248 public:
249 fillin_token(fillin_type ft) : token(type::fillin), m_fillin_type(ft)
250 {
251
252 }
253
254/* void synrestrs(std::initializer_list<synrestr> ins)
255 {
256 m_synrestrs = std::set<synrestr>(ins);
257 }
258
259 std::set<synrestr>& synrestrs()
260 {
261 return m_synrestrs;
262 }
263
264 void selrestrs(std::initializer_list<selrestr> ins)
265 {
266 m_selrestrs = std::set<selrestr>(ins);
267 }
268
269 std::set<selrestr>& selrestrs()
270 {
271 return m_selrestrs;
272 }*/
273
274 fillin_token theme(std::string theme)
275 {
276 m_theme = theme;
277
278 return *this;
279 }
280
281 std::string& theme()
282 {
283 return m_theme;
284 }
285
286 fillin_type fillin_type() const
287 {
288 return m_fillin_type;
289 }
290
291 bool complete() const
292 {
293 return false;
294 }
295
296 std::string compile() const
297 {
298 return "";
299 }
300
301 token* copy() const
302 {
303 return new fillin_token(*this);
304 }
305 };
306
307 class string_token : public token {
308 private:
309 // String
310 std::string str;
311
312 public:
313 string_token(std::string str) : token(type::string), str(str)
314 {
315
316 }
317
318 bool complete() const
319 {
320 return true;
321 }
322
323 std::string compile() const
324 {
325 return str;
326 }
327
328 token* copy() const
329 {
330 return new string_token(*this);
331 }
332 };
333
334};
335
336#endif /* end of include guard: TOKEN_H_AD62C505 */
diff --git a/verb.h b/verb.h new file mode 100644 index 0000000..42c8dc2 --- /dev/null +++ b/verb.h
@@ -0,0 +1,67 @@
1#ifndef VERB_H_BCC929AD
2#define VERB_H_BCC929AD
3
4#include <vector>
5
6namespace verbly {
7
8 /*class frame_part {
9
10 };
11
12 class frame {
13 private:
14 std::list<frame_part> content;
15 std::map<std::string, std::vector<std::list<frame_part>::iterator>> predicates;
16
17 public:
18 frame(std::list<frame_part> content) : content(content)
19 {
20
21 }
22
23 std::unique_ptr<token> make_utterance() const
24 {
25
26 }
27 };*/
28
29 enum class conjugation {
30 present_participle,
31 past_participle,
32 infinitive
33 };
34
35 class verb {
36 private:
37 int id;
38
39 public:
40 verb(int id) : id(id)
41 {
42
43 }
44
45 std::string infinitive;
46 std::string past_tense;
47 std::string past_participle;
48 std::string ing_form;
49 std::string s_form;
50 //std::vector<frame> frames;
51
52 std::string conjugate(conjugation infl) const
53 {
54 switch (infl)
55 {
56 case conjugation::infinitive: return infinitive;
57 case conjugation::past_participle: return past_participle;
58 case conjugation::present_participle: return ing_form;
59 }
60 }
61 };
62
63};
64
65#include "token.h"
66
67#endif /* end of include guard: VERB_H_BCC929AD */
diff --git a/verbly.h b/verbly.h new file mode 100644 index 0000000..139d8f8 --- /dev/null +++ b/verbly.h
@@ -0,0 +1,10 @@
1#ifndef VERBLY_H_5B39CE50
2#define VERBLY_H_5B39CE50
3
4#include "c++14.h"
5#include "token.h"
6#include "verb.h"
7#include "adjective.h"
8#include "data.h"
9
10#endif /* end of include guard: VERBLY_H_5B39CE50 */