1 // map.h
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 //
16 // \file
17 // Class to map over/transform arcs e.g., change semirings or
18 // implement project/invert.
19
20 #ifndef FST_LIB_MAP_H__
21 #define FST_LIB_MAP_H__
22
23 #include "fst/lib/cache.h"
24 #include "fst/lib/mutable-fst.h"
25
26 namespace fst {
27
28 // This determines how final weights are mapped.
29 enum MapFinalAction {
30
31 // A final weight is mapped into a final weight. An error
32 // is raised if this is not possible.
33 MAP_NO_SUPERFINAL,
34
35 // A final weight is mapped to an arc to the superfinal state
36 // when the result cannot be represented as a final weight.
37 // The superfinal state will be added only if it is needed.
38 MAP_ALLOW_SUPERFINAL,
39
40 // A final weight is mapped to an arc to the superfinal state
41 // unless the result can be represented as a final weight of weight
42 // Zero(). The superfinal state is always added (if the input is
43 // not the empty Fst).
44 MAP_REQUIRE_SUPERFINAL
45 };
46
47 // Mapper Interface - class determinies how arcs and final weights
48 // are mapped.
49 //
50 // class Mapper {
51 // public:
52 // // Maps an arc type A to arc type B.
53 // B operator()(const A &arc);
54 // // Specifies final action the mapper requires (see above).
55 // // The mapper will be passed final weights as arcs of the
56 // // form A(0, 0, weight, kNoStateId).
57 // MapFinalAction FinalAction() const;
58 // // This specifies the known properties of an Fst mapped by this
59 // // mapper. It takes as argument the input Fst's known properties.
60 // uint64 Properties(uint64 props) const;
61 // }
62 //
63 // The Map functions and classes below will use the FinalAction()
64 // method of the mapper to determine how to treat final weights,
65 // e.g. whether to add a superfinal state. They will use the Properties()
66 // method to set the result Fst properties.
67 //
68 // We include a various map versions below. One dimension of
69 // variation is whether the mapping mutates its input, writes to a
70 // new result Fst, or is an on-the-fly Fst. Another dimension is how
71 // we pass the mapper. We allow passing the mapper by pointer
72 // for cases that we need to change the state of the user's mapper.
73 // This is the case with the encode mapper, which is reused during
74 // decoding. We also include map versions that pass the mapper
75 // by value or const reference when this suffices.
76
77
78 // Maps an arc type A using a mapper function object C, passed
79 // by pointer. This version modifies its Fst input.
80 template<class A, class C>
Map(MutableFst<A> * fst,C * mapper)81 void Map(MutableFst<A> *fst, C* mapper) {
82 typedef typename A::StateId StateId;
83 typedef typename A::Weight Weight;
84
85 if (fst->Start() == kNoStateId)
86 return;
87
88 uint64 props = fst->Properties(kFstProperties, false);
89
90 MapFinalAction final_action = mapper->FinalAction();
91 StateId superfinal = kNoStateId;
92 if (final_action == MAP_REQUIRE_SUPERFINAL) {
93 superfinal = fst->AddState();
94 fst->SetFinal(superfinal, Weight::One());
95 }
96
97 for (StateId s = 0; s < fst->NumStates(); ++s) {
98 for (MutableArcIterator< MutableFst<A> > aiter(fst, s);
99 !aiter.Done(); aiter.Next()) {
100 const A &arc = aiter.Value();
101 aiter.SetValue((*mapper)(arc));
102 }
103
104 switch (final_action) {
105 case MAP_NO_SUPERFINAL:
106 default: {
107 A final_arc = (*mapper)(A(0, 0, fst->Final(s), kNoStateId));
108 CHECK(final_arc.ilabel == 0 && final_arc.olabel == 0);
109 fst->SetFinal(s, final_arc.weight);
110 break;
111 }
112 case MAP_ALLOW_SUPERFINAL: {
113 if (s != superfinal) {
114 A final_arc = (*mapper)(A(0, 0, fst->Final(s), kNoStateId));
115 if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
116 // Add a superfinal state if not already done.
117 if (superfinal == kNoStateId) {
118 superfinal = fst->AddState();
119 fst->SetFinal(superfinal, Weight::One());
120 }
121 final_arc.nextstate = superfinal;
122 fst->AddArc(s, final_arc);
123 fst->SetFinal(s, Weight::Zero());
124 } else {
125 fst->SetFinal(s, final_arc.weight);
126 }
127 break;
128 }
129 }
130 case MAP_REQUIRE_SUPERFINAL: {
131 if (s != superfinal) {
132 A final_arc = (*mapper)(A(0, 0, fst->Final(s), kNoStateId));
133 if (final_arc.ilabel != 0 || final_arc.olabel != 0 ||
134 final_arc.weight != Weight::Zero())
135 fst->AddArc(s, A(final_arc.ilabel, final_arc.olabel,
136 final_arc.weight, superfinal));
137 fst->SetFinal(s, Weight::Zero());
138 }
139 break;
140 }
141 }
142 }
143 fst->SetProperties(mapper->Properties(props), kFstProperties);
144 }
145
146 // Maps an arc type A using a mapper function object C, passed
147 // by value. This version modifies its Fst input.
148 template<class A, class C>
Map(MutableFst<A> * fst,C mapper)149 void Map(MutableFst<A> *fst, C mapper) {
150 Map(fst, &mapper);
151 }
152
153
154 // Maps an arc type A to an arc type B using mapper function
155 // object C, passed by pointer. This version writes the mapped
156 // input Fst to an output MutableFst.
157 template<class A, class B, class C>
Map(const Fst<A> & ifst,MutableFst<B> * ofst,C * mapper)158 void Map(const Fst<A> &ifst, MutableFst<B> *ofst, C* mapper) {
159 typedef typename A::StateId StateId;
160 typedef typename A::Weight Weight;
161
162 ofst->DeleteStates();
163 ofst->SetInputSymbols(ifst.InputSymbols());
164 ofst->SetOutputSymbols(ifst.OutputSymbols());
165
166 if (ifst.Start() == kNoStateId)
167 return;
168
169 // Add all states.
170 for (StateIterator< Fst<A> > siter(ifst); !siter.Done(); siter.Next())
171 ofst->AddState();
172
173 MapFinalAction final_action = mapper->FinalAction();
174 StateId superfinal = kNoStateId;
175 if (final_action == MAP_REQUIRE_SUPERFINAL) {
176 superfinal = ofst->AddState();
177 ofst->SetFinal(superfinal, B::Weight::One());
178 }
179 for (StateIterator< Fst<A> > siter(ifst); !siter.Done(); siter.Next()) {
180 StateId s = siter.Value();
181 if (s == ifst.Start())
182 ofst->SetStart(s);
183
184 for (ArcIterator< Fst<A> > aiter(ifst, s); !aiter.Done(); aiter.Next())
185 ofst->AddArc(s, (*mapper)(aiter.Value()));
186
187 switch (final_action) {
188 case MAP_NO_SUPERFINAL:
189 default: {
190 B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId));
191 CHECK(final_arc.ilabel == 0 && final_arc.olabel == 0);
192 ofst->SetFinal(s, final_arc.weight);
193 break;
194 }
195 case MAP_ALLOW_SUPERFINAL: {
196 B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId));
197 if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
198 // Add a superfinal state if not already done.
199 if (superfinal == kNoStateId) {
200 superfinal = ofst->AddState();
201 ofst->SetFinal(superfinal, B::Weight::One());
202 }
203 final_arc.nextstate = superfinal;
204 ofst->AddArc(s, final_arc);
205 ofst->SetFinal(s, B::Weight::Zero());
206 } else {
207 ofst->SetFinal(s, final_arc.weight);
208 }
209 break;
210 }
211 case MAP_REQUIRE_SUPERFINAL: {
212 B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId));
213 if (final_arc.ilabel != 0 || final_arc.olabel != 0 ||
214 final_arc.weight != B::Weight::Zero())
215 ofst->AddArc(s, B(final_arc.ilabel, final_arc.olabel,
216 final_arc.weight, superfinal));
217 ofst->SetFinal(s, B::Weight::Zero());
218 break;
219 }
220 }
221 }
222 uint64 iprops = ifst.Properties(kCopyProperties, false);
223 uint64 oprops = ofst->Properties(kFstProperties, false);
224 ofst->SetProperties(mapper->Properties(iprops) | oprops, kFstProperties);
225 }
226
227 // Maps an arc type A to an arc type B using mapper function
228 // object C, passed by value. This version writes the mapped input
229 // Fst to an output MutableFst.
230 template<class A, class B, class C>
Map(const Fst<A> & ifst,MutableFst<B> * ofst,C mapper)231 void Map(const Fst<A> &ifst, MutableFst<B> *ofst, C mapper) {
232 Map(ifst, ofst, &mapper);
233 }
234
235
236 struct MapFstOptions : public CacheOptions {
237 // MapFst default caching behaviour is to do no caching. Most
238 // mappers are cheap and therefore we save memory by not doing
239 // caching.
MapFstOptionsMapFstOptions240 MapFstOptions() : CacheOptions(true, 0) {}
MapFstOptionsMapFstOptions241 MapFstOptions(const CacheOptions& opts) : CacheOptions(opts) {}
242 };
243
244
245 template <class A, class B, class C> class MapFst;
246
247 // Implementation of delayed MapFst.
248 template <class A, class B, class C>
249 class MapFstImpl : public CacheImpl<B> {
250 public:
251 using FstImpl<B>::SetType;
252 using FstImpl<B>::SetProperties;
253 using FstImpl<B>::Properties;
254 using FstImpl<B>::SetInputSymbols;
255 using FstImpl<B>::SetOutputSymbols;
256
257 using VectorFstBaseImpl<typename CacheImpl<B>::State>::NumStates;
258
259 using CacheImpl<B>::HasArcs;
260 using CacheImpl<B>::HasFinal;
261 using CacheImpl<B>::HasStart;
262
263 friend class StateIterator< MapFst<A, B, C> >;
264
265 typedef B Arc;
266 typedef typename B::Weight Weight;
267 typedef typename B::StateId StateId;
268
MapFstImpl(const Fst<A> & fst,const C & mapper,const MapFstOptions & opts)269 MapFstImpl(const Fst<A> &fst, const C &mapper,
270 const MapFstOptions& opts)
271 : CacheImpl<B>(opts), fst_(fst.Copy()),
272 mapper_(new C(mapper)),
273 own_mapper_(true),
274 superfinal_(kNoStateId),
275 nstates_(0) {
276 Init();
277 }
278
MapFstImpl(const Fst<A> & fst,C * mapper,const MapFstOptions & opts)279 MapFstImpl(const Fst<A> &fst, C *mapper,
280 const MapFstOptions& opts)
281 : CacheImpl<B>(opts), fst_(fst.Copy()),
282 mapper_(mapper),
283 own_mapper_(false),
284 superfinal_(kNoStateId),
285 nstates_(0) {
286 Init();
287 }
288
289
~MapFstImpl()290 ~MapFstImpl() {
291 delete fst_;
292 if (own_mapper_) delete mapper_;
293 }
294
Start()295 StateId Start() {
296 if (!HasStart())
297 SetStart(FindOState(fst_->Start()));
298 return CacheImpl<B>::Start();
299 }
300
Final(StateId s)301 Weight Final(StateId s) {
302 if (!HasFinal(s)) {
303 switch (final_action_) {
304 case MAP_NO_SUPERFINAL:
305 default: {
306 B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)),
307 kNoStateId));
308 CHECK(final_arc.ilabel == 0 && final_arc.olabel == 0);
309 SetFinal(s, final_arc.weight);
310 break;
311 }
312 case MAP_ALLOW_SUPERFINAL: {
313 if (s == superfinal_) {
314 SetFinal(s, Weight::One());
315 } else {
316 B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)),
317 kNoStateId));
318 if (final_arc.ilabel == 0 && final_arc.olabel == 0)
319 SetFinal(s, final_arc.weight);
320 else
321 SetFinal(s, Weight::Zero());
322 }
323 break;
324 }
325 case MAP_REQUIRE_SUPERFINAL: {
326 SetFinal(s, s == superfinal_ ? Weight::One() : Weight::Zero());
327 break;
328 }
329 }
330 }
331 return CacheImpl<B>::Final(s);
332 }
333
NumArcs(StateId s)334 size_t NumArcs(StateId s) {
335 if (!HasArcs(s))
336 Expand(s);
337 return CacheImpl<B>::NumArcs(s);
338 }
339
NumInputEpsilons(StateId s)340 size_t NumInputEpsilons(StateId s) {
341 if (!HasArcs(s))
342 Expand(s);
343 return CacheImpl<B>::NumInputEpsilons(s);
344 }
345
NumOutputEpsilons(StateId s)346 size_t NumOutputEpsilons(StateId s) {
347 if (!HasArcs(s))
348 Expand(s);
349 return CacheImpl<B>::NumOutputEpsilons(s);
350 }
351
InitArcIterator(StateId s,ArcIteratorData<B> * data)352 void InitArcIterator(StateId s, ArcIteratorData<B> *data) {
353 if (!HasArcs(s))
354 Expand(s);
355 CacheImpl<B>::InitArcIterator(s, data);
356 }
357
Expand(StateId s)358 void Expand(StateId s) {
359 // Add exiting arcs.
360 if (s == superfinal_) { SetArcs(s); return; }
361
362 for (ArcIterator< Fst<A> > aiter(*fst_, FindIState(s));
363 !aiter.Done(); aiter.Next()) {
364 A aarc(aiter.Value());
365 aarc.nextstate = FindOState(aarc.nextstate);
366 const B& barc = (*mapper_)(aarc);
367 AddArc(s, barc);
368 }
369
370 // Check for superfinal arcs.
371 if (!HasFinal(s) || Final(s) == Weight::Zero())
372 switch (final_action_) {
373 case MAP_NO_SUPERFINAL:
374 default:
375 break;
376 case MAP_ALLOW_SUPERFINAL: {
377 B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)),
378 kNoStateId));
379 if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
380 if (superfinal_ == kNoStateId)
381 superfinal_ = nstates_++;
382 final_arc.nextstate = superfinal_;
383 AddArc(s, final_arc);
384 }
385 break;
386 }
387 case MAP_REQUIRE_SUPERFINAL: {
388 B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)),
389 kNoStateId));
390 if (final_arc.ilabel != 0 || final_arc.olabel != 0 ||
391 final_arc.weight != B::Weight::Zero())
392 AddArc(s, B(final_arc.ilabel, final_arc.olabel,
393 final_arc.weight, superfinal_));
394 break;
395 }
396 }
397 SetArcs(s);
398 }
399
400 private:
Init()401 void Init() {
402 SetType("map");
403 SetInputSymbols(fst_->InputSymbols());
404 SetOutputSymbols(fst_->OutputSymbols());
405 if (fst_->Start() == kNoStateId) {
406 final_action_ = MAP_NO_SUPERFINAL;
407 SetProperties(kNullProperties);
408 } else {
409 final_action_ = mapper_->FinalAction();
410 uint64 props = fst_->Properties(kCopyProperties, false);
411 SetProperties(mapper_->Properties(props));
412 if (final_action_ == MAP_REQUIRE_SUPERFINAL)
413 superfinal_ = 0;
414 }
415 }
416
417 // Maps from output state to input state.
FindIState(StateId s)418 StateId FindIState(StateId s) {
419 if (superfinal_ == kNoStateId || s < superfinal_)
420 return s;
421 else
422 return s - 1;
423 }
424
425 // Maps from input state to output state.
FindOState(StateId is)426 StateId FindOState(StateId is) {
427 StateId os;
428 if (superfinal_ == kNoStateId || is < superfinal_)
429 os = is;
430 else
431 os = is + 1;
432
433 if (os >= nstates_)
434 nstates_ = os + 1;
435
436 return os;
437 }
438
439
440 const Fst<A> *fst_;
441 C* mapper_;
442 bool own_mapper_;
443 MapFinalAction final_action_;
444
445 StateId superfinal_;
446 StateId nstates_;
447 };
448
449
450 // Maps an arc type A to an arc type B using Mapper function object
451 // C. This version is a delayed Fst.
452 template <class A, class B, class C>
453 class MapFst : public Fst<B> {
454 public:
455 friend class ArcIterator< MapFst<A, B, C> >;
456 friend class StateIterator< MapFst<A, B, C> >;
457 friend class CacheArcIterator< MapFst<A, B, C> >;
458
459 typedef B Arc;
460 typedef typename B::Weight Weight;
461 typedef typename B::StateId StateId;
462 typedef CacheState<B> State;
463
MapFst(const Fst<A> & fst,const C & mapper,const MapFstOptions & opts)464 MapFst(const Fst<A> &fst, const C &mapper,
465 const MapFstOptions& opts)
466 : impl_(new MapFstImpl<A, B, C>(fst, mapper, opts)) {}
467
MapFst(const Fst<A> & fst,C * mapper,const MapFstOptions & opts)468 MapFst(const Fst<A> &fst, C* mapper,
469 const MapFstOptions& opts)
470 : impl_(new MapFstImpl<A, B, C>(fst, mapper, opts)) {}
471
MapFst(const Fst<A> & fst,const C & mapper)472 MapFst(const Fst<A> &fst, const C &mapper)
473 : impl_(new MapFstImpl<A, B, C>(fst, mapper,
474 MapFstOptions())) {}
475
MapFst(const Fst<A> & fst,C * mapper)476 MapFst(const Fst<A> &fst, C* mapper)
477 : impl_(new MapFstImpl<A, B, C>(fst, mapper,
478 MapFstOptions())) {}
479
MapFst(const MapFst<A,B,C> & fst)480 MapFst(const MapFst<A, B, C> &fst) : Fst<B>(fst), impl_(fst.impl_) {
481 impl_->IncrRefCount();
482 }
483
~MapFst()484 virtual ~MapFst() { if (!impl_->DecrRefCount()) delete impl_; }
485
Start()486 virtual StateId Start() const { return impl_->Start(); }
487
Final(StateId s)488 virtual Weight Final(StateId s) const { return impl_->Final(s); }
489
NumStates()490 StateId NumStates() const { return impl_->NumStates(); }
491
NumArcs(StateId s)492 size_t NumArcs(StateId s) const { return impl_->NumArcs(s); }
493
NumInputEpsilons(StateId s)494 size_t NumInputEpsilons(StateId s) const {
495 return impl_->NumInputEpsilons(s);
496 }
497
NumOutputEpsilons(StateId s)498 size_t NumOutputEpsilons(StateId s) const {
499 return impl_->NumOutputEpsilons(s);
500 }
501
Properties(uint64 mask,bool test)502 virtual uint64 Properties(uint64 mask, bool test) const {
503 if (test) {
504 uint64 known, test = TestProperties(*this, mask, &known);
505 impl_->SetProperties(test, known);
506 return test & mask;
507 } else {
508 return impl_->Properties(mask);
509 }
510 }
511
Type()512 virtual const string& Type() const { return impl_->Type(); }
513
Copy()514 virtual MapFst<A, B, C> *Copy() const {
515 return new MapFst<A, B, C>(*this);
516 }
517
InputSymbols()518 virtual const SymbolTable* InputSymbols() const {
519 return impl_->InputSymbols();
520 }
521
OutputSymbols()522 virtual const SymbolTable* OutputSymbols() const {
523 return impl_->OutputSymbols();
524 }
525
526 virtual inline void InitStateIterator(StateIteratorData<B> *data) const;
527
InitArcIterator(StateId s,ArcIteratorData<B> * data)528 virtual void InitArcIterator(StateId s, ArcIteratorData<B> *data) const {
529 impl_->InitArcIterator(s, data);
530 }
531
532 private:
533 MapFstImpl<A, B, C> *impl_;
534
535 void operator=(const MapFst<A, B, C> &fst); // disallow
536 };
537
538
539 // Specialization for MapFst.
540 template<class A, class B, class C>
541 class StateIterator< MapFst<A, B, C> > : public StateIteratorBase<B> {
542 public:
543 typedef typename B::StateId StateId;
544
StateIterator(const MapFst<A,B,C> & fst)545 explicit StateIterator(const MapFst<A, B, C> &fst)
546 : impl_(fst.impl_), siter_(*impl_->fst_), s_(0),
547 superfinal_(impl_->final_action_ == MAP_REQUIRE_SUPERFINAL)
548 { CheckSuperfinal(); }
549
Done()550 bool Done() const { return siter_.Done() && !superfinal_; }
551
Value()552 StateId Value() const { return s_; }
553
Next()554 void Next() {
555 ++s_;
556 if (!siter_.Done()) {
557 siter_.Next();
558 CheckSuperfinal();
559 }
560 else if (superfinal_)
561 superfinal_ = false;
562 }
563
Reset()564 void Reset() {
565 s_ = 0;
566 siter_.Reset();
567 superfinal_ = impl_->final_action_ == MAP_REQUIRE_SUPERFINAL;
568 CheckSuperfinal();
569 }
570
571 private:
CheckSuperfinal()572 void CheckSuperfinal() {
573 if (impl_->final_action_ != MAP_ALLOW_SUPERFINAL || superfinal_)
574 return;
575 if (!siter_.Done()) {
576 B final_arc = (*impl_->mapper_)(A(0, 0, impl_->fst_->Final(s_),
577 kNoStateId));
578 if (final_arc.ilabel != 0 || final_arc.olabel != 0)
579 superfinal_ = true;
580 }
581 }
582
583 const MapFstImpl<A, B, C> *impl_;
584 StateIterator< Fst<A> > siter_;
585 StateId s_;
586 bool superfinal_; // true if there is a superfinal state and not done
587
588 DISALLOW_EVIL_CONSTRUCTORS(StateIterator);
589 };
590
591 // Specialization for MapFst.
592 template <class A, class B, class C>
593 class ArcIterator< MapFst<A, B, C> >
594 : public CacheArcIterator< MapFst<A, B, C> > {
595 public:
596 typedef typename A::StateId StateId;
597
ArcIterator(const MapFst<A,B,C> & fst,StateId s)598 ArcIterator(const MapFst<A, B, C> &fst, StateId s)
599 : CacheArcIterator< MapFst<A, B, C> >(fst, s) {
600 if (!fst.impl_->HasArcs(s))
601 fst.impl_->Expand(s);
602 }
603
604 private:
605 DISALLOW_EVIL_CONSTRUCTORS(ArcIterator);
606 };
607
608 template <class A, class B, class C> inline
InitStateIterator(StateIteratorData<B> * data)609 void MapFst<A, B, C>::InitStateIterator(StateIteratorData<B> *data)
610 const {
611 data->base = new StateIterator< MapFst<A, B, C> >(*this);
612 }
613
614
615 //
616 // Utility Mappers
617 //
618
619 // Mapper that returns its input.
620 template <class A>
621 struct IdentityMapper {
622 typedef A FromArc;
623 typedef A ToArc;
624
operatorIdentityMapper625 A operator()(const A &arc) const { return arc; }
626
FinalActionIdentityMapper627 MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
628
PropertiesIdentityMapper629 uint64 Properties(uint64 props) const { return props; }
630 };
631
632
633 // Mapper that returns its input with final states redirected to
634 // a single super-final state.
635 template <class A>
636 struct SuperFinalMapper {
637 typedef A FromArc;
638 typedef A ToArc;
639
operatorSuperFinalMapper640 A operator()(const A &arc) const { return arc; }
641
FinalActionSuperFinalMapper642 MapFinalAction FinalAction() const { return MAP_REQUIRE_SUPERFINAL; }
643
PropertiesSuperFinalMapper644 uint64 Properties(uint64 props) const {
645 return props & kAddSuperFinalProperties;
646 }
647 };
648
649
650 // Mapper from StdArc to LogArc.
651 struct StdToLogMapper {
652 typedef StdArc FromArc;
653 typedef LogArc ToArc;
654
operatorStdToLogMapper655 LogArc operator()(const StdArc &arc) const {
656 return LogArc(arc.ilabel, arc.olabel, arc.weight.Value(), arc.nextstate);
657 }
658
FinalActionStdToLogMapper659 MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
660
PropertiesStdToLogMapper661 uint64 Properties(uint64 props) const { return props; }
662 };
663
664
665 // Mapper from LogArc to StdArc.
666 struct LogToStdMapper {
667 typedef LogArc FromArc;
668 typedef StdArc ToArc;
669
operatorLogToStdMapper670 StdArc operator()(const LogArc &arc) const {
671 return StdArc(arc.ilabel, arc.olabel, arc.weight.Value(), arc.nextstate);
672 }
673
FinalActionLogToStdMapper674 MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
675
PropertiesLogToStdMapper676 uint64 Properties(uint64 props) const { return props; }
677 };
678
679
680 // Mapper from A to GallicArc<A>.
681 template <class A, StringType S = STRING_LEFT>
682 struct ToGallicMapper {
683 typedef A FromArc;
684 typedef GallicArc<A, S> ToArc;
685
686 typedef StringWeight<typename A::Label, S> SW;
687 typedef typename A::Weight AW;
688 typedef typename GallicArc<A, S>::Weight GW;
689
operatorToGallicMapper690 ToArc operator()(const A &arc) const {
691 // 'Super-final' arc.
692 if (arc.nextstate == kNoStateId && arc.weight != AW::Zero())
693 return ToArc(0, 0, GW(SW::One(), arc.weight), kNoStateId);
694 // 'Super-non-final' arc.
695 else if (arc.nextstate == kNoStateId)
696 return ToArc(0, 0, GW(SW::Zero(), arc.weight), kNoStateId);
697 // Epsilon label.
698 else if (arc.olabel == 0)
699 return ToArc(arc.ilabel, arc.ilabel,
700 GW(SW::One(), arc.weight), arc.nextstate);
701 // Regular label.
702 else
703 return ToArc(arc.ilabel, arc.ilabel,
704 GW(SW(arc.olabel), arc.weight), arc.nextstate);
705 }
706
FinalActionToGallicMapper707 MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
708
PropertiesToGallicMapper709 uint64 Properties(uint64 props) const {
710 return ProjectProperties(props, true) & kWeightInvariantProperties;
711 }
712 };
713
714
715 // Mapper from GallicArc<A> to A.
716 template <class A, StringType S = STRING_LEFT>
717 struct FromGallicMapper {
718 typedef GallicArc<A, S> FromArc;
719 typedef A ToArc;
720
721 typedef typename A::Label Label;
722 typedef StringWeight<Label, S> SW;
723 typedef typename A::Weight AW;
724 typedef typename GallicArc<A, S>::Weight GW;
725
operatorFromGallicMapper726 A operator()(const FromArc &arc) const {
727 // 'Super-non-final' arc.
728 if (arc.nextstate == kNoStateId && arc.weight == GW::Zero())
729 return A(arc.ilabel, 0, AW::Zero(), kNoStateId);
730
731 SW w1 = arc.weight.Value1();
732 AW w2 = arc.weight.Value2();
733 StringWeightIterator<Label, S> iter1(w1);
734
735 Label l = w1.Size() == 1 ? iter1.Value() : 0;
736
737 CHECK(l != kStringInfinity);
738 CHECK(l != kStringBad);
739 CHECK(arc.ilabel == arc.olabel);
740 CHECK(w1.Size() <= 1);
741
742 return A(arc.ilabel, l, w2, arc.nextstate);
743 }
744
FinalActionFromGallicMapper745 MapFinalAction FinalAction() const { return MAP_ALLOW_SUPERFINAL; }
746
PropertiesFromGallicMapper747 uint64 Properties(uint64 props) const {
748 return props & kOLabelInvariantProperties &
749 kWeightInvariantProperties & kAddSuperFinalProperties;
750 }
751 };
752
753
754 // Mapper from GallicArc<A> to A.
755 template <class A, StringType S = STRING_LEFT>
756 struct GallicToNewSymbolsMapper {
757 typedef GallicArc<A, S> FromArc;
758 typedef A ToArc;
759
760 typedef typename A::StateId StateId;
761 typedef typename A::Label Label;
762 typedef StringWeight<Label, S> SW;
763 typedef typename A::Weight AW;
764 typedef typename GallicArc<A, S>::Weight GW;
765
GallicToNewSymbolsMapperGallicToNewSymbolsMapper766 GallicToNewSymbolsMapper(MutableFst<ToArc> *fst)
767 : fst_(fst), lmax_(0), osymbols_(fst->OutputSymbols()), isymbols_(0) {
768 fst_->DeleteStates();
769 state_ = fst_->AddState();
770 fst_->SetStart(state_);
771 fst_->SetFinal(state_, AW::One());
772 if (osymbols_) {
773 string name = osymbols_->Name() + "_from_gallic";
774 isymbols_ = new SymbolTable(name);
775 isymbols_->AddSymbol(osymbols_->Find((int64) 0), 0);
776 }
777 fst_->SetInputSymbols(isymbols_);
778 }
779
operatorGallicToNewSymbolsMapper780 A operator()(const FromArc &arc) {
781 // 'Super-non-final' arc.
782 if (arc.nextstate == kNoStateId && arc.weight == GW::Zero())
783 return A(arc.ilabel, 0, AW::Zero(), kNoStateId);
784
785 SW w1 = arc.weight.Value1();
786 AW w2 = arc.weight.Value2();
787 Label l;
788
789 if (w1.Size() == 0) {
790 l = 0;
791 } else {
792 typename Map::iterator miter = map_.find(w1);
793 if (miter != map_.end()) {
794 l = (*miter).second;
795 } else {
796 l = ++lmax_;
797 map_.insert(pair<const SW, Label>(w1, l));
798 StringWeightIterator<Label, S> iter1(w1);
799 StateId n;
800 string s;
801 for(ssize_t i = 0, p = state_;
802 i < w1.Size();
803 ++i, iter1.Next(), p = n) {
804 n = i == w1.Size() - 1 ? state_ : fst_->AddState();
805 fst_->AddArc(p, ToArc(i ? 0 : l, iter1.Value(), AW::One(), n));
806 if (isymbols_) {
807 if (i) s = s + "_";
808 s = s + osymbols_->Find(iter1.Value());
809 }
810 }
811 if (isymbols_)
812 isymbols_->AddSymbol(s, l);
813 }
814 }
815
816 CHECK(l != kStringInfinity);
817 CHECK(l != kStringBad);
818 CHECK(arc.ilabel == arc.olabel);
819
820 return A(arc.ilabel, l, w2, arc.nextstate);
821 }
822
FinalActionGallicToNewSymbolsMapper823 MapFinalAction FinalAction() const { return MAP_ALLOW_SUPERFINAL; }
824
PropertiesGallicToNewSymbolsMapper825 uint64 Properties(uint64 props) const {
826 return props & kOLabelInvariantProperties &
827 kWeightInvariantProperties & kAddSuperFinalProperties;
828 }
829
830 private:
831 class StringKey {
832 public:
operatorGallicToNewSymbolsMapper833 size_t operator()(const SW &x) const {
834 return x.Hash();
835 }
836 };
837
838 typedef hash_map<SW, Label, StringKey> Map;
839
840 MutableFst<ToArc> *fst_;
841 Map map_;
842 Label lmax_;
843 StateId state_;
844 SymbolTable *osymbols_, *isymbols_;
845 };
846
847
848 // Mapper to add a constant to all weights.
849 template <class A>
850 struct PlusMapper {
851 typedef typename A::Weight Weight;
852
PlusMapperPlusMapper853 explicit PlusMapper(Weight w) : weight_(w) {}
854
operatorPlusMapper855 A operator()(const A &arc) const {
856 if (arc.weight == Weight::Zero())
857 return arc;
858 Weight w = Plus(arc.weight, weight_);
859 return A(arc.ilabel, arc.olabel, w, arc.nextstate);
860 }
861
FinalActionPlusMapper862 MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
863
PropertiesPlusMapper864 uint64 Properties(uint64 props) const {
865 return props & kWeightInvariantProperties;
866 }
867
868 Weight weight_;
869 };
870
871
872 // Mapper to (right) multiply a constant to all weights.
873 template <class A>
874 struct TimesMapper {
875 typedef typename A::Weight Weight;
876
TimesMapperTimesMapper877 explicit TimesMapper(Weight w) : weight_(w) {}
878
operatorTimesMapper879 A operator()(const A &arc) const {
880 if (arc.weight == Weight::Zero())
881 return arc;
882 Weight w = Times(arc.weight, weight_);
883 return A(arc.ilabel, arc.olabel, w, arc.nextstate);
884 }
885
FinalActionTimesMapper886 MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
887
PropertiesTimesMapper888 uint64 Properties(uint64 props) const {
889 return props & kWeightInvariantProperties;
890 }
891
892 Weight weight_;
893 };
894
895
896 // Mapper to map all non-Zero() weights to One().
897 template <class A, class B = A>
898 struct RmWeightMapper {
899 typedef A FromArc;
900 typedef B ToArc;
901 typedef typename FromArc::Weight FromWeight;
902 typedef typename ToArc::Weight ToWeight;
903
operatorRmWeightMapper904 B operator()(const A &arc) const {
905 ToWeight w = arc.weight != FromWeight::Zero() ?
906 ToWeight::One() : ToWeight::Zero();
907 return B(arc.ilabel, arc.olabel, w, arc.nextstate);
908 }
909
FinalActionRmWeightMapper910 MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
911
PropertiesRmWeightMapper912 uint64 Properties(uint64 props) const {
913 return props & kWeightInvariantProperties | kUnweighted;
914 }
915 };
916
917
918 // Mapper to quantize all weights.
919 template <class A, class B = A>
920 struct QuantizeMapper {
921 typedef A FromArc;
922 typedef B ToArc;
923 typedef typename FromArc::Weight FromWeight;
924 typedef typename ToArc::Weight ToWeight;
925
QuantizeMapperQuantizeMapper926 QuantizeMapper() : delta_(kDelta) {}
927
QuantizeMapperQuantizeMapper928 explicit QuantizeMapper(float d) : delta_(d) {}
929
operatorQuantizeMapper930 B operator()(const A &arc) const {
931 ToWeight w = arc.weight.Quantize(delta_);
932 return B(arc.ilabel, arc.olabel, w, arc.nextstate);
933 }
934
FinalActionQuantizeMapper935 MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
936
PropertiesQuantizeMapper937 uint64 Properties(uint64 props) const {
938 return props & kWeightInvariantProperties;
939 }
940
941 float delta_;
942 };
943
944
945 // Mapper from A to B under the assumption:
946 // B::Weight = A::Weight::ReverseWeight
947 // B::Label == A::Label
948 // B::StateId == A::StateId
949 // The weight is reversed, while the label and nextstate preserved
950 // in the mapping.
951 template <class A, class B>
952 struct ReverseWeightMapper {
953 typedef A FromArc;
954 typedef B ToArc;
955
operatorReverseWeightMapper956 B operator()(const A &arc) const {
957 return B(arc.ilabel, arc.olabel, arc.weight.Reverse(), arc.nextstate);
958 }
959
FinalActionReverseWeightMapper960 MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
961
PropertiesReverseWeightMapper962 uint64 Properties(uint64 props) const { return props; }
963 };
964
965 } // namespace fst
966
967 #endif // FST_LIB_MAP_H__
968