// See www.openfst.org for extensive documentation on this weighted // finite-state transducer library. #ifndef FST_SCRIPT_SHORTEST_DISTANCE_H_ #define FST_SCRIPT_SHORTEST_DISTANCE_H_ #include #include #include #include #include #include #include #include namespace fst { namespace script { enum ArcFilterType { ANY_ARC_FILTER, EPSILON_ARC_FILTER, INPUT_EPSILON_ARC_FILTER, OUTPUT_EPSILON_ARC_FILTER }; struct ShortestDistanceOptions { const QueueType queue_type; const ArcFilterType arc_filter_type; const int64 source; const float delta; ShortestDistanceOptions(QueueType queue_type, ArcFilterType arc_filter_type, int64 source, float delta) : queue_type(queue_type), arc_filter_type(arc_filter_type), source(source), delta(delta) {} }; namespace internal { // Code to implement switching on queue and arc filter types. template struct QueueConstructor { using Weight = typename Arc::Weight; static Queue *Construct(const Fst &, const std::vector *) { return new Queue(); } }; // Specializations to support queues with different constructors. template struct QueueConstructor, ArcFilter> { using StateId = typename Arc::StateId; using Weight = typename Arc::Weight; // template static AutoQueue *Construct(const Fst &fst, const std::vector *distance) { return new AutoQueue(fst, distance, ArcFilter()); } }; template struct QueueConstructor< Arc, NaturalShortestFirstQueue, ArcFilter> { using StateId = typename Arc::StateId; using Weight = typename Arc::Weight; static NaturalShortestFirstQueue *Construct( const Fst &, const std::vector *distance) { return new NaturalShortestFirstQueue(*distance); } }; template struct QueueConstructor, ArcFilter> { using StateId = typename Arc::StateId; using Weight = typename Arc::Weight; static TopOrderQueue *Construct(const Fst &fst, const std::vector *) { return new TopOrderQueue(fst, ArcFilter()); } }; template void ShortestDistance(const Fst &fst, std::vector *distance, const ShortestDistanceOptions &opts) { std::unique_ptr queue( QueueConstructor::Construct(fst, distance)); const fst::ShortestDistanceOptions sopts( queue.get(), ArcFilter(), opts.source, opts.delta); ShortestDistance(fst, distance, sopts); } template void ShortestDistance(const Fst &fst, std::vector *distance, const ShortestDistanceOptions &opts) { switch (opts.arc_filter_type) { case ANY_ARC_FILTER: { ShortestDistance>(fst, distance, opts); return; } case EPSILON_ARC_FILTER: { ShortestDistance>(fst, distance, opts); return; } case INPUT_EPSILON_ARC_FILTER: { ShortestDistance>(fst, distance, opts); return; } case OUTPUT_EPSILON_ARC_FILTER: { ShortestDistance>(fst, distance, opts); return; } default: { FSTERROR() << "ShortestDistance: Unknown arc filter type: " << opts.arc_filter_type; distance->clear(); distance->resize(1, Arc::Weight::NoWeight()); return; } } } } // namespace internal using ShortestDistanceArgs1 = std::tuple *, const ShortestDistanceOptions &>; template void ShortestDistance(ShortestDistanceArgs1 *args) { using StateId = typename Arc::StateId; using Weight = typename Arc::Weight; const Fst &fst = *(std::get<0>(*args).GetFst()); const auto &opts = std::get<2>(*args); std::vector typed_distance; switch (opts.queue_type) { case AUTO_QUEUE: { internal::ShortestDistance>(fst, &typed_distance, opts); break; } case FIFO_QUEUE: { internal::ShortestDistance>(fst, &typed_distance, opts); break; } case LIFO_QUEUE: { internal::ShortestDistance>(fst, &typed_distance, opts); break; } case SHORTEST_FIRST_QUEUE: { internal::ShortestDistance>( fst, &typed_distance, opts); break; } case STATE_ORDER_QUEUE: { internal::ShortestDistance>( fst, &typed_distance, opts); break; } case TOP_ORDER_QUEUE: { internal::ShortestDistance>( fst, &typed_distance, opts); break; } default: { FSTERROR() << "ShortestDistance: Unknown queue type: " << opts.queue_type; typed_distance.clear(); typed_distance.resize(1, Arc::Weight::NoWeight()); break; } } internal::CopyWeights(typed_distance, std::get<1>(*args)); } using ShortestDistanceArgs2 = std::tuple *, bool, double>; template void ShortestDistance(ShortestDistanceArgs2 *args) { using Weight = typename Arc::Weight; const Fst &fst = *(std::get<0>(*args).GetFst()); std::vector typed_distance; ShortestDistance(fst, &typed_distance, std::get<2>(*args), std::get<3>(*args)); internal::CopyWeights(typed_distance, std::get<1>(*args)); } void ShortestDistance(const FstClass &fst, std::vector *distance, const ShortestDistanceOptions &opts); void ShortestDistance(const FstClass &ifst, std::vector *distance, bool reverse = false, double delta = fst::kShortestDelta); } // namespace script } // namespace fst #endif // FST_SCRIPT_SHORTEST_DISTANCE_H_