• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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