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