FST  openfst-1.8.4
OpenFst Library
arc-map.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 // Class to map over/transform arcs e.g., change semirings or
19 // implement project/invert. Consider using when operation does
20 // not change the number of arcs (except possibly superfinal arcs).
21 
22 #ifndef FST_ARC_MAP_H_
23 #define FST_ARC_MAP_H_
24 
25 #include <cstddef>
26 #include <cstdint>
27 #include <memory>
28 #include <string>
29 #include <type_traits>
30 #include <utility>
31 
32 #include <fst/log.h>
33 #include <fst/arc.h>
34 #include <fst/cache.h>
35 #include <fst/expanded-fst.h>
36 #include <fst/float-weight.h>
37 #include <fst/fst.h>
38 #include <fst/impl-to-fst.h>
39 #include <fst/mutable-fst.h>
40 #include <fst/properties.h>
41 #include <fst/string-weight.h>
42 #include <fst/symbol-table.h>
43 #include <fst/util.h>
44 #include <fst/weight.h>
45 #include <unordered_map>
46 
47 namespace fst {
48 
49 // Determines how final weights are mapped.
51  // A final weight is mapped into a final weight. An error is raised if this
52  // is not possible.
54  // A final weight is mapped to an arc to the superfinal state when the result
55  // cannot be represented as a final weight. The superfinal state will be
56  // added only if it is needed.
58  // A final weight is mapped to an arc to the superfinal state unless the
59  // result can be represented as a final weight of weight Zero(). The
60  // superfinal state is always added (if the input is not the empty FST).
62 };
63 
64 // Determines how symbol tables are mapped.
66  // Symbols should be cleared in the result by the map.
68  // Symbols should be copied from the input FST by the map.
70  // Symbols should not be modified in the result by the map itself.
71  // (They may set by the mapper).
73 };
74 
75 // Determines whether to propagate the kExpanded property, and by extension,
76 // whether the `ArcMapFst` is an `ExpandedFst` or not.
77 enum class PropagateKExpanded {
78  // The `ArcMapFst` will neither be an `ExpandedFst` nor require one as input.
79  kNo,
80  // The `ArcMapFst` will both be an `ExpandedFst` and require one as input, as
81  // long as the mapper it is templated on can support this.
83  // TODO(wolfsonkin): Add a kYes option.
84 };
85 
86 // The ArcMapper interfaces defines how arcs and final weights are mapped.
87 // This is useful for implementing operations that apply to each arc separately
88 // and do not change the number of arcs (except possibly superfinal arcs).
89 //
90 // Having the default constructor, `Properties`, and `FinalAction` as constexpr
91 // can allow for a special optimization to be taken for `ArcMapFst` where it can
92 // be an `ExpandedFst`.
93 //
94 // template <class A, class B>
95 // class ArcMapper {
96 // public:
97 // using FromArc = A;
98 // using ToArc = B;
99 //
100 // // Maps an arc type FromArc to arc type ToArc.
101 // ToArc operator()(const FromArc &arc);
102 //
103 // // Specifies final action the mapper requires (see above).
104 // // The mapper will be passed final weights as arcs of the form
105 // // Arc(0, 0, weight, kNoStateId).
106 // MapFinalAction FinalAction() const;
107 //
108 // // Specifies input symbol table action the mapper requires (see above).
109 // MapSymbolsAction InputSymbolsAction() const;
110 //
111 // // Specifies output symbol table action the mapper requires (see above).
112 // MapSymbolsAction OutputSymbolsAction() const;
113 //
114 // // This specifies the known properties of an FST mapped by this mapper. It
115 // takes as argument the input FSTs's known properties.
116 // uint64_t Properties(uint64_t props) const;
117 // };
118 //
119 // The ArcMap functions and classes below will use the FinalAction()
120 // method of the mapper to determine how to treat final weights, e.g., whether
121 // to add a superfinal state. They will use the Properties() method to set the
122 // result FST properties.
123 //
124 // We include a various map versions below. One dimension of variation is
125 // whether the mapping mutates its input, writes to a new result FST, or is an
126 // on-the-fly FST. Another dimension is how we pass the mapper. We allow passing
127 // the mapper by pointer for cases that we need to change the state of the
128 // user's mapper. This is the case with the EncodeMapper, which is reused
129 // during decoding. We also include map versions that pass the mapper by value
130 // or const reference when this suffices.
131 
132 // Maps an arc type A using a mapper function object C, passed
133 // by pointer. This version modifies its Fst input.
134 template <class A, class C>
135 void ArcMap(MutableFst<A> *fst, C *mapper) {
136  using FromArc = A;
137  using ToArc = A;
138  using Weight = typename FromArc::Weight;
139  if (mapper->InputSymbolsAction() == MAP_CLEAR_SYMBOLS) {
140  fst->SetInputSymbols(nullptr);
141  }
142  if (mapper->OutputSymbolsAction() == MAP_CLEAR_SYMBOLS) {
143  fst->SetOutputSymbols(nullptr);
144  }
145  if (fst->Start() == kNoStateId) return;
146  const auto props = fst->Properties(kFstProperties, false);
147  const auto final_action = mapper->FinalAction();
148  auto superfinal = kNoStateId;
149  if (final_action == MAP_REQUIRE_SUPERFINAL) {
150  superfinal = fst->AddState();
151  fst->SetFinal(superfinal);
152  }
153  for (StateIterator<MutableFst<FromArc>> siter(*fst); !siter.Done();
154  siter.Next()) {
155  const auto state = siter.Value();
156  for (MutableArcIterator<MutableFst<FromArc>> aiter(fst, state);
157  !aiter.Done(); aiter.Next()) {
158  const auto &arc = aiter.Value();
159  aiter.SetValue((*mapper)(arc));
160  }
161  switch (final_action) {
162  case MAP_NO_SUPERFINAL:
163  default: {
164  const FromArc arc(0, 0, fst->Final(state), kNoStateId);
165  const auto final_arc = (*mapper)(arc);
166  if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
167  FSTERROR() << "ArcMap: Non-zero arc labels for superfinal arc";
168  fst->SetProperties(kError, kError);
169  }
170  fst->SetFinal(state, final_arc.weight);
171  break;
172  }
173  case MAP_ALLOW_SUPERFINAL: {
174  if (state != superfinal) {
175  const FromArc arc(0, 0, fst->Final(state), kNoStateId);
176  auto final_arc = (*mapper)(arc);
177  if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
178  // Add a superfinal state if not already done.
179  if (superfinal == kNoStateId) {
180  superfinal = fst->AddState();
181  fst->SetFinal(superfinal);
182  }
183  final_arc.nextstate = superfinal;
184  fst->AddArc(state, std::move(final_arc));
185  fst->SetFinal(state, Weight::Zero());
186  } else {
187  fst->SetFinal(state, final_arc.weight);
188  }
189  }
190  break;
191  }
192  case MAP_REQUIRE_SUPERFINAL: {
193  if (state != superfinal) {
194  const FromArc arc(0, 0, fst->Final(state), kNoStateId);
195  const auto final_arc = (*mapper)(arc);
196  if (final_arc.ilabel != 0 || final_arc.olabel != 0 ||
197  final_arc.weight != Weight::Zero()) {
198  fst->AddArc(state, ToArc(final_arc.ilabel, final_arc.olabel,
199  final_arc.weight, superfinal));
200  }
201  fst->SetFinal(state, Weight::Zero());
202  }
203  break;
204  }
205  }
206  }
207  fst->SetProperties(mapper->Properties(props), kFstProperties);
208 }
209 
210 // Maps an arc type A using a mapper function object C, passed by value. This
211 // version modifies its FST input.
212 template <class A, class C>
213 void ArcMap(MutableFst<A> *fst, C mapper) {
214  ArcMap(fst, &mapper);
215 }
216 
217 // Maps an arc type A to an arc type B using mapper function object C,
218 // passed by pointer. This version writes the mapped input FST to an
219 // output MutableFst.
220 template <class A, class B, class C>
221 void ArcMap(const Fst<A> &ifst, MutableFst<B> *ofst, C *mapper) {
222  using FromArc = A;
223  using StateId = typename FromArc::StateId;
224  ofst->DeleteStates();
225  if (mapper->InputSymbolsAction() == MAP_COPY_SYMBOLS) {
226  ofst->SetInputSymbols(ifst.InputSymbols());
227  } else if (mapper->InputSymbolsAction() == MAP_CLEAR_SYMBOLS) {
228  ofst->SetInputSymbols(nullptr);
229  }
230  if (mapper->OutputSymbolsAction() == MAP_COPY_SYMBOLS) {
231  ofst->SetOutputSymbols(ifst.OutputSymbols());
232  } else if (mapper->OutputSymbolsAction() == MAP_CLEAR_SYMBOLS) {
233  ofst->SetOutputSymbols(nullptr);
234  }
235  const auto iprops = ifst.Properties(kCopyProperties, false);
236  if (ifst.Start() == kNoStateId) {
237  if (iprops & kError) ofst->SetProperties(kError, kError);
238  return;
239  }
240  const auto final_action = mapper->FinalAction();
241  if (std::optional<StateId> num_states = ifst.NumStatesIfKnown()) {
242  ofst->ReserveStates(*num_states +
243  (final_action == MAP_NO_SUPERFINAL ? 0 : 1));
244  }
245  // Adds all states.
246  for (StateIterator<Fst<A>> siter(ifst); !siter.Done(); siter.Next()) {
247  ofst->AddState();
248  }
249  StateId superfinal = kNoStateId;
250  if (final_action == MAP_REQUIRE_SUPERFINAL) {
251  superfinal = ofst->AddState();
252  ofst->SetFinal(superfinal);
253  }
254  for (StateIterator<Fst<A>> siter(ifst); !siter.Done(); siter.Next()) {
255  StateId s = siter.Value();
256  if (s == ifst.Start()) ofst->SetStart(s);
257  ofst->ReserveArcs(
258  s, ifst.NumArcs(s) + (final_action != MAP_NO_SUPERFINAL ? 1 : 0));
259  for (ArcIterator<Fst<A>> aiter(ifst, s); !aiter.Done(); aiter.Next()) {
260  ofst->AddArc(s, (*mapper)(aiter.Value()));
261  }
262  switch (final_action) {
263  case MAP_NO_SUPERFINAL:
264  default: {
265  B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId));
266  if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
267  FSTERROR() << "ArcMap: Non-zero arc labels for superfinal arc";
268  ofst->SetProperties(kError, kError);
269  }
270  ofst->SetFinal(s, final_arc.weight);
271  break;
272  }
273  case MAP_ALLOW_SUPERFINAL: {
274  B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId));
275  if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
276  // Add a superfinal state if not already done.
277  if (superfinal == kNoStateId) {
278  superfinal = ofst->AddState();
279  ofst->SetFinal(superfinal);
280  }
281  final_arc.nextstate = superfinal;
282  ofst->AddArc(s, std::move(final_arc));
283  ofst->SetFinal(s, B::Weight::Zero());
284  } else {
285  ofst->SetFinal(s, final_arc.weight);
286  }
287  break;
288  }
289  case MAP_REQUIRE_SUPERFINAL: {
290  B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId));
291  if (final_arc.ilabel != 0 || final_arc.olabel != 0 ||
292  final_arc.weight != B::Weight::Zero()) {
293  ofst->AddArc(s, B(final_arc.ilabel, final_arc.olabel,
294  final_arc.weight, superfinal));
295  }
296  ofst->SetFinal(s, B::Weight::Zero());
297  break;
298  }
299  }
300  }
301  const auto oprops = ofst->Properties(kFstProperties, false);
302  ofst->SetProperties(mapper->Properties(iprops) | oprops, kFstProperties);
303 }
304 
305 // Maps an arc type A to an arc type B using mapper function
306 // object C, passed by value. This version writes the mapped input
307 // Fst to an output MutableFst.
308 template <class A, class B, class C>
309 void ArcMap(const Fst<A> &ifst, MutableFst<B> *ofst, C mapper) {
310  ArcMap(ifst, ofst, &mapper);
311 }
312 
314  // ArcMapFst default caching behaviour is to do no caching. Most mappers are
315  // cheap and therefore we save memory by not doing caching.
317 
318  explicit ArcMapFstOptions(const CacheOptions &opts) : CacheOptions(opts) {}
319 };
320 
321 template <class A, class B, class C, class CacheStore,
322  PropagateKExpanded propagate_expanded_fst>
323 class ArcMapFst;
324 
325 namespace internal {
326 
327 // ExtractOr<E, O>::type evaluates to E<O> if possible. Otherwise,
328 // std::false_type.
329 template <template <typename> class Extract, typename Obj, typename>
330 struct ExtractOr {
331  using type = std::false_type;
332 };
333 template <template <typename> class Extract, typename Obj>
334 struct ExtractOr<Extract, Obj, std::void_t<Extract<Obj>>> {
335  using type = Extract<Obj>;
336 };
337 
338 template <template <typename> class Extract, typename Obj>
340 
341 // If the mapper conserves the expanded property and doesn't create a superfinal
342 // state, then in the `ArcMapFst` case, we can make `ArcMapFst` both accept and
343 // be an `ExpandedFst`.
344 // TODO(wolfsonkin): Support kExpanded propagation for other values of
345 // `FinalAction()`.
346 template <typename C>
347 using CoreConditions =
348  std::bool_constant<(C{}.FinalAction() == MAP_NO_SUPERFINAL) &&
349  (C{}.Properties(kExpanded) == kExpanded)>;
350 // If the mapper is default constructible and the input FST is expanded, then
351 // the output FST can be expanded.
352 template <typename C>
355 
356 // Implementation of delayed ArcMapFst. If `is_expanded` is true, then the
357 // implementation will assume the input FST is an `ExpandedFst`, and define
358 // `NumStates()`. Otherwise, the `ArcMapFst` will act on any `Fst` input, and
359 // calling its `NumStates()` method will not compile.
360 template <class A, class B, class C, class CacheStore = DefaultCacheStore<B>,
361  bool is_expanded = false>
363  : public CacheBaseImpl<typename CacheStore::State, CacheStore> {
364  public:
365  using Arc = B;
366  using StateId = typename Arc::StateId;
367  using Weight = typename Arc::Weight;
368  using FromFst = std::conditional_t<is_expanded, ExpandedFst<A>, Fst<A>>;
369 
370  using FstImpl<B>::SetType;
374 
375  using State = typename CacheStore::State;
377  using CacheImpl::EmplaceArc;
378  using CacheImpl::HasArcs;
379  using CacheImpl::HasFinal;
380  using CacheImpl::HasStart;
381  using CacheImpl::PushArc;
382  using CacheImpl::SetArcs;
383  using CacheImpl::SetFinal;
384  using CacheImpl::SetStart;
385 
386  friend class StateIterator<
387  ArcMapFst<A, B, C, CacheStore, PropagateKExpanded::kIfPossible>>;
388  friend class StateIterator<
389  ArcMapFst<A, B, C, CacheStore, PropagateKExpanded::kNo>>;
390 
391  ArcMapFstImpl(const FromFst &fst, const C &mapper,
392  const ArcMapFstOptions &opts)
393  : CacheImpl(opts),
394  fst_(fst.Copy()),
395  mapper_(new C(mapper)),
396  own_mapper_(true),
397  superfinal_(kNoStateId),
398  nstates_(0) {
399  Init();
400  }
401 
402  ArcMapFstImpl(const FromFst &fst, C *mapper, const ArcMapFstOptions &opts)
403  : CacheImpl(opts),
404  fst_(fst.Copy()),
405  mapper_(mapper),
406  own_mapper_(false),
407  superfinal_(kNoStateId),
408  nstates_(0) {
409  Init();
410  }
411 
413  : CacheImpl(impl),
414  fst_(impl.fst_->Copy(true)),
415  mapper_(new C(*impl.mapper_)),
416  own_mapper_(true),
417  superfinal_(kNoStateId),
418  nstates_(0) {
419  Init();
420  }
421 
422  ~ArcMapFstImpl() override {
423  if (own_mapper_) delete mapper_;
424  }
425 
427  if (!HasStart()) SetStart(FindOState(fst_->Start()));
428  return CacheImpl::Start();
429  }
430 
432  if (!HasFinal(s)) {
433  switch (final_action_) {
434  case MAP_NO_SUPERFINAL:
435  default: {
436  const auto final_arc =
437  (*mapper_)(A(0, 0, fst_->Final(FindIState(s)), kNoStateId));
438  if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
439  FSTERROR() << "ArcMapFst: Non-zero arc labels for superfinal arc";
440  SetProperties(kError, kError);
441  }
442  SetFinal(s, final_arc.weight);
443  break;
444  }
445  case MAP_ALLOW_SUPERFINAL: {
446  if (s == superfinal_) {
447  SetFinal(s);
448  } else {
449  const auto final_arc =
450  (*mapper_)(A(0, 0, fst_->Final(FindIState(s)), kNoStateId));
451  if (final_arc.ilabel == 0 && final_arc.olabel == 0) {
452  SetFinal(s, final_arc.weight);
453  } else {
454  SetFinal(s, Weight::Zero());
455  }
456  }
457  break;
458  }
459  case MAP_REQUIRE_SUPERFINAL: {
460  SetFinal(s, s == superfinal_ ? Weight::One() : Weight::Zero());
461  break;
462  }
463  }
464  }
465  return CacheImpl::Final(s);
466  }
467 
468  size_t NumArcs(StateId s) {
469  if (final_action_ == MAP_NO_SUPERFINAL) return fst_->NumArcs(s);
470  if (!HasArcs(s)) Expand(s);
471  return CacheImpl::NumArcs(s);
472  }
473 
475  if (!HasArcs(s)) Expand(s);
476  return CacheImpl::NumInputEpsilons(s);
477  }
478 
480  if (!HasArcs(s)) Expand(s);
482  }
483 
484  // This should only be called when `fst_` is known to be an `ExpandedFst`.
485  StateId NumStates() const {
486  static_assert(is_expanded,
487  "NumStates() only supported if the input is an ExpandedFst");
488  static_assert(CoreConditions<C>::value,
489  "NumStates() only supported for mappers that conserve the "
490  "expanded property and don't create a superfinal state");
491  return fst_->NumStates();
492  }
493 
494  uint64_t Properties() const override { return Properties(kFstProperties); }
495 
496  // Sets error if found, and returns other FST impl properties.
497  uint64_t Properties(uint64_t mask) const override {
498  if ((mask & kError) && (fst_->Properties(kError, false) ||
499  (mapper_->Properties(0) & kError))) {
500  SetProperties(kError, kError);
501  }
502  return FstImpl<Arc>::Properties(mask);
503  }
504 
506  if (!HasArcs(s)) Expand(s);
507  CacheImpl::InitArcIterator(s, data);
508  }
509 
510  void Expand(StateId s) {
511  // Add exiting arcs.
512  if (s == superfinal_) {
513  SetArcs(s);
514  return;
515  }
516  for (ArcIterator<FromFst> aiter(*fst_, FindIState(s)); !aiter.Done();
517  aiter.Next()) {
518  auto aarc = aiter.Value();
519  aarc.nextstate = FindOState(aarc.nextstate);
520  PushArc(s, (*mapper_)(aarc));
521  }
522 
523  // Check for superfinal arcs.
524  if (!HasFinal(s) || Final(s) == Weight::Zero()) {
525  switch (final_action_) {
526  case MAP_NO_SUPERFINAL:
527  default:
528  break;
529  case MAP_ALLOW_SUPERFINAL: {
530  auto final_arc =
531  (*mapper_)(A(0, 0, fst_->Final(FindIState(s)), kNoStateId));
532  if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
533  if (superfinal_ == kNoStateId) superfinal_ = nstates_++;
534  final_arc.nextstate = superfinal_;
535  PushArc(s, std::move(final_arc));
536  }
537  break;
538  }
539  case MAP_REQUIRE_SUPERFINAL: {
540  const auto final_arc =
541  (*mapper_)(A(0, 0, fst_->Final(FindIState(s)), kNoStateId));
542  if (final_arc.ilabel != 0 || final_arc.olabel != 0 ||
543  final_arc.weight != B::Weight::Zero()) {
544  EmplaceArc(s, final_arc.ilabel, final_arc.olabel, final_arc.weight,
545  superfinal_);
546  }
547  break;
548  }
549  }
550  }
551  SetArcs(s);
552  }
553 
554  private:
555  void Init() {
556  SetType("map");
557  if (mapper_->InputSymbolsAction() == MAP_COPY_SYMBOLS) {
558  SetInputSymbols(fst_->InputSymbols());
559  } else if (mapper_->InputSymbolsAction() == MAP_CLEAR_SYMBOLS) {
560  SetInputSymbols(nullptr);
561  }
562  if (mapper_->OutputSymbolsAction() == MAP_COPY_SYMBOLS) {
563  SetOutputSymbols(fst_->OutputSymbols());
564  } else if (mapper_->OutputSymbolsAction() == MAP_CLEAR_SYMBOLS) {
565  SetOutputSymbols(nullptr);
566  }
567  if (fst_->Start() == kNoStateId) {
568  final_action_ = MAP_NO_SUPERFINAL;
569  SetProperties(kNullProperties);
570  } else {
571  final_action_ = mapper_->FinalAction();
572  uint64_t props = fst_->Properties(kCopyProperties, false);
573  SetProperties(mapper_->Properties(props));
574  if (final_action_ == MAP_REQUIRE_SUPERFINAL) superfinal_ = 0;
575  }
576  }
577 
578  // Maps from output state to input state.
579  StateId FindIState(StateId s) {
580  if (superfinal_ == kNoStateId || s < superfinal_) {
581  return s;
582  } else {
583  return s - 1;
584  }
585  }
586 
587  // Maps from input state to output state.
588  StateId FindOState(StateId is) {
589  auto os = is;
590  if (!(superfinal_ == kNoStateId || is < superfinal_)) ++os;
591  if (os >= nstates_) nstates_ = os + 1;
592  return os;
593  }
594 
595  std::unique_ptr<const FromFst> fst_;
596  C *mapper_;
597  const bool own_mapper_;
598  MapFinalAction final_action_;
599  StateId superfinal_;
600  StateId nstates_;
601 };
602 
603 template <class A, class B, class C, class CacheStore,
604  PropagateKExpanded should_propagate_expanded_fst>
605 using ArcMapFstBase = std::conditional_t<
606  should_propagate_expanded_fst == PropagateKExpanded::kIfPossible &&
608  ImplToExpandedFst<internal::ArcMapFstImpl<A, B, C, CacheStore,
609  /*is_expanded=*/true>>,
610  ImplToFst<internal::ArcMapFstImpl<A, B, C, CacheStore,
611  /*is_expanded=*/false>>>;
612 
613 } // namespace internal
614 
615 // Maps an arc type A to an arc type B using Mapper function object
616 // C. This version is a delayed FST. If `propagate_expanded_fst` is true,
617 // and the `ArcMapper` is known to be capable of maintaining `ExpandedFst<B>`
618 // status, the resulting `ArcMapFst` will be an `ExpandedFst<B>`, and will
619 // exclusively accept `ExpandedFst<B>`s as input in the constructor. Otherwise,
620 // it will be an `Fst<B>` that accepts `Fst<B>` as input.
621 // `propagate_expanded_fst` will be set automatically when using CTAD, but
622 // otherwise must be opted into manually if one needs to ensure to maintain
623 // `ExpandedFst` status.
624 template <class A, class B, class C, class CacheStore = DefaultCacheStore<B>,
625  PropagateKExpanded propagate_expanded_fst = PropagateKExpanded::kNo>
626 class ArcMapFst : public internal::ArcMapFstBase<A, B, C, CacheStore,
627  propagate_expanded_fst> {
628  using Base =
630 
631  public:
632  using Arc = B;
633  using StateId = typename Arc::StateId;
634  using Weight = typename Arc::Weight;
635 
636  using Store = CacheStore;
637  using State = typename Store::State;
638  using typename Base::Impl;
639  using FromFst = typename Impl::FromFst;
640 
641  friend class ArcIterator<
642  ArcMapFst<A, B, C, CacheStore, propagate_expanded_fst>>;
643  friend class StateIterator<
644  ArcMapFst<A, B, C, CacheStore, propagate_expanded_fst>>;
645 
646  explicit ArcMapFst(const FromFst &fst, const C &mapper = C(),
647  const ArcMapFstOptions &opts = ArcMapFstOptions())
648  : Base(std::make_shared<Impl>(fst, mapper, opts)) {}
649 
650  ArcMapFst(const FromFst &fst, C *mapper,
651  const ArcMapFstOptions &opts = ArcMapFstOptions())
652  : Base(std::make_shared<Impl>(fst, mapper, opts)) {}
653 
654  // See Fst<>::Copy() for doc.
655  ArcMapFst(const ArcMapFst &fst, bool safe = false) : Base(fst, safe) {}
656 
657  // Get a copy of this ArcMapFst. See Fst<>::Copy() for further doc.
658  ArcMapFst *Copy(bool safe = false) const override {
659  return new ArcMapFst(*this, safe);
660  }
661 
662  inline void InitStateIterator(StateIteratorData<B> *data) const override;
663 
664  void InitArcIterator(StateId s, ArcIteratorData<B> *data) const override {
665  GetMutableImpl()->InitArcIterator(s, data);
666  }
667 
668  protected:
669  using Base::GetImpl;
670  using Base::GetMutableImpl;
671 
672  private:
673  ArcMapFst &operator=(const ArcMapFst &) = delete;
674 };
675 
676 // Specialization for ArcMapFst.
677 //
678 // This may be derived from.
679 template <class A, class B, class C, class CacheStore,
680  PropagateKExpanded propagate_expanded_fst>
681 class StateIterator<ArcMapFst<A, B, C, CacheStore, propagate_expanded_fst>>
682  : public StateIteratorBase<B> {
683  public:
685  using StateId = typename B::StateId;
686 
687  explicit StateIterator(const FST &fst)
688  : impl_(fst.GetImpl()),
689  siter_(*impl_->fst_),
690  s_(0),
691  superfinal_(impl_->final_action_ == MAP_REQUIRE_SUPERFINAL) {
692  CheckSuperfinal();
693  }
694 
695  bool Done() const final { return siter_.Done() && !superfinal_; }
696 
697  StateId Value() const final { return s_; }
698 
699  void Next() final {
700  ++s_;
701  if (!siter_.Done()) {
702  siter_.Next();
703  CheckSuperfinal();
704  } else if (superfinal_) {
705  superfinal_ = false;
706  }
707  }
708 
709  void Reset() final {
710  s_ = 0;
711  siter_.Reset();
712  superfinal_ = impl_->final_action_ == MAP_REQUIRE_SUPERFINAL;
713  CheckSuperfinal();
714  }
715 
716  private:
717  void CheckSuperfinal() {
718  if (impl_->final_action_ != MAP_ALLOW_SUPERFINAL || superfinal_) return;
719  if (!siter_.Done()) {
720  const auto final_arc =
721  (*impl_->mapper_)(A(0, 0, impl_->fst_->Final(s_), kNoStateId));
722  if (final_arc.ilabel != 0 || final_arc.olabel != 0) superfinal_ = true;
723  }
724  }
725 
726  const typename FST::Impl *impl_;
728  StateId s_;
729  bool superfinal_; // True if there is a superfinal state and not done.
730 };
731 
732 // Specialization for ArcMapFst.
733 template <class A, class B, class C, class CacheStore,
734  PropagateKExpanded propagate_expanded_fst>
735 class ArcIterator<ArcMapFst<A, B, C, CacheStore, propagate_expanded_fst>>
736  : public CacheArcIterator<
737  ArcMapFst<A, B, C, CacheStore, propagate_expanded_fst>> {
738  public:
739  using StateId = typename A::StateId;
741 
742  ArcIterator(const FST &fst, StateId s)
743  : CacheArcIterator<FST>(fst.GetMutableImpl(), s) {
744  if (!fst.GetImpl()->HasArcs(s)) fst.GetMutableImpl()->Expand(s);
745  }
746 };
747 
748 template <class A, class B, class C, class CacheStore,
749  PropagateKExpanded propagate_expanded_fst>
750 inline void
752  StateIteratorData<B> *data) const {
753  data->base = std::make_unique<StateIterator<ArcMapFst>>(*this);
754 }
755 
756 // CTAD deduction guides
757 // This allows constructing ArcMapFsts without specifying all the types.
758 // If the constructor receives an `ExpandedFst` as the first argument, and the
759 // `ArcMapper` is known to be capable of maintaining `ExpandedFst` status, the
760 // resulting `ArcMapFst` will be an `ExpandedFst`. Otherwise, it will be an
761 // `Fst`
762 
763 template <class ArcMapper>
764 ArcMapFst(const Fst<typename ArcMapper::FromArc> &, const ArcMapper &)
765  -> ArcMapFst<typename ArcMapper::FromArc, typename ArcMapper::ToArc,
768 template <class ArcMapper,
769  typename = std::enable_if_t<
771  ArcMapper>::value>>
772 ArcMapFst(const ExpandedFst<typename ArcMapper::FromArc> &, const ArcMapper &)
773  -> ArcMapFst<typename ArcMapper::FromArc, typename ArcMapper::ToArc,
774  ArcMapper, DefaultCacheStore<typename ArcMapper::ToArc>,
776 
777 // As above, but using the ArcMapFst(..., ArcMapper *) constructor.
778 template <class ArcMapper>
779 ArcMapFst(const Fst<typename ArcMapper::FromArc> &, ArcMapper *)
780  -> ArcMapFst<typename ArcMapper::FromArc, typename ArcMapper::ToArc,
781  ArcMapper, DefaultCacheStore<typename ArcMapper::ToArc>,
782  PropagateKExpanded::kNo>;
783 template <class ArcMapper,
784  typename = std::enable_if_t<
786  ArcMapper>::value>>
788  -> ArcMapFst<typename ArcMapper::FromArc, typename ArcMapper::ToArc,
789  ArcMapper, DefaultCacheStore<typename ArcMapper::ToArc>,
790  PropagateKExpanded::kIfPossible>;
791 
792 // Utility Mappers.
793 
794 // Mapper that returns its input.
795 template <class A>
797  public:
798  using FromArc = A;
799  using ToArc = A;
800 
801  constexpr ToArc operator()(const FromArc &arc) const { return arc; }
802 
803  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
804 
806  return MAP_COPY_SYMBOLS;
807  }
808 
810  return MAP_COPY_SYMBOLS;
811  }
812 
813  constexpr uint64_t Properties(uint64_t props) const { return props; }
814 };
815 
816 // Mapper that converts all input symbols to epsilon.
817 template <class A>
819  public:
820  using FromArc = A;
821  using ToArc = A;
822 
823  constexpr ToArc operator()(const FromArc &arc) const {
824  return ToArc(0, arc.olabel, arc.weight, arc.nextstate);
825  }
826 
827  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
828 
830  return MAP_CLEAR_SYMBOLS;
831  }
832 
834  return MAP_COPY_SYMBOLS;
835  }
836 
837  constexpr uint64_t Properties(uint64_t props) const {
838  return (props & kSetArcProperties) | kIEpsilons | kILabelSorted;
839  }
840 };
841 
842 // Mapper that converts all output symbols to epsilon.
843 template <class A>
845  public:
846  using FromArc = A;
847  using ToArc = A;
848 
849  constexpr ToArc operator()(const FromArc &arc) const {
850  return ToArc(arc.ilabel, 0, arc.weight, arc.nextstate);
851  }
852 
853  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
854 
856  return MAP_COPY_SYMBOLS;
857  }
858 
860  return MAP_CLEAR_SYMBOLS;
861  }
862 
863  constexpr uint64_t Properties(uint64_t props) const {
864  return (props & kSetArcProperties) | kOEpsilons | kOLabelSorted;
865  }
866 };
867 
868 // Mapper that returns its input with final states redirected to a single
869 // super-final state.
870 template <class A>
872  public:
873  using FromArc = A;
874  using ToArc = A;
875  using Label = typename FromArc::Label;
876  using Weight = typename FromArc::Weight;
877 
878  // Arg allows setting super-final label.
879  constexpr explicit SuperFinalMapper(Label final_label = 0)
880  : final_label_(final_label) {}
881 
882  ToArc operator()(const FromArc &arc) const {
883  // Super-final arc.
884  if (arc.nextstate == kNoStateId && arc.weight != Weight::Zero()) {
885  return ToArc(final_label_, final_label_, arc.weight, kNoStateId);
886  } else {
887  return arc;
888  }
889  }
890 
891  constexpr MapFinalAction FinalAction() const {
892  return MAP_REQUIRE_SUPERFINAL;
893  }
894 
896  return MAP_COPY_SYMBOLS;
897  }
898 
900  return MAP_COPY_SYMBOLS;
901  }
902 
903  uint64_t Properties(uint64_t props) const {
904  if (final_label_ == 0) {
905  return props & kAddSuperFinalProperties;
906  } else {
909  }
910  }
911 
912  private:
913  const Label final_label_;
914 };
915 
916 // Mapper that leaves labels and nextstate unchanged and constructs a new weight
917 // from the underlying value of the arc weight. If no weight converter is
918 // explictly specified, requires that there is a WeightConvert class
919 // specialization that converts the weights.
920 template <class A, class B,
923  public:
924  using FromArc = A;
925  using ToArc = B;
926  using Converter = C;
927  using FromWeight = typename FromArc::Weight;
928  using ToWeight = typename ToArc::Weight;
929 
930  // NB: Declares the default constructor only if the converter is default
931  // constructible.
932  constexpr WeightConvertMapper() = default;
933 
934  constexpr explicit WeightConvertMapper(const Converter &c)
935  : convert_weight_(c) {}
936 
937  constexpr ToArc operator()(const FromArc &arc) const {
938  return ToArc(arc.ilabel, arc.olabel, convert_weight_(arc.weight),
939  arc.nextstate);
940  }
941 
942  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
943 
945  return MAP_COPY_SYMBOLS;
946  }
947 
949  return MAP_COPY_SYMBOLS;
950  }
951 
952  constexpr uint64_t Properties(uint64_t props) const { return props; }
953 
954  private:
955  // NB: This is non-const only to work around compiler configurations not
956  // implementing CWG defect report 2394:
957  // https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2394.
958  Converter convert_weight_;
959 };
960 
961 // Non-precision-changing weight conversions; consider using more efficient
962 // Cast method instead.
963 
965 
967 
968 // Precision-changing weight conversions.
969 
971 
973 
975 
977 
978 // Mapper from A to GallicArc<A>.
979 template <class A, GallicType G = GALLIC_LEFT>
981  public:
982  using FromArc = A;
984 
986  using AW = typename FromArc::Weight;
987  using GW = typename ToArc::Weight;
988 
989  ToArc operator()(const FromArc &arc) const {
990  // Super-final arc.
991  if (arc.nextstate == kNoStateId && arc.weight != AW::Zero()) {
992  return ToArc(0, 0, GW(SW::One(), arc.weight), kNoStateId);
993  // Super-non-final arc.
994  } else if (arc.nextstate == kNoStateId) {
995  return ToArc(0, 0, GW::Zero(), kNoStateId);
996  // Epsilon label.
997  } else if (arc.olabel == 0) {
998  return ToArc(arc.ilabel, arc.ilabel, GW(SW::One(), arc.weight),
999  arc.nextstate);
1000  // Regular label.
1001  } else {
1002  return ToArc(arc.ilabel, arc.ilabel, GW(SW(arc.olabel), arc.weight),
1003  arc.nextstate);
1004  }
1005  }
1006 
1007  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1008 
1010  return MAP_COPY_SYMBOLS;
1011  }
1012 
1014  return MAP_CLEAR_SYMBOLS;
1015  }
1016 
1017  uint64_t Properties(uint64_t props) const {
1018  return ProjectProperties(props, true) & kWeightInvariantProperties;
1019  }
1020 };
1021 
1022 // Mapper from GallicArc<A> to A.
1023 template <class A, GallicType G = GALLIC_LEFT>
1025  public:
1027  using ToArc = A;
1028 
1029  using Label = typename ToArc::Label;
1030  using AW = typename ToArc::Weight;
1031  using GW = typename FromArc::Weight;
1032 
1033  explicit FromGallicMapper(Label superfinal_label = 0)
1034  : superfinal_label_(superfinal_label), error_(false) {}
1035 
1036  ToArc operator()(const FromArc &arc) const {
1037  // 'Super-non-final' arc.
1038  if (arc.nextstate == kNoStateId && arc.weight == GW::Zero()) {
1039  return A(arc.ilabel, 0, AW::Zero(), kNoStateId);
1040  }
1041  Label l = kNoLabel;
1042  AW weight = AW::Zero();
1043  if (!Extract(arc.weight, &weight, &l) || arc.ilabel != arc.olabel) {
1044  FSTERROR() << "FromGallicMapper: Unrepresentable weight: " << arc.weight
1045  << " for arc with ilabel = " << arc.ilabel
1046  << ", olabel = " << arc.olabel
1047  << ", nextstate = " << arc.nextstate;
1048  error_ = true;
1049  }
1050  if (arc.ilabel == 0 && l != 0 && arc.nextstate == kNoStateId) {
1051  return ToArc(superfinal_label_, l, weight, arc.nextstate);
1052  } else {
1053  return ToArc(arc.ilabel, l, weight, arc.nextstate);
1054  }
1055  }
1056 
1057  constexpr MapFinalAction FinalAction() const { return MAP_ALLOW_SUPERFINAL; }
1058 
1060  return MAP_COPY_SYMBOLS;
1061  }
1062 
1064  return MAP_CLEAR_SYMBOLS;
1065  }
1066 
1067  uint64_t Properties(uint64_t inprops) const {
1068  uint64_t outprops = inprops & kOLabelInvariantProperties &
1070  if (error_) outprops |= kError;
1071  return outprops;
1072  }
1073 
1074  private:
1075  template <GallicType GT>
1076  static bool Extract(const GallicWeight<Label, AW, GT> &gallic_weight,
1077  typename A::Weight *weight, typename A::Label *label) {
1079  const GW &w1 = gallic_weight.Value1();
1080  const AW &w2 = gallic_weight.Value2();
1081  typename GW::Iterator iter1(w1);
1082  const Label l = w1.Size() == 1 ? iter1.Value() : 0;
1083  if (l == kStringInfinity || l == kStringBad || w1.Size() > 1) return false;
1084  *label = l;
1085  *weight = w2;
1086  return true;
1087  }
1088 
1089  static bool Extract(const GallicWeight<Label, AW, GALLIC> &gallic_weight,
1090  typename A::Weight *weight, typename A::Label *label) {
1091  if (gallic_weight.Size() > 1) return false;
1092  if (gallic_weight.Size() == 0) {
1093  *label = 0;
1094  *weight = A::Weight::Zero();
1095  return true;
1096  }
1097  return Extract<GALLIC_RESTRICT>(gallic_weight.Back(), weight, label);
1098  }
1099 
1100  const Label superfinal_label_;
1101  mutable bool error_;
1102 };
1103 
1104 // Mapper from GallicArc<A> to A.
1105 template <class A, GallicType G = GALLIC_LEFT>
1107  public:
1109  using ToArc = A;
1110 
1111  using Label = typename ToArc::Label;
1112  using StateId = typename ToArc::StateId;
1113  using AW = typename ToArc::Weight;
1114  using GW = typename FromArc::Weight;
1116 
1118  : fst_(fst),
1119  lmax_(0),
1120  osymbols_(fst->OutputSymbols()),
1121  isymbols_(nullptr),
1122  error_(false) {
1123  fst_->DeleteStates();
1124  state_ = fst_->AddState();
1125  fst_->SetStart(state_);
1126  fst_->SetFinal(state_);
1127  if (osymbols_) {
1128  std::string name = osymbols_->Name() + "_from_gallic";
1129  fst_->SetInputSymbols(new SymbolTable(name));
1130  isymbols_ = fst_->MutableInputSymbols();
1131  const int64_t zero = 0;
1132  isymbols_->AddSymbol(osymbols_->Find(zero), 0);
1133  } else {
1134  fst_->SetInputSymbols(nullptr);
1135  }
1136  }
1137 
1138  ToArc operator()(const FromArc &arc) {
1139  // Super-non-final arc.
1140  if (arc.nextstate == kNoStateId && arc.weight == GW::Zero()) {
1141  return ToArc(arc.ilabel, 0, AW::Zero(), kNoStateId);
1142  }
1143  SW w1 = arc.weight.Value1();
1144  AW w2 = arc.weight.Value2();
1145  Label l;
1146  if (w1.Size() == 0) {
1147  l = 0;
1148  } else if (auto [it, inserted] = map_.emplace(w1, kNoLabel); !inserted) {
1149  l = it->second;
1150  } else {
1151  l = ++lmax_;
1152  it->second = l;
1153  StringWeightIterator<SW> iter1(w1);
1154  StateId n;
1155  std::string s;
1156  for (size_t i = 0, p = state_; i < w1.Size(); ++i, iter1.Next(), p = n) {
1157  n = i == w1.Size() - 1 ? state_ : fst_->AddState();
1158  fst_->AddArc(p, ToArc(i ? 0 : l, iter1.Value(), n));
1159  if (isymbols_) {
1160  if (i) s = s + "_";
1161  s = s + osymbols_->Find(iter1.Value());
1162  }
1163  }
1164  if (isymbols_) isymbols_->AddSymbol(s, l);
1165  }
1166  if (l == kStringInfinity || l == kStringBad || arc.ilabel != arc.olabel) {
1167  FSTERROR() << "GallicToNewSymbolMapper: Unrepresentable weight: " << l;
1168  error_ = true;
1169  }
1170  return ToArc(arc.ilabel, l, w2, arc.nextstate);
1171  }
1172 
1173  constexpr MapFinalAction FinalAction() const { return MAP_ALLOW_SUPERFINAL; }
1174 
1176  return MAP_COPY_SYMBOLS;
1177  }
1178 
1180  return MAP_CLEAR_SYMBOLS;
1181  }
1182 
1183  uint64_t Properties(uint64_t inprops) const {
1184  uint64_t outprops = inprops & kOLabelInvariantProperties &
1186  if (error_) outprops |= kError;
1187  return outprops;
1188  }
1189 
1190  private:
1191  class StringKey {
1192  public:
1193  size_t operator()(const SW &x) const { return x.Hash(); }
1194  };
1195 
1196  using Map = std::unordered_map<SW, Label, StringKey>;
1197 
1198  MutableFst<ToArc> *fst_;
1199  Map map_;
1200  Label lmax_;
1201  StateId state_;
1202  const SymbolTable *osymbols_;
1203  SymbolTable *isymbols_;
1204  mutable bool error_;
1205 };
1206 
1207 // TODO(kbg): Add common base class for those mappers which do nothing except
1208 // mutate their weights.
1209 
1210 // Mapper to add a constant to all weights.
1211 template <class A>
1212 class PlusMapper {
1213  public:
1214  using FromArc = A;
1215  using ToArc = A;
1216  using Weight = typename FromArc::Weight;
1217 
1218  constexpr explicit PlusMapper(Weight weight) : weight_(std::move(weight)) {}
1219 
1220  ToArc operator()(const FromArc &arc) const {
1221  if (arc.weight == Weight::Zero()) return arc;
1222  return ToArc(arc.ilabel, arc.olabel, Plus(arc.weight, weight_),
1223  arc.nextstate);
1224  }
1225 
1226  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1227 
1229  return MAP_COPY_SYMBOLS;
1230  }
1231 
1233  return MAP_COPY_SYMBOLS;
1234  }
1235 
1236  constexpr uint64_t Properties(uint64_t props) const {
1237  return props & kWeightInvariantProperties;
1238  }
1239 
1240  private:
1241  const Weight weight_;
1242 };
1243 
1244 // Mapper to (right) multiply a constant to all weights.
1245 template <class A>
1247  public:
1248  using FromArc = A;
1249  using ToArc = A;
1250  using Weight = typename FromArc::Weight;
1251 
1252  constexpr explicit TimesMapper(Weight weight) : weight_(std::move(weight)) {}
1253 
1254  ToArc operator()(const FromArc &arc) const {
1255  if (arc.weight == Weight::Zero()) return arc;
1256  return ToArc(arc.ilabel, arc.olabel, Times(arc.weight, weight_),
1257  arc.nextstate);
1258  }
1259 
1260  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1261 
1263  return MAP_COPY_SYMBOLS;
1264  }
1265 
1267  return MAP_COPY_SYMBOLS;
1268  }
1269 
1270  constexpr uint64_t Properties(uint64_t props) const {
1271  return props & kWeightInvariantProperties;
1272  }
1273 
1274  private:
1275  const Weight weight_;
1276 };
1277 
1278 // Mapper to take all weights to a constant power. The power argument is stored
1279 // as a double, so if there is a floating-point power implementation for this
1280 // weight type, it will take precedence. Otherwise, the power argument's 53 bits
1281 // of integer precision will be implicitly converted to a size_t and the default
1282 // power implementation (iterated multiplication) will be used instead.
1283 template <class A>
1285  public:
1286  using FromArc = A;
1287  using ToArc = A;
1288  using Weight = typename FromArc::Weight;
1289 
1290  explicit PowerMapper(double power) : power_(power) {}
1291 
1292  ToArc operator()(const FromArc &arc) const {
1293  return ToArc(arc.ilabel, arc.olabel, Power(arc.weight, power_),
1294  arc.nextstate);
1295  }
1296 
1297  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1298 
1300  return MAP_COPY_SYMBOLS;
1301  }
1302 
1304  return MAP_COPY_SYMBOLS;
1305  }
1306 
1307  constexpr uint64_t Properties(uint64_t props) const {
1308  return props & kWeightInvariantProperties;
1309  }
1310 
1311  private:
1312  const double power_;
1313 };
1314 
1315 // Mapper to reciprocate all non-Zero() weights.
1316 template <class A>
1318  public:
1319  using FromArc = A;
1320  using ToArc = A;
1321  using Weight = typename FromArc::Weight;
1322 
1323  ToArc operator()(const FromArc &arc) const {
1324  if (arc.weight == Weight::Zero()) return arc;
1325  return ToArc(arc.ilabel, arc.olabel, Divide(Weight::One(), arc.weight),
1326  arc.nextstate);
1327  }
1328 
1329  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1330 
1332  return MAP_COPY_SYMBOLS;
1333  }
1334 
1336  return MAP_COPY_SYMBOLS;
1337  }
1338 
1339  constexpr uint64_t Properties(uint64_t props) const {
1340  return props & kWeightInvariantProperties;
1341  }
1342 };
1343 
1344 // Mapper to map all non-Zero() weights to One().
1345 template <class A, class B = A>
1347  public:
1348  using FromArc = A;
1349  using ToArc = B;
1350  using FromWeight = typename FromArc::Weight;
1351  using ToWeight = typename ToArc::Weight;
1352 
1353  ToArc operator()(const FromArc &arc) const {
1354  return ToArc(
1355  arc.ilabel, arc.olabel,
1356  arc.weight != FromWeight::Zero() ? ToWeight::One() : ToWeight::Zero(),
1357  arc.nextstate);
1358  }
1359 
1360  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1361 
1363  return MAP_COPY_SYMBOLS;
1364  }
1365 
1367  return MAP_COPY_SYMBOLS;
1368  }
1369 
1370  constexpr uint64_t Properties(uint64_t props) const {
1371  return (props & kWeightInvariantProperties) | kUnweighted;
1372  }
1373 };
1374 
1375 // Mapper to quantize all weights.
1376 template <class A, class B = A>
1378  public:
1379  using FromArc = A;
1380  using ToArc = B;
1381  using FromWeight = typename FromArc::Weight;
1382  using ToWeight = typename ToArc::Weight;
1383 
1384  QuantizeMapper() : delta_(kDelta) {}
1385 
1386  explicit QuantizeMapper(float d) : delta_(d) {}
1387 
1388  ToArc operator()(const FromArc &arc) const {
1389  return ToArc(arc.ilabel, arc.olabel, arc.weight.Quantize(delta_),
1390  arc.nextstate);
1391  }
1392 
1393  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1394 
1396  return MAP_COPY_SYMBOLS;
1397  }
1398 
1400  return MAP_COPY_SYMBOLS;
1401  }
1402 
1403  constexpr uint64_t Properties(uint64_t props) const {
1404  return props & kWeightInvariantProperties;
1405  }
1406 
1407  private:
1408  const float delta_;
1409 };
1410 
1411 // Mapper from A to B under the assumption:
1412 //
1413 // B::Weight = A::Weight::ReverseWeight
1414 // B::Label == A::Label
1415 // B::StateId == A::StateId
1416 //
1417 // The weight is reversed, while the label and nextstate are preserved.
1418 template <class A, class B>
1420  public:
1421  using FromArc = A;
1422  using ToArc = B;
1423  static_assert(std::is_same_v<typename ToArc::Weight,
1424  typename FromArc::Weight::ReverseWeight>,
1425  "ToArc::Weight must be FromArc::Weight::ReverseWeight");
1426  static_assert(std::is_same_v<typename ToArc::Label, typename FromArc::Label>,
1427  "ToArc::Label must be FromArc::Label");
1428  static_assert(
1429  std::is_same_v<typename ToArc::StateId, typename FromArc::StateId>,
1430  "ToArc::StateId must be FromArc::StateId");
1431 
1432  constexpr ToArc operator()(const FromArc &arc) const {
1433  return ToArc(arc.ilabel, arc.olabel, arc.weight.Reverse(), arc.nextstate);
1434  }
1435 
1436  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1437 
1439  return MAP_COPY_SYMBOLS;
1440  }
1441 
1443  return MAP_COPY_SYMBOLS;
1444  }
1445 
1446  constexpr uint64_t Properties(uint64_t props) const { return props; }
1447 };
1448 
1449 } // namespace fst
1450 
1451 #endif // FST_ARC_MAP_H_
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:1059
ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:1036
MapSymbolsAction
Definition: arc-map.h:65
ssize_t NumOutputEpsilons(const ExpandedFst< Arc > &fst, typename Arc::StateId s)
Definition: expanded-fst.h:124
void ArcMap(MutableFst< A > *fst, C *mapper)
Definition: arc-map.h:135
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:1438
constexpr SuperFinalMapper(Label final_label=0)
Definition: arc-map.h:879
typename FromArc::Weight Weight
Definition: arc-map.h:876
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:1009
GallicToNewSymbolsMapper(MutableFst< ToArc > *fst)
Definition: arc-map.h:1117
constexpr uint64_t kWeightInvariantProperties
Definition: properties.h:280
constexpr int kNoLabel
Definition: fst.h:194
uint64_t Properties(uint64_t props) const
Definition: arc-map.h:903
virtual uint64_t Properties(uint64_t mask, bool test) const =0
constexpr uint64_t kOEpsilons
Definition: properties.h:89
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:827
ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:882
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:1007
QuantizeMapper(float d)
Definition: arc-map.h:1386
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:944
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:1013
ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:1323
ErrorWeight Plus(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:61
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:1331
virtual size_t NumArcs(StateId) const =0
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:859
void InitStateIterator(StateIteratorData< B > *data) const override
Definition: arc-map.h:751
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:1366
ArcMapFstImpl(const FromFst &fst, C *mapper, const ArcMapFstOptions &opts)
Definition: arc-map.h:402
typename ToArc::Weight ToWeight
Definition: arc-map.h:1351
constexpr uint64_t Properties(uint64_t props) const
Definition: arc-map.h:1270
const Label & Value() const
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:1399
std::false_type type
Definition: arc-map.h:331
constexpr ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:849
constexpr int kStringBad
Definition: string-weight.h:44
size_t Hash() const
constexpr ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:937
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:1057
Arc::Weight Final(const ExpandedFst< Arc > &fst, typename Arc::StateId s)
Definition: expanded-fst.h:107
void InitArcIterator(StateId s, ArcIteratorData< B > *data) const override
Definition: arc-map.h:664
constexpr ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:1432
typename FromArc::Weight Weight
Definition: arc-map.h:1216
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:1173
ErrorWeight Times(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:64
Label ilabel
Definition: arc.h:50
typename FromArc::Label Label
Definition: arc-map.h:875
ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:1220
std::bool_constant<(C{}.FinalAction()==MAP_NO_SUPERFINAL)&&(C{}.Properties(kExpanded)==kExpanded)> CoreConditions
Definition: arc-map.h:349
constexpr uint64_t kError
Definition: properties.h:52
typename ToArc::Weight ToWeight
Definition: arc-map.h:1382
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:1297
virtual void SetInputSymbols(const SymbolTable *isyms)=0
typename FromArc::Weight Weight
Definition: arc-map.h:1250
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:1179
constexpr uint64_t Properties(uint64_t props) const
Definition: arc-map.h:813
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:1266
virtual Weight Final(StateId) const =0
typename ToArc::Weight GW
Definition: arc-map.h:987
uint64_t Properties(uint64_t mask) const override
Definition: arc-map.h:497
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:1360
SetType
Definition: set-weight.h:59
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:1393
virtual void SetStart(StateId)=0
constexpr uint64_t Properties(uint64_t props) const
Definition: arc-map.h:863
ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:1254
ssize_t NumArcs(const ExpandedFst< Arc > &fst, typename Arc::StateId s)
Definition: expanded-fst.h:113
ToArc operator()(const FromArc &arc)
Definition: arc-map.h:1138
uint64_t Properties(uint64_t props) const
Definition: arc-map.h:1017
typename FromArc::Weight Weight
Definition: arc-map.h:1288
uint64_t Properties(uint64_t inprops) const
Definition: arc-map.h:1067
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:1260
constexpr uint64_t Properties(uint64_t props) const
Definition: arc-map.h:1446
constexpr int kNoStateId
Definition: fst.h:195
FromGallicMapper(Label superfinal_label=0)
Definition: arc-map.h:1033
ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:1388
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:1303
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:1362
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:1329
constexpr TimesMapper(Weight weight)
Definition: arc-map.h:1252
void Expand(StateId s)
Definition: arc-map.h:510
ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:1292
virtual void ReserveArcs(StateId, size_t)
Definition: mutable-fst.h:104
#define FSTERROR()
Definition: util.h:57
size_t NumInputEpsilons(StateId s)
Definition: arc-map.h:474
ArcMapFst(const ArcMapFst &fst, bool safe=false)
Definition: arc-map.h:655
MapFinalAction
Definition: arc-map.h:50
constexpr PlusMapper(Weight weight)
Definition: arc-map.h:1218
constexpr int kStringInfinity
Definition: string-weight.h:43
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:809
uint64_t Properties() const override
Definition: arc-map.h:494
ssize_t NumInputEpsilons(const ExpandedFst< Arc > &fst, typename Arc::StateId s)
Definition: expanded-fst.h:118
typename FromArc::Weight Weight
Definition: arc-map.h:1321
std::conditional_t< is_expanded, ExpandedFst< A >, Fst< A >> FromFst
Definition: arc-map.h:368
constexpr uint64_t kOLabelSorted
Definition: properties.h:99
constexpr uint64_t kCopyProperties
Definition: properties.h:163
constexpr uint64_t Properties(uint64_t props) const
Definition: arc-map.h:952
virtual void SetProperties(uint64_t props, uint64_t mask)=0
typename CacheStore::State State
Definition: arc-map.h:375
constexpr ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:823
typename FirstCacheStore< VectorCacheStore< CacheState< Arc > > >::State State
Definition: cache.h:673
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:833
typename ExtractOr< Extract, Obj, void >::type ExtractOrT
Definition: arc-map.h:339
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:899
void InitArcIterator(StateId s, ArcIteratorData< B > *data)
Definition: arc-map.h:505
Label olabel
Definition: arc.h:51
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:1228
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:1395
virtual StateId Start() const =0
bool Done() const
Definition: fst.h:531
Weight weight
Definition: arc.h:52
std::unique_ptr< StateIteratorBase< Arc > > base
Definition: fst.h:381
constexpr uint64_t kOLabelInvariantProperties
Definition: properties.h:270
constexpr uint64_t Properties(uint64_t props) const
Definition: arc-map.h:1403
constexpr uint64_t kNullProperties
Definition: properties.h:150
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:1232
constexpr WeightConvertMapper(const Converter &c)
Definition: arc-map.h:934
constexpr uint64_t kIEpsilons
Definition: properties.h:84
typename ToArc::StateId StateId
Definition: arc-map.h:1112
typename FromArc::Weight GW
Definition: arc-map.h:1031
typename FromArc::Weight GW
Definition: arc-map.h:1114
typename ToArc::Weight AW
Definition: arc-map.h:1030
constexpr uint64_t Properties(uint64_t props) const
Definition: arc-map.h:1339
virtual std::optional< StateId > NumStatesIfKnown() const
Definition: fst.h:227
constexpr uint64_t kILabelInvariantProperties
Definition: properties.h:261
constexpr uint64_t Properties(uint64_t props) const
Definition: arc-map.h:837
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:853
constexpr uint64_t kILabelSorted
Definition: properties.h:94
constexpr uint64_t kFstProperties
Definition: properties.h:326
virtual void AddArc(StateId, const Arc &)=0
constexpr uint64_t kUnweighted
Definition: properties.h:106
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:1226
typename FromArc::Weight FromWeight
Definition: arc-map.h:927
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:829
virtual const SymbolTable * InputSymbols() const =0
StateId NumStates() const
Definition: arc-map.h:485
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:942
size_t Size() const
typename ToArc::Label Label
Definition: arc-map.h:1111
ArcMapFst(const FromFst &fst, C *mapper, const ArcMapFstOptions &opts=ArcMapFstOptions())
Definition: arc-map.h:650
ErrorWeight Divide(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:67
virtual StateId AddState()=0
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:1442
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:895
typename ToArc::Label Label
Definition: arc-map.h:1029
virtual void ReserveStates(size_t)
Definition: mutable-fst.h:101
virtual void SetFinal(StateId s, Weight weight=Weight::One())=0
typename Arc::StateId StateId
Definition: arc-map.h:366
ArcMapFst(const FromFst &fst, const C &mapper=C(), const ArcMapFstOptions &opts=ArcMapFstOptions())
Definition: arc-map.h:646
typename Arc::Weight Weight
Definition: arc-map.h:367
ArcMapFst * Copy(bool safe=false) const override
Definition: arc-map.h:658
virtual void DeleteStates(const std::vector< StateId > &)=0
StateId nextstate
Definition: arc.h:53
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:1262
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:1175
uint64_t ProjectProperties(uint64_t inprops, bool project_input)
Definition: properties.cc:195
virtual void SetOutputSymbols(const SymbolTable *osyms)=0
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:803
typename FromArc::Weight AW
Definition: arc-map.h:986
ArcMapFstImpl(const ArcMapFstImpl &impl)
Definition: arc-map.h:412
void Expand(const Fst< Arc > &ifst, const std::vector< std::pair< typename Arc::Label, typename Arc::Label >> &parens, const std::vector< typename Arc::Label > &assignments, MutableFst< Arc > *ofst, const MPdtExpandOptions &opts)
Definition: expand.h:324
void Extract(FarReader< Arc > &reader, int32_t generate_sources, const std::string &keys, std::string_view key_separator, std::string_view range_delimiter, std::string_view source_prefix, std::string_view source_suffix)
Definition: extract.h:66
ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:1353
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:891
constexpr TropicalWeightTpl< T > Power(const TropicalWeightTpl< T > &w, V n)
Definition: float-weight.h:400
typename FromArc::Weight FromWeight
Definition: arc-map.h:1350
constexpr uint64_t Properties(uint64_t props) const
Definition: arc-map.h:1370
ArcMapFstOptions(const CacheOptions &opts)
Definition: arc-map.h:318
ArcMapFst(const Fst< typename ArcMapper::FromArc > &, const ArcMapper &) -> ArcMapFst< typename ArcMapper::FromArc, typename ArcMapper::ToArc, ArcMapper, DefaultCacheStore< typename ArcMapper::ToArc >, PropagateKExpanded::kNo >
PropagateKExpanded
Definition: arc-map.h:77
typename Impl::FromFst FromFst
Definition: arc-map.h:639
constexpr ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:801
uint64_t Properties(uint64_t inprops) const
Definition: arc-map.h:1183
constexpr uint64_t kExpanded
Definition: properties.h:46
constexpr MapFinalAction FinalAction() const
Definition: arc-map.h:1436
size_t NumOutputEpsilons(StateId s)
Definition: arc-map.h:479
Weight Final(StateId s)
Definition: arc-map.h:431
constexpr float kDelta
Definition: weight.h:133
constexpr uint64_t Properties(uint64_t props) const
Definition: arc-map.h:1307
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:1335
constexpr uint64_t Properties(uint64_t props) const
Definition: arc-map.h:1236
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:948
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:805
constexpr uint64_t kSetArcProperties
Definition: properties.h:224
std::conditional_t< should_propagate_expanded_fst==PropagateKExpanded::kIfPossible &&internal::IsDefaultConstructibleExpandedNoSuperfinalArcMapper< C >::value, ImplToExpandedFst< internal::ArcMapFstImpl< A, B, C, CacheStore, true >>, ImplToFst< internal::ArcMapFstImpl< A, B, C, CacheStore, false >>> ArcMapFstBase
Definition: arc-map.h:611
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:1299
constexpr MapSymbolsAction InputSymbolsAction() const
Definition: arc-map.h:855
constexpr MapSymbolsAction OutputSymbolsAction() const
Definition: arc-map.h:1063
PowerMapper(double power)
Definition: arc-map.h:1290
ToArc operator()(const FromArc &arc) const
Definition: arc-map.h:989
constexpr uint64_t kAddSuperFinalProperties
Definition: properties.h:291
ExtractOrT< CoreConditions, C > IsDefaultConstructibleExpandedNoSuperfinalArcMapper
Definition: arc-map.h:354
const StringWeight< Label, GallicStringType(G)> & Value1() const
Definition: pair-weight.h:93
size_t NumArcs(StateId s)
Definition: arc-map.h:468
typename ToArc::Weight AW
Definition: arc-map.h:1113
typename ToArc::Weight ToWeight
Definition: arc-map.h:928
virtual const SymbolTable * OutputSymbols() const =0
typename FromArc::Weight FromWeight
Definition: arc-map.h:1381