You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.6 KiB

  1. // Copyright 2005-2024 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the 'License');
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an 'AS IS' BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. // See www.openfst.org for extensive documentation on this weighted
  16. // finite-state transducer library.
  17. //
  18. // Functions and classes to invert an FST.
  19. #ifndef FST_INVERT_H_
  20. #define FST_INVERT_H_
  21. #include <cstdint>
  22. #include <memory>
  23. #include <fst/arc-map.h>
  24. #include <fst/arc.h>
  25. #include <fst/cache.h>
  26. #include <fst/float-weight.h>
  27. #include <fst/fst.h>
  28. #include <fst/impl-to-fst.h>
  29. #include <fst/mutable-fst.h>
  30. #include <fst/properties.h>
  31. #include <fst/symbol-table.h>
  32. namespace fst {
  33. // Mapper to implement inversion of an arc.
  34. template <class A>
  35. struct InvertMapper {
  36. using FromArc = A;
  37. using ToArc = A;
  38. InvertMapper() = default;
  39. ToArc operator()(const FromArc &arc) const {
  40. return ToArc(arc.olabel, arc.ilabel, arc.weight, arc.nextstate);
  41. }
  42. constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
  43. constexpr MapSymbolsAction InputSymbolsAction() const {
  44. return MAP_CLEAR_SYMBOLS;
  45. }
  46. constexpr MapSymbolsAction OutputSymbolsAction() const {
  47. return MAP_CLEAR_SYMBOLS;
  48. }
  49. uint64_t Properties(uint64_t props) const { return InvertProperties(props); }
  50. };
  51. // Inverts the transduction corresponding to an FST by exchanging the
  52. // FST's input and output labels.
  53. //
  54. // Complexity:
  55. //
  56. // Time: O(V + E)
  57. // Space: O(1)
  58. //
  59. // where V is the number of states and E is the number of arcs.
  60. template <class Arc>
  61. inline void Invert(const Fst<Arc> &ifst, MutableFst<Arc> *ofst) {
  62. std::unique_ptr<SymbolTable> input(
  63. ifst.InputSymbols() ? ifst.InputSymbols()->Copy() : nullptr);
  64. std::unique_ptr<SymbolTable> output(
  65. ifst.OutputSymbols() ? ifst.OutputSymbols()->Copy() : nullptr);
  66. ArcMap(ifst, ofst, InvertMapper<Arc>());
  67. ofst->SetInputSymbols(output.get());
  68. ofst->SetOutputSymbols(input.get());
  69. }
  70. // Destructive variant of the above.
  71. template <class Arc>
  72. inline void Invert(MutableFst<Arc> *fst) {
  73. std::unique_ptr<SymbolTable> input(
  74. fst->InputSymbols() ? fst->InputSymbols()->Copy() : nullptr);
  75. std::unique_ptr<SymbolTable> output(
  76. fst->OutputSymbols() ? fst->OutputSymbols()->Copy() : nullptr);
  77. ArcMap(fst, InvertMapper<Arc>());
  78. fst->SetInputSymbols(output.get());
  79. fst->SetOutputSymbols(input.get());
  80. }
  81. // Inverts the transduction corresponding to an FST by exchanging the
  82. // FST's input and output labels. This version is a delayed FST.
  83. //
  84. // Complexity:
  85. //
  86. // Time: O(v + e)
  87. // Space: O(1)
  88. //
  89. // where v is the number of states visited and e is the number of arcs visited.
  90. // Constant time and to visit an input state or arc is assumed and exclusive of
  91. // caching.
  92. template <class A>
  93. class InvertFst : public ArcMapFst<A, A, InvertMapper<A>> {
  94. public:
  95. using Arc = A;
  96. using Mapper = InvertMapper<Arc>;
  97. using Impl = internal::ArcMapFstImpl<A, A, InvertMapper<A>>;
  98. explicit InvertFst(const Fst<Arc> &fst) : ArcMapFst<Arc, Arc, Mapper>(fst) {
  99. GetMutableImpl()->SetOutputSymbols(fst.InputSymbols());
  100. GetMutableImpl()->SetInputSymbols(fst.OutputSymbols());
  101. }
  102. // See Fst<>::Copy() for doc.
  103. InvertFst(const InvertFst &fst, bool safe = false)
  104. : ArcMapFst<Arc, Arc, Mapper>(fst, safe) {}
  105. // Get a copy of this InvertFst. See Fst<>::Copy() for further doc.
  106. InvertFst *Copy(bool safe = false) const override {
  107. return new InvertFst(*this, safe);
  108. }
  109. private:
  110. using ImplToFst<Impl>::GetMutableImpl;
  111. };
  112. // Specialization for InvertFst.
  113. template <class Arc>
  114. class StateIterator<InvertFst<Arc>>
  115. : public StateIterator<ArcMapFst<Arc, Arc, InvertMapper<Arc>>> {
  116. public:
  117. explicit StateIterator(const InvertFst<Arc> &fst)
  118. : StateIterator<ArcMapFst<Arc, Arc, InvertMapper<Arc>>>(fst) {}
  119. };
  120. // Specialization for InvertFst.
  121. template <class Arc>
  122. class ArcIterator<InvertFst<Arc>>
  123. : public ArcIterator<ArcMapFst<Arc, Arc, InvertMapper<Arc>>> {
  124. public:
  125. using StateId = typename Arc::StateId;
  126. ArcIterator(const InvertFst<Arc> &fst, StateId s)
  127. : ArcIterator<ArcMapFst<Arc, Arc, InvertMapper<Arc>>>(fst, s) {}
  128. };
  129. // Useful alias when using StdArc.
  130. using StdInvertFst = InvertFst<StdArc>;
  131. } // namespace fst
  132. #endif // FST_INVERT_H_