ruby-sfst 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -0
  3. data/COPYING +280 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +54 -0
  6. data/README.md +1 -1
  7. data/Rakefile +9 -18
  8. data/bin/console +7 -0
  9. data/bin/setup +6 -0
  10. data/ext/sfst/alphabet.cc +879 -0
  11. data/ext/sfst/alphabet.h +302 -0
  12. data/ext/sfst/basic.cc +85 -0
  13. data/ext/{sfst_machine → sfst}/basic.h +7 -4
  14. data/ext/sfst/compact.cc +629 -0
  15. data/ext/sfst/compact.h +100 -0
  16. data/ext/sfst/determinise.cc +279 -0
  17. data/ext/{sfst_machine → sfst}/extconf.rb +2 -1
  18. data/ext/sfst/fst.cc +1150 -0
  19. data/ext/sfst/fst.h +374 -0
  20. data/ext/sfst/hopcroft.cc +681 -0
  21. data/ext/sfst/interface.cc +1921 -0
  22. data/ext/sfst/interface.h +171 -0
  23. data/ext/sfst/make-compact.cc +323 -0
  24. data/ext/{sfst_machine → sfst}/make-compact.h +15 -13
  25. data/ext/sfst/mem.h +80 -0
  26. data/ext/sfst/operators.cc +1273 -0
  27. data/ext/{sfst_machine → sfst}/sfst_machine.cc +89 -78
  28. data/ext/sfst/sgi.h +72 -0
  29. data/ext/sfst/utf8.cc +149 -0
  30. data/ext/{sfst_machine → sfst}/utf8.h +7 -4
  31. data/lib/sfst.rb +2 -1
  32. data/lib/sfst/version.rb +1 -1
  33. data/ruby-sfst.gemspec +23 -23
  34. metadata +107 -35
  35. data/ext/sfst_machine/alphabet.cc +0 -812
  36. data/ext/sfst_machine/alphabet.h +0 -273
  37. data/ext/sfst_machine/basic.cc +0 -84
  38. data/ext/sfst_machine/compact.cc +0 -616
  39. data/ext/sfst_machine/compact.h +0 -98
  40. data/ext/sfst_machine/determinise.cc +0 -303
  41. data/ext/sfst_machine/fst.cc +0 -1000
  42. data/ext/sfst_machine/fst.h +0 -369
  43. data/ext/sfst_machine/interface.cc +0 -1842
  44. data/ext/sfst_machine/interface.h +0 -93
  45. data/ext/sfst_machine/make-compact.cc +0 -327
  46. data/ext/sfst_machine/mem.h +0 -74
  47. data/ext/sfst_machine/operators.cc +0 -1131
  48. data/ext/sfst_machine/sgi.h +0 -44
  49. data/ext/sfst_machine/utf8.cc +0 -146
  50. data/test/test_sfst.fst +0 -3
  51. data/test/test_sfst.rb +0 -114
@@ -1,1131 +0,0 @@
1
-
2
- /*******************************************************************/
3
- /* */
4
- /* FILE operators.C */
5
- /* MODULE operators */
6
- /* PROGRAM SFST */
7
- /* AUTHOR Helmut Schmid, IMS, University of Stuttgart */
8
- /* */
9
- /*******************************************************************/
10
-
11
-
12
- #include "fst.h"
13
-
14
- using std::pair;
15
- using std::cerr;
16
-
17
- static void compose_nodes( Node*, Node*, Node*, Transducer*, PairMapping& );
18
-
19
-
20
- /*******************************************************************/
21
- /* */
22
- /* check_cyclicity */
23
- /* */
24
- /*******************************************************************/
25
-
26
- static bool check_cyclicity( Node *node, NodeHashSet &visited,
27
- const Alphabet &alphabet)
28
- {
29
-
30
- if (!visited.insert(node).second)
31
- return true; // node was visited before
32
-
33
- for( ArcsIter p(node->arcs()); p; p++ ) {
34
- Arc *arc=p;
35
- if (arc->label().upper_is_epsilon())
36
- if (check_cyclicity(arc->target_node(), visited, alphabet)) {
37
- cerr << alphabet.write_label(arc->label()) << "\n";
38
- return true;
39
- }
40
- }
41
- visited.erase(node);
42
- return false;
43
- }
44
-
45
-
46
- /*******************************************************************/
47
- /* */
48
- /* Transducer::infinitely_ambiguous_node */
49
- /* */
50
- /*******************************************************************/
51
-
52
- bool Transducer::infinitely_ambiguous_node( Node *node )
53
-
54
- {
55
- if (!node->was_visited( vmark )) {
56
- NodeHashSet visited;
57
- if (check_cyclicity(node, visited, alphabet))
58
- return true;
59
-
60
- // iterate over all outgoing arcs
61
- for( ArcsIter p(node->arcs()); p; p++ ) {
62
- Arc *arc=p;
63
- if (infinitely_ambiguous_node( arc->target_node() ))
64
- return true;
65
- }
66
- }
67
- return false;
68
- }
69
-
70
-
71
- /*******************************************************************/
72
- /* */
73
- /* Transducer::is_infinitely_ambiguous */
74
- /* */
75
- /*******************************************************************/
76
-
77
- bool Transducer::is_infinitely_ambiguous()
78
-
79
- {
80
- incr_vmark();
81
- return infinitely_ambiguous_node(root_node());
82
- }
83
-
84
-
85
- /*******************************************************************/
86
- /* */
87
- /* Transducer::is_cyclic_node */
88
- /* */
89
- /*******************************************************************/
90
-
91
- bool Transducer::is_cyclic_node( Node *node, NodeHashSet &previous )
92
-
93
- {
94
- if (!node->was_visited( vmark )) {
95
- NodeHashSet visited;
96
-
97
- NodeHashSet::iterator it=previous.insert(node).first;
98
-
99
- // iterate over all outgoing arcs
100
- for( ArcsIter p(node->arcs()); p; p++ ) {
101
- Arc *arc=p;
102
- if (previous.find(arc->target_node()) != previous.end() ||
103
- is_cyclic_node( arc->target_node(), previous ))
104
- return true;
105
- }
106
-
107
- previous.erase(it);
108
- }
109
- return false;
110
- }
111
-
112
-
113
- /*******************************************************************/
114
- /* */
115
- /* Transducer::is_cyclic */
116
- /* */
117
- /*******************************************************************/
118
-
119
- bool Transducer::is_cyclic()
120
-
121
- {
122
- incr_vmark();
123
- NodeHashSet previous;
124
- return is_cyclic_node(root_node(), previous);
125
- }
126
-
127
-
128
-
129
- /*******************************************************************/
130
- /* */
131
- /* Transducer::is_automaton_node */
132
- /* */
133
- /*******************************************************************/
134
-
135
- bool Transducer::is_automaton_node( Node *node )
136
-
137
- {
138
- if (!node->was_visited( vmark )) {
139
- // iterate over all outgoing arcs
140
- for( ArcsIter p(node->arcs()); p; p++ ) {
141
- Arc *arc=p;
142
- Label l=arc->label();
143
- if (l.upper_char() != l.lower_char())
144
- return false;
145
- if (!is_automaton_node( arc->target_node()))
146
- return false;
147
- }
148
- }
149
- return true;
150
- }
151
-
152
-
153
- /*******************************************************************/
154
- /* */
155
- /* Transducer::is_automaton */
156
- /* */
157
- /*******************************************************************/
158
-
159
- bool Transducer::is_automaton()
160
-
161
- {
162
- incr_vmark();
163
- return is_automaton_node(root_node());
164
- }
165
-
166
-
167
- /*******************************************************************/
168
- /* */
169
- /* Transducer::is_empty */
170
- /* */
171
- /*******************************************************************/
172
-
173
- bool Transducer::is_empty()
174
-
175
- {
176
- if (!minimised) {
177
- Transducer *tmp=&minimise();
178
- bool result=tmp->is_empty();
179
- delete tmp;
180
- return result;
181
- }
182
- if (root_node()->is_final())
183
- return false;
184
- return root_node()->arcs()->is_empty();
185
- }
186
-
187
-
188
- /*******************************************************************/
189
- /* */
190
- /* Transducer::generates_empty_string */
191
- /* */
192
- /*******************************************************************/
193
-
194
- bool Transducer::generates_empty_string()
195
-
196
- {
197
- if (!minimised) {
198
- Transducer *tmp=&minimise();
199
- bool result=tmp->root_node()->is_final();
200
- delete tmp;
201
- return result;
202
- }
203
- return root_node()->is_final();
204
- }
205
-
206
-
207
- /*******************************************************************/
208
- /* */
209
- /* Transducer::reverse_node */
210
- /* */
211
- /*******************************************************************/
212
-
213
- void Transducer::reverse_node( Node *node, Transducer *na )
214
-
215
- {
216
- if (!node->was_visited( vmark )) {
217
-
218
- // create a new node
219
- node->set_forward( na->new_node() );
220
-
221
- if (node->is_final())
222
- // add epsilon transition from new root to this node
223
- na->root_node()->add_arc( Label(), node->forward(), na );
224
-
225
- // iterate over all outgoing arcs
226
- for( ArcsIter p(node->arcs()); p; p++ ) {
227
- Arc *arc=p;
228
-
229
- // reverse the subgraph headed by the target node
230
- reverse_node( arc->target_node(), na );
231
- Node *n = arc->target_node()->forward();
232
-
233
- // create the reverse arc
234
- n->add_arc( arc->label(), node->forward(), na );
235
- }
236
- }
237
- }
238
-
239
-
240
- /*******************************************************************/
241
- /* */
242
- /* Transducer::reverse */
243
- /* */
244
- /*******************************************************************/
245
-
246
- Transducer &Transducer::reverse()
247
-
248
- {
249
- Transducer *na = new Transducer();
250
- na->alphabet.copy(alphabet);
251
-
252
- incr_vmark();
253
- reverse_node(root_node(), na);
254
- root_node()->forward()->set_final(1);
255
- return *na;
256
- }
257
-
258
-
259
- /*******************************************************************/
260
- /* */
261
- /* Transducer::recode_label */
262
- /* */
263
- /*******************************************************************/
264
-
265
- Label Transducer::recode_label( Label l, bool lswitch, bool recode,
266
- Alphabet &al )
267
- {
268
- if (lswitch)
269
- l = Label(l.upper_char(), l.lower_char());
270
-
271
- if (recode) {
272
- Character lc = al.add_symbol(alphabet.code2symbol(l.lower_char()));
273
- Character uc = al.add_symbol(alphabet.code2symbol(l.upper_char()));
274
- l = Label(lc, uc);
275
- al.insert(l);
276
- }
277
-
278
- return l;
279
- }
280
-
281
-
282
- /*******************************************************************/
283
- /* */
284
- /* Transducer::copy_nodes */
285
- /* */
286
- /*******************************************************************/
287
-
288
- Node *Transducer::copy_nodes( Node *node, Transducer *a,
289
- bool lswitch, bool recode )
290
- {
291
- if (!node->was_visited(vmark)) {
292
-
293
- node->set_forward(a->new_node());
294
-
295
- // define final nodes
296
- if (node->is_final())
297
- node->forward()->set_final(1);
298
-
299
- // iterate over all outgoing arcs of node
300
- for( ArcsIter p(node->arcs()); p; p++ ) {
301
- Arc *arc=p;
302
- Node *tn = copy_nodes( arc->target_node(), a, lswitch, recode );
303
-
304
- // Add a link to the new node
305
- Label l=recode_label(arc->label(), lswitch, recode, a->alphabet);
306
- node->forward()->add_arc( l, tn, a );
307
- }
308
- }
309
-
310
- return node->forward();
311
- }
312
-
313
-
314
- /*******************************************************************/
315
- /* */
316
- /* Transducer::copy */
317
- /* */
318
- /*******************************************************************/
319
-
320
- Transducer &Transducer::copy( bool lswitch, const Alphabet *al )
321
-
322
- {
323
- bool recode = false;
324
- Transducer *na = new Transducer();
325
- if (al == NULL)
326
- al = &alphabet;
327
- else
328
- recode = true;
329
-
330
- na->alphabet.utf8 = al->utf8;
331
- if (lswitch) {
332
- na->alphabet.insert_symbols(*al);
333
- for( Alphabet::iterator it=al->begin(); it!=al->end(); it++ ) {
334
- Character lc=it->lower_char();
335
- Character uc=it->upper_char();
336
- na->alphabet.insert(Label(uc,lc));
337
- }
338
- }
339
- else
340
- na->alphabet.copy(*al);
341
-
342
- na->deterministic = deterministic;
343
- na->minimised = minimised;
344
- na->root_node()->set_final(root_node()->is_final());
345
- incr_vmark();
346
-
347
- root_node()->set_forward(na->root_node());
348
- root_node()->was_visited(vmark);
349
-
350
- for( ArcsIter p(root_node()->arcs()); p; p++ ) {
351
- Arc *arc=p;
352
- Node *target_node=copy_nodes(arc->target_node(), na, lswitch, recode);
353
- Label l = recode_label(arc->label(), lswitch, recode, na->alphabet);
354
- na->root_node()->add_arc( l, target_node, na);
355
- }
356
-
357
- return *na;
358
- }
359
-
360
-
361
- /*******************************************************************/
362
- /* */
363
- /* Transducer::operator | */
364
- /* */
365
- /*******************************************************************/
366
-
367
- Transducer &Transducer::operator|( Transducer &a )
368
-
369
- {
370
- Transducer *na = new Transducer();
371
- na->alphabet.copy(alphabet);
372
- na->alphabet.copy(a.alphabet);
373
-
374
- incr_vmark();
375
- na->root_node()->add_arc( Label(), copy_nodes(root_node(), na), na);
376
- a.incr_vmark();
377
- na->root_node()->add_arc( Label(), a.copy_nodes(a.root_node(), na), na);
378
-
379
- return *na;
380
- }
381
-
382
-
383
- /*******************************************************************/
384
- /* */
385
- /* Transducer::rec_cat_nodes */
386
- /* */
387
- /*******************************************************************/
388
-
389
- void Transducer::rec_cat_nodes( Node *node, Node *node2 )
390
-
391
- {
392
- if (!node->was_visited( vmark )) {
393
-
394
- // iterate over all outgoing arcs of node
395
- for( ArcsIter p(node->arcs()); p; p++ ) {
396
- Arc *arc=p;
397
- rec_cat_nodes( arc->target_node(), node2 );
398
- }
399
-
400
- if (node->is_final()) {
401
- // link this node to node2
402
- node->set_final(0);
403
- node->add_arc( Label(), node2, this );
404
- }
405
- }
406
- }
407
-
408
-
409
- /*******************************************************************/
410
- /* */
411
- /* Transducer::operator+ */
412
- /* */
413
- /*******************************************************************/
414
-
415
- Transducer &Transducer::operator+( Transducer &a )
416
-
417
- {
418
- Transducer *na = new Transducer();
419
- na->alphabet.copy(alphabet);
420
- na->alphabet.copy(a.alphabet);
421
-
422
- // copy Transducer1 to the new Transducer
423
- incr_vmark();
424
- Node *node=copy_nodes(root_node(), na);
425
- na->root_node()->add_arc( Label(), node, na);
426
-
427
- // copy Transducer2 to the new Transducer
428
- a.incr_vmark();
429
- node=a.copy_nodes(a.root_node(), na);
430
-
431
- // catenate the two automata
432
- na->incr_vmark();
433
- na->rec_cat_nodes(na->root_node(), node);
434
-
435
- return *na;
436
- }
437
-
438
-
439
- /*******************************************************************/
440
- /* */
441
- /* Transducer::kleene_star */
442
- /* */
443
- /*******************************************************************/
444
-
445
- Transducer &Transducer::kleene_star()
446
-
447
- {
448
- Transducer *na = &copy();
449
- na->alphabet.copy(alphabet);
450
-
451
- // link back to the start node
452
- na->incr_vmark();
453
- na->rec_cat_nodes(na->root_node(), na->root_node());
454
- na->root_node()->set_final(1);
455
-
456
- na->deterministic = na->minimised = false;
457
-
458
- return *na;
459
- }
460
-
461
-
462
- /*******************************************************************/
463
- /* */
464
- /* Transducer::negate_nodes */
465
- /* */
466
- /*******************************************************************/
467
-
468
- void Transducer::negate_nodes( Node *node, Node *accept )
469
-
470
- {
471
- if (!node->was_visited(vmark)) {
472
- node->set_final( !node->is_final() );
473
-
474
- for( ArcsIter p(node->arcs()); p; p++ ) {
475
- Arc *arc=p;
476
- negate_nodes( arc->target_node(), accept );
477
- }
478
-
479
- for( Alphabet::iterator it=alphabet.begin(); it!=alphabet.end(); it++)
480
- if (!node->target_node(*it))
481
- node->add_arc( *it, accept, this );
482
- }
483
- }
484
-
485
-
486
- /*******************************************************************/
487
- /* */
488
- /* Transducer::productive_node */
489
- /* */
490
- /*******************************************************************/
491
-
492
- bool Transducer::productive_node( Node *node )
493
-
494
- {
495
- if (node->was_visited(vmark))
496
- return (node->forward() != NULL);
497
-
498
- bool productive;
499
- if (node->is_final()) {
500
- productive = true;
501
- node->set_forward( node );
502
- }
503
- else {
504
- productive = false;
505
- node->set_forward( NULL );
506
- }
507
-
508
- for( ArcsIter p(node->arcs()); p; p++ ) {
509
- Arc *arc=p;
510
- if (productive_node( arc->target_node() ))
511
- productive = true;
512
- }
513
-
514
- if (productive)
515
- // use forwardp to indicate whether the node is productive
516
- node->set_forward(node);
517
- return productive;
518
- }
519
-
520
-
521
- /*******************************************************************/
522
- /* */
523
- /* Transducer::prune_nodes */
524
- /* */
525
- /*******************************************************************/
526
-
527
- bool Transducer::prune_nodes( Node *node )
528
-
529
- {
530
- if (!node->was_visited(vmark)) {
531
- for( ArcsIter p(node->arcs()); p; p++ ) {
532
- Arc *arc=p;
533
- if (prune_nodes( arc->target_node() ))
534
- node->arcs()->remove_arc(arc);
535
- }
536
- if (!node->arcs()->is_empty())
537
- node->set_forward(node);
538
- }
539
- return (node->forward() == NULL);
540
- }
541
-
542
-
543
- /*******************************************************************/
544
- /* */
545
- /* Transducer::prune */
546
- /* */
547
- /*******************************************************************/
548
-
549
- void Transducer::prune()
550
-
551
- {
552
- incr_vmark();
553
- productive_node( root_node() );
554
- incr_vmark();
555
- prune_nodes( root_node() );
556
- }
557
-
558
-
559
- /*******************************************************************/
560
- /* */
561
- /* Transducer::operator! */
562
- /* */
563
- /*******************************************************************/
564
-
565
- Transducer &Transducer::operator!()
566
-
567
- {
568
- Transducer *na;
569
-
570
- if (alphabet.size() == 0)
571
- throw "Negation of Transducer with undefined alphabet attempted!";
572
-
573
- if (minimised)
574
- na = &copy();
575
- else
576
- na = &minimise();
577
- na->alphabet.copy(alphabet);
578
-
579
- Node *accept_node=na->new_node();
580
- accept_node->set_final(1);
581
- for( Alphabet::iterator it=alphabet.begin(); it!=alphabet.end(); it++)
582
- accept_node->add_arc( *it, accept_node, na );
583
-
584
- na->incr_vmark();
585
- na->negate_nodes( na->root_node(), accept_node );
586
- //na->prune();
587
- na->minimised = na->deterministic = false;
588
-
589
- return *na;
590
- }
591
-
592
-
593
- /*******************************************************************/
594
- /* */
595
- /* conjoin_nodes */
596
- /* */
597
- /*******************************************************************/
598
-
599
- static void conjoin_nodes( Node *n1, Node *n2, Node *node,
600
- Transducer *a, PairMapping &map )
601
-
602
- {
603
- // if both input nodes are final, so is the new one
604
- if (n1->is_final() && n2->is_final())
605
- node->set_final(1);
606
-
607
- // iterate over all outgoing arcs of the first node
608
- for( ArcsIter i(n1->arcs()); i; i++ ) {
609
- Arc *arc=i;
610
- Label l=arc->label();
611
- Node *t1 = arc->target_node();
612
- Node *t2 = n2->target_node(l);
613
-
614
- // Does the second node have an outgoing arc with the same label?
615
- if (t2) {
616
- // Check whether this node pair has been encountered before
617
- PairMapping::iterator it=map.find(t1, t2);
618
-
619
- if (it == map.end()) {
620
- // new node pair
621
- // create a new node in the conjunction Transducer
622
- Node *target_node = a->new_node();
623
- // map the target node pair to the new node
624
- map[pair<Node*,Node*>(t1,t2)] = target_node;
625
- // add an arc to the new node
626
- node->add_arc( l, target_node, a );
627
- // recursion
628
- conjoin_nodes( t1, t2, target_node, a, map );
629
- }
630
- else {
631
- // add an arc to the already existing target node
632
- node->add_arc( l, it->second, a );
633
- }
634
- }
635
- }
636
- }
637
-
638
-
639
- /*******************************************************************/
640
- /* */
641
- /* Transducer::operator & */
642
- /* */
643
- /*******************************************************************/
644
-
645
- Transducer &Transducer::operator&( Transducer &a )
646
-
647
- {
648
- Transducer *tmp1=NULL;
649
- Transducer *tmp2=NULL;
650
- Node *r1, *r2;
651
-
652
- if (deterministic)
653
- r1 = root_node();
654
- else {
655
- tmp1 = &determinise();
656
- r1 = tmp1->root_node();
657
- }
658
-
659
- if (a.deterministic)
660
- r2 = a.root_node();
661
- else {
662
- tmp2 = &a.determinise();
663
- r2 = tmp2->root_node();
664
- }
665
-
666
- PairMapping map;
667
-
668
- Transducer *na = new Transducer();
669
- na->alphabet.copy(alphabet);
670
- na->alphabet.copy(a.alphabet);
671
-
672
- // map the two root nodes to the new root node
673
- map[pair<Node*,Node*>(r1, r2)] = na->root_node();
674
-
675
- // recursively conjoin the two automata
676
- conjoin_nodes( r1, r2, na->root_node(), na, map);
677
-
678
- na->deterministic = 1;
679
- delete tmp1;
680
- delete tmp2;
681
-
682
- return *na;
683
- }
684
-
685
-
686
- /*******************************************************************/
687
- /* */
688
- /* add_composed_node */
689
- /* */
690
- /*******************************************************************/
691
-
692
- static void add_composed_node( Label l, Node *n1, Node *n2, Node *node,
693
- Transducer *a, PairMapping &map )
694
-
695
- {
696
- // Check whether this node pair has been encountered before
697
- PairMapping::iterator it=map.find(n1, n2);
698
-
699
- if (it != map.end()) {
700
- // add an arc to the already existing target node
701
- node->add_arc( l, it->second, a );
702
- return;
703
- }
704
-
705
- // create a new node in the composed Transducer
706
- Node *target_node = a->new_node();
707
-
708
- // map the target node pair to the new node
709
- map[pair<Node*,Node*>(n1,n2)] = target_node;
710
-
711
- // add an arc to the new node
712
- node->add_arc( l, target_node, a );
713
-
714
- // recursion
715
- compose_nodes( n1, n2, target_node, a, map );
716
- }
717
-
718
-
719
- /*******************************************************************/
720
- /* */
721
- /* compose_nodes */
722
- /* */
723
- /*******************************************************************/
724
-
725
- static void compose_nodes( Node *n1, Node *n2, Node *node,
726
- Transducer *a, PairMapping &map )
727
- {
728
- // if both input nodes are final, so is the new one
729
- if (n1->is_final() && n2->is_final())
730
- node->set_final(1);
731
-
732
- // iterate over all outgoing arcs of the first node
733
- for( ArcsIter i(n1->arcs()); i; i++ ) {
734
- Arc *arc1=i;
735
- Node *t1 = arc1->target_node();
736
- Label l1=arc1->label();
737
- Character uc1=l1.upper_char();
738
- Character lc1=l1.lower_char();
739
-
740
- if (uc1 == Label::epsilon)
741
- add_composed_node( l1, t1, n2, node, a, map );
742
-
743
- else {
744
- for( ArcsIter k(n2->arcs()); k; k++ ) {
745
- Arc *arc2=k;
746
- Node *t2 = arc2->target_node();
747
- Label l2=arc2->label();
748
- Character lc2=l2.lower_char();
749
- Character uc2=l2.upper_char();
750
-
751
- if (uc1 == lc2)
752
- add_composed_node( Label(lc1,uc2), t1, t2, node, a, map );
753
- }
754
- }
755
- }
756
-
757
- // epsilon input characters of the second Transducer
758
- for( ArcsIter i(n2->arcs()); i; i++ ) {
759
- Arc *arc=i;
760
- Node *t = arc->target_node();
761
- Label l=arc->label();
762
- Character lc=l.lower_char();
763
-
764
- if (lc == Label::epsilon)
765
- add_composed_node( l, n1, t, node, a, map );
766
- }
767
- }
768
-
769
-
770
- /*******************************************************************/
771
- /* */
772
- /* Transducer::operator || */
773
- /* */
774
- /*******************************************************************/
775
-
776
- Transducer &Transducer::operator||( Transducer &a )
777
-
778
- {
779
- PairMapping map;
780
-
781
- Transducer *na = new Transducer();
782
- na->alphabet.compose(alphabet, a.alphabet);
783
-
784
- // map the two root nodes to the new root node
785
- map[pair<Node*,Node*>(root_node(), a.root_node())] = na->root_node();
786
-
787
- // recursively compose the two automata
788
- compose_nodes( root_node(), a.root_node(), na->root_node(), na, map );
789
-
790
- return *na;
791
- }
792
-
793
-
794
-
795
- /*******************************************************************/
796
- /* */
797
- /* Transducer::operator / */
798
- /* */
799
- /*******************************************************************/
800
-
801
- Transducer &Transducer::operator/( Transducer &a )
802
-
803
- {
804
- complete_alphabet();
805
- a.alphabet.copy(alphabet);
806
- Transducer *a1 = &(!a);
807
- Transducer *a2 = &(*this & *a1);
808
- delete a1;
809
- return *a2;
810
- }
811
-
812
-
813
- /*******************************************************************/
814
- /* */
815
- /* Transducer::compare_nodes */
816
- /* */
817
- /*******************************************************************/
818
-
819
- bool Transducer::compare_nodes( Node *node, Node *node2, Transducer &a2 )
820
-
821
- {
822
- if (node->was_visited( vmark )) {
823
- if (node2->was_visited( a2.vmark ))
824
- return (node->forward() == node2 && node2->forward() == node);
825
- else
826
- return false;
827
- }
828
- else if (node2->was_visited( a2.vmark ))
829
- return false;
830
-
831
- node->set_forward( node2 );
832
- node2->set_forward( node );
833
-
834
- if (node->is_final() != node2->is_final())
835
- return false;
836
-
837
- // iterate over all outgoing arcs
838
- for( ArcsIter p(node->arcs()); p; p++ ) {
839
- Arc *arc=p;
840
- Node *t2=node2->target_node(arc->label());
841
-
842
- if (t2 == NULL)
843
- return false;
844
- else if (!compare_nodes(arc->target_node(), t2, a2))
845
- return false;
846
- }
847
- for( ArcsIter p(node2->arcs()); p; p++ ) {
848
- Arc *arc=p;
849
- if (node->target_node(arc->label()) == NULL)
850
- return false;
851
- }
852
-
853
- return true;
854
- }
855
-
856
-
857
- /*******************************************************************/
858
- /* */
859
- /* Transducer::operator == */
860
- /* */
861
- /*******************************************************************/
862
-
863
- bool Transducer::operator==( Transducer &a )
864
-
865
- {
866
- Transducer *p1 = (minimised)? this: &minimise();
867
- Transducer *p2 = (a.minimised)? &a: &a.minimise();
868
-
869
- p1->incr_vmark();
870
- p2->incr_vmark();
871
- bool result = p1->compare_nodes(p1->root_node(), p2->root_node(), *p2 );
872
-
873
- if (p1 != this) delete p1;
874
- if (p2 != &a) delete p2;
875
-
876
- return result;
877
- }
878
-
879
-
880
-
881
- /*******************************************************************/
882
- /* */
883
- /* Transducer::map_nodes */
884
- /* */
885
- /*******************************************************************/
886
-
887
- void Transducer::map_nodes( Node *node, Node *node2, Transducer *a, Level level)
888
-
889
- {
890
- if (!node->was_visited(vmark)) {
891
-
892
- node->set_forward(node2);
893
-
894
- // define final nodes
895
- if (node->is_final())
896
- node2->set_final(1);
897
-
898
- // iterate over all outgoing arcs of node
899
- for( ArcsIter p(node->arcs()); p; p++ ) {
900
- Arc *arc=p;
901
- Label l(arc->label().get_char(level));
902
- Node *t2=NULL, *t=arc->target_node();
903
-
904
- if (t->check_visited(vmark))
905
- t2 = t->forward();
906
- else
907
- t2 = a->new_node(); // create a new node
908
-
909
- node2->add_arc(l, t2, a); // add a link to the node
910
-
911
- map_nodes( t, t2, a, level );
912
- }
913
- }
914
- }
915
-
916
-
917
- /*******************************************************************/
918
- /* */
919
- /* Transducer::level */
920
- /* */
921
- /*******************************************************************/
922
-
923
- Transducer &Transducer::level( Level level )
924
-
925
- {
926
- Transducer *na = new Transducer();
927
-
928
- for( Alphabet::iterator it=alphabet.begin(); it!=alphabet.end(); it++ ) {
929
- Character c = it->get_char(level);
930
- if (alphabet.code2symbol(c) != NULL)
931
- na->alphabet.add_symbol( alphabet.code2symbol(c), c );
932
- na->alphabet.insert(Label(c));
933
- }
934
-
935
- incr_vmark();
936
- map_nodes(root_node(), na->root_node(), na, level );
937
-
938
- return *na;
939
- }
940
-
941
-
942
- /*******************************************************************/
943
- /* */
944
- /* Transducer::freely_insert_at_node */
945
- /* */
946
- /*******************************************************************/
947
-
948
- void Transducer::freely_insert_at_node( Node *node, Label l )
949
-
950
- {
951
- if (!node->was_visited(vmark)) {
952
- node->add_arc(l, node, this); // add a recursive link labelled with l
953
-
954
- // iterate over all outgoing arcs of node
955
- for( ArcsIter p(node->arcs()); p; p++ ) {
956
- Arc *arc=p;
957
- freely_insert_at_node(arc->target_node(), l );
958
- }
959
- }
960
- }
961
-
962
-
963
- /*******************************************************************/
964
- /* */
965
- /* Transducer::freely_insert */
966
- /* */
967
- /*******************************************************************/
968
-
969
- Transducer &Transducer::freely_insert( Label l )
970
-
971
- {
972
- Transducer *na = &copy();
973
-
974
- na->incr_vmark();
975
- na->freely_insert_at_node(na->root_node(), l );
976
-
977
- return *na;
978
- }
979
-
980
-
981
- /*******************************************************************/
982
- /* */
983
- /* Transducer::splice_arc */
984
- /* */
985
- /*******************************************************************/
986
-
987
- void Transducer::splice_arc( Node *node, Node *node2, Node *next_node,
988
- Transducer *a )
989
- {
990
- if (node->is_final()) {
991
- // link final node to the next node
992
- node2->add_arc( Label(), next_node, a );
993
- return;
994
- }
995
-
996
- // iterate over the outgoing arcs
997
- for( ArcsIter p(node->arcs()); p; p++ ) {
998
- Arc *arc=p;
999
- Node *tn=a->new_node();
1000
-
1001
- node2->add_arc( arc->label(), tn, a );
1002
- splice_arc( arc->target_node(), tn, next_node, a );
1003
- }
1004
- }
1005
-
1006
-
1007
- /*******************************************************************/
1008
- /* */
1009
- /* Transducer::splice_nodes */
1010
- /* */
1011
- /*******************************************************************/
1012
-
1013
- void Transducer::splice_nodes(Node *node, Node *node2, Label sl,
1014
- Transducer *sa, Transducer *a)
1015
- {
1016
- if (!node->was_visited(vmark)) {
1017
-
1018
- node->set_forward(node2);
1019
-
1020
- // define final nodes
1021
- if (node->is_final())
1022
- node2->set_final(1);
1023
-
1024
- // iterate over all outgoing arcs of node
1025
- for( ArcsIter p(node->arcs()); p; p++ ) {
1026
- Arc *arc=p;
1027
- Node *t2=NULL, *t=arc->target_node();
1028
-
1029
- if (t->check_visited(vmark))
1030
- t2 = t->forward();
1031
- else
1032
- t2 = a->new_node(); // create a new node
1033
-
1034
- if (arc->label() == sl)
1035
- // insert the transducer
1036
- splice_arc(sa->root_node(), node2, t2, a);
1037
- else
1038
- // add a link to the node
1039
- node2->add_arc(arc->label(), t2, a);
1040
-
1041
- splice_nodes( t, t2, sl, sa, a );
1042
- }
1043
- }
1044
- }
1045
-
1046
-
1047
- /*******************************************************************/
1048
- /* */
1049
- /* Transducer::splice */
1050
- /* */
1051
- /*******************************************************************/
1052
-
1053
- Transducer &Transducer::splice( Label sl, Transducer *sa )
1054
-
1055
- {
1056
- Alphabet::iterator it;
1057
-
1058
- Transducer *na = new Transducer();
1059
-
1060
- for( it=alphabet.begin(); it!=alphabet.end(); it++ ) {
1061
- Label l = *it;
1062
- if (l != sl)
1063
- na->alphabet.insert(l);
1064
- }
1065
- for( it=sa->alphabet.begin(); it!=sa->alphabet.end(); it++ )
1066
- na->alphabet.insert(*it);
1067
-
1068
- incr_vmark();
1069
- splice_nodes(root_node(), na->root_node(), sl, sa, na );
1070
-
1071
- return *na;
1072
- }
1073
-
1074
-
1075
- /*******************************************************************/
1076
- /* */
1077
- /* Transducer::replace_char */
1078
- /* */
1079
- /*******************************************************************/
1080
-
1081
- Transducer &Transducer::replace_char( Character c, Character nc )
1082
-
1083
- {
1084
- Alphabet::iterator it;
1085
-
1086
- Transducer *na = new Transducer();
1087
-
1088
- for( it=alphabet.begin(); it!=alphabet.end(); it++ ) {
1089
- Label l = *it;
1090
- na->alphabet.insert(l.replace_char(c,nc));
1091
- }
1092
-
1093
- incr_vmark();
1094
- replace_char2(root_node(), na->root_node(), c, nc, na );
1095
-
1096
- return *na;
1097
- }
1098
-
1099
-
1100
- /*******************************************************************/
1101
- /* */
1102
- /* Transducer::replace_char2 */
1103
- /* */
1104
- /*******************************************************************/
1105
-
1106
- void Transducer::replace_char2(Node *node, Node *node2, Character c,
1107
- Character nc, Transducer *a)
1108
- {
1109
- if (!node->was_visited(vmark)) {
1110
-
1111
- node->set_forward(node2);
1112
-
1113
- // define final nodes
1114
- if (node->is_final())
1115
- node2->set_final(1);
1116
-
1117
- // iterate over all outgoing arcs of node
1118
- for( ArcsIter p(node->arcs()); p; p++ ) {
1119
- Arc *arc=p;
1120
- Node *t2=NULL, *t=arc->target_node();
1121
-
1122
- if (t->check_visited(vmark))
1123
- t2 = t->forward();
1124
- else
1125
- t2 = a->new_node(); // create a new node
1126
-
1127
- node2->add_arc(arc->label().replace_char(c, nc), t2, a);
1128
- replace_char2( t, t2, c, nc, a );
1129
- }
1130
- }
1131
- }