Context algorithm
Semi-predictive context algorithm implementation
 All Data Structures Files Functions Variables Typedefs Macros Pages
fsmTree.c
Go to the documentation of this file.
1 /* Copyright 2013 Jorge Merlino
2 
3  This file is part of Context.
4 
5  Context is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  Context is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with Context. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <assert.h>
20 #include "fsmTree.h"
21 #include "alpha.h"
22 #include "text.h"
23 #include "spacedef.h"
24 #include "debug.h"
25 #include "arithmetic/coder.h"
26 #include "arithmetic/bitio.h"
27 
29 #define ROOT -1
30 
31 #define obstack_chunk_alloc malloc
32 #define obstack_chunk_free free
33 
35 static short pos;
36 
39 
42 
56 static void fastCanonize(fsmTree_t tree, Uint xLeft, Uint xRight, fsmTree_t *r, Uint *uLeft, Uint *uRight, Uint *vLeft, Uint *vRight) {
57  BOOL end;
58  fsmTree_t child = NULL;
59 
60  *vLeft = 1;
61  *vRight = 0; /* v is empty */
62 
63  if (tree->left != ROOT) {
64  xLeft += tree->length + tree->right - tree->left + 1;
65  }
66  end = xLeft > xRight;
67 
68  while (!end) {
69  child = tree->children[GETINDEX(xLeft)];
70  if ((child->right - child->left) <= (xRight - xLeft)) {
71  xLeft += child->right - child->left + 1;
72  tree = child;
73  end = xLeft > xRight;
74  }
75  else {
76  end = True;
77  }
78  }
79 
80  *r = tree;
81  if (xLeft <= xRight) {
82  *uLeft = child->left;
83  *uRight = child->left + xRight - xLeft;
84  }
85  else {
86  *uLeft = 1;
87  *uRight = 0; /* u is empty */
88  }
89 }
90 
91 
105 static void canonize(fsmTree_t tree, Uint xLeft, Uint xRight, fsmTree_t *r, Uint *uLeft, Uint *uRight, Uint *vLeft, Uint *vRight) {
106  BOOL end = False;
107  Uint i;
108  fsmTree_t child;
109 
110  if (xLeft > xRight) {
111  *uLeft = 1;
112  *uRight = 0; /* u is empty */
113  end = True;
114  }
115  else if (tree->left != ROOT) {
116  xLeft += tree->length + tree->right - tree->left + 1;
117  }
118 
119  while (!end) {
120  child = tree->children[GETINDEX(xLeft)];
121  if (child) { /* there is an edge in the direction of xLeft */
122  for (i=child->left; (i<=child->right) && (xLeft<=xRight) && (text[i]==text[xLeft]); i++, xLeft++);
123  if (i > child->right) { /* all the edge is in x */
124  tree = child;
125  if (xLeft > xRight) {
126  end = True;
127  *uLeft = 1;
128  *uRight = 0; /* u is empty */
129  }
130  }
131  else {
132  end = True;
133  *uLeft = child->left;
134  *uRight = i-1;
135  }
136  }
137  else {
138  end = True;
139  *uLeft = 1;
140  *uRight = 0; /* u is empty */
141  }
142  }
143 
144  *r = tree;
145  *vLeft = xLeft;
146  *vRight = xRight;
147 }
148 
149 
159 static fsmTree_t insert (fsmTree_t r, Uint uLeft, Uint uRight, Uint vLeft, Uint vRight) {
160  fsmTree_t new = initFsmTree(), newLeaf, ret;
161 
162  if (uLeft > uRight) {
163  /* add */
164  new->left = vLeft;
165  new->right = vRight;
166  if (r->left != ROOT) {
167  new->length = r->length + r->right - r->left + 1;
168  }
169  new->parent = r;
170  r->children[GETINDEX(vLeft)] = new;
171 
172  new->origin = r->origin;
173  ret = new;
174  }
175  else {
176  /* split */
177  new->left = uLeft;
178  new->right = uRight;
179  new->length = r->children[GETINDEX(uLeft)]->length;
180  new->children[GETINDEX(uRight+1)] = r->children[GETINDEX(uLeft)];
181  new->children[GETINDEX(uRight+1)]->left = uRight+1;
182  new->children[GETINDEX(uRight+1)]->length = new->length + uRight - uLeft + 1;
183  new->children[GETINDEX(uRight+1)]->parent = new;
184  new->parent = r;
185  r->children[GETINDEX(uLeft)] = new;
186 
187  new->origin = r->origin;
188  new->traversed[GETINDEX(uRight+1)] = r->traversed[GETINDEX(uLeft)];
189 
190  if (vLeft <= vRight) {
191  newLeaf = initFsmTree();
192  /* add */
193  newLeaf->left = vLeft;
194  newLeaf->right = vRight;
195  newLeaf->length = new->length + new->right - new->left + 1;
196  newLeaf->parent = new;
197  new->children[GETINDEX(vLeft)] = newLeaf;
198 
199  newLeaf->origin = new->origin;
200  ret = newLeaf;
201  }
202  else {
203  ret = new;
204  }
205  }
206  return ret;
207 }
208 
209 
216 static void verify(const fsmTree_t root, fsmTree_t node, BOOL fast) {
217  Uint xLeft, uLeft, uRight, vLeft, vRight, i, cidx;
218  fsmTree_t r, x;
219 
220  if (node->left != ROOT) {
221  cidx = GETINDEX(node->left - node->length);
222  xLeft = node->left - node->length + 1;
223 
224  if (fast) {
225  fastCanonize(root, xLeft, node->right, &r, &uLeft, &uRight, &vLeft, &vRight);
226  }
227  else {
228  canonize(root, xLeft, node->right, &r, &uLeft, &uRight, &vLeft, &vRight);
229  }
230 
231  if ((uLeft <= uRight) || (vLeft <= vRight)) {
232  x = insert(r, uLeft, uRight, vLeft, vRight);
233  if (uLeft <= uRight) {
234  if (r->traversed[GETINDEX(uLeft)]) {
235  verify((r->left == ROOT ? r : r->tail), r->children[GETINDEX(uLeft)], True);
236  }
237  }
238  else if (r->traversed[GETINDEX(vLeft)]) {
239  verify((r->left == ROOT ? r : r->tail), r->children[GETINDEX(vLeft)], False);
240  }
241  }
242  else { /* the node already exists */
243  x = r;
244  }
245  node->tail = x;
246  x->transitions[cidx] = node;
247  }
248  for (i=0; i<alphasize; i++) {
249  if (!node->traversed[i]) {
250  node->traversed[i] = True;
251  if (node->children[i]) {
252  verify((node->left == ROOT ? node : node->tail), node->children[i], False);
253  }
254  }
255  }
256 }
257 
258 
265  Uint i;
266 
267  for (i=0; i<alphasize; i++) {
268  if (!tree->transitions[i]) {
269  tree->transitions[i] = transitions[i];
270  }
271  }
272 
273  for (i=0; i<alphasize; i++) {
274  if (tree->children[i]) {
275  propagateTransitions(tree->transitions, tree->children[i]);
276  }
277  }
278 }
279 
286 static BOOL writeEncoder(BOOL internal, FILE *file) {
287  SYMBOL s;
288  Uint shift = 0, totalN = totalNodes, internalN = internalNodes;
289 
290  while ((totalN & 0xFFFFC000) != 0) { /* some of the most significative 18 bits on */
291  totalN >>= 1;
292  shift++;
293  }
294 
295  if (shift > 0) {
296  internalN >>= shift;
297  totalN = (internalN * alphasize) + 1;
298  }
299 
300  s.scale = totalN;
301  if (internal) {
302  s.low_count = 0;
303  s.high_count = internalN;
304  internalNodes--;
305  }
306  else {
307  s.low_count = internalN;
308  s.high_count = totalN;
309  }
310  totalNodes--;
311  encode_symbol(file, &s);
312 
313  return ((totalNodes == internalNodes) || internalNodes == 0);
314 }
315 
316 
324 static BOOL writeFsmTreeRec(const fsmTree_t tree, Uint offset, FILE *file) {
325  Uint i;
326  BOOL leaf = True, stop;
327 
328  if (tree->left + offset == tree->right) {
329  for (i=0; i<alphasize && leaf; i++) {
330  leaf = !tree->children[i];
331  }
332  if (leaf) {
333  return writeEncoder(0, file);
334  }
335  else {
336  stop = writeEncoder(1, file);
337  if (stop) return True;
338  for (i=0; i<alphasize; i++) {
339  if (tree->children[i]) {
340  stop = writeFsmTreeRec(tree->children[i], 0, file);
341  if (stop) return True;
342  }
343  else {
344  stop = writeEncoder(0, file);
345  if (stop) return True;
346  }
347  }
348  }
349  }
350  else {
351  stop = writeEncoder(1, file);
352  if (stop) return True;
353  for (i=0; i<alphasize; i++) {
354  if (GETINDEX(tree->left + offset + 1) == i) {
355  stop = writeFsmTreeRec(tree, offset+1, file);
356  if (stop) return True;
357  }
358  else {
359  stop = writeEncoder(0, file);
360  if (stop) return True;
361  }
362  }
363  }
364  return False;
365 }
366 
367 
375 static Ushort getInternalNodeCount (const fsmTree_t tree, const Uint offset) {
376  Uint i, count = 0;
377  BOOL leaf = True;
378 
379  if (tree->left + offset == tree->right) {
380  for (i=0; i<alphasize; i++) {
381  if (tree->children[i]) {
382  count += getInternalNodeCount(tree->children[i], 0);
383  leaf = False;
384  }
385  }
386  if (!leaf) count ++;
387  }
388  else {
389  count = getInternalNodeCount(tree, offset+1) + 1;
390  }
391  return count;
392 }
393 
394 static void copyStatisticsRec (const fsmTree_t orig, const int offsetOrig, fsmTree_t dest, const int offsetDest, const Uchar * text2) {
395  int i, posDest, posOrig;
396  BOOL end;
397 
398  posDest = dest->left + offsetDest;
399  posOrig = orig->left + offsetOrig;
400  end = False;
401  while (posOrig <= orig->right && posDest <= dest->right && !end) {
402  if (text2[posOrig] == text[posDest]) {
403  posOrig++;
404  posDest++;
405  }
406  else {
407  end = True;
408  }
409  }
410 
411  if (!end) {
412  if (posDest > dest->right) { /* reached a node in dest */
413  dest->origin->totalSyms = orig->origin->totalSyms;
414  dest->origin->totalCount = orig->origin->totalCount;
415  for (i=0; i<alphasize; i++) {
416  dest->origin->symbols[i] = orig->origin->symbols[i];
417  dest->origin->count[i] = orig->origin->count[i];
418  }
419 
420  if (posOrig > orig->right) { /* reached a node in orig also */
421  for (i=0; i<alphasize; i++) {
422  if (orig->children[i] && dest->children[i]) {
423  copyStatisticsRec(orig->children[i], 0, dest->children[i], 0, text2);
424  }
425  }
426  }
427  else {
428  if (dest->children[GETINDEX3(posOrig)]) {
429  copyStatisticsRec(orig, posOrig, dest->children[GETINDEX3(posOrig)], 0, text2);
430  }
431  }
432 
433  }
434  else { /* reached a node in orig */
435  if (orig->children[GETINDEX(posDest)])
436  copyStatisticsRec(orig->children[GETINDEX(posDest)], 0, dest, posDest, text2);
437  }
438  }
439 }
440 
441 #ifdef DEBUG
442 
448 static void printRec(const fsmTree_t tree, int level) {
449  int i;
450 
451  if (level > 0) {
452  for (i=1; i<=level; i++) {
453  printf("-");
454  }
455 
456  assert (tree->right < textlen);
457  assert (tree->left < textlen);
458  printf("%ld - %ld (%p) parent: %p orig: %p\n", tree->left, tree->right, (void*)tree, (void*)tree->parent, (void*)tree->origin);
459  for (i=tree->left; i< tree->right; i++) {
460  printf("%d-", *(text + i));
461  }
462  if (tree->right == textlen) {
463  printf("$\n");
464  }
465  else {
466  printf("%d\n", *(text + tree->right));
467  }
468  }
469  else {
470  printf("(root)\n");
471  }
472 
473  level++;
474  for (i=0; i<alphasize; i++) {
475  if (tree->children[i]) {
476  printf ("hijo %d ", i);
477  printRec(tree->children[i], level);
478  }
479  }
480 }
481 
482 #endif
483 
488  fsmTree_t ret;
489 
490  CALLOC(ret, struct fsmTree, 1);
491  memset(ret, 0, sizeof(struct fsmTree));
492 
493 #ifndef WIN32
494  obstack_init (&(ret->nodeStack));
495  if (obstack_chunk_size (&(ret->nodeStack)) < 16384) {
496  obstack_chunk_size (&(ret->nodeStack)) = 16384;
497  }
498 
499  ret->children = (fsmTree_t *)obstack_alloc(&(ret->nodeStack), sizeof(struct fsmTree *) * alphasize);
500  memset(ret->children, 0, sizeof(struct fsmTree *) * alphasize);
501 
502  ret->transitions = (fsmTree_t *)obstack_alloc(&(ret->nodeStack), sizeof(struct fsmTree *) * alphasize);
503  memset(ret->transitions, 0, sizeof(struct fsmTree *) * alphasize);
504 
505  ret->traversed = (BOOL *)obstack_alloc(&(ret->nodeStack), sizeof(BOOL) * alphasize);
506  memset(ret->traversed, 0, sizeof(BOOL) * alphasize);
507 
508  ret->count = (Uint *)obstack_alloc(&(ret->nodeStack), sizeof(Uint) * alphasize);
509  ret->symbols = (Uchar *)obstack_alloc(&(ret->nodeStack), sizeof(Uchar) * alphasize);
510 #else
511  CALLOC(ret, struct fsmTree, 1);
512  CALLOC(ret->children, struct fsmTree *, alphasize);
513  CALLOC(ret->transitions, struct fsmTree *, alphasize);
514  CALLOC(ret->traversed, BOOL, alphasize);
515  MALLOC(ret->count, Uint, alphasize);
516  MALLOC(ret->symbols, Uchar, alphasize);
517 #endif
518 
519  /* not always true but makes sense as init */
520  ret->left = ret->right = ROOT;
521  ret->origin = ret;
522  ret->used = False;
523  return ret;
524 }
525 
526 
530 void freeFsmTree(fsmTree_t tree) {
531 #ifndef WIN32
532  obstack_free(&(tree->nodeStack), NULL);
533 #else
534  FREE(tree->children);
535  FREE(tree->transitions);
536  FREE(tree->traversed);
537  FREE(tree->count);
538  FREE(tree->symbols);
539  FREE(tree);
540 #endif
541 }
542 
543 void addSymbol(fsmTree_t tree, const Uchar sym) {
544  tree->symbols[tree->totalSyms] = sym;
545  tree->count[tree->totalSyms] = 1;
546  tree->totalSyms++;
547  tree->totalCount++;
548 }
549 
553 void makeFsm(fsmTree_t tree) {
555  Uint i;
556 
557  CALLOC(transitions, fsmTree_t, alphasize);
558  tree->used = True;
559  verify(tree, tree, False);
560  for (i=0; i<alphasize; i++) {
561  transitions[i] = tree; /* ROOT */
562  }
563  propagateTransitions (transitions, tree);
564  FREE(transitions);
565 }
566 
567 
572 void writeFsmTree(const fsmTree_t tree, FILE *file) {
573  Uint total, internal;
574  SYMBOL s;
575  long cost;
576 
577  pos = 0;
578 
579  internalNodes = internal = getInternalNodeCount(tree, 0);
580  totalNodes = total = (internalNodes * alphasize) + 1;
581 
582  cost = bit_ftell_output(file);
583 
584  assert(internalNodes < 16383);
585  s.scale = 16383;
587  s.high_count = internalNodes + 1;
588  encode_symbol(file, &s);
589 
590  if (internalNodes > 0) {
591  writeFsmTreeRec(tree, 0, file);
592  }
593  printf("Representantion cost: %ld (internal: %ld, total: %ld)\n",
594  bit_ftell_output(file) - cost, internal, total);
595 }
596 
597 
603  return tree->left == ROOT;
604 }
605 
606 Uint getHeight (const fsmTree_t tree) {
607  Uint i, max = 0, h;
608 
609  for (i=0; i<alphasize; i++) {
610  if (tree->children[i]) {
611  h = getHeight(tree->children[i]);
612  if (h > max) max = h;
613  }
614  }
615 
616  return max + tree->right - tree->left + 1;
617 }
618 
619 void printContext (fsmTree_t tree) {
620  int i;
621 
622  while (tree->left != ROOT) {
623  for (i=tree->left; i< tree->right; i++) {
624  printf("%c", *(text + i));
625  }
626  if (tree->right == textlen) {
627  printf("$\n");
628  }
629  else {
630  printf("%c\n", *(text + tree->right));
631  }
632  tree = tree->parent;
633  }
634  printf("root\n");
635 }
636 
637 static int compareTreesRec (const fsmTree_t treeA, const fsmTree_t treeB, int level) {
638  int i, minLevel, actLevel;
639 
640  if ((treeA == NULL && treeB != NULL) || (treeA != NULL && treeB == NULL)) {
641  return level;
642  }
643  else if (treeA == NULL && treeB == NULL) {
644  return -1;
645  }
646  else {
647  minLevel = compareTreesRec(treeA->children[0], treeB->children[0], level+1);
648  for (i=1; (i<alphasize) && (minLevel != level+1); i++) {
649  actLevel = compareTreesRec(treeA->children[i], treeB->children[i], level+1);
650  if ((actLevel > 0) && (minLevel > actLevel)) {
651  minLevel = actLevel;
652  }
653  }
654 
655  return minLevel;
656  }
657 }
658 
659 void compareTrees (const fsmTree_t treeA, const fsmTree_t treeB) {
660  int level = compareTreesRec(treeA, treeB, 0);
661  printf("First different level = %d\n", level);
662 }
663 
664 void copyStatistics (const fsmTree_t orig, fsmTree_t dest, const Uchar * text2) {
665  int i;
666 
667  dest->totalSyms = orig->totalSyms;
668  dest->totalCount = orig->totalCount;
669  for (i=0; i<alphasize; i++) {
670  dest->symbols[i] = orig->symbols[i];
671  dest->count[i] = orig->count[i];
672  }
673 
674  for (i=0; i<alphasize; i++) {
675  if (orig->children[i] && dest->children[i]) {
676  copyStatisticsRec(orig->children[i], 0, dest->children[i], 0, text2);
677  }
678  }
679 }
680 
681 #ifdef DEBUG
682 
686 void printFsmTree(const fsmTree_t tree) {
687  printRec(tree, 0);
688 }
689 
690 #endif
static void verify(const fsmTree_t root, fsmTree_t node, BOOL fast)
Verifies that the tail of root is in the tree, adding it if necessary and continuing recursively on t...
Definition: fsmTree.c:216
void addSymbol(fsmTree_t tree, const Uchar sym)
Adds a new symbol to this tree node.
Definition: fsmTree.c:543
fsmTree_t initFsmTree()
Creates and initializes a new fsm tree structure instance.
Definition: fsmTree.c:487
static fsmTree_t insert(fsmTree_t r, Uint uLeft, Uint uRight, Uint vLeft, Uint vRight)
Inserts new nodes in the FSM closure of the tree.
Definition: fsmTree.c:159
static void canonize(fsmTree_t tree, Uint xLeft, Uint xRight, fsmTree_t *r, Uint *uLeft, Uint *uRight, Uint *vLeft, Uint *vRight)
Calculates the canonical decomposition of a string.
Definition: fsmTree.c:105
void printContext(fsmTree_t tree)
Definition: fsmTree.c:619
Uint textlen
Length of the input text in the encoder.
Definition: text.h:23
unsigned short int scale
Definition: coder.h:24
void encode_symbol(FILE *stream, SYMBOL *s)
Definition: coder.c:54
struct fsmTree ** transitions
List of FSM transitions from this state.
Definition: fsmTree.h:39
BOOL isRootFsmTree(const fsmTree_t tree)
Indicates if the parameter node is the root of the tree.
Definition: fsmTree.c:602
Definition: coder.h:21
Uint getHeight(const fsmTree_t tree)
Definition: fsmTree.c:606
#define True
True boolean constant.
Definition: types.h:108
Uint totalCount
Definition: fsmTree.h:29
Uint alphasize
Alphabet size.
Definition: alpha.h:25
static void fastCanonize(fsmTree_t tree, Uint xLeft, Uint xRight, fsmTree_t *r, Uint *uLeft, Uint *uRight, Uint *vLeft, Uint *vRight)
Calculates the canonical decomposition of a string in a faster way.
Definition: fsmTree.c:56
unsigned char Uchar
Unsigned char type.
Definition: types.h:48
Uint right
Index of the rightmost character of the label of this node.
Definition: decoderTree.h:26
Uchar * text
Input text to the encoder.
Definition: text.h:26
BOOL used
Flag that indicates if this node has been used to encode a symbol.
Definition: fsmTree.h:45
BOOL * traversed
List of flags indicating an attempt was made to traverse each child edge.
Definition: fsmTree.h:45
Uchar * symbols
Definition: fsmTree.h:37
static BOOL writeEncoder(BOOL internal, FILE *file)
Auxiliary function to write a tree node to a file using an arithmetic encoder.
Definition: fsmTree.c:286
#define FREE(P)
Frees a block of memory and makes the pointer NULL.
Definition: spacedef.h:58
struct fsmTree * origin
Pointer to the original node this one descends from.
Definition: fsmTree.h:39
#define CALLOC(S, T, N)
Allocs a new block of memory and sets all its bits to zero.
Definition: spacedef.h:72
unsigned long Uint
Unsigned int type.
Definition: types.h:54
#define BOOL
Boolean data type.
Definition: types.h:92
Uint * count
List containing the number of occurrences of each character in this state.
Definition: fsmTree.h:29
unsigned short int low_count
Definition: coder.h:22
Encoder context tree structure.
Definition: fsmTree.h:28
static void copyStatisticsRec(const fsmTree_t orig, const int offsetOrig, fsmTree_t dest, const int offsetDest, const Uchar *text2)
Definition: fsmTree.c:394
void writeFsmTree(const fsmTree_t tree, FILE *file)
Writes this tree into a file.
Definition: fsmTree.c:572
static short pos
Current position in the buffer.
Definition: fsmTree.c:35
static BOOL writeFsmTreeRec(const fsmTree_t tree, Uint offset, FILE *file)
Auxiliary recursive function to write a tree to a file using an arithemtic encoder.
Definition: fsmTree.c:324
struct obstack nodeStack
Obstack used to allocate memory for this tree.
Definition: fsmTree.h:49
Uint right
Index of the rightmost character of this node label in the input string.
Definition: fsmTree.h:29
struct decoderTree ** transitions
List of FSM transitions from this state.
Definition: decoderTree.h:32
#define False
False boolean constant.
Definition: types.h:100
Uint left
Index of the leftmost character of this node label in the input string.
Definition: fsmTree.h:29
#define MALLOC(S, T, N)
Definition: spacedef.h:81
Uint totalSyms
Total number of symbols occuring at this state.
Definition: fsmTree.h:29
void makeFsm(fsmTree_t tree)
Calculates the FSM closure of this tree.
Definition: fsmTree.c:553
#define GETINDEX3(N)
Definition: alpha.h:40
struct fsmTree ** children
List of pointers to all the children of this node.
Definition: fsmTree.h:39
unsigned short int high_count
Definition: coder.h:23
Uint * count
Counts of the number of occurrences of each symbol in this state.
Definition: decoderTree.h:26
static Ushort getInternalNodeCount(const fsmTree_t tree, const Uint offset)
Counts the number of internal nodes in a full tree.
Definition: fsmTree.c:375
void copyStatistics(const fsmTree_t orig, fsmTree_t dest, const Uchar *text2)
Definition: fsmTree.c:664
#define GETINDEX(N)
Returns the index of the Nth character in the input text.
Definition: alpha.h:38
struct fsmTree * tail
Pointer to the node whose label is the tail of this one.
Definition: fsmTree.h:39
struct fsmTree * parent
Pointer to the parent of this node.
Definition: fsmTree.h:39
void freeFsmTree(fsmTree_t tree)
Deletes a fsm tree structure instance.
Definition: fsmTree.c:530
static Ushort internalNodes
Number of internal nodes in the tree.
Definition: fsmTree.c:38
Uint length
Distance from this node to the root of the tree.
Definition: fsmTree.h:29
static Uint totalNodes
Total number of nodes in the tree.
Definition: fsmTree.c:41
static int compareTreesRec(const fsmTree_t treeA, const fsmTree_t treeB, int level)
Definition: fsmTree.c:637
long bit_ftell_output(FILE *stream)
Definition: bitio.c:148
#define ROOT
Flag to indicate a node is the root.
Definition: fsmTree.c:29
unsigned short Ushort
Unsigned short type.
Definition: types.h:51
static void propagateTransitions(fsmTree_t *transitions, fsmTree_t tree)
Adds to the FSM a set of transitions originating from tree if they were not defined by verify...
Definition: fsmTree.c:264
void compareTrees(const fsmTree_t treeA, const fsmTree_t treeB)
Definition: fsmTree.c:659