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