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.

219 lines
7.1 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. // Commonly used FST arc types.
  19. #ifndef FST_ARC_H_
  20. #define FST_ARC_H_
  21. #include <climits>
  22. #include <cstddef>
  23. #include <cstdint>
  24. #include <string>
  25. #include <type_traits>
  26. #include <utility>
  27. #include <fst/error-weight.h>
  28. #include <fst/expectation-weight.h>
  29. #include <fst/float-weight.h>
  30. #include <fst/fst-decl.h> // For optional argument declarations
  31. #include <fst/lexicographic-weight.h>
  32. #include <fst/power-weight.h>
  33. #include <fst/product-weight.h>
  34. #include <fst/signed-log-weight.h>
  35. #include <fst/sparse-power-weight.h>
  36. #include <fst/string-weight.h>
  37. namespace fst {
  38. template <class W, class L /* = int */, class S /* = int */>
  39. struct ArcTpl {
  40. public:
  41. using Weight = W;
  42. using Label = L;
  43. using StateId = S;
  44. Label ilabel;
  45. Label olabel;
  46. Weight weight;
  47. StateId nextstate;
  48. ArcTpl() noexcept(std::is_nothrow_default_constructible_v<Weight>) = default;
  49. template <class T>
  50. ArcTpl(Label ilabel, Label olabel, T &&weight, StateId nextstate)
  51. : ilabel(ilabel),
  52. olabel(olabel),
  53. weight(std::forward<T>(weight)),
  54. nextstate(nextstate) {}
  55. // Arc with weight One.
  56. ArcTpl(Label ilabel, Label olabel, StateId nextstate)
  57. : ArcTpl(ilabel, olabel, Weight::One(), nextstate) {}
  58. static const std::string &Type() {
  59. static const auto *const type = new std::string(
  60. Weight::Type() == "tropical" ? "standard" : Weight::Type());
  61. return *type;
  62. }
  63. };
  64. using StdArc = ArcTpl<TropicalWeight>;
  65. using LogArc = ArcTpl<LogWeight>;
  66. using Log64Arc = ArcTpl<Log64Weight>;
  67. using RealArc = ArcTpl<RealWeight>;
  68. using Real64Arc = ArcTpl<Real64Weight>;
  69. using SignedLogArc = ArcTpl<SignedLogWeight>;
  70. using SignedLog64Arc = ArcTpl<SignedLog64Weight>;
  71. using ErrorArc = ArcTpl<ErrorWeight>;
  72. using MinMaxArc = ArcTpl<MinMaxWeight>;
  73. // Arc with integer labels and state IDs and string weights.
  74. template <StringType S = STRING_LEFT>
  75. struct StringArc : public ArcTpl<StringWeight<int, S>> {
  76. public:
  77. using Base = ArcTpl<StringWeight<int, S>>;
  78. using Base::Base;
  79. static const std::string &Type() {
  80. static const auto *const type = new std::string(
  81. S == STRING_LEFT ? "left_standard_string"
  82. : (S == STRING_RIGHT ? "right_standard_string"
  83. : "restricted_standard_string"));
  84. return *type;
  85. }
  86. };
  87. // Arc with label and state Id type the same as template arg and with
  88. // weights over the Gallic semiring w.r.t the output labels and weights of A.
  89. template <class A, GallicType G = GALLIC_LEFT>
  90. struct GallicArc : public ArcTpl<GallicWeight<int, typename A::Weight, G>,
  91. typename A::Label, typename A::StateId> {
  92. using Base = ArcTpl<GallicWeight<int, typename A::Weight, G>,
  93. typename A::Label, typename A::StateId>;
  94. using Arc = A;
  95. using Base::Base;
  96. explicit GallicArc(const Arc &arc)
  97. : Base(arc.ilabel, arc.ilabel, Weight(arc.olabel, arc.weight),
  98. arc.nextstate) {}
  99. static const std::string &Type() {
  100. static const auto *const type = new std::string(
  101. (G == GALLIC_LEFT
  102. ? "left_gallic_"
  103. : (G == GALLIC_RIGHT
  104. ? "right_gallic_"
  105. : (G == GALLIC_RESTRICT
  106. ? "restricted_gallic_"
  107. : (G == GALLIC_MIN ? "min_gallic_" : "gallic_")))) +
  108. Arc::Type());
  109. return *type;
  110. }
  111. };
  112. // Arc with the reverse of the weight found in its template arg.
  113. template <class A>
  114. struct ReverseArc : public ArcTpl<typename A::Weight::ReverseWeight,
  115. typename A::Label, typename A::StateId> {
  116. using Base = ArcTpl<typename A::Weight::ReverseWeight, typename A::Label,
  117. typename A::StateId>;
  118. using Arc = A;
  119. using Base::Base;
  120. static const std::string &Type() {
  121. static const auto *const type = new std::string("reverse_" + Arc::Type());
  122. return *type;
  123. }
  124. };
  125. // Arc with integer labels and state IDs and lexicographic weights.
  126. template <class Weight1, class Weight2>
  127. using LexicographicArc = ArcTpl<LexicographicWeight<Weight1, Weight2>>;
  128. // Arc with integer labels and state IDs and product weights.
  129. template <class Weight1, class Weight2>
  130. using ProductArc = ArcTpl<ProductWeight<Weight1, Weight2>>;
  131. // Arc with label and state ID type the same as first template argument and with
  132. // weights over the n-th Cartesian power of the weight type of the template
  133. // argument.
  134. template <class A, size_t n>
  135. struct PowerArc : public ArcTpl<PowerWeight<typename A::Weight, n>,
  136. typename A::Label, typename A::StateId> {
  137. using Base = ArcTpl<PowerWeight<typename A::Weight, n>, typename A::Label,
  138. typename A::StateId>;
  139. using Arc = A;
  140. using Base::Base;
  141. static const std::string &Type() {
  142. static const auto *const type =
  143. new std::string(Arc::Type() + "_^" + std::to_string(n));
  144. return *type;
  145. }
  146. };
  147. // Arc with label and state ID type the same as first template argument and with
  148. // weights over the arbitrary Cartesian power of the weight type.
  149. template <class A, class K = int>
  150. struct SparsePowerArc : public ArcTpl<SparsePowerWeight<typename A::Weight, K>,
  151. typename A::Label, typename A::StateId> {
  152. using Base = ArcTpl<SparsePowerWeight<typename A::Weight, K>,
  153. typename A::Label, typename A::StateId>;
  154. using Arc = A;
  155. using Base::Base;
  156. static const std::string &Type() {
  157. static const std::string *const type = [] {
  158. std::string type = Arc::Type() + "_^n";
  159. if (sizeof(K) != sizeof(uint32_t)) {
  160. type += "_" + std::to_string(CHAR_BIT * sizeof(K));
  161. }
  162. return new std::string(type);
  163. }();
  164. return *type;
  165. }
  166. };
  167. // Arc with label and state ID type the same as first template argument and with
  168. // expectation weight over the first template argument's weight type and the
  169. // second template argument.
  170. template <class A, class X2>
  171. struct ExpectationArc : public ArcTpl<ExpectationWeight<typename A::Weight, X2>,
  172. typename A::Label, typename A::StateId> {
  173. using Base = ArcTpl<ExpectationWeight<typename A::Weight, X2>,
  174. typename A::Label, typename A::StateId>;
  175. using Arc = A;
  176. using X1 = typename Arc::Weight;
  177. using Base::Base;
  178. static const std::string &Type() {
  179. static const auto *const type =
  180. new std::string("expectation_" + Arc::Type() + "_" + X2::Type());
  181. return *type;
  182. }
  183. };
  184. } // namespace fst
  185. #endif // FST_ARC_H_