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