smntc
an in-memory multimodal graph database
Loading...
Searching...
No Matches
Words.c
Go to the documentation of this file.
1// word cluster
2//
3// top bottom type
4// vertex vertex vertex
5// o=========o========o
6//
7//
8//
9// a top vertex of the word layer
10//
11// all
12// previous and next
13// next one-letter one-word
14// word ^ words ^ phrase
15// | V |
16// o=========o========o
17// ^ ^
18// | |
19// previous word
20// word type
21//
22//
23//
24// the low border of the word layer
25//
26// all
27// previous and next
28// one-letter
29// words
30// V
31// o=========o========o
32// ^ ^
33// | |
34// binary word
35// code type
36//
37
38#include <stdlib.h>
39#include "errors.h"
40#include "Graph.h"
41#include "Binary.h"
42#include "Utf8.h"
43
44#include <stdio.h>
45
46#define WORD_CLUSTER_LENGTH 3
47#define BUFFER_LENGTH 256 // No large alphabets, no large dictionaries, because otherwise either no sense or no time. It's the natural constraint on the mind. Many cultures and many people and many contextual meanings of one word are nessecary. Degradation follows too much of unavoidable unification.
48
50struct Words {
51 struct Binary *binary;
52 struct Utf8 *utf8;
53 struct Graph *graph;
54 unsigned int wordType;
55};
56
57struct Words* Words_construct(unsigned int wordType, struct Binary *binary, struct Utf8 *utf8, struct Graph *graph, int *error)
58{
59 struct Words *this = malloc(sizeof(struct Words));
60
61 if (0 == this) {
62 *error = ERROR_NO_MEMORY;
63 return 0;
64 }
65
66 this->binary = binary;
67 this->utf8 = utf8;
68 this->graph = graph;
69 this->wordType = wordType;
70
71 return this;
72}
73
74struct Words* Words_destruct(struct Words *this)
75{
76 if (0 != this) {
78 Utf8_destruct(this->utf8);
79 free(this);
80 }
81
82 return 0;
83}
84
85unsigned int Words_writeWord(struct Words *this, unsigned int length, unsigned int *characters, int *error)
86{
87 unsigned int bottoms[BUFFER_LENGTH];
88 unsigned int wordCluster[WORD_CLUSTER_LENGTH];
89 unsigned int typeVertex = 0;
90
91 if (length > BUFFER_LENGTH) {
92 *error = ERROR_WORD_TOO_LONG;
93 return 0;
94 }
95
96 // connect binary codes to single-letter words
97
98 for (unsigned int offset = length; offset > 0; offset--) {
99
100 unsigned int index = offset - 1;
101
102 unsigned int characterCode = Binary_writeCode(this->binary, characters[index], error);
103
104 if (*error) {
105 return 0;
106 }
107
108 unsigned int wordClusterStart = Graph_readLastTarget(this->graph, characterCode, error);
109
110 if (*error) {
111 return 0;
112 }
113
114
115 if (0 == wordClusterStart) {
116
117 Graph_addCluster(this->graph, WORD_CLUSTER_LENGTH, wordCluster, error);
118
119 if (*error) {
120 return 0;
121 }
122
123 Graph_addEdge(this->graph, characterCode, wordCluster[0], error);
124
125 if (*error) {
126 return 0;
127 }
128
129 Graph_addEdge(this->graph, this->wordType, wordCluster[2], error);
130
131 if (*error) {
132 return 0;
133 }
134
135 } else {
136
137 Graph_readCluster(this->graph, wordClusterStart, WORD_CLUSTER_LENGTH, wordCluster, error);
138
139 if (*error) {
140 return 0;
141 }
142 }
143
144 bottoms[index] = wordCluster[1];
145 }
146
147 // build the word pyramid
148
149 if (1 == length) {
150 typeVertex = wordCluster[2];
151 }
152
153 unsigned int targets[BUFFER_LENGTH];
154 unsigned int sources[BUFFER_LENGTH];
155
156 for (unsigned int last = length - 1; last > 0; last--) {
157
158 for (unsigned int current = 1; current <= last; current++) {
159
160 unsigned int previous = current - 1;
161
162 unsigned int targetCount = Graph_countTargets(this->graph, bottoms[previous], error);
163
164 if (*error) {
165 return 0;
166 }
167
168 if (targetCount > BUFFER_LENGTH) {
169 *error = ERROR_WORD_TOO_RICH;
170 return 0;
171 }
172
173 unsigned int sourceCount = Graph_countSources(this->graph, bottoms[current], error);
174
175 if (*error) {
176 return 0;
177 }
178
179 if (sourceCount > BUFFER_LENGTH) {
180 *error = ERROR_WORD_TOO_RICH;
181 return 0;
182 }
183
184 Graph_readTargets(this->graph, bottoms[previous], BUFFER_LENGTH, targets, error);
185
186 if (*error) {
187 return 0;
188 }
189
190 Graph_readSources(this->graph, bottoms[current], BUFFER_LENGTH, sources, error);
191
192 if (*error) {
193 return 0;
194 }
195
196 unsigned int common = 0;
197
198 for (unsigned int targetIndex = 0; targetIndex < targetCount; targetIndex++) { // TODO: perhapse, check intersection after ordering
199 for (unsigned int sourceIndex = 0; sourceIndex < sourceCount; sourceIndex++) {
200 if (targets[targetIndex] == sources[sourceIndex]) {
201 common = targets[targetIndex];
202 break;
203 }
204 }
205 }
206
207 if (0 == common) {
208
209 Graph_addCluster(this->graph, WORD_CLUSTER_LENGTH, wordCluster, error);
210
211 if (*error) {
212 return 0;
213 }
214
215 Graph_addEdge(this->graph, this->wordType, wordCluster[2], error);
216
217 if (*error) {
218 return 0;
219 }
220
221 Graph_addEdge(this->graph, bottoms[previous], wordCluster[0], error);
222
223 if (*error) {
224 return 0;
225 }
226
227 Graph_addEdge(this->graph, wordCluster[0], bottoms[current], error);
228
229 if (*error) {
230 return 0;
231 }
232
233 } else {
234
235 Graph_readCluster(this->graph, common, WORD_CLUSTER_LENGTH, wordCluster, error);
236
237 if (*error) {
238 return 0;
239 }
240
241 }
242
243 bottoms[previous] = wordCluster[1];
244 typeVertex = wordCluster[2];
245 }
246 }
247
248 return typeVertex;
249}
250
251void Words_readWord(struct Words *this, unsigned int word, unsigned int length, unsigned int *characters, int *error)
252{
253 if (0 == length) {
255 return;
256 }
257
258 // traverse the word pyramid
259
260 unsigned int wordCluster[WORD_CLUSTER_LENGTH];
261
262 Graph_readCluster(this->graph, word, WORD_CLUSTER_LENGTH, wordCluster, error); // reversed
263
264 if (*error) {
265 return;
266 }
267
268 unsigned int tops[BUFFER_LENGTH];
269
270 tops[0] = wordCluster[1];
271
272 unsigned int last = 0;
273 int atBinaryBorder = 0;
274
275 while (! atBinaryBorder) {
276
277 unsigned int index = last;
278
279 while (index >= 0) {
280
281 unsigned int lastTarget = Graph_readLastTarget(this->graph, tops[index], error);
282
283 if (*error) {
284 return;
285 }
286
287 if (0 == lastTarget) {
288 atBinaryBorder = 1;
289 break;
290 }
291
292 Graph_readCluster(this->graph, lastTarget, WORD_CLUSTER_LENGTH, wordCluster, error);
293
294 if (*error) {
295 return;
296 }
297
298 tops[index + 1] = wordCluster[2];
299
300 if (0 == index) {
301
302 unsigned int lastSource = Graph_readLastSource(this->graph, tops[index], error);
303
304 if (*error) {
305 return;
306 }
307
308 Graph_readCluster(this->graph, lastSource, WORD_CLUSTER_LENGTH, wordCluster, error);
309
310 if (*error) {
311 return;
312 }
313
314 tops[index] = wordCluster[2];
315 }
316
317 if (index == 0) {
318 break;
319 } else {
320 index--;
321 }
322 };
323
324 if (! atBinaryBorder) {
325
326 last++;
327
328 if (last == length) {
330 return;
331 }
332 }
333 }
334
335 // read codes
336
337 for (unsigned int index = 0; index <= last; index++) {
338
339 unsigned int lastSource = Graph_readLastSource(this->graph, tops[index], error);
340
341 if (*error) {
342 return;
343 }
344
345 unsigned int code = Binary_readCode(this->binary, lastSource, error);
346
347 if (*error) {
348 return;
349 }
350
351 characters[index] = code;
352 }
353}
unsigned int Binary_writeCode(struct Binary *this, unsigned int input, int *error)
It writes binary value from an unsigned integer into a graph.
Definition Binary.c:96
struct Binary * Binary_destruct(struct Binary *this)
Definition Binary.c:87
unsigned int Binary_readCode(struct Binary *this, unsigned int code, int *error)
It reads binary value into an unsigned integer when given a vertex from a binary cluster.
Definition Binary.c:211
void Graph_readSources(const struct Graph *this, unsigned int target, unsigned int length, unsigned int *sources, int *error)
It reads all source vertices that have an edge leading to a particular target vertex.
Definition Graph.c:526
unsigned int Graph_countTargets(const struct Graph *this, unsigned int source, int *error)
It counts all target vertices that have an edge leading from a particular source vertex.
Definition Graph.c:504
unsigned int Graph_countSources(const struct Graph *this, unsigned int target, int *error)
It counts all source vertices that have an edge leading to a particular target vertex.
Definition Graph.c:482
void Graph_addEdge(struct Graph *this, unsigned int source, unsigned int target, int *error)
It adds a directed edge from a source vertex to a target vertex.
Definition Graph.c:298
unsigned int Graph_readLastTarget(const struct Graph *this, unsigned int source, int *error)
It reads the last target vertex of a source vertex, if it exists.
Definition Graph.c:712
unsigned int Graph_readLastSource(const struct Graph *this, unsigned int target, int *error)
It reads the last source vertex of a target vertex, if it exists.
Definition Graph.c:680
void Graph_readCluster(const struct Graph *this, unsigned int predecessor, unsigned int length, unsigned int *vertices, int *error)
Definition Graph.c:776
void Graph_readTargets(const struct Graph *this, unsigned int source, unsigned int length, unsigned int *targets, int *error)
It reads all target vertices that have an edge leading from a particular source vertex.
Definition Graph.c:603
void Graph_addCluster(struct Graph *this, unsigned int length, unsigned int *vertices, int *error)
Definition Graph.c:744
struct Utf8 * Utf8_destruct(struct Utf8 *this)
Definition Utf8.c:43
struct Words * Words_destruct(struct Words *this)
It destructs a managing object for all words in a graph.
Definition Words.c:74
struct Words * Words_construct(unsigned int wordType, struct Binary *binary, struct Utf8 *utf8, struct Graph *graph, int *error)
It constructs a new managing object for all words in a graph.
Definition Words.c:57
#define WORD_CLUSTER_LENGTH
Definition Words.c:46
void Words_readWord(struct Words *this, unsigned int word, unsigned int length, unsigned int *characters, int *error)
It reads a word from a graph.
Definition Words.c:251
#define BUFFER_LENGTH
Definition Words.c:47
unsigned int Words_writeWord(struct Words *this, unsigned int length, unsigned int *characters, int *error)
It writes one word into a graph.
Definition Words.c:85
#define ERROR_WORD_TOO_LONG
Definition errors.h:13
#define ERROR_NO_MEMORY
Definition errors.h:5
#define ERROR_WORD_BUFFER_TOO_SMALL
Definition errors.h:15
#define ERROR_WORD_TOO_RICH
Definition errors.h:14
Definition Graph.c:20
Definition Utf8.c:10
A managing object for all words in a graph.
Definition Words.c:50
struct Utf8 * utf8
its UTF8 converter
Definition Words.c:52
unsigned int wordType
its vertex that all word clusters will be connected to
Definition Words.c:54
struct Graph * graph
its graph storage with needed managing objects installed
Definition Words.c:53
struct Binary * binary
its manging object for binary character codes
Definition Words.c:51