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