FST  openfst-1.8.3
OpenFst Library
rmepsilon.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 // Functions and classes that implemement epsilon-removal.
19 
20 #ifndef FST_RMEPSILON_H_
21 #define FST_RMEPSILON_H_
22 
23 #include <cstddef>
24 #include <cstdint>
25 #include <memory>
26 #include <stack>
27 #include <string>
28 #include <utility>
29 #include <vector>
30 
31 #include <fst/log.h>
32 #include <fst/arc.h>
33 #include <fst/arcfilter.h>
34 #include <fst/cache.h>
35 #include <fst/cc-visitors.h>
36 #include <fst/connect.h>
37 #include <fst/dfs-visit.h>
38 #include <fst/factor-weight.h>
39 #include <fst/float-weight.h>
40 #include <fst/fst.h>
41 #include <fst/impl-to-fst.h>
42 #include <fst/invert.h>
43 #include <fst/mutable-fst.h>
44 #include <fst/properties.h>
45 #include <fst/prune.h>
46 #include <fst/queue.h>
47 #include <fst/shortest-distance.h>
48 #include <fst/topsort.h>
49 #include <fst/util.h>
50 #include <fst/weight.h>
51 #include <unordered_map>
52 
53 namespace fst {
54 
55 template <class Arc, class Queue>
57  : public ShortestDistanceOptions<Arc, Queue, EpsilonArcFilter<Arc>> {
58  using StateId = typename Arc::StateId;
59  using Weight = typename Arc::Weight;
60 
61  bool connect; // Connect output
62  Weight weight_threshold; // Pruning weight threshold.
63  StateId state_threshold; // Pruning state threshold.
64 
65  explicit RmEpsilonOptions(Queue *queue, float delta = kShortestDelta,
66  bool connect = true,
67  Weight weight_threshold = Weight::Zero(),
68  StateId state_threshold = kNoStateId)
69  : ShortestDistanceOptions<Arc, Queue, EpsilonArcFilter<Arc>>(
70  queue, EpsilonArcFilter<Arc>(), kNoStateId, delta),
71  connect(connect),
72  weight_threshold(std::move(weight_threshold)),
73  state_threshold(state_threshold) {}
74 };
75 
76 namespace internal {
77 
78 // Computation state of the epsilon-removal algorithm.
79 template <class Arc, class Queue>
81  public:
82  using Label = typename Arc::Label;
83  using StateId = typename Arc::StateId;
84  using Weight = typename Arc::Weight;
85 
86  RmEpsilonState(const Fst<Arc> &fst, std::vector<Weight> *distance,
87  const RmEpsilonOptions<Arc, Queue> &opts)
88  : fst_(fst),
89  distance_(distance),
90  sd_state_(fst_, distance, opts, true),
91  expand_id_(0) {}
92 
93  void Expand(StateId s);
94 
95  std::vector<Arc> &Arcs() { return arcs_; }
96 
97  const Weight &Final() const { return final_weight_; }
98 
99  bool Error() const { return sd_state_.Error(); }
100 
101  private:
102  struct Element {
103  Label ilabel;
104  Label olabel;
105  StateId nextstate;
106 
107  Element() = default;
108 
109  Element(Label ilabel, Label olabel, StateId nexstate)
110  : ilabel(ilabel), olabel(olabel), nextstate(nexstate) {}
111  };
112 
113  struct ElementHash {
114  public:
115  size_t operator()(const Element &element) const {
116  static constexpr size_t prime0 = 7853;
117  static constexpr size_t prime1 = 7867;
118  return static_cast<size_t>(element.nextstate) +
119  static_cast<size_t>(element.ilabel) * prime0 +
120  static_cast<size_t>(element.olabel) * prime1;
121  }
122  };
123 
124  class ElementEqual {
125  public:
126  bool operator()(const Element &e1, const Element &e2) const {
127  return (e1.ilabel == e2.ilabel) && (e1.olabel == e2.olabel) &&
128  (e1.nextstate == e2.nextstate);
129  }
130  };
131 
132  using ElementMap = std::unordered_map<Element, std::pair<StateId, size_t>,
133  ElementHash, ElementEqual>;
134 
135  const Fst<Arc> &fst_;
136  // Distance from state being expanded in epsilon-closure.
137  std::vector<Weight> *distance_;
138  // Shortest distance algorithm computation state.
140  // Maps an element to a pair corresponding to a position in the arcs vector
141  // of the state being expanded. The element corresopnds to the position in
142  // the arcs_ vector if p.first is equal to the state being expanded.
143  ElementMap element_map_;
144  EpsilonArcFilter<Arc> eps_filter_;
145  std::stack<StateId, std::vector<StateId>>
146  eps_queue_; // Queue used to visit the epsilon-closure.
147  std::vector<bool> visited_; // True if the state has been visited.
148  std::vector<StateId> visited_states_; // List of visited states.
149  std::vector<Arc> arcs_; // Arcs of state being expanded.
150  Weight final_weight_; // Final weight of state being expanded.
151  StateId expand_id_; // Unique ID for each call to Expand
152 
153  RmEpsilonState(const RmEpsilonState &) = delete;
154  RmEpsilonState &operator=(const RmEpsilonState &) = delete;
155 };
156 
157 template <class Arc, class Queue>
158 void RmEpsilonState<Arc, Queue>::Expand(typename Arc::StateId source) {
159  final_weight_ = Weight::Zero();
160  arcs_.clear();
161  sd_state_.ShortestDistance(source);
162  if (sd_state_.Error()) return;
163  eps_queue_.push(source);
164  while (!eps_queue_.empty()) {
165  const auto state = eps_queue_.top();
166  eps_queue_.pop();
167  if (static_cast<decltype(state)>(visited_.size()) <= state) {
168  visited_.resize(state + 1, false);
169  }
170  if (visited_[state]) continue;
171  visited_[state] = true;
172  visited_states_.push_back(state);
173  for (ArcIterator<Fst<Arc>> aiter(fst_, state); !aiter.Done();
174  aiter.Next()) {
175  auto arc = aiter.Value();
176  arc.weight = Times((*distance_)[state], arc.weight);
177  if (eps_filter_(arc)) {
178  if (static_cast<decltype(arc.nextstate)>(visited_.size()) <=
179  arc.nextstate) {
180  visited_.resize(arc.nextstate + 1, false);
181  }
182  if (!visited_[arc.nextstate]) eps_queue_.push(arc.nextstate);
183  } else if (auto [insert_it, success] = element_map_.emplace(
184  Element(arc.ilabel, arc.olabel, arc.nextstate),
185  std::make_pair(expand_id_, arcs_.size()));
186  success) {
187  arcs_.push_back(std::move(arc));
188  } else if (auto &[xid, arc_idx] = insert_it->second; xid == expand_id_) {
189  auto &weight = arcs_[arc_idx].weight;
190  weight = Plus(weight, arc.weight);
191  } else {
192  xid = expand_id_;
193  arc_idx = arcs_.size();
194  arcs_.push_back(std::move(arc));
195  }
196  }
197  final_weight_ =
198  Plus(final_weight_, Times((*distance_)[state], fst_.Final(state)));
199  }
200 
201  for (const auto state_id : visited_states_) visited_[state_id] = false;
202  visited_states_.clear();
203  ++expand_id_;
204 }
205 
206 } // namespace internal
207 
208 // Removes epsilon-transitions (when both the input and output label are an
209 // epsilon) from a transducer. The result will be an equivalent FST that has no
210 // such epsilon transitions. This version modifies its input. It allows fine
211 // control via the options argument; see below for a simpler interface.
212 //
213 // The distance vector will be used to hold the shortest distances during the
214 // epsilon-closure computation. The state queue discipline and convergence delta
215 // are taken in the options argument.
216 template <class Arc, class Queue>
218  std::vector<typename Arc::Weight> *distance,
219  const RmEpsilonOptions<Arc, Queue> &opts) {
220  using StateId = typename Arc::StateId;
221  using Weight = typename Arc::Weight;
222  if (fst->Start() == kNoStateId) return;
223  // noneps_in[s] will be set to true iff s admits a non-epsilon incoming
224  // transition or is the start state.
225  std::vector<bool> noneps_in(fst->NumStates(), false);
226  noneps_in[fst->Start()] = true;
227  for (size_t i = 0; i < fst->NumStates(); ++i) {
228  for (ArcIterator<Fst<Arc>> aiter(*fst, i); !aiter.Done(); aiter.Next()) {
229  const auto &arc = aiter.Value();
230  if (arc.ilabel != 0 || arc.olabel != 0) {
231  noneps_in[arc.nextstate] = true;
232  }
233  }
234  }
235  // States sorted in topological order when (acyclic) or generic topological
236  // order (cyclic).
237  std::vector<StateId> states;
238  states.reserve(fst->NumStates());
239  if (fst->Properties(kTopSorted, false) & kTopSorted) {
240  for (size_t i = 0; i < fst->NumStates(); i++) states.push_back(i);
241  } else if (fst->Properties(kAcyclic, false) & kAcyclic) {
242  std::vector<StateId> order;
243  bool acyclic;
244  TopOrderVisitor<Arc> top_order_visitor(&order, &acyclic);
245  DfsVisit(*fst, &top_order_visitor, EpsilonArcFilter<Arc>());
246  // Sanity check: should be acyclic if property bit is set.
247  if (!acyclic) {
248  FSTERROR() << "RmEpsilon: Inconsistent acyclic property bit";
249  fst->SetProperties(kError, kError);
250  return;
251  }
252  states.resize(order.size());
253  for (StateId i = 0; i < order.size(); i++) states[order[i]] = i;
254  } else {
255  uint64_t props;
256  std::vector<StateId> scc;
257  SccVisitor<Arc> scc_visitor(&scc, nullptr, nullptr, &props);
258  DfsVisit(*fst, &scc_visitor, EpsilonArcFilter<Arc>());
259  std::vector<StateId> first(scc.size(), kNoStateId);
260  std::vector<StateId> next(scc.size(), kNoStateId);
261  for (StateId i = 0; i < scc.size(); i++) {
262  if (first[scc[i]] != kNoStateId) next[i] = first[scc[i]];
263  first[scc[i]] = i;
264  }
265  for (StateId i = 0; i < first.size(); i++) {
266  for (auto j = first[i]; j != kNoStateId; j = next[j]) {
267  states.push_back(j);
268  }
269  }
270  }
271  internal::RmEpsilonState<Arc, Queue> rmeps_state(*fst, distance, opts);
272  while (!states.empty()) {
273  const auto state = states.back();
274  states.pop_back();
275  if (!noneps_in[state] &&
276  (opts.connect || opts.weight_threshold != Weight::Zero() ||
277  opts.state_threshold != kNoStateId)) {
278  continue;
279  }
280  rmeps_state.Expand(state);
281  fst->SetFinal(state, rmeps_state.Final());
282  fst->DeleteArcs(state);
283  auto &arcs = rmeps_state.Arcs();
284  fst->ReserveArcs(state, arcs.size());
285  while (!arcs.empty()) {
286  fst->AddArc(state, arcs.back());
287  arcs.pop_back();
288  }
289  }
290  if (opts.connect || opts.weight_threshold != Weight::Zero() ||
291  opts.state_threshold != kNoStateId) {
292  for (size_t s = 0; s < fst->NumStates(); ++s) {
293  if (!noneps_in[s]) fst->DeleteArcs(s);
294  }
295  }
296  if (rmeps_state.Error()) fst->SetProperties(kError, kError);
297  fst->SetProperties(
300  if (opts.weight_threshold != Weight::Zero() ||
301  opts.state_threshold != kNoStateId) {
302  if constexpr (IsPath<Weight>::value) {
303  Prune(fst, opts.weight_threshold, opts.state_threshold);
304  } else {
305  FSTERROR() << "RmEpsilon: Weight must have path property: "
306  << Weight::Type();
307  fst->SetProperties(kError, kError);
308  return;
309  }
310  }
311  if (opts.connect && opts.weight_threshold == Weight::Zero() &&
312  opts.state_threshold == kNoStateId) {
313  Connect(fst);
314  }
315 }
316 
317 // Removes epsilon-transitions (when both the input and output label
318 // are an epsilon) from a transducer. The result will be an equivalent
319 // FST that has no such epsilon transitions. This version modifies its
320 // input. It has a simplified interface; see above for a version that
321 // allows finer control.
322 //
323 // Complexity:
324 //
325 // - Time:
326 //
327 // Unweighted: O(v^2 + ve).
328 // Acyclic: O(v^2 + V e).
329 // Tropical semiring: O(v^2 log V + ve).
330 // General: exponential.
331 //
332 // - Space: O(vE)
333 //
334 // where v is the number of states visited and e is the number of arcs visited.
335 //
336 // For more information, see:
337 //
338 // Mohri, M. 2002. Generic epsilon-removal and input epsilon-normalization
339 // algorithms for weighted transducers. International Journal of Computer
340 // Science 13(1): 129-143.
341 template <class Arc>
342 void RmEpsilon(MutableFst<Arc> *fst, bool connect = true,
343  typename Arc::Weight weight_threshold = Arc::Weight::Zero(),
344  typename Arc::StateId state_threshold = kNoStateId,
345  float delta = kShortestDelta) {
346  using StateId = typename Arc::StateId;
347  using Weight = typename Arc::Weight;
348  std::vector<Weight> distance;
351  &state_queue, delta, connect, weight_threshold, state_threshold);
352  RmEpsilon(fst, &distance, opts);
353 }
354 
356  float delta;
357 
358  explicit RmEpsilonFstOptions(const CacheOptions &opts,
359  float delta = kShortestDelta)
360  : CacheOptions(opts), delta(delta) {}
361 
362  explicit RmEpsilonFstOptions(float delta = kShortestDelta) : delta(delta) {}
363 };
364 
365 namespace internal {
366 
367 // Implementation of delayed RmEpsilonFst.
368 template <class Arc>
369 class RmEpsilonFstImpl : public CacheImpl<Arc> {
370  public:
371  using StateId = typename Arc::StateId;
372  using Weight = typename Arc::Weight;
373 
375  using State = typename Store::State;
376 
378  using FstImpl<Arc>::SetType;
382 
383  using CacheBaseImpl<CacheState<Arc>>::HasArcs;
384  using CacheBaseImpl<CacheState<Arc>>::HasFinal;
385  using CacheBaseImpl<CacheState<Arc>>::HasStart;
386  using CacheBaseImpl<CacheState<Arc>>::PushArc;
387  using CacheBaseImpl<CacheState<Arc>>::SetArcs;
388  using CacheBaseImpl<CacheState<Arc>>::SetFinal;
389  using CacheBaseImpl<CacheState<Arc>>::SetStart;
390 
392  : CacheImpl<Arc>(opts),
393  fst_(fst.Copy()),
394  delta_(opts.delta),
395  rmeps_state_(
396  *fst_, &distance_,
397  RmEpsilonOptions<Arc, FifoQueue<StateId>>(&queue_, delta_, false)) {
398  SetType("rmepsilon");
399  SetProperties(
400  RmEpsilonProperties(fst.Properties(kFstProperties, false), true),
402  SetInputSymbols(fst.InputSymbols());
403  SetOutputSymbols(fst.OutputSymbols());
404  }
405 
407  : CacheImpl<Arc>(impl),
408  fst_(impl.fst_->Copy(true)),
409  delta_(impl.delta_),
410  rmeps_state_(
411  *fst_, &distance_,
412  RmEpsilonOptions<Arc, FifoQueue<StateId>>(&queue_, delta_, false)) {
413  SetType("rmepsilon");
414  SetProperties(impl.Properties(), kCopyProperties);
415  SetInputSymbols(impl.InputSymbols());
416  SetOutputSymbols(impl.OutputSymbols());
417  }
418 
420  if (!HasStart()) SetStart(fst_->Start());
421  return CacheImpl<Arc>::Start();
422  }
423 
425  if (!HasFinal(s)) Expand(s);
426  return CacheImpl<Arc>::Final(s);
427  }
428 
429  size_t NumArcs(StateId s) {
430  if (!HasArcs(s)) Expand(s);
431  return CacheImpl<Arc>::NumArcs(s);
432  }
433 
435  if (!HasArcs(s)) Expand(s);
437  }
438 
440  if (!HasArcs(s)) Expand(s);
442  }
443 
444  uint64_t Properties() const override { return Properties(kFstProperties); }
445 
446  // Sets error if found and returns other FST impl properties.
447  uint64_t Properties(uint64_t mask) const override {
448  if ((mask & kError) &&
449  (fst_->Properties(kError, false) || rmeps_state_.Error())) {
450  SetProperties(kError, kError);
451  }
452  return FstImpl<Arc>::Properties(mask);
453  }
454 
456  if (!HasArcs(s)) Expand(s);
458  }
459 
460  void Expand(StateId s) {
461  rmeps_state_.Expand(s);
462  SetFinal(s, rmeps_state_.Final());
463  auto &arcs = rmeps_state_.Arcs();
464  while (!arcs.empty()) {
465  PushArc(s, std::move(arcs.back()));
466  arcs.pop_back();
467  }
468  SetArcs(s);
469  }
470 
471  private:
472  std::unique_ptr<const Fst<Arc>> fst_;
473  float delta_;
474  std::vector<Weight> distance_;
475  FifoQueue<StateId> queue_;
477 };
478 
479 } // namespace internal
480 
481 // Removes epsilon-transitions (when both the input and output label are an
482 // epsilon) from a transducer. The result will be an equivalent FST that has no
483 // such epsilon transitions. This version is a
484 // delayed FST.
485 //
486 // Complexity:
487 //
488 // - Time:
489 // Unweighted: O(v^2 + ve).
490 // General: exponential.
491 //
492 // - Space: O(vE)
493 //
494 // where v is the number of states visited and e is the number of arcs visited.
495 // Constant time to visit an input state or arc is assumed and exclusive of
496 // caching.
497 //
498 // For more information, see:
499 //
500 // Mohri, M. 2002. Generic epsilon-removal and input epsilon-normalization
501 // algorithms for weighted transducers. International Journal of Computer
502 // Science 13(1): 129-143.
503 //
504 // This class attaches interface to implementation and handles
505 // reference counting, delegating most methods to ImplToFst.
506 template <class A>
507 class RmEpsilonFst : public ImplToFst<internal::RmEpsilonFstImpl<A>> {
508  public:
509  using Arc = A;
510  using StateId = typename Arc::StateId;
511 
513  using State = typename Store::State;
515 
516  friend class ArcIterator<RmEpsilonFst<Arc>>;
518 
519  explicit RmEpsilonFst(const Fst<Arc> &fst)
520  : ImplToFst<Impl>(std::make_shared<Impl>(fst, RmEpsilonFstOptions())) {}
521 
522  RmEpsilonFst(const Fst<A> &fst, const RmEpsilonFstOptions &opts)
523  : ImplToFst<Impl>(std::make_shared<Impl>(fst, opts)) {}
524 
525  // See Fst<>::Copy() for doc.
526  RmEpsilonFst(const RmEpsilonFst &fst, bool safe = false)
527  : ImplToFst<Impl>(fst, safe) {}
528 
529  // Get a copy of this RmEpsilonFst. See Fst<>::Copy() for further doc.
530  RmEpsilonFst *Copy(bool safe = false) const override {
531  return new RmEpsilonFst(*this, safe);
532  }
533 
534  inline void InitStateIterator(StateIteratorData<Arc> *data) const override;
535 
536  void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const override {
537  GetMutableImpl()->InitArcIterator(s, data);
538  }
539 
540  private:
543 
544  RmEpsilonFst &operator=(const RmEpsilonFst &) = delete;
545 };
546 
547 // Specialization for RmEpsilonFst.
548 template <class Arc>
550  : public CacheStateIterator<RmEpsilonFst<Arc>> {
551  public:
552  explicit StateIterator(const RmEpsilonFst<Arc> &fst)
553  : CacheStateIterator<RmEpsilonFst<Arc>>(fst, fst.GetMutableImpl()) {}
554 };
555 
556 // Specialization for RmEpsilonFst.
557 template <class Arc>
559  : public CacheArcIterator<RmEpsilonFst<Arc>> {
560  public:
561  using StateId = typename Arc::StateId;
562 
564  : CacheArcIterator<RmEpsilonFst<Arc>>(fst.GetMutableImpl(), s) {
565  if (!fst.GetImpl()->HasArcs(s)) fst.GetMutableImpl()->Expand(s);
566  }
567 };
568 
569 template <class Arc>
571  StateIteratorData<Arc> *data) const {
572  data->base = std::make_unique<StateIterator<RmEpsilonFst<Arc>>>(*this);
573 }
574 
575 // Useful alias when using StdArc.
577 
578 } // namespace fst
579 
580 #endif // FST_RMEPSILON_H_
RmEpsilonState(const Fst< Arc > &fst, std::vector< Weight > *distance, const RmEpsilonOptions< Arc, Queue > &opts)
Definition: rmepsilon.h:86
ssize_t NumOutputEpsilons(const ExpandedFst< Arc > &fst, typename Arc::StateId s)
Definition: expanded-fst.h:124
uint64_t Properties() const override
Definition: rmepsilon.h:444
void RmEpsilon(MutableFst< Arc > *fst, std::vector< typename Arc::Weight > *distance, const RmEpsilonOptions< Arc, Queue > &opts)
Definition: rmepsilon.h:217
typename Arc::Weight Weight
Definition: rmepsilon.h:372
virtual uint64_t Properties(uint64_t mask, bool test) const =0
void InitArcIterator(StateId s, ArcIteratorData< Arc > *data)
Definition: rmepsilon.h:455
ErrorWeight Plus(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:61
size_t NumOutputEpsilons(StateId s)
Definition: rmepsilon.h:439
uint64_t RmEpsilonProperties(uint64_t inprops, bool delayed=false)
Definition: properties.cc:358
RmEpsilonFst(const RmEpsilonFst &fst, bool safe=false)
Definition: rmepsilon.h:526
const Weight & Final() const
Definition: rmepsilon.h:97
void InitStateIterator(StateIteratorData< Arc > *data) const override
Definition: rmepsilon.h:570
Arc::Weight Final(const ExpandedFst< Arc > &fst, typename Arc::StateId s)
Definition: expanded-fst.h:107
const SymbolTable * OutputSymbols() const
Definition: fst.h:761
ErrorWeight Times(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:64
constexpr uint64_t kError
Definition: properties.h:52
void DfsVisit(const FST &fst, Visitor *visitor, ArcFilter filter, bool access_only=false)
Definition: dfs-visit.h:112
typename Store::State State
Definition: rmepsilon.h:513
SetType
Definition: set-weight.h:59
typename RmEpsilonFst< Arc >::Arc Arc
Definition: cache.h:1156
void Connect(MutableFst< Arc > *fst)
Definition: connect.h:47
ssize_t NumArcs(const ExpandedFst< Arc > &fst, typename Arc::StateId s)
Definition: expanded-fst.h:113
constexpr uint64_t kTopSorted
Definition: properties.h:119
constexpr int kNoStateId
Definition: fst.h:196
void Prune(MutableFst< Arc > *fst, const PruneOptions< Arc, ArcFilter > &opts=PruneOptions< Arc, ArcFilter >())
Definition: prune.h:114
virtual void ReserveArcs(StateId, size_t)
Definition: mutable-fst.h:104
#define FSTERROR()
Definition: util.h:56
size_t NumInputEpsilons(StateId s)
Definition: rmepsilon.h:434
RmEpsilonFst(const Fst< A > &fst, const RmEpsilonFstOptions &opts)
Definition: rmepsilon.h:522
ArcIterator(const RmEpsilonFst< Arc > &fst, StateId s)
Definition: rmepsilon.h:563
ssize_t NumInputEpsilons(const ExpandedFst< Arc > &fst, typename Arc::StateId s)
Definition: expanded-fst.h:118
RmEpsilonFstOptions(const CacheOptions &opts, float delta=kShortestDelta)
Definition: rmepsilon.h:358
RmEpsilonFst * Copy(bool safe=false) const override
Definition: rmepsilon.h:530
std::vector< Arc > & Arcs()
Definition: rmepsilon.h:95
constexpr uint64_t kCopyProperties
Definition: properties.h:163
constexpr uint64_t kAcyclic
Definition: properties.h:111
virtual void SetProperties(uint64_t props, uint64_t mask)=0
typename FirstCacheStore< VectorCacheStore< CacheState< Arc > > >::State State
Definition: cache.h:673
virtual void DeleteArcs(StateId, size_t)=0
virtual StateId Start() const =0
size_t NumArcs(StateId s)
Definition: rmepsilon.h:429
RmEpsilonOptions(Queue *queue, float delta=kShortestDelta, bool connect=true, Weight weight_threshold=Weight::Zero(), StateId state_threshold=kNoStateId)
Definition: rmepsilon.h:65
std::unique_ptr< StateIteratorBase< Arc > > base
Definition: fst.h:382
constexpr float kShortestDelta
void Expand(const FstClass &ifst, const std::vector< std::pair< int64_t, int64_t >> &parens, const std::vector< int64_t > &assignments, MutableFstClass *ofst, const MPdtExpandOptions &opts)
Definition: mpdtscript.cc:55
typename Arc::StateId StateId
Definition: rmepsilon.h:371
RmEpsilonFstImpl(const Fst< Arc > &fst, const RmEpsilonFstOptions &opts)
Definition: rmepsilon.h:391
constexpr uint64_t kFstProperties
Definition: properties.h:326
virtual void AddArc(StateId, const Arc &)=0
typename Arc::Weight Weight
Definition: rmepsilon.h:59
RmEpsilonFstImpl(const RmEpsilonFstImpl &impl)
Definition: rmepsilon.h:406
typename internal::RmEpsilonFstImpl< Arc >::Arc Arc
Definition: fst.h:205
void InitArcIterator(StateId s, ArcIteratorData< Arc > *data) const override
Definition: rmepsilon.h:536
RmEpsilonFst(const Fst< Arc > &fst)
Definition: rmepsilon.h:519
typename RmEpsilonFst< Arc >::Arc Arc
Definition: cache.h:1202
virtual const SymbolTable * InputSymbols() const =0
const SymbolTable * InputSymbols() const
Definition: fst.h:759
typename Arc::StateId StateId
Definition: rmepsilon.h:58
virtual void SetFinal(StateId s, Weight weight=Weight::One())=0
void Expand(const Fst< Arc > &ifst, const std::vector< std::pair< typename Arc::Label, typename Arc::Label >> &parens, const std::vector< typename Arc::Label > &assignments, MutableFst< Arc > *ofst, const MPdtExpandOptions &opts)
Definition: expand.h:323
uint64_t Properties(uint64_t mask) const override
Definition: rmepsilon.h:447
StateId state_threshold
Definition: rmepsilon.h:63
StateIterator(const RmEpsilonFst< Arc > &fst)
Definition: rmepsilon.h:552
typename CacheState< Arc >::Arc Arc
Definition: cache.h:859
Impl * GetMutableImpl() const
Definition: impl-to-fst.h:125
RmEpsilonFstOptions(float delta=kShortestDelta)
Definition: rmepsilon.h:362
virtual StateId NumStates() const =0
std::bool_constant<(W::Properties()&kPath)!=0 > IsPath
Definition: weight.h:162
const Impl * GetImpl() const
Definition: impl-to-fst.h:123
virtual const SymbolTable * OutputSymbols() const =0