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.

138 lines
4.2 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. #ifndef FST_SCRIPT_RMEPSILON_H_
  18. #define FST_SCRIPT_RMEPSILON_H_
  19. #include <cstdint>
  20. #include <utility>
  21. #include <vector>
  22. #include <fst/log.h>
  23. #include <fst/arcfilter.h>
  24. #include <fst/fst.h>
  25. #include <fst/mutable-fst.h>
  26. #include <fst/properties.h>
  27. #include <fst/queue.h>
  28. #include <fst/rmepsilon.h>
  29. #include <fst/util.h>
  30. #include <fst/weight.h>
  31. #include <fst/script/arcfilter-impl.h>
  32. #include <fst/script/fst-class.h>
  33. #include <fst/script/shortest-distance.h>
  34. #include <fst/script/weight-class.h>
  35. namespace fst {
  36. namespace script {
  37. struct RmEpsilonOptions : public ShortestDistanceOptions {
  38. const bool connect;
  39. const WeightClass &weight_threshold;
  40. const int64_t state_threshold;
  41. RmEpsilonOptions(QueueType queue_type, bool connect,
  42. const WeightClass &weight_threshold,
  43. int64_t state_threshold = kNoStateId, float delta = kDelta)
  44. : ShortestDistanceOptions(queue_type, ArcFilterType::EPSILON, kNoStateId,
  45. delta),
  46. connect(connect),
  47. weight_threshold(weight_threshold),
  48. state_threshold(state_threshold) {}
  49. };
  50. namespace internal {
  51. // Code to implement switching on queue types.
  52. template <class Arc, class Queue>
  53. void RmEpsilon(MutableFst<Arc> *fst,
  54. std::vector<typename Arc::Weight> *distance,
  55. const RmEpsilonOptions &opts, Queue *queue) {
  56. using Weight = typename Arc::Weight;
  57. const fst::RmEpsilonOptions<Arc, Queue> ropts(
  58. queue, opts.delta, opts.connect,
  59. *opts.weight_threshold.GetWeight<Weight>(), opts.state_threshold);
  60. RmEpsilon(fst, distance, ropts);
  61. }
  62. template <class Arc>
  63. void RmEpsilon(MutableFst<Arc> *fst, const RmEpsilonOptions &opts) {
  64. using StateId = typename Arc::StateId;
  65. using Weight = typename Arc::Weight;
  66. std::vector<Weight> distance;
  67. switch (opts.queue_type) {
  68. case AUTO_QUEUE: {
  69. AutoQueue<StateId> queue(*fst, &distance, EpsilonArcFilter<Arc>());
  70. RmEpsilon(fst, &distance, opts, &queue);
  71. return;
  72. }
  73. case FIFO_QUEUE: {
  74. FifoQueue<StateId> queue;
  75. RmEpsilon(fst, &distance, opts, &queue);
  76. return;
  77. }
  78. case LIFO_QUEUE: {
  79. LifoQueue<StateId> queue;
  80. RmEpsilon(fst, &distance, opts, &queue);
  81. return;
  82. }
  83. case SHORTEST_FIRST_QUEUE: {
  84. if constexpr (IsIdempotent<Weight>::value) {
  85. NaturalShortestFirstQueue<StateId, Weight> queue(distance);
  86. RmEpsilon(fst, &distance, opts, &queue);
  87. } else {
  88. FSTERROR() << "RmEpsilon: Bad queue type SHORTEST_FIRST_QUEUE for"
  89. << " non-idempotent Weight " << Weight::Type();
  90. fst->SetProperties(kError, kError);
  91. }
  92. return;
  93. }
  94. case STATE_ORDER_QUEUE: {
  95. StateOrderQueue<StateId> queue;
  96. RmEpsilon(fst, &distance, opts, &queue);
  97. return;
  98. }
  99. case TOP_ORDER_QUEUE: {
  100. TopOrderQueue<StateId> queue(*fst, EpsilonArcFilter<Arc>());
  101. internal::RmEpsilon(fst, &distance, opts, &queue);
  102. return;
  103. }
  104. default: {
  105. FSTERROR() << "RmEpsilon: Unknown queue type: " << opts.queue_type;
  106. fst->SetProperties(kError, kError);
  107. return;
  108. }
  109. }
  110. }
  111. } // namespace internal
  112. using FstRmEpsilonArgs = std::pair<MutableFstClass *, const RmEpsilonOptions &>;
  113. template <class Arc>
  114. void RmEpsilon(FstRmEpsilonArgs *args) {
  115. MutableFst<Arc> *fst = std::get<0>(*args)->GetMutableFst<Arc>();
  116. const auto &opts = std::get<1>(*args);
  117. internal::RmEpsilon(fst, opts);
  118. }
  119. void RmEpsilon(MutableFstClass *fst, const RmEpsilonOptions &opts);
  120. } // namespace script
  121. } // namespace fst
  122. #endif // FST_SCRIPT_RMEPSILON_H_