Home | History | Annotate | Download | only in lib
      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 
     42   VectorFstBaseImpl() : start_(kNoStateId) {}
     43 
     44   ~VectorFstBaseImpl() {
     45     for (StateId s = 0; s < (StateId)states_.size(); ++s)
     46       delete states_[s];
     47   }
     48 
     49   StateId Start() const { return start_; }
     50 
     51   Weight Final(StateId s) const { return states_[s]->final; }
     52 
     53   StateId NumStates() const { return states_.size(); }
     54 
     55   size_t NumArcs(StateId s) const { return states_[s]->arcs.size(); }
     56 
     57   void SetStart(StateId s) { start_ = s; }
     58 
     59   void SetFinal(StateId s, Weight w) { states_[s]->final = w; }
     60 
     61   StateId AddState() {
     62     states_.push_back(new State);
     63     return states_.size() - 1;
     64   }
     65 
     66   StateId AddState(State *state) {
     67     states_.push_back(state);
     68     return states_.size() - 1;
     69   }
     70 
     71   void AddArc(StateId s, const Arc &arc) {
     72     states_[s]->arcs.push_back(arc);
     73   }
     74 
     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 
    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 
    121   void DeleteArcs(StateId s, size_t n) {
    122     states_[s]->arcs.resize(states_[s]->arcs.size() - n);
    123   }
    124 
    125   void DeleteArcs(StateId s) { states_[s]->arcs.clear(); }
    126 
    127   State *GetState(StateId s) { return states_[s]; }
    128 
    129   const State *GetState(StateId s) const { return states_[s]; }
    130 
    131   void SetState(StateId s, State *state) { states_[s] = state; }
    132 
    133   void ReserveStates(StateId n) { states_.reserve(n); }
    134 
    135   void ReserveArcs(StateId s, size_t n) { states_[s]->arcs.reserve(n); }
    136 
    137   // Provide information needed for generic state iterator
    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
    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 
    165   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 
    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 
    200   size_t NumInputEpsilons(StateId s) const { return GetState(s)->niepsilons; }
    201 
    202   size_t NumOutputEpsilons(StateId s) const { return GetState(s)->noepsilons; }
    203 
    204   bool Write(ostream &strm, const FstWriteOptions &opts) const;
    205 
    206   void SetStart(StateId s) {
    207     BaseImpl::SetStart(s);
    208     SetProperties(Properties() & kSetStartProperties);
    209     if (Properties() & kAcyclic)
    210       SetProperties(Properties() | kInitialAcyclic);
    211   }
    212 
    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 
    226   StateId AddState() {
    227     StateId s = BaseImpl::AddState();
    228     SetProperties(Properties() & kAddStateProperties);
    229     return s;
    230   }
    231 
    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 
    280   void DeleteStates(const vector<StateId> &dstates) {
    281     BaseImpl::DeleteStates(dstates);
    282     SetProperties(Properties() & kDeleteStatesProperties);
    283   }
    284 
    285   void DeleteStates() {
    286     BaseImpl::DeleteStates();
    287     SetProperties(kNullProperties | kStaticProperties);
    288   }
    289 
    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 
    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>
    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>
    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
    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
    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
    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>
    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 
    463   VectorFst() : impl_(new VectorFstImpl<A>) {}
    464 
    465   VectorFst(const VectorFst<A> &fst) : MutableFst<A>(fst), impl_(fst.impl_) {
    466     impl_->IncrRefCount();
    467   }
    468   explicit VectorFst(const Fst<A> &fst) : impl_(new VectorFstImpl<A>(fst)) {}
    469 
    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 
    489   virtual StateId Start() const { return impl_->Start(); }
    490 
    491   virtual Weight Final(StateId s) const { return impl_->Final(s); }
    492 
    493   virtual StateId NumStates() const { return impl_->NumStates(); }
    494 
    495   virtual size_t NumArcs(StateId s) const { return impl_->NumArcs(s); }
    496 
    497   virtual size_t NumInputEpsilons(StateId s) const {
    498     return impl_->NumInputEpsilons(s);
    499   }
    500 
    501   virtual size_t NumOutputEpsilons(StateId s) const {
    502     return impl_->NumOutputEpsilons(s);
    503   }
    504 
    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 
    515   virtual const string& Type() const { return impl_->Type(); }
    516 
    517   // Get a copy of this VectorFst
    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
    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
    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
    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
    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 
    558   virtual SymbolTable* InputSymbols() {
    559     return impl_->InputSymbols();
    560   }
    561 
    562   virtual SymbolTable* OutputSymbols() {
    563     return impl_->OutputSymbols();
    564   }
    565 
    566   virtual const SymbolTable* InputSymbols() const {
    567     return impl_->InputSymbols();
    568   }
    569 
    570   virtual const SymbolTable* OutputSymbols() const {
    571     return impl_->OutputSymbols();
    572   }
    573 
    574   virtual void SetStart(StateId s) {
    575     MutateCheck();
    576     impl_->SetStart(s);
    577   }
    578 
    579   virtual void SetFinal(StateId s, Weight w) {
    580     MutateCheck();
    581     impl_->SetFinal(s, w);
    582   }
    583 
    584   virtual void SetProperties(uint64 props, uint64 mask) {
    585     impl_->SetProperties(props, mask);
    586   }
    587 
    588   virtual StateId AddState() {
    589     MutateCheck();
    590     return impl_->AddState();
    591   }
    592 
    593   virtual void AddArc(StateId s, const A &arc) {
    594     MutateCheck();
    595     impl_->AddArc(s, arc);
    596   }
    597 
    598   virtual void DeleteStates(const vector<StateId> &dstates) {
    599     MutateCheck();
    600     impl_->DeleteStates(dstates);
    601   }
    602 
    603   virtual void DeleteStates() {
    604     MutateCheck();
    605     impl_->DeleteStates();
    606   }
    607 
    608   virtual void DeleteArcs(StateId s, size_t n) {
    609     MutateCheck();
    610     impl_->DeleteArcs(s, n);
    611   }
    612 
    613   virtual void DeleteArcs(StateId s) {
    614     MutateCheck();
    615     impl_->DeleteArcs(s);
    616   }
    617 
    618   virtual void SetInputSymbols(const SymbolTable* isyms) {
    619     MutateCheck();
    620     impl_->SetInputSymbols(isyms);
    621   }
    622 
    623   virtual void SetOutputSymbols(const SymbolTable* osyms) {
    624     MutateCheck();
    625     impl_->SetOutputSymbols(osyms);
    626   }
    627 
    628   void ReserveStates(StateId n) {
    629     MutateCheck();
    630     impl_->ReserveStates(n);
    631   }
    632 
    633   void ReserveArcs(StateId s, size_t n) {
    634     MutateCheck();
    635     impl_->ReserveArcs(s, n);
    636   }
    637 
    638   virtual void InitStateIterator(StateIteratorData<A> *data) const {
    639     impl_->InitStateIterator(data);
    640   }
    641 
    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:
    650   explicit VectorFst(VectorFstImpl<A> *impl) : impl_(impl) {}
    651 
    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 
    671   explicit StateIterator(const VectorFst<A> &fst)
    672     : nstates_(fst.impl_->NumStates()), s_(0) {}
    673 
    674   bool Done() const { return s_ >= nstates_; }
    675 
    676   StateId Value() const { return s_; }
    677 
    678   void Next() { ++s_; }
    679 
    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 
    697   ArcIterator(const VectorFst<A> &fst, StateId s)
    698     : arcs_(fst.impl_->GetState(s)->arcs), i_(0) {}
    699 
    700   bool Done() const { return i_ >= arcs_.size(); }
    701 
    702   const A& Value() const { return arcs_[i_]; }
    703 
    704   void Next() { ++i_; }
    705 
    706   void Reset() { i_ = 0; }
    707 
    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 
    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 
    733   virtual bool Done() const { return i_ >= state_->arcs.size(); }
    734 
    735   virtual const A& Value() const { return state_->arcs[i_]; }
    736 
    737   virtual void Next() { ++i_; }
    738 
    739   virtual void Reset() { i_ = 0; }
    740 
    741   virtual void Seek(size_t a) { i_ = a; }
    742 
    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