FST  openfst-1.8.3
OpenFst Library
disambiguate.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 to disambiguate an FST.
19 
20 #ifndef FST_DISAMBIGUATE_H_
21 #define FST_DISAMBIGUATE_H_
22 
23 #include <sys/types.h>
24 
25 #include <cstdint>
26 #include <list>
27 #include <map>
28 #include <memory>
29 #include <set>
30 #include <utility>
31 #include <vector>
32 
33 #include <fst/log.h>
34 #include <fst/arcsort.h>
35 #include <fst/cc-visitors.h>
36 #include <fst/compose-filter.h>
37 #include <fst/compose.h>
38 #include <fst/connect.h>
39 #include <fst/determinize.h>
40 #include <fst/dfs-visit.h>
41 #include <fst/expanded-fst.h>
42 #include <fst/filter-state.h>
43 #include <fst/fst.h>
44 #include <fst/matcher.h>
45 #include <fst/mutable-fst.h>
46 #include <fst/project.h>
47 #include <fst/properties.h>
48 #include <fst/prune.h>
49 #include <fst/state-map.h>
50 #include <fst/state-table.h>
51 #include <fst/union-find.h>
52 #include <fst/util.h>
53 #include <fst/vector-fst.h>
54 #include <fst/verify.h>
55 #include <fst/weight.h>
56 
57 namespace fst {
58 
59 template <class Arc>
61  using Label = typename Arc::Label;
62  using StateId = typename Arc::StateId;
63  using Weight = typename Arc::Weight;
64 
65  explicit DisambiguateOptions(float delta = kDelta,
66  Weight weight = Weight::Zero(),
67  StateId n = kNoStateId, Label label = 0)
68  : DeterminizeOptions<Arc>(delta, std::move(weight), n, label,
70 };
71 
72 namespace internal {
73 
74 // A determinization filter based on a subset element relation. The relation is
75 // assumed to be reflexive and symmetric.
76 template <class Arc, class Relation>
77 class RelationDeterminizeFilter {
78  public:
79  using Label = typename Arc::Label;
80  using StateId = typename Arc::StateId;
81  using Weight = typename Arc::Weight;
82 
85  using Subset = typename StateTuple::Subset;
86  using Element = typename StateTuple::Element;
87  using LabelMap = std::multimap<Label, DeterminizeArc<StateTuple>>;
88 
89  // This is needed (e.g.) to go into the gallic domain for transducers; there
90  // is no need to rebind the relation since its use here only depends on the
91  // state IDs.
92  template <class A>
93  struct rebind {
95  };
96 
98  : fst_(fst.Copy()),
99  head_(nullptr),
100  r_(std::make_unique<Relation>()),
101  s_(kNoStateId) {}
102 
103  RelationDeterminizeFilter(const Fst<Arc> &fst, std::unique_ptr<Relation> r,
104  std::vector<StateId> *head = nullptr)
105  : fst_(fst.Copy()), head_(head), r_(std::move(r)), s_(kNoStateId) {}
106 
107  // This is needed, e.g., to go into the gallic domain for transducers.
108  template <class Filter>
109  RelationDeterminizeFilter(const Fst<Arc> &fst, std::unique_ptr<Filter> filter)
110  : fst_(fst.Copy()),
111  head_(filter->GetHeadStates()),
112  r_(std::move(*filter).GetRelation()),
113  s_(kNoStateId) {}
114 
115  // Copy constructor; the FST can be passed if it has been deep-copied.
117  const Fst<Arc> *fst = nullptr)
118  : fst_(fst ? fst->Copy() : filter.fst_->Copy()),
119  head_(nullptr),
120  r_(std::make_unique<Relation>(*filter.r_)),
121  s_(kNoStateId) {}
122 
123  FilterState Start() const { return FilterState(fst_->Start()); }
124 
125  void SetState(StateId s, const StateTuple &tuple) {
126  if (s_ != s) {
127  s_ = s;
128  tuple_ = &tuple;
129  const auto head = tuple.filter_state.GetState();
130  is_final_ = fst_->Final(head) != Weight::Zero();
131  if (head_) {
132  if (head_->size() <= s) head_->resize(s + 1, kNoStateId);
133  (*head_)[s] = head;
134  }
135  }
136  }
137 
138  // Filters transition, possibly modifying label map. Returns true if arc is
139  // added to label map.
140  bool FilterArc(const Arc &arc, const Element &src_element,
141  const Element &dest_element, LabelMap *label_map) const;
142 
143  // Filters super-final transition, returning new final weight.
144  Weight FilterFinal(const Weight final_weight, const Element &element) const {
145  return is_final_ ? final_weight : Weight::Zero();
146  }
147 
148  static uint64_t Properties(uint64_t props) {
149  return props & ~(kIDeterministic | kODeterministic);
150  }
151 
152  std::unique_ptr<Relation> GetRelation() && { return std::move(r_); }
153 
154  std::vector<StateId> *GetHeadStates() { return head_; }
155 
156  private:
157  // Pairs arc labels with state tuples with possible heads and empty subsets.
158  void InitLabelMap(LabelMap *label_map) const;
159 
160  std::unique_ptr<Fst<Arc>> fst_; // Input FST.
161  std::vector<StateId> *head_; // Head state for a given state,
162  // owned by the Disambiguator.
163  std::unique_ptr<Relation> r_; // Relation compatible with inv. trans. fnc.
164  StateId s_; // Current state.
165  const StateTuple *tuple_; // Current tuple.
166  bool is_final_; // Is the current head state final?
167 };
168 
169 template <class Arc, class Relation>
171  const Arc &arc, const Element &src_element, const Element &dest_element,
172  LabelMap *label_map) const {
173  bool added = false;
174  if (label_map->empty()) InitLabelMap(label_map);
175  // Adds element to state tuple if element state is related to tuple head.
176  for (auto liter = label_map->lower_bound(arc.ilabel);
177  liter != label_map->end() && liter->first == arc.ilabel; ++liter) {
178  const auto &dest_tuple = liter->second.dest_tuple;
179  const auto dest_head = dest_tuple->filter_state.GetState();
180  if ((*r_)(dest_element.state_id, dest_head)) {
181  dest_tuple->subset.push_front(dest_element);
182  added = true;
183  }
184  }
185  return added;
186 }
187 
188 template <class Arc, class Relation>
190  LabelMap *label_map) const {
191  const auto src_head = tuple_->filter_state.GetState();
192  Label label = kNoLabel;
193  StateId nextstate = kNoStateId;
194  for (ArcIterator<Fst<Arc>> aiter(*fst_, src_head); !aiter.Done();
195  aiter.Next()) {
196  const auto &arc = aiter.Value();
197  // Continues if multiarc.
198  if (arc.ilabel == label && arc.nextstate == nextstate) continue;
199  DeterminizeArc<StateTuple> det_arc(arc);
200  det_arc.dest_tuple->filter_state = FilterState(arc.nextstate);
201  label_map->emplace(arc.ilabel, std::move(det_arc));
202  label = arc.ilabel;
203  nextstate = arc.nextstate;
204  }
205 }
206 
207 // Helper class to disambiguate an FST via Disambiguate().
208 template <class Arc>
210  public:
211  using Label = typename Arc::Label;
212  using StateId = typename Arc::StateId;
213  using Weight = typename Arc::Weight;
214 
215  // IDs arcs with state ID and arc position. Arc position -1 indicates final
216  // (super-final transition).
217  using ArcId = std::pair<StateId, ssize_t>;
218 
219  Disambiguator() : error_(false) {}
220 
222  const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
224  VectorFst<Arc> sfst(ifst);
225  Connect(&sfst);
226  ArcSort(&sfst, ArcCompare());
227  PreDisambiguate(sfst, ofst, opts);
228  ArcSort(ofst, ArcCompare());
229  FindAmbiguities(*ofst);
230  RemoveSplits(ofst);
231  MarkAmbiguities();
232  RemoveAmbiguities(ofst);
233  if (error_) ofst->SetProperties(kError, kError);
234  }
235 
236  private:
237  // Comparison functor for comparing input labels and next states of arcs. This
238  // sort order facilitates the predisambiguation.
239  class ArcCompare {
240  public:
241  bool operator()(const Arc &arc1, const Arc &arc2) const {
242  return arc1.ilabel < arc2.ilabel ||
243  (arc1.ilabel == arc2.ilabel && arc1.nextstate < arc2.nextstate);
244  }
245 
246  uint64_t Properties(uint64_t props) const {
247  return (props & kArcSortProperties) | kILabelSorted |
248  (props & kAcceptor ? kOLabelSorted : 0);
249  }
250  };
251 
252  // Comparison functor for comparing transitions represented by their arc ID.
253  // This sort order facilitates ambiguity detection.
254  class ArcIdCompare {
255  public:
256  explicit ArcIdCompare(const std::vector<StateId> &head) : head_(head) {}
257 
258  bool operator()(const ArcId &a1, const ArcId &a2) const {
259  // Sort first by source head state...
260  const auto src1 = a1.first;
261  const auto src2 = a2.first;
262  const auto head1 = head_[src1];
263  const auto head2 = head_[src2];
264  if (head1 < head2) return true;
265  if (head2 < head1) return false;
266  // ...then by source state...
267  if (src1 < src2) return true;
268  if (src2 < src1) return false;
269  // ...then by position.
270  return a1.second < a2.second;
271  }
272 
273  private:
274  const std::vector<StateId> &head_;
275  };
276 
277  // A relation that determines if two states share a common future.
278  class CommonFuture {
279  public:
281  using StateTuple = typename StateTable::StateTuple;
282 
283  // Needed for compilation with DeterminizeRelationFilter.
284  CommonFuture() {
285  FSTERROR() << "Disambiguate::CommonFuture: FST not provided";
286  }
287 
288  explicit CommonFuture(const Fst<Arc> &ifst) {
289  using M = Matcher<Fst<Arc>>;
291  // Ensures composition is between acceptors.
292  const bool trans = ifst.Properties(kNotAcceptor, true);
293  const auto *fsa =
294  trans ? new ProjectFst<Arc>(ifst, ProjectType::INPUT) : &ifst;
295  opts.state_table = new StateTable(*fsa, *fsa);
296  const ComposeFst<Arc> cfst(*fsa, *fsa, opts);
297  std::vector<bool> coaccess;
298  uint64_t props = 0;
299  SccVisitor<Arc> scc_visitor(nullptr, nullptr, &coaccess, &props);
300  DfsVisit(cfst, &scc_visitor);
301  for (StateId s = 0; s < coaccess.size(); ++s) {
302  if (coaccess[s]) {
303  related_.insert(opts.state_table->Tuple(s).StatePair());
304  }
305  }
306  if (trans) delete fsa;
307  }
308 
309  bool operator()(const StateId s1, StateId s2) const {
310  return related_.count(std::make_pair(s1, s2)) > 0;
311  }
312 
313  private:
314  // States s1 and s2 resp. are in this relation iff they there is a
315  // path from s1 to a final state that has the same label as some
316  // path from s2 to a final state.
317  std::set<std::pair<StateId, StateId>> related_;
318  };
319 
320  using ArcIdMap = std::multimap<ArcId, ArcId, ArcIdCompare>;
321 
322  // Inserts candidate into the arc ID map.
323  inline void InsertCandidate(StateId s1, StateId s2, const ArcId &a1,
324  const ArcId &a2) {
325  candidates_->insert(head_[s1] > head_[s2] ? std::make_pair(a1, a2)
326  : std::make_pair(a2, a1));
327  }
328 
329  // Returns the arc corresponding to ArcId a.
330  static Arc GetArc(const Fst<Arc> &fst, ArcId aid) {
331  if (aid.second == -1) { // Returns super-final transition.
332  return Arc(kNoLabel, kNoLabel, fst.Final(aid.first), kNoStateId);
333  } else {
334  ArcIterator<Fst<Arc>> aiter(fst, aid.first);
335  aiter.Seek(aid.second);
336  return aiter.Value();
337  }
338  }
339 
340  // Outputs an equivalent FST whose states are subsets of states that have a
341  // future path in common.
342  void PreDisambiguate(const ExpandedFst<Arc> &ifst, MutableFst<Arc> *ofst,
343  const DisambiguateOptions<Arc> &opts);
344 
345  // Finds transitions that are ambiguous candidates in the result of
346  // PreDisambiguate.
347  void FindAmbiguities(const ExpandedFst<Arc> &fst);
348 
349  // Finds transition pairs that are ambiguous candidates from two specified
350  // source states.
351  void FindAmbiguousPairs(const ExpandedFst<Arc> &fst, StateId s1, StateId s2);
352 
353  // Marks ambiguous transitions to be removed.
354  void MarkAmbiguities();
355 
356  // Deletes spurious ambiguous transitions (due to quantization).
357  void RemoveSplits(MutableFst<Arc> *ofst);
358 
359  // Deletes actual ambiguous transitions.
360  void RemoveAmbiguities(MutableFst<Arc> *ofst);
361 
362  // States s1 and s2 are in this relation iff there is a path from the initial
363  // state to s1 that has the same label as some path from the initial state to
364  // s2. We store only state pairs s1, s2 such that s1 <= s2.
365  std::set<std::pair<StateId, StateId>> coreachable_;
366 
367  // Queue of disambiguation-related states to be processed. We store only
368  // state pairs s1, s2 such that s1 <= s2.
369  std::list<std::pair<StateId, StateId>> queue_;
370 
371  // Head state in the pre-disambiguation for a given state.
372  std::vector<StateId> head_;
373 
374  // Maps from a candidate ambiguous arc A to each ambiguous candidate arc B
375  // with the same label and destination state as A, whose source state s' is
376  // coreachable with the source state s of A, and for which head(s') < head(s).
377  std::unique_ptr<ArcIdMap> candidates_;
378 
379  // Set of ambiguous transitions to be removed.
380  std::set<ArcId> ambiguous_;
381 
382  // States to merge due to quantization issues.
383  std::unique_ptr<UnionFind<StateId>> merge_;
384  // Marks error condition.
385  bool error_;
386 
387  Disambiguator(const Disambiguator &) = delete;
388  Disambiguator &operator=(const Disambiguator &) = delete;
389 };
390 
391 template <class Arc>
393  MutableFst<Arc> *ofst,
394  const DisambiguateOptions<Arc> &opts) {
395  using CommonDivisor = DefaultCommonDivisor<Weight>;
397  // Subset elements with states s1 and s2 (resp.) are in this relation iff they
398  // there is a path from s1 to a final state that has the same label as some
399  // path from s2 to a final state.
400  auto common_future = std::make_unique<CommonFuture>(ifst);
402  nopts.delta = opts.delta;
403  nopts.subsequential_label = opts.subsequential_label;
404  nopts.filter = new Filter(ifst, std::move(common_future), &head_);
405  // Determinization takes ownership of the filter itself.
406  nopts.gc_limit = 0; // Cache only the last state for fastest copy.
407  if (opts.weight_threshold != Weight::Zero() ||
408  opts.state_threshold != kNoStateId) {
409  if constexpr (IsPath<Weight>::value) {
410  /* TODO(riley): fails regression test; understand why
411  if (ifst.Properties(kAcceptor, true)) {
412  std::vector<Weight> idistance, odistance;
413  ShortestDistance(ifst, &idistance, true);
414  DeterminizeFst<Arc> dfst(ifst, &idistance, &odistance, nopts);
415  PruneOptions< Arc, AnyArcFilter<Arc>> popts(opts.weight_threshold,
416  opts.state_threshold,
417  AnyArcFilter<Arc>(),
418  &odistance);
419  Prune(dfst, ofst, popts);
420  } else */
421  {
422  *ofst = DeterminizeFst<Arc>(ifst, nopts);
423  Prune(ofst, opts.weight_threshold, opts.state_threshold);
424  }
425  } else {
426  FSTERROR() << "Disambiguate: Weight must have path property to use "
427  << "pruning options: " << Weight::Type();
428  error_ = true;
429  }
430  } else {
431  *ofst = DeterminizeFst<Arc>(ifst, nopts);
432  }
433  head_.resize(ofst->NumStates(), kNoStateId);
434 }
435 
436 template <class Arc>
438  if (fst.Start() == kNoStateId) return;
439  candidates_ = std::make_unique<ArcIdMap>(ArcIdCompare(head_));
440  const auto start_pr = std::make_pair(fst.Start(), fst.Start());
441  coreachable_.insert(start_pr);
442  queue_.push_back(start_pr);
443  while (!queue_.empty()) {
444  const auto &pr = queue_.front();
445  const auto s1 = pr.first;
446  const auto s2 = pr.second;
447  queue_.pop_front();
448  FindAmbiguousPairs(fst, s1, s2);
449  }
450 }
451 
452 template <class Arc>
454  StateId s1, StateId s2) {
455  if (fst.NumArcs(s2) > fst.NumArcs(s1)) FindAmbiguousPairs(fst, s2, s1);
456  SortedMatcher<Fst<Arc>> matcher(fst, MATCH_INPUT);
457  matcher.SetState(s2);
458  for (ArcIterator<Fst<Arc>> aiter(fst, s1); !aiter.Done(); aiter.Next()) {
459  const auto &arc1 = aiter.Value();
460  const ArcId a1(s1, aiter.Position());
461  if (matcher.Find(arc1.ilabel)) {
462  for (; !matcher.Done(); matcher.Next()) {
463  const auto &arc2 = matcher.Value();
464  // Continues on implicit epsilon match.
465  if (arc2.ilabel == kNoLabel) continue;
466  const ArcId a2(s2, matcher.Position());
467  // Actual transition is ambiguous.
468  if (s1 != s2 && arc1.nextstate == arc2.nextstate) {
469  InsertCandidate(s1, s2, a1, a2);
470  }
471  const auto spr = arc1.nextstate <= arc2.nextstate
472  ? std::make_pair(arc1.nextstate, arc2.nextstate)
473  : std::make_pair(arc2.nextstate, arc1.nextstate);
474  // Not already marked as coreachable?
475  if (coreachable_.insert(spr).second) {
476  // Only possible if state split by quantization issues.
477  if (spr.first != spr.second &&
478  head_[spr.first] == head_[spr.second]) {
479  if (!merge_) {
480  merge_ = std::make_unique<UnionFind<StateId>>(fst.NumStates(),
481  kNoStateId);
482  merge_->MakeAllSet(fst.NumStates());
483  }
484  merge_->Union(spr.first, spr.second);
485  } else {
486  queue_.push_back(spr);
487  }
488  }
489  }
490  }
491  }
492  // Super-final transition is ambiguous.
493  if (s1 != s2 && fst.Final(s1) != Weight::Zero() &&
494  fst.Final(s2) != Weight::Zero()) {
495  const ArcId a1(s1, -1);
496  const ArcId a2(s2, -1);
497  InsertCandidate(s1, s2, a1, a2);
498  }
499 }
500 
501 template <class Arc>
503  if (!candidates_) return;
504  for (auto it = candidates_->begin(); it != candidates_->end(); ++it) {
505  const auto a = it->first;
506  const auto b = it->second;
507  // If b is not to be removed, then a is.
508  if (ambiguous_.count(b) == 0) ambiguous_.insert(a);
509  }
510  coreachable_.clear();
511  candidates_.reset();
512 }
513 
514 template <class Arc>
516  if (!merge_) return;
517  // Merges split states to remove spurious ambiguities.
518  for (StateIterator<MutableFst<Arc>> siter(*ofst); !siter.Done();
519  siter.Next()) {
520  for (MutableArcIterator<MutableFst<Arc>> aiter(ofst, siter.Value());
521  !aiter.Done(); aiter.Next()) {
522  auto arc = aiter.Value();
523  const auto nextstate = merge_->FindSet(arc.nextstate);
524  if (nextstate != arc.nextstate) {
525  arc.nextstate = nextstate;
526  aiter.SetValue(arc);
527  }
528  }
529  }
530  // Repeats search for actual ambiguities on modified FST.
531  coreachable_.clear();
532  merge_.reset();
533  candidates_.reset();
534  FindAmbiguities(*ofst);
535  if (merge_) { // Shouldn't get here; sanity test.
536  FSTERROR() << "Disambiguate: Unable to remove spurious ambiguities";
537  error_ = true;
538  return;
539  }
540 }
541 
542 template <class Arc>
544  if (ambiguous_.empty()) return;
545  // Adds dead state to redirect ambiguous transitions to be removed.
546  const auto dead = ofst->AddState();
547  for (auto it = ambiguous_.begin(); it != ambiguous_.end(); ++it) {
548  const auto pos = it->second;
549  if (pos >= 0) { // Actual transition.
550  MutableArcIterator<MutableFst<Arc>> aiter(ofst, it->first);
551  aiter.Seek(pos);
552  auto arc = aiter.Value();
553  arc.nextstate = dead;
554  aiter.SetValue(arc);
555  } else { // Super-final transition.
556  ofst->SetFinal(it->first, Weight::Zero());
557  }
558  }
559  Connect(ofst);
560  ambiguous_.clear();
561 }
562 
563 } // namespace internal
564 
565 // Disambiguates a weighted FST. This version writes the disambiguated FST to an
566 // output MutableFst. The result will be an equivalent FST that has the
567 // property that there are not two distinct paths from the initial state to a
568 // final state with the same input labeling.
569 //
570 // The weights must be (weakly) left divisible (valid for Tropical and
571 // LogWeight).
572 //
573 // Complexity:
574 //
575 // Disambiguable: exponential (polynomial in the size of the output).
576 // Non-disambiguable: does not terminate.
577 //
578 // The disambiguable transducers include all automata and functional transducers
579 // that are unweighted or that are acyclic or that are unambiguous.
580 //
581 // For more information, see:
582 //
583 // Mohri, M. and Riley, M. 2015. On the disambiguation of weighted automata.
584 // In CIAA, pages 263-278.
585 template <class Arc>
587  const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
589  internal::Disambiguator<Arc> disambiguator;
590  disambiguator.Disambiguate(ifst, ofst, opts);
591 }
592 
593 } // namespace fst
594 
595 #endif // FST_DISAMBIGUATE_H_
static uint64_t Properties(uint64_t props)
Definition: disambiguate.h:148
void Next() final
Definition: matcher.h:317
void SetState(StateId s) final
Definition: matcher.h:257
constexpr uint64_t kArcSortProperties
Definition: properties.h:251
constexpr int kNoLabel
Definition: fst.h:195
size_t Position() const
Definition: matcher.h:335
virtual uint64_t Properties(uint64_t mask, bool test) const =0
RelationDeterminizeFilter(const Fst< Arc > &fst)
Definition: disambiguate.h:97
typename Arc::StateId StateId
Definition: disambiguate.h:212
virtual size_t NumArcs(StateId) const =0
RelationDeterminizeFilter(const RelationDeterminizeFilter &filter, const Fst< Arc > *fst=nullptr)
Definition: disambiguate.h:116
const Arc & Value() const final
Definition: matcher.h:311
std::multimap< Label, DeterminizeArc< StateTuple >> LabelMap
Definition: disambiguate.h:87
typename Arc::Weight Weight
Definition: disambiguate.h:213
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
virtual Weight Final(StateId) const =0
typename Arc::Label Label
Definition: disambiguate.h:211
void Connect(MutableFst< Arc > *fst)
Definition: connect.h:47
void SetValue(const Arc &arc)
Definition: mutable-fst.h:246
void SetState(StateId s, const StateTuple &tuple)
Definition: disambiguate.h:125
RelationDeterminizeFilter(const Fst< Arc > &fst, std::unique_ptr< Relation > r, std::vector< StateId > *head=nullptr)
Definition: disambiguate.h:103
constexpr uint64_t kODeterministic
Definition: properties.h:74
constexpr int kNoStateId
Definition: fst.h:196
const Arc & Value() const
Definition: fst.h:536
const Arc & Value() const
Definition: mutable-fst.h:236
void Prune(MutableFst< Arc > *fst, const PruneOptions< Arc, ArcFilter > &opts=PruneOptions< Arc, ArcFilter >())
Definition: prune.h:114
#define FSTERROR()
Definition: util.h:56
typename StateTuple::Subset Subset
Definition: disambiguate.h:85
RelationDeterminizeFilter(const Fst< Arc > &fst, std::unique_ptr< Filter > filter)
Definition: disambiguate.h:109
std::unique_ptr< Relation > GetRelation()&&
Definition: disambiguate.h:152
bool Done() const final
Definition: matcher.h:301
std::pair< StateId, ssize_t > ArcId
Definition: disambiguate.h:217
bool Find(Label match_label) final
Definition: matcher.h:270
void Seek(size_t a)
Definition: mutable-fst.h:244
void Seek(size_t a)
Definition: fst.h:556
void ArcSort(MutableFst< Arc > *fst, Compare comp)
Definition: arcsort.h:109
constexpr uint64_t kOLabelSorted
Definition: properties.h:99
constexpr uint64_t kNotAcceptor
Definition: properties.h:66
virtual void SetProperties(uint64_t props, uint64_t mask)=0
typename Arc::Weight Weight
Definition: determinize.h:1054
std::forward_list< Element > Subset
Definition: determinize.h:187
virtual StateId Start() const =0
constexpr uint64_t kIDeterministic
Definition: properties.h:69
typename Arc::Label Label
Definition: determinize.h:1052
Weight FilterFinal(const Weight final_weight, const Element &element) const
Definition: disambiguate.h:144
typename StateTuple::Element Element
Definition: disambiguate.h:86
constexpr uint64_t kILabelSorted
Definition: properties.h:94
typename Arc::StateId StateId
Definition: determinize.h:1053
std::vector< StateId > * GetHeadStates()
Definition: disambiguate.h:154
virtual StateId AddState()=0
virtual void SetFinal(StateId s, Weight weight=Weight::One())=0
std::unique_ptr< StateTuple > dest_tuple
Definition: determinize.h:219
DisambiguateOptions(float delta=kDelta, Weight weight=Weight::Zero(), StateId n=kNoStateId, Label label=0)
Definition: disambiguate.h:65
virtual StateId NumStates() const =0
constexpr float kDelta
Definition: weight.h:133
void Disambiguate(const Fst< Arc > &ifst, MutableFst< Arc > *ofst, const DisambiguateOptions< Arc > &opts=DisambiguateOptions< Arc >())
Definition: disambiguate.h:586
void Disambiguate(const Fst< Arc > &ifst, MutableFst< Arc > *ofst, const DisambiguateOptions< Arc > &opts=DisambiguateOptions< Arc >())
Definition: disambiguate.h:221
std::bool_constant<(W::Properties()&kPath)!=0 > IsPath
Definition: weight.h:162
constexpr uint64_t kAcceptor
Definition: properties.h:64
StateTable * state_table
Definition: compose.h:68