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