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.

183 lines
5.5 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 project an FST on to its domain or range.
  19. #ifndef FST_PROJECT_H_
  20. #define FST_PROJECT_H_
  21. #include <cstdint>
  22. #include <fst/arc-map.h>
  23. #include <fst/arc.h>
  24. #include <fst/cache.h>
  25. #include <fst/float-weight.h>
  26. #include <fst/fst.h>
  27. #include <fst/impl-to-fst.h>
  28. #include <fst/mutable-fst.h>
  29. #include <fst/properties.h>
  30. namespace fst {
  31. // This specifies whether to project on input or output.
  32. enum class ProjectType { INPUT = 1, OUTPUT = 2 };
  33. OPENFST_DEPRECATED("Use `ProjectType::INPUT` instead.")
  34. inline constexpr ProjectType PROJECT_INPUT = ProjectType::INPUT;
  35. OPENFST_DEPRECATED("Use `ProjectType::OUTPUT` instead.")
  36. inline constexpr ProjectType PROJECT_OUTPUT = ProjectType::OUTPUT;
  37. // Mapper to implement projection per arc.
  38. template <class A>
  39. class ProjectMapper {
  40. public:
  41. using FromArc = A;
  42. using ToArc = A;
  43. constexpr explicit ProjectMapper(ProjectType project_type)
  44. : project_type_(project_type) {}
  45. ToArc operator()(const FromArc &arc) const {
  46. const auto label =
  47. project_type_ == ProjectType::INPUT ? arc.ilabel : arc.olabel;
  48. return ToArc(label, label, arc.weight, arc.nextstate);
  49. }
  50. constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
  51. constexpr MapSymbolsAction InputSymbolsAction() const {
  52. return project_type_ == ProjectType::INPUT ? MAP_COPY_SYMBOLS
  53. : MAP_CLEAR_SYMBOLS;
  54. }
  55. constexpr MapSymbolsAction OutputSymbolsAction() const {
  56. return project_type_ == ProjectType::OUTPUT ? MAP_COPY_SYMBOLS
  57. : MAP_CLEAR_SYMBOLS;
  58. }
  59. constexpr uint64_t Properties(uint64_t props) const {
  60. return ProjectProperties(props, project_type_ == ProjectType::INPUT);
  61. }
  62. private:
  63. const ProjectType project_type_;
  64. };
  65. // Projects an FST onto its domain or range by either copying each arcs' input
  66. // label to the output label or vice versa.
  67. //
  68. // Complexity:
  69. //
  70. // Time: O(V + E)
  71. // Space: O(1)
  72. //
  73. // where V is the number of states and E is the number of arcs.
  74. template <class Arc>
  75. inline void Project(const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
  76. ProjectType project_type) {
  77. ArcMap(ifst, ofst, ProjectMapper<Arc>(project_type));
  78. switch (project_type) {
  79. case ProjectType::INPUT:
  80. ofst->SetOutputSymbols(ifst.InputSymbols());
  81. return;
  82. case ProjectType::OUTPUT:
  83. ofst->SetInputSymbols(ifst.OutputSymbols());
  84. return;
  85. }
  86. }
  87. // Destructive variant of the above.
  88. template <class Arc>
  89. inline void Project(MutableFst<Arc> *fst, ProjectType project_type) {
  90. ArcMap(fst, ProjectMapper<Arc>(project_type));
  91. switch (project_type) {
  92. case ProjectType::INPUT:
  93. fst->SetOutputSymbols(fst->InputSymbols());
  94. return;
  95. case ProjectType::OUTPUT:
  96. fst->SetInputSymbols(fst->OutputSymbols());
  97. return;
  98. }
  99. }
  100. // Projects an FST onto its domain or range by either copying each arc's input
  101. // label to the output label or vice versa. This version is a delayed FST.
  102. //
  103. // Complexity:
  104. //
  105. // Time: O(v + e)
  106. // Space: O(1)
  107. //
  108. // where v is the number of states visited and e is the number of arcs visited.
  109. // Constant time and to visit an input state or arc is assumed and exclusive of
  110. // caching.
  111. template <class A>
  112. class ProjectFst : public ArcMapFst<A, A, ProjectMapper<A>> {
  113. public:
  114. using FromArc = A;
  115. using ToArc = A;
  116. using Impl = internal::ArcMapFstImpl<A, A, ProjectMapper<A>>;
  117. ProjectFst(const Fst<A> &fst, ProjectType project_type)
  118. : ArcMapFst<A, A, ProjectMapper<A>>(fst, ProjectMapper<A>(project_type)) {
  119. if (project_type == ProjectType::INPUT) {
  120. GetMutableImpl()->SetOutputSymbols(fst.InputSymbols());
  121. }
  122. if (project_type == ProjectType::OUTPUT) {
  123. GetMutableImpl()->SetInputSymbols(fst.OutputSymbols());
  124. }
  125. }
  126. // See Fst<>::Copy() for doc.
  127. ProjectFst(const ProjectFst &fst, bool safe = false)
  128. : ArcMapFst<A, A, ProjectMapper<A>>(fst, safe) {}
  129. // Gets a copy of this ProjectFst. See Fst<>::Copy() for further doc.
  130. ProjectFst *Copy(bool safe = false) const override {
  131. return new ProjectFst(*this, safe);
  132. }
  133. private:
  134. using ImplToFst<Impl>::GetMutableImpl;
  135. };
  136. // Specialization for ProjectFst.
  137. template <class A>
  138. class StateIterator<ProjectFst<A>>
  139. : public StateIterator<ArcMapFst<A, A, ProjectMapper<A>>> {
  140. public:
  141. explicit StateIterator(const ProjectFst<A> &fst)
  142. : StateIterator<ArcMapFst<A, A, ProjectMapper<A>>>(fst) {}
  143. };
  144. // Specialization for ProjectFst.
  145. template <class A>
  146. class ArcIterator<ProjectFst<A>>
  147. : public ArcIterator<ArcMapFst<A, A, ProjectMapper<A>>> {
  148. public:
  149. using StateId = typename A::StateId;
  150. ArcIterator(const ProjectFst<A> &fst, StateId s)
  151. : ArcIterator<ArcMapFst<A, A, ProjectMapper<A>>>(fst, s) {}
  152. };
  153. // Useful alias when using StdArc.
  154. using StdProjectFst = ProjectFst<StdArc>;
  155. } // namespace fst
  156. #endif // FST_PROJECT_H_