FST  openfst-1.7.1
OpenFst Library
mutable-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 // Expanded FST augmented with mutators; interface class definition and
5 // mutable arc iterator interface.
6 
7 #ifndef FST_MUTABLE_FST_H_
8 #define FST_MUTABLE_FST_H_
9 
10 #include <stddef.h>
11 #include <sys/types.h>
12 
13 #include <istream>
14 #include <string>
15 #include <utility>
16 #include <vector>
17 
18 #include <fst/log.h>
19 #include <fstream>
20 
21 #include <fst/expanded-fst.h>
22 
23 
24 namespace fst {
25 
26 template <class Arc>
28 
29 // Abstract interface for an expanded FST which also supports mutation
30 // operations. To modify arcs, use MutableArcIterator.
31 template <class A>
32 class MutableFst : public ExpandedFst<A> {
33  public:
34  using Arc = A;
35  using StateId = typename Arc::StateId;
36  using Weight = typename Arc::Weight;
37 
38  virtual MutableFst<Arc> &operator=(const Fst<Arc> &fst) = 0;
39 
41  return operator=(static_cast<const Fst<Arc> &>(fst));
42  }
43 
44  // Sets the initial state.
45  virtual void SetStart(StateId) = 0;
46 
47  // Sets a state's final weight.
48  virtual void SetFinal(StateId, Weight) = 0;
49 
50  // Sets property bits w.r.t. mask.
51  virtual void SetProperties(uint64 props, uint64 mask) = 0;
52 
53  // Adds a state and returns its ID.
54  virtual StateId AddState() = 0;
55 
56  // Adds an arc to state.
57  virtual void AddArc(StateId, const Arc &arc) = 0;
58 
59  // Adds an arc (passed by rvalue reference) to state. Allows subclasses
60  // to optionally implement move semantics. Defaults to lvalue overload.
61  virtual void AddArc(StateId state, Arc &&arc) { AddArc(state, arc); }
62 
63  // Deletes some states, preserving original StateId ordering.
64  virtual void DeleteStates(const std::vector<StateId> &) = 0;
65 
66  // Delete all states.
67  virtual void DeleteStates() = 0;
68 
69  // Delete some arcs at a given state.
70  virtual void DeleteArcs(StateId, size_t n) = 0;
71 
72  // Delete all arcs at a given state.
73  virtual void DeleteArcs(StateId) = 0;
74 
75  // Optional, best effort only.
76  virtual void ReserveStates(StateId n) {}
77 
78  // Optional, best effort only.
79  virtual void ReserveArcs(StateId s, size_t n) {}
80 
81  // Returns input label symbol table or nullptr if not specified.
82  const SymbolTable *InputSymbols() const override = 0;
83 
84  // Returns output label symbol table or nullptr if not specified.
85  const SymbolTable *OutputSymbols() const override = 0;
86 
87  // Returns input label symbol table or nullptr if not specified.
88  virtual SymbolTable *MutableInputSymbols() = 0;
89 
90  // Returns output label symbol table or nullptr if not specified.
91  virtual SymbolTable *MutableOutputSymbols() = 0;
92 
93  // Sets input label symbol table; pass nullptr to delete table.
94  virtual void SetInputSymbols(const SymbolTable *isyms) = 0;
95 
96  // Sets output label symbol table; pass nullptr to delete table.
97  virtual void SetOutputSymbols(const SymbolTable *osyms) = 0;
98 
99  // Gets a copy of this MutableFst. See Fst<>::Copy() for further doc.
100  MutableFst<A> *Copy(bool safe = false) const override = 0;
101 
102  // Reads a MutableFst from an input stream, returning nullptr on error.
103  static MutableFst<Arc> *Read(std::istream &strm, const FstReadOptions &opts) {
104  FstReadOptions ropts(opts);
105  FstHeader hdr;
106  if (ropts.header) {
107  hdr = *opts.header;
108  } else {
109  if (!hdr.Read(strm, opts.source)) return nullptr;
110  ropts.header = &hdr;
111  }
112  if (!(hdr.Properties() & kMutable)) {
113  LOG(ERROR) << "MutableFst::Read: Not a MutableFst: " << ropts.source;
114  return nullptr;
115  }
116  const auto &fst_type = hdr.FstType();
117  const auto reader = FstRegister<Arc>::GetRegister()->GetReader(fst_type);
118  if (!reader) {
119  LOG(ERROR) << "MutableFst::Read: Unknown FST type \"" << fst_type
120  << "\" (arc type = \"" << A::Type() << "\"): " << ropts.source;
121  return nullptr;
122  }
123  auto *fst = reader(strm, ropts);
124  if (!fst) return nullptr;
125  return static_cast<MutableFst<Arc> *>(fst);
126  }
127 
128  // Reads a MutableFst from a file; returns nullptr on error. An empty
129  // filename results in reading from standard input. If convert is true,
130  // convert to a mutable FST subclass (given by convert_type) in the case
131  // that the input FST is non-mutable.
132  static MutableFst<Arc> *Read(const string &filename, bool convert = false,
133  const string &convert_type = "vector") {
134  if (convert == false) {
135  if (!filename.empty()) {
136  std::ifstream strm(filename,
137  std::ios_base::in | std::ios_base::binary);
138  if (!strm) {
139  LOG(ERROR) << "MutableFst::Read: Can't open file: " << filename;
140  return nullptr;
141  }
142  return Read(strm, FstReadOptions(filename));
143  } else {
144  return Read(std::cin, FstReadOptions("standard input"));
145  }
146  } else { // Converts to 'convert_type' if not mutable.
147  std::unique_ptr<Fst<Arc>> ifst(Fst<Arc>::Read(filename));
148  if (!ifst) return nullptr;
149  if (ifst->Properties(kMutable, false)) {
150  return static_cast<MutableFst<Arc> *>(ifst.release());
151  } else {
152  std::unique_ptr<Fst<Arc>> ofst(Convert(*ifst, convert_type));
153  ifst.reset();
154  if (!ofst) return nullptr;
155  if (!ofst->Properties(kMutable, false)) {
156  LOG(ERROR) << "MutableFst: Bad convert type: " << convert_type;
157  }
158  return static_cast<MutableFst<Arc> *>(ofst.release());
159  }
160  }
161  }
162 
163  // For generic mutuble arc iterator construction; not normally called
164  // directly by users.
165  virtual void InitMutableArcIterator(StateId s,
166  MutableArcIteratorData<Arc> *data) = 0;
167 };
168 
169 // Mutable arc iterator interface, templated on the Arc definition. This is
170 // used by mutable arc iterator specializations that are returned by the
171 // InitMutableArcIterator MutableFst method.
172 template <class Arc>
174  public:
175  // Sets current arc.
176  virtual void SetValue(const Arc &) = 0;
177 };
178 
179 template <class Arc>
180 struct MutableArcIteratorData {
181  MutableArcIteratorBase<Arc> *base; // Specific iterator.
182 };
183 
184 // Generic mutable arc iterator, templated on the FST definition; a wrapper
185 // around a pointer to a more specific one.
186 //
187 // Here is a typical use:
188 //
189 // for (MutableArcIterator<StdFst> aiter(&fst, s);
190 // !aiter.Done();
191 // aiter.Next()) {
192 // StdArc arc = aiter.Value();
193 // arc.ilabel = 7;
194 // aiter.SetValue(arc);
195 // ...
196 // }
197 //
198 // This version requires function calls.
199 template <class FST>
201  public:
202  using Arc = typename FST::Arc;
203  using StateId = typename Arc::StateId;
204 
206  fst->InitMutableArcIterator(s, &data_);
207  }
208 
209  ~MutableArcIterator() { delete data_.base; }
210 
211  bool Done() const { return data_.base->Done(); }
212 
213  const Arc &Value() const { return data_.base->Value(); }
214 
215  void Next() { data_.base->Next(); }
216 
217  size_t Position() const { return data_.base->Position(); }
218 
219  void Reset() { data_.base->Reset(); }
220 
221  void Seek(size_t a) { data_.base->Seek(a); }
222 
223  void SetValue(const Arc &arc) { data_.base->SetValue(arc); }
224 
225  uint32 Flags() const { return data_.base->Flags(); }
226 
227  void SetFlags(uint32 flags, uint32 mask) {
228  return data_.base->SetFlags(flags, mask);
229  }
230 
231  private:
233 
234  MutableArcIterator(const MutableArcIterator &) = delete;
236 };
237 
238 namespace internal {
239 
240 // MutableFst<A> case: abstract methods.
241 template <class Arc>
242 inline typename Arc::Weight Final(const MutableFst<Arc> &fst,
243  typename Arc::StateId s) {
244  return fst.Final(s);
245 }
246 
247 template <class Arc>
248 inline ssize_t NumArcs(const MutableFst<Arc> &fst, typename Arc::StateId s) {
249  return fst.NumArcs(s);
250 }
251 
252 template <class Arc>
253 inline ssize_t NumInputEpsilons(const MutableFst<Arc> &fst,
254  typename Arc::StateId s) {
255  return fst.NumInputEpsilons(s);
256 }
257 
258 template <class Arc>
259 inline ssize_t NumOutputEpsilons(const MutableFst<Arc> &fst,
260  typename Arc::StateId s) {
261  return fst.NumOutputEpsilons(s);
262 }
263 
264 } // namespace internal
265 
266 // A useful alias when using StdArc.
268 
269 // This is a helper class template useful for attaching a MutableFst interface
270 // to its implementation, handling reference counting and COW semantics.
271 template <class Impl, class FST = MutableFst<typename Impl::Arc>>
272 class ImplToMutableFst : public ImplToExpandedFst<Impl, FST> {
273  public:
274  using Arc = typename Impl::Arc;
275  using StateId = typename Arc::StateId;
276  using Weight = typename Arc::Weight;
277 
279 
280  void SetStart(StateId s) override {
281  MutateCheck();
282  GetMutableImpl()->SetStart(s);
283  }
284 
285  void SetFinal(StateId s, Weight weight) override {
286  MutateCheck();
287  GetMutableImpl()->SetFinal(s, std::move(weight));
288  }
289 
290  void SetProperties(uint64 props, uint64 mask) override {
291  // Can skip mutate check if extrinsic properties don't change,
292  // since it is then safe to update all (shallow) copies
293  const auto exprops = kExtrinsicProperties & mask;
294  if (GetImpl()->Properties(exprops) != (props & exprops)) MutateCheck();
295  GetMutableImpl()->SetProperties(props, mask);
296  }
297 
298  StateId AddState() override {
299  MutateCheck();
300  return GetMutableImpl()->AddState();
301  }
302 
303  void AddArc(StateId s, const Arc &arc) override {
304  MutateCheck();
305  GetMutableImpl()->AddArc(s, arc);
306  }
307 
308  void AddArc(StateId s, Arc &&arc) override {
309  MutateCheck();
310  GetMutableImpl()->AddArc(s, std::move(arc));
311  }
312 
313  void DeleteStates(const std::vector<StateId> &dstates) override {
314  MutateCheck();
315  GetMutableImpl()->DeleteStates(dstates);
316  }
317 
318  void DeleteStates() override {
319  if (!Unique()) {
320  const auto *isymbols = GetImpl()->InputSymbols();
321  const auto *osymbols = GetImpl()->OutputSymbols();
322  SetImpl(std::make_shared<Impl>());
323  GetMutableImpl()->SetInputSymbols(isymbols);
324  GetMutableImpl()->SetOutputSymbols(osymbols);
325  } else {
326  GetMutableImpl()->DeleteStates();
327  }
328  }
329 
330  void DeleteArcs(StateId s, size_t n) override {
331  MutateCheck();
332  GetMutableImpl()->DeleteArcs(s, n);
333  }
334 
335  void DeleteArcs(StateId s) override {
336  MutateCheck();
337  GetMutableImpl()->DeleteArcs(s);
338  }
339 
340  void ReserveStates(StateId s) override {
341  MutateCheck();
342  GetMutableImpl()->ReserveStates(s);
343  }
344 
345  void ReserveArcs(StateId s, size_t n) override {
346  MutateCheck();
347  GetMutableImpl()->ReserveArcs(s, n);
348  }
349 
350  const SymbolTable *InputSymbols() const override {
351  return GetImpl()->InputSymbols();
352  }
353 
354  const SymbolTable *OutputSymbols() const override {
355  return GetImpl()->OutputSymbols();
356  }
357 
359  MutateCheck();
360  return GetMutableImpl()->InputSymbols();
361  }
362 
364  MutateCheck();
365  return GetMutableImpl()->OutputSymbols();
366  }
367 
368  void SetInputSymbols(const SymbolTable *isyms) override {
369  MutateCheck();
370  GetMutableImpl()->SetInputSymbols(isyms);
371  }
372 
373  void SetOutputSymbols(const SymbolTable *osyms) override {
374  MutateCheck();
375  GetMutableImpl()->SetOutputSymbols(osyms);
376  }
377 
378  protected:
384 
385  explicit ImplToMutableFst(std::shared_ptr<Impl> impl)
386  : ImplToExpandedFst<Impl, FST>(impl) {}
387 
389  : ImplToExpandedFst<Impl, FST>(fst, safe) {}
390 
391  void MutateCheck() {
392  if (!Unique()) SetImpl(std::make_shared<Impl>(*this));
393  }
394 };
395 
396 } // namespace fst
397 
398 #endif // FST_MUTABLE_FST_H_
void DeleteArcs(StateId s, size_t n) override
Definition: mutable-fst.h:330
void ReserveArcs(StateId s, size_t n) override
Definition: mutable-fst.h:345
void DeleteStates() override
Definition: mutable-fst.h:318
void AddArc(StateId s, const Arc &arc) override
Definition: mutable-fst.h:303
void SetStart(StateId s) override
Definition: mutable-fst.h:280
const FstHeader * header
Definition: fst.h:58
void SetProperties(uint64 props, uint64 mask) override
Definition: mutable-fst.h:290
uint64_t uint64
Definition: types.h:32
virtual SymbolTable * MutableOutputSymbols()=0
void SetFinal(StateId s, Weight weight) override
Definition: mutable-fst.h:285
virtual size_t NumArcs(StateId) const =0
const SymbolTable * OutputSymbols() const override
Definition: mutable-fst.h:354
typename fst::MutableFst< Arc >::Arc Arc
Definition: mutable-fst.h:202
uint32 Flags() const
Definition: mutable-fst.h:225
MutableFst< Arc > & operator=(const MutableFst< Arc > &fst)
Definition: mutable-fst.h:40
virtual void AddArc(StateId, const Arc &arc)=0
typename Arc::Weight Weight
Definition: fst.h:190
virtual void InitMutableArcIterator(StateId s, MutableArcIteratorData< Arc > *data)=0
const SymbolTable * InputSymbols() const override=0
virtual void SetInputSymbols(const SymbolTable *isyms)=0
#define LOG(type)
Definition: log.h:48
virtual Weight Final(StateId) const =0
Fst< Arc > * Convert(const Fst< Arc > &fst, const string &fst_type)
Definition: register.h:102
SymbolTable * MutableOutputSymbols() override
Definition: mutable-fst.h:363
virtual void SetStart(StateId)=0
void DeleteArcs(StateId s) override
Definition: mutable-fst.h:335
void SetValue(const Arc &arc)
Definition: mutable-fst.h:223
SymbolTable * MutableInputSymbols() override
Definition: mutable-fst.h:358
const Arc & Value() const
Definition: mutable-fst.h:213
virtual uint64 Properties(uint64 mask, bool test) const =0
virtual size_t NumInputEpsilons(StateId) const =0
MutableArcIterator(FST *fst, StateId s)
Definition: mutable-fst.h:205
StateId AddState() override
Definition: mutable-fst.h:298
ImplToMutableFst(const ImplToMutableFst< Impl, FST > &fst, bool safe)
Definition: mutable-fst.h:388
const SymbolTable * OutputSymbols() const override=0
void SetOutputSymbols(const SymbolTable *osyms) override
Definition: mutable-fst.h:373
virtual void ReserveArcs(StateId s, size_t n)
Definition: mutable-fst.h:79
virtual void SetFinal(StateId, Weight)=0
void Seek(size_t a)
Definition: mutable-fst.h:221
bool Read(std::istream &strm, const string &source, bool rewind=false)
Definition: fst.cc:58
void SetInputSymbols(const SymbolTable *isyms) override
Definition: mutable-fst.h:368
virtual void AddArc(StateId state, Arc &&arc)
Definition: mutable-fst.h:61
void ReserveStates(StateId s) override
Definition: mutable-fst.h:340
virtual void DeleteArcs(StateId, size_t n)=0
string source
Definition: fst.h:57
void DeleteStates(const std::vector< StateId > &dstates) override
Definition: mutable-fst.h:313
typename Arc::StateId StateId
Definition: expanded-fst.h:27
virtual void ReserveStates(StateId n)
Definition: mutable-fst.h:76
const string & FstType() const
Definition: fst.h:119
virtual MutableFst< Arc > & operator=(const Fst< Arc > &fst)=0
virtual SymbolTable * MutableInputSymbols()=0
uint32_t uint32
Definition: types.h:31
A Arc
Definition: fst.h:188
ImplToMutableFst(std::shared_ptr< Impl > impl)
Definition: mutable-fst.h:385
MutableArcIteratorBase< Arc > * base
Definition: mutable-fst.h:181
size_t Position() const
Definition: mutable-fst.h:217
virtual StateId AddState()=0
const SymbolTable * InputSymbols() const override
Definition: mutable-fst.h:350
typename Arc::StateId StateId
Definition: fst.h:189
virtual void SetOutputSymbols(const SymbolTable *osyms)=0
static MutableFst< Arc > * Read(std::istream &strm, const FstReadOptions &opts)
Definition: mutable-fst.h:103
constexpr uint64 kMutable
Definition: properties.h:30
virtual size_t NumOutputEpsilons(StateId) const =0
void AddArc(StateId s, Arc &&arc) override
Definition: mutable-fst.h:308
virtual void DeleteStates()=0
constexpr uint64 kExtrinsicProperties
Definition: properties.h:160
uint64 Properties() const
Definition: fst.h:127
void SetFlags(uint32 flags, uint32 mask)
Definition: mutable-fst.h:227
static MutableFst< Arc > * Read(const string &filename, bool convert=false, const string &convert_type="vector")
Definition: mutable-fst.h:132
MutableFst< A > * Copy(bool safe=false) const override=0
virtual void SetProperties(uint64 props, uint64 mask)=0