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.

91 lines
3.3 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_REPLACE_H_
  18. #define FST_SCRIPT_REPLACE_H_
  19. #include <cstdint>
  20. #include <tuple>
  21. #include <utility>
  22. #include <vector>
  23. #include <fst/log.h>
  24. #include <fst/fst.h>
  25. #include <fst/mutable-fst.h>
  26. #include <fst/properties.h>
  27. #include <fst/replace-util.h>
  28. #include <fst/replace.h>
  29. #include <fst/util.h>
  30. #include <fst/script/fst-class.h>
  31. namespace fst {
  32. namespace script {
  33. struct ReplaceOptions {
  34. const int64_t root; // Root rule for expansion.
  35. const ReplaceLabelType call_label_type; // How to label call arc.
  36. const ReplaceLabelType return_label_type; // How to label return arc.
  37. const int64_t return_label; // Specifies return arc label.
  38. explicit ReplaceOptions(
  39. int64_t root, ReplaceLabelType call_label_type = REPLACE_LABEL_INPUT,
  40. ReplaceLabelType return_label_type = REPLACE_LABEL_NEITHER,
  41. int64_t return_label = 0)
  42. : root(root),
  43. call_label_type(call_label_type),
  44. return_label_type(return_label_type),
  45. return_label(return_label) {}
  46. };
  47. using FstReplaceArgs =
  48. std::tuple<const std::vector<std::pair<int64_t, const FstClass *>> &,
  49. MutableFstClass *, const ReplaceOptions &>;
  50. template <class Arc>
  51. void Replace(FstReplaceArgs *args) {
  52. // Now that we know the arc type, we construct a vector of
  53. // std::pair<real label, real fst> that the real Replace will use.
  54. const auto &untyped_pairs = std::get<0>(*args);
  55. std::vector<std::pair<typename Arc::Label, const Fst<Arc> *>> typed_pairs;
  56. typed_pairs.reserve(untyped_pairs.size());
  57. for (const auto &untyped_pair : untyped_pairs) {
  58. typed_pairs.emplace_back(untyped_pair.first, // Converts label.
  59. untyped_pair.second->GetFst<Arc>());
  60. }
  61. MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
  62. const auto &opts = std::get<2>(*args);
  63. ReplaceFstOptions<Arc> typed_opts(opts.root, opts.call_label_type,
  64. opts.return_label_type, opts.return_label);
  65. ReplaceFst<Arc> rfst(typed_pairs, typed_opts);
  66. // Checks for cyclic dependencies before attempting expansion.
  67. if (rfst.CyclicDependencies()) {
  68. FSTERROR() << "Replace: Cyclic dependencies detected; cannot expand";
  69. ofst->SetProperties(kError, kError);
  70. return;
  71. }
  72. typed_opts.gc = true; // Caching options to speed up batch copy.
  73. typed_opts.gc_limit = 0;
  74. *ofst = rfst;
  75. }
  76. void Replace(const std::vector<std::pair<int64_t, const FstClass *>> &pairs,
  77. MutableFstClass *ofst, const ReplaceOptions &opts);
  78. } // namespace script
  79. } // namespace fst
  80. #endif // FST_SCRIPT_REPLACE_H_