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