FST  openfst-1.7.2
OpenFst Library
edit-fst.h
Go to the documentation of this file.
1 // See www.openfst.org for extensive documentation on this weighted
2 // finite-state transducer library.
3 //
4 // An FST implementation that allows non-destructive edit operations on an
5 // existing FST.
6 //
7 // The EditFst class enables non-destructive edit operations on a wrapped
8 // ExpandedFst. The implementation uses copy-on-write semantics at the node
9 // level: if a user has an underlying fst on which he or she wants to perform a
10 // relatively small number of edits (read: mutations), then this implementation
11 // will copy the edited node to an internal MutableFst and perform any edits in
12 // situ on that copied node. This class supports all the methods of MutableFst
13 // except for DeleteStates(const std::vector<StateId> &); thus, new nodes may
14 // also be
15 // added, and one may add transitions from existing nodes of the wrapped fst to
16 // new nodes.
17 //
18 // N.B.: The documentation for Fst::Copy(true) says that its behavior is
19 // undefined if invoked on an fst that has already been accessed. This class
20 // requires that the Fst implementation it wraps provides consistent, reliable
21 // behavior when its Copy(true) method is invoked, where consistent means
22 // the graph structure, graph properties and state numbering and do not change.
23 // VectorFst and CompactFst, for example, are both well-behaved in this regard.
24 
25 #ifndef FST_EDIT_FST_H_
26 #define FST_EDIT_FST_H_
27 
28 #include <string>
29 #include <unordered_map>
30 #include <vector>
31 
32 #include <fst/log.h>
33 
34 #include <fst/cache.h>
35 
36 
37 namespace fst {
38 namespace internal {
39 
40 // The EditFstData class is a container for all mutable data for EditFstImpl;
41 // also, this class provides most of the actual implementation of what EditFst
42 // does (that is, most of EditFstImpl's methods delegate to methods in this, the
43 // EditFstData class). Instances of this class are reference-counted and can be
44 // shared between otherwise independent EditFstImpl instances. This scheme
45 // allows EditFstImpl to implement the thread-safe, copy-on-write semantics
46 // required by Fst::Copy(true).
47 //
48 // template parameters:
49 // A the type of arc to use
50 // WrappedFstT the type of fst wrapped by the EditFst instance that
51 // this EditFstData instance is backing
52 // MutableFstT the type of mutable fst to use internally for edited states;
53 // crucially, MutableFstT::Copy(false) *must* yield an fst that is
54 // thread-safe for reading (VectorFst, for example, has this property)
55 template <typename Arc, typename WrappedFstT = ExpandedFst<Arc>,
56  typename MutableFstT = VectorFst<Arc>>
57 class EditFstData {
58  public:
59  using StateId = typename Arc::StateId;
60  using Weight = typename Arc::Weight;
61 
62  EditFstData() : num_new_states_(0) {}
63 
64  EditFstData(const EditFstData &other)
65  : edits_(other.edits_),
66  external_to_internal_ids_(other.external_to_internal_ids_),
67  edited_final_weights_(other.edited_final_weights_),
68  num_new_states_(other.num_new_states_) {}
69 
71 
73  std::istream &strm, const FstReadOptions &opts);
74 
75  bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
76  // Serialize all private data members of this class.
77  FstWriteOptions edits_opts(opts);
78  edits_opts.write_header = true; // Force writing contained header.
79  edits_.Write(strm, edits_opts);
80  WriteType(strm, external_to_internal_ids_);
81  WriteType(strm, edited_final_weights_);
82  WriteType(strm, num_new_states_);
83  if (!strm) {
84  LOG(ERROR) << "EditFstData::Write: Write failed: " << opts.source;
85  return false;
86  }
87  return true;
88  }
89 
90  StateId NumNewStates() const { return num_new_states_; }
91 
92  // accessor methods for the fst holding edited states
93  StateId EditedStart() const { return edits_.Start(); }
94 
95  Weight Final(StateId s, const WrappedFstT *wrapped) const {
96  auto final_weight_it = GetFinalWeightIterator(s);
97  if (final_weight_it == NotInFinalWeightMap()) {
98  auto it = GetEditedIdMapIterator(s);
99  return it == NotInEditedMap() ? wrapped->Final(s)
100  : edits_.Final(it->second);
101  } else {
102  return final_weight_it->second;
103  }
104  }
105 
106  size_t NumArcs(StateId s, const WrappedFstT *wrapped) const {
107  auto it = GetEditedIdMapIterator(s);
108  return it == NotInEditedMap() ? wrapped->NumArcs(s)
109  : edits_.NumArcs(it->second);
110  }
111 
112  size_t NumInputEpsilons(StateId s, const WrappedFstT *wrapped) const {
113  auto it = GetEditedIdMapIterator(s);
114  return it == NotInEditedMap() ? wrapped->NumInputEpsilons(s)
115  : edits_.NumInputEpsilons(it->second);
116  }
117 
118  size_t NumOutputEpsilons(StateId s, const WrappedFstT *wrapped) const {
119  auto it = GetEditedIdMapIterator(s);
120  return it == NotInEditedMap() ? wrapped->NumOutputEpsilons(s)
121  : edits_.NumOutputEpsilons(it->second);
122  }
123 
124  void SetEditedProperties(uint64 props, uint64 mask) {
125  edits_.SetProperties(props, mask);
126  }
127 
128  // Non-const MutableFst operations.
129 
130  // Sets the start state for this FST.
131  void SetStart(StateId s) { edits_.SetStart(s); }
132 
133  // Sets the final state for this FST.
134  Weight SetFinal(StateId s, Weight w, const WrappedFstT *wrapped) {
135  Weight old_weight = Final(s, wrapped);
136  auto it = GetEditedIdMapIterator(s);
137  // If we haven't already edited state s, don't add it to edited_ (which can
138  // be expensive if s has many transitions); just use the
139  // edited_final_weights_ map.
140  if (it == NotInEditedMap()) {
141  edited_final_weights_[s] = w;
142  } else {
143  edits_.SetFinal(GetEditableInternalId(s, wrapped), w);
144  }
145  return old_weight;
146  }
147 
148  // Adds a new state to this FST, initially with no arcs.
149  StateId AddState(StateId curr_num_states) {
150  StateId internal_state_id = edits_.AddState();
151  StateId external_state_id = curr_num_states;
152  external_to_internal_ids_[external_state_id] = internal_state_id;
153  num_new_states_++;
154  return external_state_id;
155  }
156 
157  // Adds the specified arc to the specified state of this FST.
158  const Arc *AddArc(StateId s, const Arc &arc, const WrappedFstT *wrapped) {
159  const auto internal_id = GetEditableInternalId(s, wrapped);
160  const auto num_arcs = edits_.NumArcs(internal_id);
161  ArcIterator<MutableFstT> arc_it(edits_, internal_id);
162  const Arc *prev_arc = nullptr;
163  if (num_arcs > 0) {
164  // grab the final arc associated with this state in edits_
165  arc_it.Seek(num_arcs - 1);
166  prev_arc = &(arc_it.Value());
167  }
168  edits_.AddArc(internal_id, arc);
169  return prev_arc;
170  }
171 
172  void DeleteStates() {
173  edits_.DeleteStates();
174  num_new_states_ = 0;
175  external_to_internal_ids_.clear();
176  edited_final_weights_.clear();
177  }
178 
179  // Removes all but the first n outgoing arcs of the specified state.
180  void DeleteArcs(StateId s, size_t n, const WrappedFstT *wrapped) {
181  edits_.DeleteArcs(GetEditableInternalId(s, wrapped), n);
182  }
183 
184  // Removes all outgoing arcs from the specified state.
185  void DeleteArcs(StateId s, const WrappedFstT *wrapped) {
186  edits_.DeleteArcs(GetEditableInternalId(s, wrapped));
187  }
188 
189  // End methods for non-const MutableFst operations.
190 
191  // Provides information for the generic arc iterator.
193  const WrappedFstT *wrapped) const {
194  auto id_map_it = GetEditedIdMapIterator(s);
195  if (id_map_it == NotInEditedMap()) {
196  VLOG(3) << "EditFstData::InitArcIterator: iterating on state " << s
197  << " of original fst";
198  wrapped->InitArcIterator(s, data);
199  } else {
200  VLOG(2) << "EditFstData::InitArcIterator: iterating on edited state " << s
201  << " (internal state id: " << id_map_it->second << ")";
202  edits_.InitArcIterator(id_map_it->second, data);
203  }
204  }
205 
206  // Provides information for the generic mutable arc iterator.
208  const WrappedFstT *wrapped) {
210  &edits_, GetEditableInternalId(s, wrapped));
211  }
212 
213  // Prints out the map from external to internal state id's (for debugging
214  // purposes).
215  void PrintMap() {
216  for (auto map_it = external_to_internal_ids_.begin();
217  map_it != NotInEditedMap(); ++map_it) {
218  LOG(INFO) << "(external,internal)=(" << map_it->first << ","
219  << map_it->second << ")";
220  }
221  }
222 
223  private:
224  // Returns the iterator of the map from external to internal state id's
225  // of edits_ for the specified external state id.
226  typename std::unordered_map<StateId, StateId>::const_iterator
227  GetEditedIdMapIterator(StateId s) const {
228  return external_to_internal_ids_.find(s);
229  }
230 
231  typename std::unordered_map<StateId, StateId>::const_iterator
232  NotInEditedMap() const {
233  return external_to_internal_ids_.end();
234  }
235 
236  typename std::unordered_map<StateId, Weight>::const_iterator
237  GetFinalWeightIterator(StateId s) const {
238  return edited_final_weights_.find(s);
239  }
240 
241  typename std::unordered_map<StateId, Weight>::const_iterator
242  NotInFinalWeightMap() const {
243  return edited_final_weights_.end();
244  }
245 
246  // Returns the internal state ID of the specified external ID if the state has
247  // already been made editable, or else copies the state from wrapped_ to
248  // edits_ and returns the state id of the newly editable state in edits_.
249  StateId GetEditableInternalId(StateId s, const WrappedFstT *wrapped) {
250  auto id_map_it = GetEditedIdMapIterator(s);
251  if (id_map_it == NotInEditedMap()) {
252  StateId new_internal_id = edits_.AddState();
253  VLOG(2) << "EditFstData::GetEditableInternalId: editing state " << s
254  << " of original fst; new internal state id:" << new_internal_id;
255  external_to_internal_ids_[s] = new_internal_id;
256  for (ArcIterator<Fst<Arc>> arc_iterator(*wrapped, s);
257  !arc_iterator.Done(); arc_iterator.Next()) {
258  edits_.AddArc(new_internal_id, arc_iterator.Value());
259  }
260  // Copies the final weight.
261  auto final_weight_it = GetFinalWeightIterator(s);
262  if (final_weight_it == NotInFinalWeightMap()) {
263  edits_.SetFinal(new_internal_id, wrapped->Final(s));
264  } else {
265  edits_.SetFinal(new_internal_id, final_weight_it->second);
266  edited_final_weights_.erase(s);
267  }
268  return new_internal_id;
269  } else {
270  return id_map_it->second;
271  }
272  }
273 
274  // A mutable FST (by default, a VectorFst) to contain new states, and/or
275  // copies of states from a wrapped ExpandedFst that have been modified in
276  // some way.
277  MutableFstT edits_;
278  // A mapping from external state IDs to the internal IDs of states that
279  // appear in edits_.
280  std::unordered_map<StateId, StateId> external_to_internal_ids_;
281  // A mapping from external state IDs to final state weights assigned to
282  // those states. The states in this map are *only* those whose final weight
283  // has been modified; if any other part of the state has been modified,
284  // the entire state is copied to edits_, and all modifications reside there.
285  std::unordered_map<StateId, Weight> edited_final_weights_;
286  // The number of new states added to this mutable fst impl, which is <= the
287  // number of states in edits_ (since edits_ contains both edited *and* new
288  // states).
289  StateId num_new_states_;
290 };
291 
292 // EditFstData method implementations: just the Read method.
293 template <typename A, typename WrappedFstT, typename MutableFstT>
296  const FstReadOptions &opts) {
297  auto *data = new EditFstData<A, WrappedFstT, MutableFstT>();
298  // next read in MutabelFstT machine that stores edits
299  FstReadOptions edits_opts(opts);
300  // Contained header was written out, so read it in.
301  edits_opts.header = nullptr;
302 
303  // Because our internal representation of edited states is a solid object
304  // of type MutableFstT (defaults to VectorFst<A>) and not a pointer,
305  // and because the static Read method allocates a new object on the heap,
306  // we need to call Read, check if there was a failure, use
307  // MutableFstT::operator= to assign the object (not the pointer) to the
308  // edits_ data member (which will increase the ref count by 1 on the impl)
309  // and, finally, delete the heap-allocated object.
310  std::unique_ptr<MutableFstT> edits(MutableFstT::Read(strm, edits_opts));
311  if (!edits) return nullptr;
312  data->edits_ = *edits;
313  edits.reset();
314  // Finally, reads in rest of private data members.
315  ReadType(strm, &data->external_to_internal_ids_);
316  ReadType(strm, &data->edited_final_weights_);
317  ReadType(strm, &data->num_new_states_);
318  if (!strm) {
319  LOG(ERROR) << "EditFst::Read: read failed: " << opts.source;
320  return nullptr;
321  }
322  return data;
323 }
324 
325 // This class enables non-destructive edit operations on a wrapped ExpandedFst.
326 // The implementation uses copy-on-write semantics at the node level: if a user
327 // has an underlying fst on which he or she wants to perform a relatively small
328 // number of edits (read: mutations), then this implementation will copy the
329 // edited node to an internal MutableFst and perform any edits in situ on that
330 // copied node. This class supports all the methods of MutableFst except for
331 // DeleteStates(const std::vector<StateId> &); thus, new nodes may also be
332 // added, and
333 // one may add transitions from existing nodes of the wrapped fst to new nodes.
334 //
335 // template parameters:
336 // A the type of arc to use
337 // WrappedFstT the type of fst wrapped by the EditFst instance that
338 // this EditFstImpl instance is backing
339 // MutableFstT the type of mutable fst to use internally for edited states;
340 // crucially, MutableFstT::Copy(false) *must* yield an fst that is
341 // thread-safe for reading (VectorFst, for example, has this property)
342 template <typename A, typename WrappedFstT = ExpandedFst<A>,
343  typename MutableFstT = VectorFst<A>>
344 class EditFstImpl : public FstImpl<A> {
345  public:
346  using Arc = A;
347  using StateId = typename Arc::StateId;
348  using Weight = typename Arc::Weight;
349 
354 
355  // Constructs an editable FST implementation with no states. Effectively, this
356  // initially-empty fst will in every way mimic the behavior of a
357  // VectorFst---more precisely, a VectorFstImpl instance---but with slightly
358  // slower performance (by a constant factor), due to the fact that
359  // this class maintains a mapping between external state id's and
360  // their internal equivalents.
361  EditFstImpl() : wrapped_(new MutableFstT()) {
362  FstImpl<Arc>::SetType("edit");
363  InheritPropertiesFromWrapped();
364  data_ = std::make_shared<EditFstData<Arc, WrappedFstT, MutableFstT>>();
365  }
366 
367  // Wraps the specified ExpandedFst. This constructor requires that the
368  // specified Fst is an ExpandedFst instance. This requirement is only enforced
369  // at runtime. (See below for the reason.)
370  //
371  // This library uses the pointer-to-implementation or "PIMPL" design pattern.
372  // In particular, to make it convenient to bind an implementation class to its
373  // interface, there are a pair of template "binder" classes, one for immutable
374  // and one for mutable fst's (ImplToFst and ImplToMutableFst, respectively).
375  // As it happens, the API for the ImplToMutableFst<I,F> class requires that
376  // the implementation class--the template parameter "I"--have a constructor
377  // taking a const Fst<A> reference. Accordingly, the constructor here must
378  // perform a static_cast to the WrappedFstT type required by EditFst and
379  // therefore EditFstImpl.
380  explicit EditFstImpl(const Fst<Arc> &wrapped)
381  : wrapped_(static_cast<WrappedFstT *>(wrapped.Copy())) {
382  FstImpl<Arc>::SetType("edit");
383  data_ = std::make_shared<EditFstData<Arc, WrappedFstT, MutableFstT>>();
384  // have edits_ inherit all properties from wrapped_
385  data_->SetEditedProperties(wrapped_->Properties(kFstProperties, false),
387  InheritPropertiesFromWrapped();
388  }
389 
390  // A copy constructor for this implementation class, used to implement
391  // the Copy() method of the Fst interface.
393  : FstImpl<Arc>(),
394  wrapped_(static_cast<WrappedFstT *>(impl.wrapped_->Copy(true))),
395  data_(impl.data_) {
396  SetProperties(impl.Properties());
397  }
398 
399  // const Fst/ExpandedFst operations, declared in the Fst and ExpandedFst
400  // interfaces
401  StateId Start() const {
402  const auto edited_start = data_->EditedStart();
403  return edited_start == kNoStateId ? wrapped_->Start() : edited_start;
404  }
405 
406  Weight Final(StateId s) const { return data_->Final(s, wrapped_.get()); }
407 
408  size_t NumArcs(StateId s) const { return data_->NumArcs(s, wrapped_.get()); }
409 
410  size_t NumInputEpsilons(StateId s) const {
411  return data_->NumInputEpsilons(s, wrapped_.get());
412  }
413 
414  size_t NumOutputEpsilons(StateId s) const {
415  return data_->NumOutputEpsilons(s, wrapped_.get());
416  }
417 
418  StateId NumStates() const {
419  return wrapped_->NumStates() + data_->NumNewStates();
420  }
421 
423  std::istream &strm, const FstReadOptions &opts);
424 
425  bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
426  FstHeader hdr;
427  hdr.SetStart(Start());
428  hdr.SetNumStates(NumStates());
429  FstWriteOptions header_opts(opts);
430  // Allows the contained FST to hold any symbols.
431  header_opts.write_isymbols = false;
432  header_opts.write_osymbols = false;
433  WriteHeader(strm, header_opts, kFileVersion, &hdr);
434  // First, serializes the wrapped FST to stream.
435  FstWriteOptions wrapped_opts(opts);
436  // Forcse writing the contained header.
437  wrapped_opts.write_header = true;
438  wrapped_->Write(strm, wrapped_opts);
439  data_->Write(strm, opts);
440  strm.flush();
441  if (!strm) {
442  LOG(ERROR) << "EditFst::Write: Write failed: " << opts.source;
443  return false;
444  }
445  return true;
446  }
447 
448  // Sets the start state for this FST.
449  void SetStart(StateId s) {
450  MutateCheck();
451  data_->SetStart(s);
453  }
454 
455  // Sets the final state for this fst.
456  void SetFinal(StateId s, Weight weight) {
457  MutateCheck();
458  Weight old_weight = data_->SetFinal(s, weight, wrapped_.get());
459  SetProperties(
460  SetFinalProperties(FstImpl<Arc>::Properties(), old_weight, weight));
461  }
462 
463  // Adds a new state to this fst, initially with no arcs.
465  MutateCheck();
467  return data_->AddState(NumStates());
468  }
469 
470  // Adds the specified arc to the specified state of this fst.
471  void AddArc(StateId s, const Arc &arc) {
472  MutateCheck();
473  const auto *prev_arc = data_->AddArc(s, arc, wrapped_.get());
474  SetProperties(
475  AddArcProperties(FstImpl<Arc>::Properties(), s, arc, prev_arc));
476  }
477 
478  void DeleteStates(const std::vector<StateId> &dstates) {
479  FSTERROR() << ": EditFstImpl::DeleteStates(const std::vector<StateId>&): "
480  << " not implemented";
481  SetProperties(kError, kError);
482  }
483 
484  // Deletes all states in this fst.
485  void DeleteStates();
486 
487  // Removes all but the first n outgoing arcs of the specified state.
488  void DeleteArcs(StateId s, size_t n) {
489  MutateCheck();
490  data_->DeleteArcs(s, n, wrapped_.get());
492  }
493 
494  // Removes all outgoing arcs from the specified state.
495  void DeleteArcs(StateId s) {
496  MutateCheck();
497  data_->DeleteArcs(s, wrapped_.get());
499  }
500 
502 
503  void ReserveArcs(StateId s, size_t n) {}
504 
505  // Ends non-const MutableFst operations.
506 
507  // Provides information for the generic state iterator.
509  data->base = nullptr;
510  data->nstates = NumStates();
511  }
512 
513  // Provides information for the generic arc iterator.
515  data_->InitArcIterator(s, data, wrapped_.get());
516  }
517 
518  // Provides information for the generic mutable arc iterator.
520  MutateCheck();
521  data_->InitMutableArcIterator(s, data, wrapped_.get());
522  }
523 
524  private:
525  // Properties always true of this FST class.
526  static constexpr uint64 kStaticProperties = kExpanded | kMutable;
527  // Current file format version.
528  static constexpr int kFileVersion = 2;
529  // Minimum file format version supported
530  static constexpr int kMinFileVersion = 2;
531 
532  // Causes this FST to inherit all the properties from its wrapped FST, except
533  // for the two properties that always apply to EditFst instances: kExpanded
534  // and kMutable.
535  void InheritPropertiesFromWrapped() {
536  SetProperties(wrapped_->Properties(kCopyProperties, false) |
537  kStaticProperties);
538  SetInputSymbols(wrapped_->InputSymbols());
539  SetOutputSymbols(wrapped_->OutputSymbols());
540  }
541 
542  // This method ensures that any operations that alter the mutable data
543  // portion of this EditFstImpl cause the data_ member to be copied when its
544  // reference count is greater than 1. Note that this method is distinct from
545  // MutableFst::Mutate, which gets invoked whenever one of the basic mutation
546  // methods defined in MutableFst is invoked, such as SetInputSymbols.
547  // The MutateCheck here in EditFstImpl is invoked whenever one of the
548  // mutating methods specifically related to the types of edits provided
549  // by EditFst is performed, such as changing an arc of an existing state
550  // of the wrapped fst via a MutableArcIterator, or adding a new state via
551  // AddState().
552  void MutateCheck() {
553  if (!data_.unique()) {
554  data_ =
555  std::make_shared<EditFstData<Arc, WrappedFstT, MutableFstT>>(*data_);
556  }
557  }
558 
559  // The FST that this FST wraps. The purpose of this class is to enable
560  // non-destructive edits on this wrapped FST.
561  std::unique_ptr<const WrappedFstT> wrapped_;
562  // The mutable data for this EditFst instance, with delegates for all the
563  // methods that can mutate data.
564  std::shared_ptr<EditFstData<Arc, WrappedFstT, MutableFstT>> data_;
565 };
566 
567 template <typename Arc, typename WrappedFstT, typename MutableFstT>
569 
570 template <typename Arc, typename WrappedFstT, typename MutableFstT>
572 
573 template <typename Arc, typename WrappedFstT, typename MutableFstT>
575 
576 template <typename Arc, typename WrappedFstT, typename MutableFstT>
578  data_->DeleteStates();
579  // we are deleting all states, so just forget about pointer to wrapped_
580  // and do what default constructor does: set wrapped_ to a new VectorFst
581  wrapped_.reset(new MutableFstT());
582  const auto new_props =
584  FstImpl<Arc>::SetProperties(new_props);
585 }
586 
587 template <typename Arc, typename WrappedFstT, typename MutableFstT>
590  const FstReadOptions &opts) {
591  auto *impl = new EditFstImpl();
592  FstHeader hdr;
593  if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) return nullptr;
594  impl->SetStart(hdr.Start());
595  // Reads in wrapped FST.
596  FstReadOptions wrapped_opts(opts);
597  // Contained header was written out, so reads it in too.
598  wrapped_opts.header = nullptr;
599  std::unique_ptr<Fst<Arc>> wrapped_fst(Fst<Arc>::Read(strm, wrapped_opts));
600  if (!wrapped_fst) return nullptr;
601  impl->wrapped_.reset(static_cast<WrappedFstT *>(wrapped_fst.release()));
602  impl->data_ = std::shared_ptr<EditFstData<Arc, WrappedFstT, MutableFstT>>(
604  if (!impl->data_) return nullptr;
605  return impl;
606 }
607 
608 } // namespace internal
609 
610 // Concrete, editable FST. This class attaches interface to implementation.
611 template <typename A, typename WrappedFstT = ExpandedFst<A>,
612  typename MutableFstT = VectorFst<A>>
613 class EditFst : public ImplToMutableFst<
614  internal::EditFstImpl<A, WrappedFstT, MutableFstT>> {
615  public:
616  using Arc = A;
617  using StateId = typename Arc::StateId;
618 
620 
621  friend class MutableArcIterator<EditFst<Arc, WrappedFstT, MutableFstT>>;
622 
623  EditFst() : ImplToMutableFst<Impl>(std::make_shared<Impl>()) {}
624 
625  explicit EditFst(const Fst<Arc> &fst)
626  : ImplToMutableFst<Impl>(std::make_shared<Impl>(fst)) {}
627 
628  explicit EditFst(const WrappedFstT &fst)
629  : ImplToMutableFst<Impl>(std::make_shared<Impl>(fst)) {}
630 
631  // See Fst<>::Copy() for doc.
633  : ImplToMutableFst<Impl>(fst, safe) {}
634 
635  ~EditFst() override {}
636 
637  // Gets a copy of this EditFst. See Fst<>::Copy() for further doc.
639  bool safe = false) const override {
640  return new EditFst<Arc, WrappedFstT, MutableFstT>(*this, safe);
641  }
642 
645  SetImpl(fst.GetSharedImpl());
646  return *this;
647  }
648 
650  const Fst<Arc> &fst) override {
651  SetImpl(std::make_shared<Impl>(fst));
652  return *this;
653  }
654 
655  // Reads an EditFst from an input stream, returning nullptr on error.
657  std::istream &strm, const FstReadOptions &opts) {
658  auto *impl = Impl::Read(strm, opts);
659  return impl ? new EditFst<Arc>(std::shared_ptr<Impl>(impl)) : nullptr;
660  }
661 
662  // Reads an EditFst from a file, returning nullptr on error. If the filename
663  // argument is an empty string, it reads from standard input.
664  static EditFst<Arc, WrappedFstT, MutableFstT> *Read(const string &filename) {
665  auto *impl = ImplToExpandedFst<Impl, MutableFst<Arc>>::Read(filename);
666  return impl ? new EditFst<Arc, WrappedFstT, MutableFstT>(
667  std::shared_ptr<Impl>(impl))
668  : nullptr;
669  }
670 
671  bool Write(std::ostream &strm, const FstWriteOptions &opts) const override {
672  return GetImpl()->Write(strm, opts);
673  }
674 
675  bool Write(const string &filename) const override {
676  return Fst<Arc>::WriteFile(filename);
677  }
678 
679  void InitStateIterator(StateIteratorData<Arc> *data) const override {
680  GetImpl()->InitStateIterator(data);
681  }
682 
683  void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const override {
684  GetImpl()->InitArcIterator(s, data);
685  }
686 
688  MutableArcIteratorData<A> *data) override {
689  GetMutableImpl()->InitMutableArcIterator(s, data);
690  }
691 
692  private:
693  explicit EditFst(std::shared_ptr<Impl> impl) : ImplToMutableFst<Impl>(impl) {}
694 
695  using ImplToFst<Impl, MutableFst<Arc>>::GetImpl;
696  using ImplToFst<Impl, MutableFst<Arc>>::GetMutableImpl;
697  using ImplToFst<Impl, MutableFst<Arc>>::SetImpl;
698 };
699 
700 } // namespace fst
701 
702 #endif // FST_EDIT_FST_H_
void SetStart(StateId s)
Definition: edit-fst.h:449
void ReserveArcs(StateId s, size_t n)
Definition: edit-fst.h:503
string source
Definition: fst.h:84
EditFst< Arc, WrappedFstT, MutableFstT > * Copy(bool safe=false) const override
Definition: edit-fst.h:638
void InitMutableArcIterator(StateId s, MutableArcIteratorData< Arc > *data, const WrappedFstT *wrapped)
Definition: edit-fst.h:207
~EditFst() override
Definition: edit-fst.h:635
typename Arc::Weight Weight
Definition: edit-fst.h:348
const FstHeader * header
Definition: fst.h:58
uint64 AddArcProperties(uint64 inprops, typename A::StateId s, const A &arc, const A *prev_arc)
uint64_t uint64
Definition: types.h:32
void AddArc(StateId s, const Arc &arc)
Definition: edit-fst.h:471
void InitArcIterator(StateId s, ArcIteratorData< Arc > *data) const
Definition: edit-fst.h:514
StateId NumStates() const
Definition: edit-fst.h:418
size_t NumInputEpsilons(StateId s, const WrappedFstT *wrapped) const
Definition: edit-fst.h:112
StateId AddState(StateId curr_num_states)
Definition: edit-fst.h:149
StateId Start() const
Definition: edit-fst.h:401
int64 Start() const
Definition: fst.h:129
EditFst(const EditFst< Arc, WrappedFstT, MutableFstT > &fst, bool safe=false)
Definition: edit-fst.h:632
#define LOG(type)
Definition: log.h:48
size_t NumArcs(StateId s, const WrappedFstT *wrapped) const
Definition: edit-fst.h:106
EditFstImpl(const Fst< Arc > &wrapped)
Definition: edit-fst.h:380
void DeleteArcs(StateId s)
Definition: edit-fst.h:495
void SetStart(StateId s)
Definition: edit-fst.h:131
StateId NumNewStates() const
Definition: edit-fst.h:90
static EditFstData< Arc, WrappedFstT, MutableFstT > * Read(std::istream &strm, const FstReadOptions &opts)
Definition: edit-fst.h:295
constexpr uint64 kFstProperties
Definition: properties.h:301
constexpr uint64 kCopyProperties
Definition: properties.h:138
typename Arc::StateId StateId
Definition: edit-fst.h:617
virtual uint64 Properties() const
Definition: fst.h:666
constexpr int kNoStateId
Definition: fst.h:180
constexpr uint64 kExpanded
Definition: properties.h:27
void DeleteStates(const std::vector< StateId > &dstates)
Definition: edit-fst.h:478
EditFst(const WrappedFstT &fst)
Definition: edit-fst.h:628
const Arc & Value() const
Definition: fst.h:503
typename Arc::StateId StateId
Definition: edit-fst.h:347
void SetType(const string &type)
Definition: fst.h:664
std::ostream & WriteType(std::ostream &strm, const T t)
Definition: util.h:155
EditFst< Arc, WrappedFstT, MutableFstT > & operator=(const EditFst< Arc, WrappedFstT, MutableFstT > &fst)
Definition: edit-fst.h:643
#define FSTERROR()
Definition: util.h:35
bool WriteFile(const string &filename) const
Definition: fst.h:303
void DeleteArcs(StateId s, size_t n, const WrappedFstT *wrapped)
Definition: edit-fst.h:180
static EditFstImpl< Arc, WrappedFstT, MutableFstT > * Read(std::istream &strm, const FstReadOptions &opts)
Definition: edit-fst.h:589
bool write_osymbols
Definition: fst.h:87
StateIteratorBase< Arc > * base
Definition: fst.h:351
typename Arc::Weight Weight
Definition: edit-fst.h:60
uint64 AddStateProperties(uint64 inprops)
Definition: properties.h:375
void Seek(size_t a)
Definition: fst.h:523
Weight Final(StateId s, const WrappedFstT *wrapped) const
Definition: edit-fst.h:95
void DeleteArcs(StateId s, size_t n)
Definition: edit-fst.h:488
bool write_isymbols
Definition: fst.h:86
StateId EditedStart() const
Definition: edit-fst.h:93
void InitArcIterator(StateId s, ArcIteratorData< Arc > *data, const WrappedFstT *wrapped) const
Definition: edit-fst.h:192
void InitArcIterator(StateId s, ArcIteratorData< Arc > *data) const override
Definition: edit-fst.h:683
EditFst< Arc, WrappedFstT, MutableFstT > & operator=(const Fst< Arc > &fst) override
Definition: edit-fst.h:649
void SetNumStates(int64 numstates)
Definition: fst.h:147
StateId nstates
Definition: fst.h:353
EditFst(const Fst< Arc > &fst)
Definition: edit-fst.h:625
#define VLOG(level)
Definition: log.h:49
size_t NumInputEpsilons(StateId s) const
Definition: edit-fst.h:410
size_t NumOutputEpsilons(StateId s, const WrappedFstT *wrapped) const
Definition: edit-fst.h:118
uint64 SetStartProperties(uint64 inprops)
Definition: properties.h:367
string source
Definition: fst.h:57
bool Write(std::ostream &strm, const FstWriteOptions &opts) const override
Definition: edit-fst.h:671
EditFstImpl(const EditFstImpl &impl)
Definition: edit-fst.h:392
bool write_header
Definition: fst.h:85
static EditFst< Arc, WrappedFstT, MutableFstT > * Read(const string &filename)
Definition: edit-fst.h:664
EditFstData(const EditFstData &other)
Definition: edit-fst.h:64
void ReserveStates(StateId s)
Definition: edit-fst.h:501
void SetStart(int64 start)
Definition: fst.h:145
void SetEditedProperties(uint64 props, uint64 mask)
Definition: edit-fst.h:124
Weight Final(StateId s) const
Definition: edit-fst.h:406
void InitStateIterator(StateIteratorData< Arc > *data) const override
Definition: edit-fst.h:679
MutableArcIteratorBase< Arc > * base
Definition: mutable-fst.h:181
uint64 DeleteAllStatesProperties(uint64 inprops, uint64 staticProps)
Definition: properties.h:383
const Arc * AddArc(StateId s, const Arc &arc, const WrappedFstT *wrapped)
Definition: edit-fst.h:158
void SetProperties(uint64 props)
Definition: fst.h:670
constexpr uint64 kError
Definition: properties.h:33
void SetFinal(StateId s, Weight weight)
Definition: edit-fst.h:456
bool Write(const string &filename) const override
Definition: edit-fst.h:675
uint64 SetFinalProperties(uint64 inprops, const Weight &old_weight, const Weight &new_weight)
Definition: properties.h:395
static EditFst< Arc, WrappedFstT, MutableFstT > * Read(std::istream &strm, const FstReadOptions &opts)
Definition: edit-fst.h:656
std::istream & ReadType(std::istream &strm, T *t)
Definition: util.h:47
void InitMutableArcIterator(StateId s, MutableArcIteratorData< Arc > *data)
Definition: edit-fst.h:519
uint64 DeleteArcsProperties(uint64 inprops)
Definition: properties.h:388
typename Arc::StateId StateId
Definition: edit-fst.h:59
Weight SetFinal(StateId s, Weight w, const WrappedFstT *wrapped)
Definition: edit-fst.h:134
size_t NumArcs(StateId s) const
Definition: edit-fst.h:408
bool Write(std::ostream &strm, const FstWriteOptions &opts) const
Definition: edit-fst.h:75
size_t NumOutputEpsilons(StateId s) const
Definition: edit-fst.h:414
void InitMutableArcIterator(StateId s, MutableArcIteratorData< A > *data) override
Definition: edit-fst.h:687
void InitStateIterator(StateIteratorData< Arc > *data) const
Definition: edit-fst.h:508
void DeleteArcs(StateId s, const WrappedFstT *wrapped)
Definition: edit-fst.h:185
bool Write(std::ostream &strm, const FstWriteOptions &opts) const
Definition: edit-fst.h:425
constexpr uint64 kMutable
Definition: properties.h:30