FST  openfst-1.8.3
OpenFst Library
shortest-distance.h
Go to the documentation of this file.
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 #ifndef FST_SCRIPT_SHORTEST_DISTANCE_H_
19 #define FST_SCRIPT_SHORTEST_DISTANCE_H_
20 
21 #include <cstdint>
22 #include <memory>
23 #include <tuple>
24 #include <type_traits>
25 #include <vector>
26 
27 #include <fst/log.h>
28 #include <fst/arcfilter.h>
29 #include <fst/fst.h>
30 #include <fst/queue.h>
31 #include <fst/shortest-distance.h>
32 #include <fst/util.h>
33 #include <fst/weight.h>
35 #include <fst/script/arg-packs.h>
36 #include <fst/script/fst-class.h>
37 #include <fst/script/prune.h>
38 #include <fst/script/script-impl.h>
40 
41 namespace fst {
42 namespace script {
43 
47  const int64_t source;
48  const float delta;
49 
50  ShortestDistanceOptions(QueueType queue_type, ArcFilterType arc_filter_type,
51  int64_t source, float delta)
52  : queue_type(queue_type),
53  arc_filter_type(arc_filter_type),
54  source(source),
55  delta(delta) {}
56 };
57 
58 namespace internal {
59 
60 // Code to implement switching on queue and arc filter types.
61 
62 template <class Arc, class Queue, class ArcFilter>
64  using Weight = typename Arc::Weight;
65 
66  static std::unique_ptr<Queue> Construct(const Fst<Arc> &,
67  const std::vector<Weight> *) {
68  return std::make_unique<Queue>();
69  }
70 };
71 
72 // Specializations to support queues with different constructors.
73 
74 template <class Arc, class ArcFilter>
75 struct QueueConstructor<Arc, AutoQueue<typename Arc::StateId>, ArcFilter> {
76  using StateId = typename Arc::StateId;
77  using Weight = typename Arc::Weight;
78 
79  // template<class Arc, class ArcFilter>
80  static std::unique_ptr<AutoQueue<StateId>> Construct(
81  const Fst<Arc> &fst, const std::vector<Weight> *distance) {
82  return std::make_unique<AutoQueue<StateId>>(fst, distance, ArcFilter());
83  }
84 };
85 
86 template <class Arc, class ArcFilter>
88  Arc, NaturalShortestFirstQueue<typename Arc::StateId, typename Arc::Weight>,
89  ArcFilter> {
90  using StateId = typename Arc::StateId;
91  using Weight = typename Arc::Weight;
92 
93  static std::unique_ptr<NaturalShortestFirstQueue<StateId, Weight>> Construct(
94  const Fst<Arc> &, const std::vector<Weight> *distance) {
95  return std::make_unique<NaturalShortestFirstQueue<StateId, Weight>>(
96  *distance);
97  }
98 };
99 
100 template <class Arc, class ArcFilter>
101 struct QueueConstructor<Arc, TopOrderQueue<typename Arc::StateId>, ArcFilter> {
102  using StateId = typename Arc::StateId;
103  using Weight = typename Arc::Weight;
104 
105  static std::unique_ptr<TopOrderQueue<StateId>> Construct(
106  const Fst<Arc> &fst, const std::vector<Weight> *) {
107  return std::make_unique<TopOrderQueue<StateId>>(fst, ArcFilter());
108  }
109 };
110 
111 template <class Arc, class Queue, class ArcFilter>
113  std::vector<typename Arc::Weight> *distance,
114  const ShortestDistanceOptions &opts) {
115  std::unique_ptr<Queue> queue(
118  queue.get(), ArcFilter(), opts.source, opts.delta);
119  ShortestDistance(fst, distance, sopts);
120 }
121 
122 template <class Arc, class Queue>
124  std::vector<typename Arc::Weight> *distance,
125  const ShortestDistanceOptions &opts) {
126  switch (opts.arc_filter_type) {
127  case ArcFilterType::ANY: {
128  ShortestDistance<Arc, Queue, AnyArcFilter<Arc>>(fst, distance, opts);
129  return;
130  }
131  case ArcFilterType::EPSILON: {
132  ShortestDistance<Arc, Queue, EpsilonArcFilter<Arc>>(fst, distance, opts);
133  return;
134  }
136  ShortestDistance<Arc, Queue, InputEpsilonArcFilter<Arc>>(fst, distance,
137  opts);
138  return;
139  }
141  ShortestDistance<Arc, Queue, OutputEpsilonArcFilter<Arc>>(fst, distance,
142  opts);
143  return;
144  }
145  default: {
146  FSTERROR() << "ShortestDistance: Unknown arc filter type: "
147  << static_cast<std::underlying_type_t<ArcFilterType>>(
148  opts.arc_filter_type);
149  distance->clear();
150  distance->resize(1, Arc::Weight::NoWeight());
151  return;
152  }
153  }
154 }
155 
156 } // namespace internal
157 
159  std::tuple<const FstClass &, std::vector<WeightClass> *,
161 
162 template <class Arc>
164  using StateId = typename Arc::StateId;
165  using Weight = typename Arc::Weight;
166  const Fst<Arc> &fst = *std::get<0>(*args).GetFst<Arc>();
167  const auto &opts = std::get<2>(*args);
168  std::vector<Weight> typed_distance;
169  switch (opts.queue_type) {
170  case AUTO_QUEUE: {
171  internal::ShortestDistance<Arc, AutoQueue<StateId>>(fst, &typed_distance,
172  opts);
173  break;
174  }
175  case FIFO_QUEUE: {
176  internal::ShortestDistance<Arc, FifoQueue<StateId>>(fst, &typed_distance,
177  opts);
178  break;
179  }
180  case LIFO_QUEUE: {
181  internal::ShortestDistance<Arc, LifoQueue<StateId>>(fst, &typed_distance,
182  opts);
183  break;
184  }
185  case SHORTEST_FIRST_QUEUE: {
186  if constexpr (IsIdempotent<Weight>::value) {
189  fst, &typed_distance, opts);
190  } else {
191  FSTERROR() << "ShortestDistance: Bad queue type SHORTEST_FIRST_QUEUE"
192  << " for non-idempotent Weight " << Weight::Type();
193  }
194  break;
195  }
196  case STATE_ORDER_QUEUE: {
197  internal::ShortestDistance<Arc, StateOrderQueue<StateId>>(
198  fst, &typed_distance, opts);
199  break;
200  }
201  case TOP_ORDER_QUEUE: {
202  internal::ShortestDistance<Arc, TopOrderQueue<StateId>>(
203  fst, &typed_distance, opts);
204  break;
205  }
206  default: {
207  FSTERROR() << "ShortestDistance: Unknown queue type: " << opts.queue_type;
208  typed_distance.clear();
209  typed_distance.resize(1, Arc::Weight::NoWeight());
210  break;
211  }
212  }
213  internal::CopyWeights(typed_distance, std::get<1>(*args));
214 }
215 
217  std::tuple<const FstClass &, std::vector<WeightClass> *, bool, double>;
218 
219 template <class Arc>
221  using Weight = typename Arc::Weight;
222  const Fst<Arc> &fst = *std::get<0>(*args).GetFst<Arc>();
223  std::vector<Weight> typed_distance;
224  ShortestDistance(fst, &typed_distance, std::get<2>(*args),
225  std::get<3>(*args));
226  internal::CopyWeights(typed_distance, std::get<1>(*args));
227 }
228 
229 using FstShortestDistanceInnerArgs3 = std::tuple<const FstClass &, double>;
230 
233 
234 template <class Arc>
236  const Fst<Arc> &fst = *std::get<0>(args->args).GetFst<Arc>();
237  args->retval = WeightClass(ShortestDistance(fst, std::get<1>(args->args)));
238 }
239 
240 void ShortestDistance(const FstClass &fst, std::vector<WeightClass> *distance,
241  const ShortestDistanceOptions &opts);
242 
243 void ShortestDistance(const FstClass &ifst, std::vector<WeightClass> *distance,
244  bool reverse = false,
245  double delta = fst::kShortestDelta);
246 
248  double delta = fst::kShortestDelta);
249 
250 } // namespace script
251 } // namespace fst
252 
253 #endif // FST_SCRIPT_SHORTEST_DISTANCE_H_
QueueType
Definition: queue.h:76
std::tuple< const FstClass &, std::vector< WeightClass > *, bool, double > FstShortestDistanceArgs2
static std::unique_ptr< TopOrderQueue< StateId > > Construct(const Fst< Arc > &fst, const std::vector< Weight > *)
std::bool_constant<(W::Properties()&kIdempotent)!=0 > IsIdempotent
Definition: weight.h:159
void CopyWeights(const std::vector< WeightClass > &weights, std::vector< Weight > *typed_weights)
Definition: script-impl.h:206
static std::unique_ptr< AutoQueue< StateId > > Construct(const Fst< Arc > &fst, const std::vector< Weight > *distance)
#define FSTERROR()
Definition: util.h:56
void ShortestDistance(const Fst< Arc > &fst, std::vector< typename Arc::Weight > *distance, const ShortestDistanceOptions &opts)
static std::unique_ptr< Queue > Construct(const Fst< Arc > &, const std::vector< Weight > *)
static std::unique_ptr< NaturalShortestFirstQueue< StateId, Weight > > Construct(const Fst< Arc > &, const std::vector< Weight > *distance)
ShortestDistanceOptions(QueueType queue_type, ArcFilterType arc_filter_type, int64_t source, float delta)
constexpr float kShortestDelta
void ShortestDistance(FstShortestDistanceArgs1 *args)
std::tuple< const FstClass &, std::vector< WeightClass > *, const ShortestDistanceOptions & > FstShortestDistanceArgs1
std::tuple< const FstClass &, double > FstShortestDistanceInnerArgs3