// See www.openfst.org for extensive documentation on this weighted // finite-state transducer library. // // Functions and classes to sort arcs in an FST. #ifndef FST_ARCSORT_H_ #define FST_ARCSORT_H_ #include #include #include #include #include #include namespace fst { template class ArcSortMapper { public: using FromArc = Arc; using ToArc = Arc; using StateId = typename Arc::StateId; using Weight = typename Arc::Weight; ArcSortMapper(const Fst &fst, const Compare &comp) : fst_(fst), comp_(comp), i_(0) {} // Allows updating Fst argument; pass only if changed. ArcSortMapper(const ArcSortMapper &mapper, const Fst *fst = nullptr) : fst_(fst ? *fst : mapper.fst_), comp_(mapper.comp_), i_(0) {} StateId Start() { return fst_.Start(); } Weight Final(StateId s) const { return fst_.Final(s); } void SetState(StateId s) { i_ = 0; arcs_.clear(); arcs_.reserve(fst_.NumArcs(s)); for (ArcIterator> aiter(fst_, s); !aiter.Done(); aiter.Next()) { arcs_.push_back(aiter.Value()); } std::sort(arcs_.begin(), arcs_.end(), comp_); } bool Done() const { return i_ >= arcs_.size(); } const Arc &Value() const { return arcs_[i_]; } void Next() { ++i_; } MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; } MapSymbolsAction OutputSymbolsAction() const { return MAP_COPY_SYMBOLS; } uint64 Properties(uint64 props) const { return comp_.Properties(props); } private: const Fst &fst_; const Compare &comp_; std::vector arcs_; ssize_t i_; // current arc position ArcSortMapper &operator=(const ArcSortMapper &) = delete; }; // Sorts the arcs in an FST according to function object 'comp' of type Compare. // This version modifies its input. Comparison function objects ILabelCompare // and OLabelCompare are provided by the library. In general, Compare must meet // the requirements for a comparison function object (e.g., similar to those // used by std::sort). It must also have a member Properties(uint64) that // specifies the known properties of the sorted FST; it takes as argument the // input FST's known properties before the sort. // // Complexity: // // - Time: O(v d log d) // - Space: O(d) // // where v = # of states and d = maximum out-degree. template void ArcSort(MutableFst *fst, Compare comp) { ArcSortMapper mapper(*fst, comp); StateMap(fst, mapper); } using ArcSortFstOptions = CacheOptions; // Sorts the arcs in an FST according to function object 'comp' of type Compare. // This version is a delayed FST. Comparsion function objects ILabelCompare and // OLabelCompare are provided by the library. In general, Compare must meet the // requirements for a comparision function object (e.g., similar to those // used by std::sort). It must also have a member Properties(uint64) that // specifies the known properties of the sorted FST; it takes as argument the // input FST's known properties. // // Complexity: // // - Time: O(v d log d) // - Space: O(d) // // where v = # of states visited, d = maximum out-degree of states visited. // Constant time and space to visit an input state is assumed and exclusive of // caching. template class ArcSortFst : public StateMapFst> { using StateMapFst>::GetImpl; public: using StateId = typename Arc::StateId; using Mapper = ArcSortMapper; ArcSortFst(const Fst &fst, const Compare &comp) : StateMapFst(fst, ArcSortMapper(fst, comp)) {} ArcSortFst(const Fst &fst, const Compare &comp, const ArcSortFstOptions &opts) : StateMapFst(fst, Mapper(fst, comp), opts) {} // See Fst<>::Copy() for doc. ArcSortFst(const ArcSortFst &fst, bool safe = false) : StateMapFst(fst, safe) {} // Gets a copy of this ArcSortFst. See Fst<>::Copy() for further doc. ArcSortFst *Copy(bool safe = false) const override { return new ArcSortFst(*this, safe); } size_t NumArcs(StateId s) const override { return GetImpl()->GetFst()->NumArcs(s); } size_t NumInputEpsilons(StateId s) const override { return GetImpl()->GetFst()->NumInputEpsilons(s); } size_t NumOutputEpsilons(StateId s) const override { return GetImpl()->GetFst()->NumOutputEpsilons(s); } }; // Specialization for ArcSortFst. template class StateIterator> : public StateIterator>> { public: explicit StateIterator(const ArcSortFst &fst) : StateIterator>>(fst) { } }; // Specialization for ArcSortFst. template class ArcIterator> : public ArcIterator>> { public: ArcIterator(const ArcSortFst &fst, typename Arc::StateId s) : ArcIterator>>(fst, s) {} }; // Compare class for comparing input labels of arcs. template class ILabelCompare { public: ILabelCompare() {} bool operator()(const Arc &arc1, const Arc &arc2) const { return arc1.ilabel < arc2.ilabel; } uint64 Properties(uint64 props) const { return (props & kArcSortProperties) | kILabelSorted | (props & kAcceptor ? kOLabelSorted : 0); } }; // Compare class for comparing output labels of arcs. template class OLabelCompare { public: OLabelCompare() {} bool operator()(const Arc &arc1, const Arc &arc2) const { return arc1.olabel < arc2.olabel; } uint64 Properties(uint64 props) const { return (props & kArcSortProperties) | kOLabelSorted | (props & kAcceptor ? kILabelSorted : 0); } }; // Useful aliases when using StdArc. template using StdArcSortFst = ArcSortFst; using StdILabelCompare = ILabelCompare; using StdOLabelCompare = OLabelCompare; } // namespace fst #endif // FST_ARCSORT_H_