• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // vector-fst.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 // Simple concrete, mutable FST whose states and arcs are stored in STL
18 // vectors.
19 
20 #ifndef FST_LIB_VECTOR_FST_H__
21 #define FST_LIB_VECTOR_FST_H__
22 
23 #include <string>
24 #include <string.h>
25 
26 #include "fst/lib/mutable-fst.h"
27 #include "fst/lib/test-properties.h"
28 
29 namespace fst {
30 
31 template <class A> class VectorFst;
32 
33 // States and arcs implemented by STL vectors, templated on the
34 // State definition. This does not manage the Fst properties.
35 template <class State>
36 class VectorFstBaseImpl : public FstImpl<typename State::Arc> {
37  public:
38   typedef typename State::Arc Arc;
39   typedef typename Arc::Weight Weight;
40   typedef typename Arc::StateId StateId;
41 
VectorFstBaseImpl()42   VectorFstBaseImpl() : start_(kNoStateId) {}
43 
~VectorFstBaseImpl()44   ~VectorFstBaseImpl() {
45     for (StateId s = 0; s < (StateId)states_.size(); ++s)
46       delete states_[s];
47   }
48 
Start()49   StateId Start() const { return start_; }
50 
Final(StateId s)51   Weight Final(StateId s) const { return states_[s]->final; }
52 
NumStates()53   StateId NumStates() const { return states_.size(); }
54 
NumArcs(StateId s)55   size_t NumArcs(StateId s) const { return states_[s]->arcs.size(); }
56 
SetStart(StateId s)57   void SetStart(StateId s) { start_ = s; }
58 
SetFinal(StateId s,Weight w)59   void SetFinal(StateId s, Weight w) { states_[s]->final = w; }
60 
AddState()61   StateId AddState() {
62     states_.push_back(new State);
63     return states_.size() - 1;
64   }
65 
AddState(State * state)66   StateId AddState(State *state) {
67     states_.push_back(state);
68     return states_.size() - 1;
69   }
70 
AddArc(StateId s,const Arc & arc)71   void AddArc(StateId s, const Arc &arc) {
72     states_[s]->arcs.push_back(arc);
73   }
74 
DeleteStates(const vector<StateId> & dstates)75   void DeleteStates(const vector<StateId>& dstates) {
76     vector<StateId> newid(states_.size(), 0);
77     for (size_t i = 0; i < dstates.size(); ++i)
78       newid[dstates[i]] = kNoStateId;
79     StateId nstates = 0;
80     for (StateId s = 0; s < (StateId)states_.size(); ++s) {
81       if (newid[s] != kNoStateId) {
82         newid[s] = nstates;
83         if (s != nstates)
84           states_[nstates] = states_[s];
85         ++nstates;
86       } else {
87         delete states_[s];
88       }
89     }
90     states_.resize(nstates);
91     for (StateId s = 0; s < (StateId)states_.size(); ++s) {
92       vector<Arc> &arcs = states_[s]->arcs;
93       size_t narcs = 0;
94       for (size_t i = 0; i < arcs.size(); ++i) {
95         StateId t = newid[arcs[i].nextstate];
96         if (t != kNoStateId) {
97           arcs[i].nextstate = t;
98           if (i != narcs)
99             arcs[narcs] = arcs[i];
100           ++narcs;
101         } else {
102           if (arcs[i].ilabel == 0)
103             --states_[s]->niepsilons;
104           if (arcs[i].olabel == 0)
105             --states_[s]->noepsilons;
106         }
107       }
108       arcs.resize(narcs);
109     }
110     if (Start() != kNoStateId)
111       SetStart(newid[Start()]);
112   }
113 
DeleteStates()114   void DeleteStates() {
115     for (StateId s = 0; s < (StateId)states_.size(); ++s)
116       delete states_[s];
117     states_.clear();
118     SetStart(kNoStateId);
119   }
120 
DeleteArcs(StateId s,size_t n)121   void DeleteArcs(StateId s, size_t n) {
122     states_[s]->arcs.resize(states_[s]->arcs.size() - n);
123   }
124 
DeleteArcs(StateId s)125   void DeleteArcs(StateId s) { states_[s]->arcs.clear(); }
126 
GetState(StateId s)127   State *GetState(StateId s) { return states_[s]; }
128 
GetState(StateId s)129   const State *GetState(StateId s) const { return states_[s]; }
130 
SetState(StateId s,State * state)131   void SetState(StateId s, State *state) { states_[s] = state; }
132 
ReserveStates(StateId n)133   void ReserveStates(StateId n) { states_.reserve(n); }
134 
ReserveArcs(StateId s,size_t n)135   void ReserveArcs(StateId s, size_t n) { states_[s]->arcs.reserve(n); }
136 
137   // Provide information needed for generic state iterator
InitStateIterator(StateIteratorData<Arc> * data)138   void InitStateIterator(StateIteratorData<Arc> *data) const {
139     data->base = 0;
140     data->nstates = states_.size();
141   }
142 
143   // Provide information needed for generic arc iterator
InitArcIterator(StateId s,ArcIteratorData<Arc> * data)144   void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const {
145     data->base = 0;
146     data->narcs = states_[s]->arcs.size();
147     data->arcs = data->narcs > 0 ? &states_[s]->arcs[0] : 0;
148     data->ref_count = 0;
149   }
150 
151  private:
152   vector<State *> states_;      // States represenation.
153   StateId start_;               // initial state
154 
155   DISALLOW_EVIL_CONSTRUCTORS(VectorFstBaseImpl);
156 };
157 
158 // Arcs implemented by an STL vector per state.
159 template <class A>
160 struct VectorState {
161   typedef A Arc;
162   typedef typename A::Weight Weight;
163   typedef typename A::StateId StateId;
164 
VectorStateVectorState165   VectorState() : final(Weight::Zero()), niepsilons(0), noepsilons(0) {}
166 
167   Weight final;              // Final weight
168   vector<A> arcs;            // Arcs represenation
169   size_t niepsilons;         // # of input epsilons
170   size_t noepsilons;         // # of output epsilons
171 };
172 
173 // This is a VectorFstBaseImpl container that holds VectorState's.  It
174 // manages Fst properties and the # of input and output epsilons.
175 template <class A>
176 class VectorFstImpl : public VectorFstBaseImpl< VectorState<A> > {
177  public:
178   using FstImpl<A>::SetType;
179   using FstImpl<A>::SetProperties;
180   using FstImpl<A>::Properties;
181   using FstImpl<A>::WriteHeaderAndSymbols;
182 
183   using VectorFstBaseImpl<VectorState<A> >::Start;
184   using VectorFstBaseImpl<VectorState<A> >::NumStates;
185 
186   friend class MutableArcIterator< VectorFst<A> >;
187 
188   typedef VectorFstBaseImpl< VectorState<A> > BaseImpl;
189   typedef typename A::Weight Weight;
190   typedef typename A::StateId StateId;
191 
VectorFstImpl()192   VectorFstImpl() {
193     SetType("vector");
194     SetProperties(kNullProperties | kStaticProperties);
195   }
196   explicit VectorFstImpl(const Fst<A> &fst);
197 
198   static VectorFstImpl<A> *Read(istream &strm, const FstReadOptions &opts);
199 
NumInputEpsilons(StateId s)200   size_t NumInputEpsilons(StateId s) const { return GetState(s)->niepsilons; }
201 
NumOutputEpsilons(StateId s)202   size_t NumOutputEpsilons(StateId s) const { return GetState(s)->noepsilons; }
203 
204   bool Write(ostream &strm, const FstWriteOptions &opts) const;
205 
SetStart(StateId s)206   void SetStart(StateId s) {
207     BaseImpl::SetStart(s);
208     SetProperties(Properties() & kSetStartProperties);
209     if (Properties() & kAcyclic)
210       SetProperties(Properties() | kInitialAcyclic);
211   }
212 
SetFinal(StateId s,Weight w)213   void SetFinal(StateId s, Weight w) {
214     Weight ow = Final(s);
215     if (ow != Weight::Zero() && ow != Weight::One())
216       SetProperties(Properties() & ~kWeighted);
217     BaseImpl::SetFinal(s, w);
218     if (w != Weight::Zero() && w != Weight::One()) {
219       SetProperties(Properties() | kWeighted);
220       SetProperties(Properties() & ~kUnweighted);
221     }
222     SetProperties(Properties() &
223                   (kSetFinalProperties | kWeighted | kUnweighted));
224   }
225 
AddState()226   StateId AddState() {
227     StateId s = BaseImpl::AddState();
228     SetProperties(Properties() & kAddStateProperties);
229     return s;
230   }
231 
AddArc(StateId s,const A & arc)232   void AddArc(StateId s, const A &arc) {
233     VectorState<A> *state = GetState(s);
234     if (arc.ilabel != arc.olabel) {
235       SetProperties(Properties() | kNotAcceptor);
236       SetProperties(Properties() & ~kAcceptor);
237     }
238     if (arc.ilabel == 0) {
239       ++state->niepsilons;
240       SetProperties(Properties() | kIEpsilons);
241       SetProperties(Properties() & ~kNoIEpsilons);
242       if (arc.olabel == 0) {
243         SetProperties(Properties() | kEpsilons);
244         SetProperties(Properties() & ~kNoEpsilons);
245       }
246     }
247     if (arc.olabel == 0) {
248       ++state->noepsilons;
249       SetProperties(Properties() | kOEpsilons);
250       SetProperties(Properties() & ~kNoOEpsilons);
251     }
252     if (!state->arcs.empty()) {
253       A &parc = state->arcs.back();
254       if (parc.ilabel > arc.ilabel) {
255         SetProperties(Properties() | kNotILabelSorted);
256         SetProperties(Properties() & ~kILabelSorted);
257       }
258       if (parc.olabel > arc.olabel) {
259         SetProperties(Properties() | kNotOLabelSorted);
260         SetProperties(Properties() & ~kOLabelSorted);
261       }
262     }
263     if (arc.weight != Weight::Zero() && arc.weight != Weight::One()) {
264       SetProperties(Properties() | kWeighted);
265       SetProperties(Properties() & ~kUnweighted);
266     }
267     if (arc.nextstate <= s) {
268       SetProperties(Properties() | kNotTopSorted);
269       SetProperties(Properties() & ~kTopSorted);
270     }
271     SetProperties(Properties() &
272                   (kAddArcProperties | kAcceptor |
273                    kNoEpsilons | kNoIEpsilons | kNoOEpsilons |
274                    kILabelSorted | kOLabelSorted | kUnweighted | kTopSorted));
275     if (Properties() & kTopSorted)
276       SetProperties(Properties() | kAcyclic | kInitialAcyclic);
277     BaseImpl::AddArc(s, arc);
278   }
279 
DeleteStates(const vector<StateId> & dstates)280   void DeleteStates(const vector<StateId> &dstates) {
281     BaseImpl::DeleteStates(dstates);
282     SetProperties(Properties() & kDeleteStatesProperties);
283   }
284 
DeleteStates()285   void DeleteStates() {
286     BaseImpl::DeleteStates();
287     SetProperties(kNullProperties | kStaticProperties);
288   }
289 
DeleteArcs(StateId s,size_t n)290   void DeleteArcs(StateId s, size_t n) {
291     const vector<A> &arcs = GetState(s)->arcs;
292     for (size_t i = 0; i < n; ++i) {
293       size_t j = arcs.size() - i - 1;
294       if (arcs[j].ilabel == 0)
295         --GetState(s)->niepsilons;
296       if (arcs[j].olabel == 0)
297         --GetState(s)->noepsilons;
298     }
299     BaseImpl::DeleteArcs(s, n);
300     SetProperties(Properties() & kDeleteArcsProperties);
301   }
302 
DeleteArcs(StateId s)303   void DeleteArcs(StateId s) {
304     GetState(s)->niepsilons = 0;
305     GetState(s)->noepsilons = 0;
306     BaseImpl::DeleteArcs(s);
307     SetProperties(Properties() & kDeleteArcsProperties);
308   }
309 
310  private:
311   // Properties always true of this Fst class
312   static const uint64 kStaticProperties = kExpanded | kMutable;
313   // Current file format version
314   static const int kFileVersion = 2;
315   // Minimum file format version supported
316   static const int kMinFileVersion = 2;
317 
318   DISALLOW_EVIL_CONSTRUCTORS(VectorFstImpl);
319 };
320 
321 template <class A>
VectorFstImpl(const Fst<A> & fst)322 VectorFstImpl<A>::VectorFstImpl(const Fst<A> &fst) {
323   SetType("vector");
324   SetProperties(fst.Properties(kCopyProperties, false) | kStaticProperties);
325   SetInputSymbols(fst.InputSymbols());
326   SetOutputSymbols(fst.OutputSymbols());
327   BaseImpl::SetStart(fst.Start());
328 
329   for (StateIterator< Fst<A> > siter(fst);
330        !siter.Done();
331        siter.Next()) {
332     StateId s = siter.Value();
333     BaseImpl::AddState();
334     BaseImpl::SetFinal(s, fst.Final(s));
335     ReserveArcs(s, fst.NumArcs(s));
336     for (ArcIterator< Fst<A> > aiter(fst, s);
337          !aiter.Done();
338          aiter.Next()) {
339       const A &arc = aiter.Value();
340       BaseImpl::AddArc(s, arc);
341       if (arc.ilabel == 0)
342         ++GetState(s)->niepsilons;
343       if (arc.olabel == 0)
344         ++GetState(s)->noepsilons;
345     }
346   }
347 }
348 
349 template <class A>
Read(istream & strm,const FstReadOptions & opts)350 VectorFstImpl<A> *VectorFstImpl<A>::Read(istream &strm,
351                                          const FstReadOptions &opts) {
352   VectorFstImpl<A> *impl = new VectorFstImpl;
353   FstHeader hdr;
354   if (!impl->ReadHeaderAndSymbols(strm, opts, kMinFileVersion, &hdr))
355     return 0;
356   impl->BaseImpl::SetStart(hdr.Start());
357   impl->ReserveStates(hdr.NumStates());
358 
359   for (StateId s = 0; s < hdr.NumStates(); ++s) {
360     impl->BaseImpl::AddState();
361     VectorState<A> *state = impl->GetState(s);
362     state->final.Read(strm);
363     int64 narcs;
364     ReadType(strm, &narcs);
365     if (!strm) {
366       LOG(ERROR) << "VectorFst::Read: read failed: " << opts.source;
367       return 0;
368     }
369     impl->ReserveArcs(s, narcs);
370     for (size_t j = 0; j < narcs; ++j) {
371       A arc;
372       ReadType(strm, &arc.ilabel);
373       ReadType(strm, &arc.olabel);
374       arc.weight.Read(strm);
375       ReadType(strm, &arc.nextstate);
376       if (!strm) {
377         LOG(ERROR) << "VectorFst::Read: read failed: " << opts.source;
378         return 0;
379       }
380       impl->BaseImpl::AddArc(s, arc);
381       if (arc.ilabel == 0)
382         ++state->niepsilons;
383       if (arc.olabel == 0)
384         ++state->noepsilons;
385     }
386   }
387   return impl;
388 }
389 
390 // Converts a string into a weight.
391 template <class W> class WeightFromString {
392  public:
393   W operator()(const string &s);
394 };
395 
396 // Generic case fails.
397 template <class W> inline
operator()398 W WeightFromString<W>::operator()(const string &s) {
399   LOG(FATAL) << "VectorFst::Read: Obsolete file format";
400   return W();
401 }
402 
403 // TropicalWeight version.
404 template <> inline
operator()405 TropicalWeight WeightFromString<TropicalWeight>::operator()(const string &s) {
406   float f;
407   memcpy(&f, s.data(), sizeof(f));
408   return TropicalWeight(f);
409 }
410 
411 // LogWeight version.
412 template <> inline
operator()413 LogWeight WeightFromString<LogWeight>::operator()(const string &s) {
414   float f;
415   memcpy(&f, s.data(), sizeof(f));
416   return LogWeight(f);
417 }
418 
419 template <class A>
Write(ostream & strm,const FstWriteOptions & opts)420 bool VectorFstImpl<A>::Write(ostream &strm,
421                              const FstWriteOptions &opts) const {
422   FstHeader hdr;
423   hdr.SetStart(Start());
424   hdr.SetNumStates(NumStates());
425   WriteHeaderAndSymbols(strm, opts, kFileVersion, &hdr);
426   if (!strm)
427     return false;
428 
429   for (StateId s = 0; s < NumStates(); ++s) {
430     const VectorState<A> *state = GetState(s);
431     state->final.Write(strm);
432     int64 narcs = state->arcs.size();
433     WriteType(strm, narcs);
434     for (size_t a = 0; a < narcs; ++a) {
435       const A &arc = state->arcs[a];
436       WriteType(strm, arc.ilabel);
437       WriteType(strm, arc.olabel);
438       arc.weight.Write(strm);
439       WriteType(strm, arc.nextstate);
440     }
441   }
442   strm.flush();
443   if (!strm)
444     LOG(ERROR) << "VectorFst::Write: write failed: " << opts.source;
445   return strm;
446 }
447 
448 // Simple concrete, mutable FST. Supports additional operations:
449 // ReserveStates and ReserveArcs (cf. STL vectors). This class
450 // attaches interface to implementation and handles reference
451 // counting.
452 template <class A>
453 class VectorFst : public MutableFst<A> {
454  public:
455   friend class StateIterator< VectorFst<A> >;
456   friend class ArcIterator< VectorFst<A> >;
457   friend class MutableArcIterator< VectorFst<A> >;
458 
459   typedef A Arc;
460   typedef typename A::Weight Weight;
461   typedef typename A::StateId StateId;
462 
VectorFst()463   VectorFst() : impl_(new VectorFstImpl<A>) {}
464 
VectorFst(const VectorFst<A> & fst)465   VectorFst(const VectorFst<A> &fst) : MutableFst<A>(fst), impl_(fst.impl_) {
466     impl_->IncrRefCount();
467   }
VectorFst(const Fst<A> & fst)468   explicit VectorFst(const Fst<A> &fst) : impl_(new VectorFstImpl<A>(fst)) {}
469 
~VectorFst()470   virtual ~VectorFst() { if (!impl_->DecrRefCount()) delete impl_; }
471 
472   VectorFst<A> &operator=(const VectorFst<A> &fst) {
473     if (this != &fst) {
474       if (!impl_->DecrRefCount()) delete impl_;
475       fst.impl_->IncrRefCount();
476       impl_ = fst.impl_;
477     }
478     return *this;
479   }
480 
481   virtual VectorFst<A> &operator=(const Fst<A> &fst) {
482     if (this != &fst) {
483       if (!impl_->DecrRefCount()) delete impl_;
484       impl_ = new VectorFstImpl<A>(fst);
485     }
486     return *this;
487   }
488 
Start()489   virtual StateId Start() const { return impl_->Start(); }
490 
Final(StateId s)491   virtual Weight Final(StateId s) const { return impl_->Final(s); }
492 
NumStates()493   virtual StateId NumStates() const { return impl_->NumStates(); }
494 
NumArcs(StateId s)495   virtual size_t NumArcs(StateId s) const { return impl_->NumArcs(s); }
496 
NumInputEpsilons(StateId s)497   virtual size_t NumInputEpsilons(StateId s) const {
498     return impl_->NumInputEpsilons(s);
499   }
500 
NumOutputEpsilons(StateId s)501   virtual size_t NumOutputEpsilons(StateId s) const {
502     return impl_->NumOutputEpsilons(s);
503   }
504 
Properties(uint64 mask,bool test)505   virtual uint64 Properties(uint64 mask, bool test) const {
506     if (test) {
507       uint64 known, test = TestProperties(*this, mask, &known);
508       impl_->SetProperties(test, known);
509       return test & mask;
510     } else {
511       return impl_->Properties(mask);
512     }
513   }
514 
Type()515   virtual const string& Type() const { return impl_->Type(); }
516 
517   // Get a copy of this VectorFst
Copy()518   virtual VectorFst<A> *Copy() const {
519     impl_->IncrRefCount();
520     return new VectorFst<A>(impl_);
521   }
522 
523   // Read a VectorFst from an input stream; return NULL on error
Read(istream & strm,const FstReadOptions & opts)524   static VectorFst<A> *Read(istream &strm, const FstReadOptions &opts) {
525     VectorFstImpl<A>* impl = VectorFstImpl<A>::Read(strm, opts);
526     return impl ? new VectorFst<A>(impl) : 0;
527   }
528 
529   // Read a VectorFst from a file; return NULL on error
Read(const string & filename)530   static VectorFst<A> *Read(const string &filename) {
531     ifstream strm(filename.c_str());
532     if (!strm) {
533       LOG(ERROR) << "VectorFst::Read: Can't open file: " << filename;
534       return 0;
535     }
536     return Read(strm, FstReadOptions(filename));
537   }
538 
539   // Write a VectorFst to an output stream; return false on error
Write(ostream & strm,const FstWriteOptions & opts)540   virtual bool Write(ostream &strm, const FstWriteOptions &opts) const {
541     return impl_->Write(strm, opts);
542   }
543 
544   // Write a VectorFst to a file; return false on error
Write(const string & filename)545   virtual bool Write(const string &filename) const {
546     if (!filename.empty()) {
547       ofstream strm(filename.c_str());
548       if (!strm) {
549         LOG(ERROR) << "VectorFst::Write: Can't open file: " << filename;
550         return false;
551       }
552       return Write(strm, FstWriteOptions(filename));
553     } else {
554       return Write(std::cout, FstWriteOptions("standard output"));
555     }
556   }
557 
InputSymbols()558   virtual SymbolTable* InputSymbols() {
559     return impl_->InputSymbols();
560   }
561 
OutputSymbols()562   virtual SymbolTable* OutputSymbols() {
563     return impl_->OutputSymbols();
564   }
565 
InputSymbols()566   virtual const SymbolTable* InputSymbols() const {
567     return impl_->InputSymbols();
568   }
569 
OutputSymbols()570   virtual const SymbolTable* OutputSymbols() const {
571     return impl_->OutputSymbols();
572   }
573 
SetStart(StateId s)574   virtual void SetStart(StateId s) {
575     MutateCheck();
576     impl_->SetStart(s);
577   }
578 
SetFinal(StateId s,Weight w)579   virtual void SetFinal(StateId s, Weight w) {
580     MutateCheck();
581     impl_->SetFinal(s, w);
582   }
583 
SetProperties(uint64 props,uint64 mask)584   virtual void SetProperties(uint64 props, uint64 mask) {
585     impl_->SetProperties(props, mask);
586   }
587 
AddState()588   virtual StateId AddState() {
589     MutateCheck();
590     return impl_->AddState();
591   }
592 
AddArc(StateId s,const A & arc)593   virtual void AddArc(StateId s, const A &arc) {
594     MutateCheck();
595     impl_->AddArc(s, arc);
596   }
597 
DeleteStates(const vector<StateId> & dstates)598   virtual void DeleteStates(const vector<StateId> &dstates) {
599     MutateCheck();
600     impl_->DeleteStates(dstates);
601   }
602 
DeleteStates()603   virtual void DeleteStates() {
604     MutateCheck();
605     impl_->DeleteStates();
606   }
607 
DeleteArcs(StateId s,size_t n)608   virtual void DeleteArcs(StateId s, size_t n) {
609     MutateCheck();
610     impl_->DeleteArcs(s, n);
611   }
612 
DeleteArcs(StateId s)613   virtual void DeleteArcs(StateId s) {
614     MutateCheck();
615     impl_->DeleteArcs(s);
616   }
617 
SetInputSymbols(const SymbolTable * isyms)618   virtual void SetInputSymbols(const SymbolTable* isyms) {
619     MutateCheck();
620     impl_->SetInputSymbols(isyms);
621   }
622 
SetOutputSymbols(const SymbolTable * osyms)623   virtual void SetOutputSymbols(const SymbolTable* osyms) {
624     MutateCheck();
625     impl_->SetOutputSymbols(osyms);
626   }
627 
ReserveStates(StateId n)628   void ReserveStates(StateId n) {
629     MutateCheck();
630     impl_->ReserveStates(n);
631   }
632 
ReserveArcs(StateId s,size_t n)633   void ReserveArcs(StateId s, size_t n) {
634     MutateCheck();
635     impl_->ReserveArcs(s, n);
636   }
637 
InitStateIterator(StateIteratorData<A> * data)638   virtual void InitStateIterator(StateIteratorData<A> *data) const {
639     impl_->InitStateIterator(data);
640   }
641 
InitArcIterator(StateId s,ArcIteratorData<A> * data)642   virtual void InitArcIterator(StateId s, ArcIteratorData<A> *data) const {
643     impl_->InitArcIterator(s, data);
644   }
645 
646   virtual inline
647   void InitMutableArcIterator(StateId s, MutableArcIteratorData<A> *);
648 
649  private:
VectorFst(VectorFstImpl<A> * impl)650   explicit VectorFst(VectorFstImpl<A> *impl) : impl_(impl) {}
651 
MutateCheck()652   void MutateCheck() {
653     // Copy on write
654     if (impl_->RefCount() > 1) {
655       impl_->DecrRefCount();
656       impl_ = new VectorFstImpl<A>(*this);
657     }
658   }
659 
660   VectorFstImpl<A> *impl_;  // FST's impl
661 };
662 
663 // Specialization for VectorFst; see generic version in fst.h
664 // for sample usage (but use the VectorFst type!). This version
665 // should inline.
666 template <class A>
667 class StateIterator< VectorFst<A> > {
668  public:
669   typedef typename A::StateId StateId;
670 
StateIterator(const VectorFst<A> & fst)671   explicit StateIterator(const VectorFst<A> &fst)
672     : nstates_(fst.impl_->NumStates()), s_(0) {}
673 
Done()674   bool Done() const { return s_ >= nstates_; }
675 
Value()676   StateId Value() const { return s_; }
677 
Next()678   void Next() { ++s_; }
679 
Reset()680   void Reset() { s_ = 0; }
681 
682  private:
683   StateId nstates_;
684   StateId s_;
685 
686   DISALLOW_EVIL_CONSTRUCTORS(StateIterator);
687 };
688 
689 // Specialization for VectorFst; see generic version in fst.h
690 // for sample usage (but use the VectorFst type!). This version
691 // should inline.
692 template <class A>
693 class ArcIterator< VectorFst<A> > {
694  public:
695   typedef typename A::StateId StateId;
696 
ArcIterator(const VectorFst<A> & fst,StateId s)697   ArcIterator(const VectorFst<A> &fst, StateId s)
698     : arcs_(fst.impl_->GetState(s)->arcs), i_(0) {}
699 
Done()700   bool Done() const { return i_ >= arcs_.size(); }
701 
Value()702   const A& Value() const { return arcs_[i_]; }
703 
Next()704   void Next() { ++i_; }
705 
Reset()706   void Reset() { i_ = 0; }
707 
Seek(size_t a)708   void Seek(size_t a) { i_ = a; }
709 
710  private:
711   const vector<A>& arcs_;
712   size_t i_;
713 
714   DISALLOW_EVIL_CONSTRUCTORS(ArcIterator);
715 };
716 
717 // Specialization for VectorFst; see generic version in fst.h
718 // for sample usage (but use the VectorFst type!). This version
719 // should inline.
720 template <class A>
721 class MutableArcIterator< VectorFst<A> >
722   : public MutableArcIteratorBase<A> {
723  public:
724   typedef typename A::StateId StateId;
725   typedef typename A::Weight Weight;
726 
MutableArcIterator(VectorFst<A> * fst,StateId s)727   MutableArcIterator(VectorFst<A> *fst, StateId s) : i_(0) {
728     fst->MutateCheck();
729     state_ = fst->impl_->GetState(s);
730     properties_ = &fst->impl_->properties_;
731   }
732 
Done()733   virtual bool Done() const { return i_ >= state_->arcs.size(); }
734 
Value()735   virtual const A& Value() const { return state_->arcs[i_]; }
736 
Next()737   virtual void Next() { ++i_; }
738 
Reset()739   virtual void Reset() { i_ = 0; }
740 
Seek(size_t a)741   virtual void Seek(size_t a) { i_ = a; }
742 
SetValue(const A & arc)743   virtual void SetValue(const A &arc) {
744     A& oarc = state_->arcs[i_];
745     if (oarc.ilabel != oarc.olabel)
746       *properties_ &= ~kNotAcceptor;
747     if (oarc.ilabel == 0) {
748       --state_->niepsilons;
749       *properties_ &= ~kIEpsilons;
750       if (oarc.olabel == 0)
751         *properties_ &= ~kEpsilons;
752     }
753     if (oarc.olabel == 0) {
754       --state_->noepsilons;
755       *properties_ &= ~kOEpsilons;
756     }
757     if (oarc.weight != Weight::Zero() && oarc.weight != Weight::One())
758       *properties_ &= ~kWeighted;
759     oarc = arc;
760     if (arc.ilabel != arc.olabel)
761       *properties_ |= kNotAcceptor;
762     if (arc.ilabel == 0) {
763       ++state_->niepsilons;
764       *properties_ |= kIEpsilons;
765       if (arc.olabel == 0)
766         *properties_ |= kEpsilons;
767     }
768     if (arc.olabel == 0) {
769       ++state_->noepsilons;
770       *properties_ |= kOEpsilons;
771     }
772     if (arc.weight != Weight::Zero() && arc.weight != Weight::One())
773       *properties_ |= kWeighted;
774     *properties_ &= kSetArcProperties | kNotAcceptor |
775                     kEpsilons | kIEpsilons | kOEpsilons | kWeighted;
776   }
777 
778  private:
779   struct VectorState<A> *state_;
780   uint64 *properties_;
781   size_t i_;
782 
783   DISALLOW_EVIL_CONSTRUCTORS(MutableArcIterator);
784 };
785 
786 // Provide information needed for the generic mutable arc iterator
787 template <class A> inline
788 void VectorFst<A>::InitMutableArcIterator(
789     StateId s, MutableArcIteratorData<A> *data) {
790   data->base = new MutableArcIterator< VectorFst<A> >(this, s);
791 }
792 
793 // A useful alias when using StdArc.
794 typedef VectorFst<StdArc> StdVectorFst;
795 
796 }  // namespace fst
797 
798 #endif  // FST_LIB_VECTOR_FST_H__
799