FST  openfst-1.8.3
OpenFst Library
lookahead-filter.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 // Composition filters to support lookahead matchers, useful for improving
19 // composition efficiency with certain inputs.
20 
21 #ifndef FST_LOOKAHEAD_FILTER_H_
22 #define FST_LOOKAHEAD_FILTER_H_
23 
24 #include <sys/types.h>
25 
26 #include <cstdint>
27 #include <memory>
28 #include <vector>
29 
30 #include <fst/log.h>
31 #include <fst/arc.h>
32 #include <fst/filter-state.h>
33 #include <fst/fst-decl.h>
34 #include <fst/fst.h>
35 #include <fst/lookahead-matcher.h>
36 #include <fst/matcher.h>
37 #include <fst/properties.h>
38 #include <fst/util.h>
39 
40 namespace fst {
41 
42 // Identifies and verifies the capabilities of the matcher to be used for
43 // lookahead with the composition filters below. This version is passed two
44 // matchers.
45 template <class Matcher1, class Matcher2>
46 MatchType LookAheadMatchType(const Matcher1 &m1, const Matcher2 &m2) {
47  const auto type1 = m1.Type(false);
48  const auto type2 = m2.Type(false);
49  if (type1 == MATCH_OUTPUT && m1.Flags() & kOutputLookAheadMatcher) {
50  return MATCH_OUTPUT;
51  } else if (type2 == MATCH_INPUT && m2.Flags() & kInputLookAheadMatcher) {
52  return MATCH_INPUT;
53  } else if (m1.Flags() & kOutputLookAheadMatcher &&
54  m1.Type(true) == MATCH_OUTPUT) {
55  return MATCH_OUTPUT;
56  } else if (m2.Flags() & kInputLookAheadMatcher &&
57  m2.Type(true) == MATCH_INPUT) {
58  return MATCH_INPUT;
59  } else {
60  return MATCH_NONE;
61  }
62 }
63 
64 // Identifies and verifies the capabilities of the matcher to be used for
65 // lookahead with the composition filters below. This version uses the FST's
66 // default matchers.
67 template <class Arc>
68 MatchType LookAheadMatchType(const Fst<Arc> &fst1, const Fst<Arc> &fst2) {
69  LookAheadMatcher<Fst<Arc>> matcher1(fst1, MATCH_OUTPUT);
70  LookAheadMatcher<Fst<Arc>> matcher2(fst2, MATCH_INPUT);
71  return LookAheadMatchType(matcher1, matcher2);
72 }
73 
74 // LookAheadSelector is a helper class for selecting among possibly distinct
75 // FST and matcher types without using a common base class. This lets us avoid
76 // virtual function calls. It stores and returns the appropriate FSTs and
77 // matcher for lookahead. It is templated on the matcher types. General case
78 // has no methods.
79 template <class Matcher1, class Matcher2, MatchType MT>
81 
82 // Stores and returns the appropriate FST and matcher for lookahead. Specialized
83 // for two matchers of same type with the (match) type argument determining
84 // which is used for lookahead.
85 template <class Matcher, MatchType MT>
87  public:
88  using FST = typename Matcher::FST;
89 
90  LookAheadSelector(Matcher *lmatcher1, Matcher *lmatcher2, MatchType type)
91  : lmatcher1_(lmatcher1->Copy()),
92  lmatcher2_(lmatcher2->Copy()),
93  type_(type) {}
94 
96  : lmatcher1_(selector.lmatcher1_->Copy()),
97  lmatcher2_(selector.lmatcher2_->Copy()),
98  type_(selector.type_) {}
99 
100  const FST &GetFst() const {
101  return type_ == MATCH_OUTPUT ? lmatcher2_->GetFst() : lmatcher1_->GetFst();
102  }
103 
104  Matcher *GetMatcher() const {
105  return type_ == MATCH_OUTPUT ? lmatcher1_.get() : lmatcher2_.get();
106  }
107 
108  private:
109  std::unique_ptr<Matcher> lmatcher1_;
110  std::unique_ptr<Matcher> lmatcher2_;
111  MatchType type_;
112 };
113 
114 // Stores and returns the appropriate FST and matcher for lookahead.
115 // Specialized for lookahead on input labels.
116 template <class Matcher1, class Matcher2>
117 class LookAheadSelector<Matcher1, Matcher2, MATCH_INPUT> {
118  public:
119  using FST1 = typename Matcher1::FST;
120 
121  LookAheadSelector(Matcher1 *lmatcher1, Matcher2 *lmatcher2, MatchType)
122  : fst_(lmatcher1->GetFst().Copy()), lmatcher_(lmatcher2->Copy()) {}
123 
126  : fst_(selector.fst_->Copy()), lmatcher_(selector.lmatcher_->Copy()) {}
127 
128  const FST1 &GetFst() const { return *fst_; }
129 
130  Matcher2 *GetMatcher() const { return lmatcher_.get(); }
131 
132  private:
133  std::unique_ptr<const FST1> fst_;
134  std::unique_ptr<Matcher2> lmatcher_;
135 };
136 
137 // Stores and returns the appropriate FST and matcher for lookahead.
138 // Specialized for lookahead on output labels.
139 template <class Matcher1, class Matcher2>
140 class LookAheadSelector<Matcher1, Matcher2, MATCH_OUTPUT> {
141  public:
142  using FST2 = typename Matcher2::FST;
143 
144  LookAheadSelector(Matcher1 *lmatcher1, Matcher2 *lmatcher2, MatchType)
145  : fst_(lmatcher2->GetFst().Copy()), lmatcher_(lmatcher1->Copy()) {}
146 
149  : fst_(selector.fst_->Copy()), lmatcher_(selector.lmatcher_->Copy()) {}
150 
151  const FST2 &GetFst() const { return *fst_; }
152 
153  Matcher1 *GetMatcher() const { return lmatcher_.get(); }
154 
155  private:
156  std::unique_ptr<const FST2> fst_;
157  std::unique_ptr<Matcher1> lmatcher_;
158 };
159 
160 // This filter uses a lookahead matcher in FilterArc(arc1, arc2) to examine the
161 // future of the composition state (arc1.nextstate, arc2.nextstate), blocking
162 // moving forward when its determined to be
163 // non-coaccessible. It is templated on an underlying filter, typically the
164 // epsilon filter. Which matcher is the lookahead matcher is determined by the
165 // template argument MT unless it is MATCH_BOTH. In that case, both matcher
166 // arguments must be lookahead matchers of the same type and one will be
167 // selected by LookAheadMatchType() based on their capability.
168 template <class Filter, class M1 = LookAheadMatcher<typename Filter::FST1>,
169  class M2 = M1, MatchType MT = MATCH_BOTH>
171  public:
172  using Arc = typename Filter::Arc;
173  using StateId = typename Arc::StateId;
174  using Weight = typename Arc::Weight;
175 
176  using FST1 = typename Filter::FST1;
177  using FST2 = typename Filter::FST2;
178  using Matcher1 = typename Filter::Matcher1;
179  using Matcher2 = typename Filter::Matcher2;
180  using FilterState = typename Filter::FilterState;
181 
182  LookAheadComposeFilter(const FST1 &fst1, const FST2 &fst2, M1 *matcher1,
183  M2 *matcher2)
184  : filter_(fst1, fst2, matcher1, matcher2),
185  lookahead_type_(MT == MATCH_BOTH
186  ? LookAheadMatchType(*filter_.GetMatcher1(),
187  *filter_.GetMatcher2())
188  : MT),
189  selector_(filter_.GetMatcher1(), filter_.GetMatcher2(),
190  lookahead_type_),
191  flags_(lookahead_type_ == MATCH_OUTPUT
192  ? filter_.GetMatcher1()->Flags()
193  : filter_.GetMatcher2()->Flags()) {
194  if (lookahead_type_ == MATCH_NONE) {
195  FSTERROR() << "LookAheadComposeFilter: 1st argument cannot "
196  << "match/look-ahead on output labels and 2nd argument "
197  << "cannot match/look-ahead on input labels";
198  }
199  selector_.GetMatcher()->InitLookAheadFst(selector_.GetFst());
200  }
201 
204  bool safe = false)
205  : filter_(filter.filter_, safe),
206  lookahead_type_(filter.lookahead_type_),
207  selector_(filter_.GetMatcher1(), filter_.GetMatcher2(),
208  lookahead_type_),
209  flags_(filter.flags_) {
210  selector_.GetMatcher()->InitLookAheadFst(selector_.GetFst(), true);
211  }
212 
213  FilterState Start() const { return filter_.Start(); }
214 
215  void SetState(StateId s1, StateId s2, const FilterState &fs) {
216  filter_.SetState(s1, s2, fs);
217  }
218 
219  FilterState FilterArc(Arc *arc1, Arc *arc2) const {
220  lookahead_arc_ = false;
221  const FilterState &fs = filter_.FilterArc(arc1, arc2);
222  if (fs == FilterState::NoState()) return FilterState::NoState();
223  return LookAheadOutput() ? LookAheadFilterArc(arc1, arc2, fs)
224  : LookAheadFilterArc(arc2, arc1, fs);
225  }
226 
227  void FilterFinal(Weight *weight1, Weight *weight2) const {
228  filter_.FilterFinal(weight1, weight2);
229  }
230 
231  // Returns matchers; ownership stays with filter.
232 
233  Matcher1 *GetMatcher1() { return filter_.GetMatcher1(); }
234 
235  Matcher2 *GetMatcher2() { return filter_.GetMatcher2(); }
236 
238  return selector_;
239  }
240 
241  uint64_t Properties(uint64_t inprops) const {
242  auto outprops = filter_.Properties(inprops);
243  if (lookahead_type_ == MATCH_NONE) outprops |= kError;
244  return outprops;
245  }
246 
247  uint32_t LookAheadFlags() const { return flags_; }
248 
249  bool LookAheadArc() const { return lookahead_arc_; }
250 
251  bool LookAheadOutput() const {
252  if (MT == MATCH_OUTPUT) {
253  return true;
254  } else if (MT == MATCH_INPUT) {
255  return false;
256  } else if (lookahead_type_ == MATCH_OUTPUT) {
257  return true;
258  } else {
259  return false;
260  }
261  }
262 
263  private:
264  FilterState LookAheadFilterArc(Arc *arca, Arc *arcb,
265  const FilterState &fs) const {
266  auto &labela = LookAheadOutput() ? arca->olabel : arca->ilabel;
267  if (labela != 0 && !(flags_ & kLookAheadNonEpsilons)) return fs;
268  if (labela == 0 && !(flags_ & kLookAheadEpsilons)) return fs;
269  lookahead_arc_ = true;
270  selector_.GetMatcher()->SetState(arca->nextstate);
271  return selector_.GetMatcher()->LookAheadFst(selector_.GetFst(),
272  arcb->nextstate)
273  ? fs
274  : FilterState::NoState();
275  }
276 
277  Filter filter_; // Underlying filter.
278  MatchType lookahead_type_; // Lookahead match type.
280  uint32_t flags_; // Lookahead flags.
281  mutable bool lookahead_arc_; // Look-ahead performed at last FilterArc()?
282 
283  LookAheadComposeFilter &operator=(const LookAheadComposeFilter &) = delete;
284 };
285 
286 // This filter adds weight-pushing to a lookahead composition filter using the
287 // LookAheadWeight() method of matcher argument. It is templated on an
288 // underlying lookahead filter, typically the basic lookahead filter.
289 // Weight-pushing in composition brings weights forward as much as possible
290 // based on the lookahead information.
291 template <class Filter, class M1 = LookAheadMatcher<typename Filter::FST1>,
292  class M2 = M1, MatchType MT = MATCH_BOTH>
294  public:
295  using Arc = typename Filter::Arc;
296  using StateId = typename Filter::StateId;
297  using Weight = typename Filter::Weight;
298 
299  using FST1 = typename Filter::FST1;
300  using FST2 = typename Filter::FST2;
301  using Matcher1 = typename Filter::Matcher1;
302  using Matcher2 = typename Filter::Matcher2;
303 
304  using FilterState1 = typename Filter::FilterState;
307 
308  PushWeightsComposeFilter(const FST1 &fst1, const FST2 &fst2, M1 *matcher1,
309  M2 *matcher2)
310  : filter_(fst1, fst2, matcher1, matcher2), fs_(FilterState::NoState()) {}
311 
314  bool safe = false)
315  : filter_(filter.filter_, safe), fs_(FilterState::NoState()) {}
316 
317  FilterState Start() const {
318  return FilterState(filter_.Start(), FilterState2(Weight::One()));
319  }
320 
321  void SetState(StateId s1, StateId s2, const FilterState &fs) {
322  fs_ = fs;
323  filter_.SetState(s1, s2, fs.GetState1());
324  }
325 
326  FilterState FilterArc(Arc *arc1, Arc *arc2) const {
327  const auto &fs1 = filter_.FilterArc(arc1, arc2);
328  if (fs1 == FilterState1::NoState()) return FilterState::NoState();
329  if (!(LookAheadFlags() & kLookAheadWeight)) {
330  return FilterState(fs1, FilterState2(Weight::One()));
331  }
332  const auto &lweight = LookAheadArc()
333  ? Selector().GetMatcher()->LookAheadWeight()
334  : Weight::One();
335  const auto &fs2 = fs_.GetState2();
336  const auto &fweight = fs2.GetWeight();
337  // Disallows Zero() weight futures.
338  if (lweight == Weight::Zero()) return FilterState::NoState();
339  arc2->weight = Divide(Times(arc2->weight, lweight), fweight);
340  return FilterState(fs1, FilterState2(lweight.Quantize()));
341  }
342 
343  void FilterFinal(Weight *weight1, Weight *weight2) const {
344  filter_.FilterFinal(weight1, weight2);
345  if (!(LookAheadFlags() & kLookAheadWeight) || *weight1 == Weight::Zero()) {
346  return;
347  }
348  const auto &fs2 = fs_.GetState2();
349  const auto &fweight = fs2.GetWeight();
350  *weight1 = Divide(*weight1, fweight);
351  }
352 
353  // Returns matchers; ownership states with filter.
354 
355  Matcher1 *GetMatcher1() { return filter_.GetMatcher1(); }
356 
357  Matcher2 *GetMatcher2() { return filter_.GetMatcher2(); }
358 
360  return filter_.Selector();
361  }
362 
363  uint32_t LookAheadFlags() const { return filter_.LookAheadFlags(); }
364 
365  bool LookAheadArc() const { return filter_.LookAheadArc(); }
366 
367  bool LookAheadOutput() const { return filter_.LookAheadOutput(); }
368 
369  uint64_t Properties(uint64_t props) const {
370  return filter_.Properties(props) & kWeightInvariantProperties;
371  }
372 
373  private:
374  Filter filter_; // Underlying filter.
375  FilterState fs_; // Current filter state.
376 
378  delete;
379 };
380 
381 // This filter adds label-pushing to a lookahead composition filter using the
382 // LookAheadPrefix() method of the matcher argument. It is templated on an
383 // underlying filter, typically the basic lookahead or weight-pushing lookahead
384 // filter. Label-pushing in composition matches labels as early as possible
385 // based on the lookahead information.
386 template <class Filter, class M1 = LookAheadMatcher<typename Filter::FST1>,
387  class M2 = M1, MatchType MT = MATCH_BOTH>
389  public:
390  using Arc = typename Filter::Arc;
391  using Label = typename Arc::Label;
392  using StateId = typename Arc::StateId;
393  using Weight = typename Arc::Weight;
394 
395  using FST1 = typename Filter::FST1;
396  using FST2 = typename Filter::FST2;
399  using FilterState1 = typename Filter::FilterState;
402 
403  PushLabelsComposeFilter(const FST1 &fst1, const FST2 &fst2, M1 *matcher1,
404  M2 *matcher2)
405  : filter_(fst1, fst2, matcher1, matcher2),
406  fs_(FilterState::NoState()),
407  fst1_(filter_.GetMatcher1()->GetFst()),
408  fst2_(filter_.GetMatcher2()->GetFst()),
409  matcher1_(fst1_, MATCH_OUTPUT,
410  filter_.LookAheadOutput() ? kMultiEpsList : kMultiEpsLoop,
411  filter_.GetMatcher1(), /*own_matcher=*/false),
412  matcher2_(fst2_, MATCH_INPUT,
413  filter_.LookAheadOutput() ? kMultiEpsLoop : kMultiEpsList,
414  filter_.GetMatcher2(), /*own_matcher=*/false) {}
415 
418  bool safe = false)
419  : filter_(filter.filter_, safe),
420  fs_(FilterState::NoState()),
421  fst1_(filter_.GetMatcher1()->GetFst()),
422  fst2_(filter_.GetMatcher2()->GetFst()),
423  matcher1_(fst1_, MATCH_OUTPUT,
424  filter_.LookAheadOutput() ? kMultiEpsList : kMultiEpsLoop,
425  filter_.GetMatcher1(), /*own_matcher=*/false),
426  matcher2_(fst2_, MATCH_INPUT,
427  filter_.LookAheadOutput() ? kMultiEpsLoop : kMultiEpsList,
428  filter_.GetMatcher2(), /*own_matcher=*/false) {}
429 
430  FilterState Start() const {
431  return FilterState(filter_.Start(), FilterState2(kNoLabel));
432  }
433 
434  void SetState(StateId s1, StateId s2, const FilterState &fs) {
435  fs_ = fs;
436  filter_.SetState(s1, s2, fs.GetState1());
437  if (!(LookAheadFlags() & kLookAheadPrefix)) return;
438  narcsa_ = LookAheadOutput() ? internal::NumArcs(fst1_, s1)
439  : internal::NumArcs(fst2_, s2);
440  const auto &fs2 = fs_.GetState2();
441  const auto &flabel = fs2.GetState();
442  GetMatcher1()->ClearMultiEpsLabels();
443  GetMatcher2()->ClearMultiEpsLabels();
444  if (flabel != kNoLabel) { // Have a lookahead label?
445  GetMatcher1()->AddMultiEpsLabel(flabel); // Yes, make it a multi-epsilon
446  GetMatcher2()->AddMultiEpsLabel(flabel); // label so that it matches the
447  } // implicit epsilon arc to be
448  } // modified below when pushing.
449 
450  FilterState FilterArc(Arc *arc1, Arc *arc2) const {
451  if (!(LookAheadFlags() & kLookAheadPrefix)) {
452  return FilterState(filter_.FilterArc(arc1, arc2), FilterState2(kNoLabel));
453  }
454  const auto &fs2 = fs_.GetState2();
455  const auto &flabel = fs2.GetState();
456  if (flabel != kNoLabel) { // Have a lookahead label?
457  return LookAheadOutput() ? PushedLabelFilterArc(arc1, arc2, flabel)
458  : PushedLabelFilterArc(arc2, arc1, flabel);
459  }
460  const auto &fs1 = filter_.FilterArc(arc1, arc2);
461  if (fs1 == FilterState1::NoState()) return FilterState::NoState();
462  if (!LookAheadArc()) return FilterState(fs1, FilterState2(kNoLabel));
463  return LookAheadOutput() ? PushLabelFilterArc(arc1, arc2, fs1)
464  : PushLabelFilterArc(arc2, arc1, fs1);
465  }
466 
467  void FilterFinal(Weight *weight1, Weight *weight2) const {
468  filter_.FilterFinal(weight1, weight2);
469  if (!(LookAheadFlags() & kLookAheadPrefix) || *weight1 == Weight::Zero()) {
470  return;
471  }
472  const auto &fs2 = fs_.GetState2();
473  const auto &flabel = fs2.GetState();
474  if (flabel != kNoLabel) *weight1 = Weight::Zero();
475  }
476 
477  // Returns matchers; ownership states with filter.
478 
479  Matcher1 *GetMatcher1() { return &matcher1_; }
480 
481  Matcher2 *GetMatcher2() { return &matcher2_; }
482 
483  uint64_t Properties(uint64_t iprops) const {
484  const auto oprops = filter_.Properties(iprops);
485  if (LookAheadOutput()) {
486  return oprops & kOLabelInvariantProperties;
487  } else {
488  return oprops & kILabelInvariantProperties;
489  }
490  }
491 
492  private:
493  const LookAheadSelector<typename Filter::Matcher1, typename Filter::Matcher2,
494  MT>
495  &Selector() const {
496  return filter_.Selector();
497  }
498 
499  // Consumes an already pushed label.
500  FilterState PushedLabelFilterArc(Arc *arca, Arc *arcb, Label flabel) const {
501  auto &labela = LookAheadOutput() ? arca->olabel : arca->ilabel;
502  const auto &labelb = LookAheadOutput() ? arcb->ilabel : arcb->olabel;
503  if (labelb != kNoLabel) {
504  return FilterState::NoState(); // Blocks non-(multi-)epsilon label
505  } else if (labela == flabel) {
506  labela = 0; // Converts match to multi-epsilon to epsilon.
507  return Start();
508  } else if (labela == 0) {
509  if (narcsa_ == 1) return fs_; // Takes epsilon, keeping state with label.
510  Selector().GetMatcher()->SetState(arca->nextstate);
511  if (Selector().GetMatcher()->LookAheadLabel(flabel)) {
512  return fs_; // Takes epsilon, keeping state with label.
513  } else {
514  return FilterState::NoState(); // Blocks non-coaccessible path.
515  }
516  } else {
517  return FilterState::NoState(); // Blocks mismatch to multi-epsilon label.
518  }
519  }
520 
521  // Pushes a label forward when possible.
522  FilterState PushLabelFilterArc(Arc *arca, Arc *arcb,
523  const FilterState1 &fs1) const {
524  auto &labela = LookAheadOutput() ? arca->olabel : arca->ilabel;
525  const auto &labelb = LookAheadOutput() ? arcb->olabel : arcb->ilabel;
526  if (labelb != 0) { // No place to push.
527  return FilterState(fs1, FilterState2(kNoLabel));
528  }
529  if (labela != 0 && // Wrong lookahead prefix type?
530  LookAheadFlags() & kLookAheadNonEpsilonPrefix) {
531  return FilterState(fs1, FilterState2(kNoLabel));
532  }
533  Arc larc(kNoLabel, kNoLabel, Weight::Zero(), kNoStateId);
534  if (Selector().GetMatcher()->LookAheadPrefix(&larc)) { // Have prefix arc?
535  labela = LookAheadOutput() ? larc.ilabel : larc.olabel;
536  arcb->ilabel = larc.ilabel; // Goes forward on that arc,
537  arcb->olabel = larc.olabel; // thus pushing the label.
538  arcb->weight = Times(arcb->weight, larc.weight);
539  arcb->nextstate = larc.nextstate;
540  return FilterState(fs1, FilterState2(labela));
541  } else {
542  return FilterState(fs1, FilterState2(kNoLabel));
543  }
544  }
545 
546  uint32_t LookAheadFlags() const { return filter_.LookAheadFlags(); }
547 
548  bool LookAheadArc() const { return filter_.LookAheadArc(); }
549 
550  bool LookAheadOutput() const { return filter_.LookAheadOutput(); }
551 
552  Filter filter_; // Underlying filter.
553  FilterState fs_; // Current filter state.
554  const FST1 &fst1_;
555  const FST2 &fst2_;
556  Matcher1 matcher1_; // Multi-epsilon matcher for fst1_.
557  Matcher2 matcher2_; // Multi-epsilon matcher for fst2_.
558  ssize_t narcsa_; // Number of arcs leaving look-ahead match FST.
559 
560  PushLabelsComposeFilter &operator=(const PushLabelsComposeFilter &) = delete;
561 };
562 
563 // Convenience class for setting up composition with a default lookahead matcher
564 // and filter.
565 template <class Arc, MatchType type>
567  public:
568  using M = Matcher<Fst<Arc>>;
570  using FstMatcher = M;
571 };
572 
573 // Specializes for MATCH_INPUT to allow lookahead.
574 template <class Arc>
576  public:
580  using FstMatcher = M;
581 };
582 
583 // Specializes for MATCH_OUTPUT to allow lookahead.
584 template <class Arc>
586  public:
590  using FstMatcher = M;
591 };
592 
593 // Specializes for StdArc to allow weight and label pushing.
594 template <>
596  public:
602  using FstMatcher = M;
603 };
604 
605 // Specializes for StdArc to allow weight and label pushing.
606 template <>
608  public:
614  using FstMatcher = M;
615 };
616 
617 // Specializes for LogArc to allow weight and label pushing.
618 template <>
620  public:
626  using FstMatcher = M;
627 };
628 
629 // Specializes for LogArc to allow weight and label pushing.
630 template <>
632  public:
638  using FstMatcher = M;
639 };
640 
641 } // namespace fst
642 
643 #endif // FST_LOOKAHEAD_FILTER_H_
PushWeightsComposeFilter(const FST1 &fst1, const FST2 &fst2, M1 *matcher1, M2 *matcher2)
typename Arc::Weight Weight
typename Filter::StateId StateId
void FilterFinal(Weight *weight1, Weight *weight2) const
LookAheadComposeFilter(const FST1 &fst1, const FST2 &fst2, M1 *matcher1, M2 *matcher2)
uint32_t LookAheadFlags() const
constexpr uint64_t kWeightInvariantProperties
Definition: properties.h:280
constexpr int kNoLabel
Definition: fst.h:195
typename Filter::FST1 FST1
void FilterFinal(Weight *weight1, Weight *weight2) const
FilterState Start() const
const LookAheadSelector< Matcher1, Matcher2, MT > & Selector() const
typename Filter::FilterState FilterState
typename Filter::FST2 FST2
LookAheadSelector(Matcher1 *lmatcher1, Matcher2 *lmatcher2, MatchType)
MatchType LookAheadMatchType(const Matcher1 &m1, const Matcher2 &m2)
LookAheadSelector(Matcher1 *lmatcher1, Matcher2 *lmatcher2, MatchType)
constexpr uint32_t kMultiEpsList
Definition: matcher.h:1234
MatchType
Definition: fst.h:187
LookAheadSelector(const LookAheadSelector< Matcher1, Matcher2, MATCH_OUTPUT > &selector)
ErrorWeight Times(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:64
constexpr uint64_t kError
Definition: properties.h:52
uint64_t Properties(uint64_t props) const
typename Filter::Arc Arc
FilterState FilterArc(Arc *arc1, Arc *arc2) const
typename Arc::StateId StateId
const LookAheadSelector< Matcher1, Matcher2, MT > & Selector() const
ssize_t NumArcs(const ExpandedFst< Arc > &fst, typename Arc::StateId s)
Definition: expanded-fst.h:113
FilterState FilterArc(Arc *arc1, Arc *arc2) const
constexpr int kNoStateId
Definition: fst.h:196
void FilterFinal(Weight *weight1, Weight *weight2) const
constexpr uint32_t kOutputLookAheadMatcher
#define FSTERROR()
Definition: util.h:56
constexpr uint32_t kMultiEpsLoop
Definition: matcher.h:1237
FilterState Start() const
LookAheadSelector(Matcher *lmatcher1, Matcher *lmatcher2, MatchType type)
constexpr uint32_t kLookAheadEpsilons
void SetState(StateId s1, StateId s2, const FilterState &fs)
constexpr uint32_t kLookAheadNonEpsilonPrefix
typename Filter::Matcher1 Matcher1
constexpr uint32_t kLookAheadNonEpsilons
constexpr uint32_t kInputLookAheadMatcher
void SetState(StateId s1, StateId s2, const FilterState &fs)
constexpr uint32_t kLookAheadPrefix
typename Filter::Weight Weight
typename Filter::FST1 FST1
PushLabelsComposeFilter(const PushLabelsComposeFilter< Filter, M1, M2, MT > &filter, bool safe=false)
typename Filter::FilterState FilterState1
constexpr uint64_t kOLabelInvariantProperties
Definition: properties.h:270
LookAheadComposeFilter(const LookAheadComposeFilter< Filter, M1, M2, MT > &filter, bool safe=false)
uint64_t Properties(uint64_t iprops) const
uint64_t Properties(uint64_t inprops) const
constexpr uint64_t kILabelInvariantProperties
Definition: properties.h:261
typename Filter::Matcher2 Matcher2
typename Filter::FST2 FST2
typename Filter::FST2 FST2
constexpr uint32_t kLookAheadWeight
const FilterState1 & GetState1() const
Definition: filter-state.h:175
typename Arc::Weight Weight
typename Filter::Matcher1 Matcher1
ErrorWeight Divide(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:67
PushLabelsComposeFilter(const FST1 &fst1, const FST2 &fst2, M1 *matcher1, M2 *matcher2)
void SetState(StateId s1, StateId s2, const FilterState &fs)
PushWeightsComposeFilter(const PushWeightsComposeFilter< Filter, M1, M2, MT > &filter, bool safe=false)
const FilterState2 & GetState2() const
Definition: filter-state.h:177
typename Filter::FST1 FST1
typename Filter::FilterState FilterState1
LookAheadSelector(const LookAheadSelector< Matcher1, Matcher2, MATCH_INPUT > &selector)
typename Filter::Matcher2 Matcher2
LookAheadSelector(const LookAheadSelector< Matcher, Matcher, MT > &selector)
FilterState FilterArc(Arc *arc1, Arc *arc2) const
typename Arc::StateId StateId