// See www.openfst.org for extensive documentation on this weighted // finite-state transducer library. // // String weight set and associated semiring operation definitions. #ifndef FST_STRING_WEIGHT_H_ #define FST_STRING_WEIGHT_H_ #include #include #include #include #include #include #include namespace fst { constexpr int kStringInfinity = -1; // Label for the infinite string. constexpr int kStringBad = -2; // Label for a non-string. constexpr char kStringSeparator = '_'; // Label separator in strings. // Determines whether to use left or right string semiring. Includes a // 'restricted' version that signals an error if proper prefixes/suffixes // would otherwise be returned by Plus, useful with various // algorithms that require functional transducer input with the // string semirings. enum StringType { STRING_LEFT = 0, STRING_RIGHT = 1, STRING_RESTRICT = 2 }; constexpr StringType ReverseStringType(StringType s) { return s == STRING_LEFT ? STRING_RIGHT : (s == STRING_RIGHT ? STRING_LEFT : STRING_RESTRICT); } template class StringWeightIterator; template class StringWeightReverseIterator; // String semiring: (longest_common_prefix/suffix, ., Infinity, Epsilon) template class StringWeight { public: using Label = Label_; using ReverseWeight = StringWeight; using Iterator = StringWeightIterator; using ReverseIterator = StringWeightReverseIterator; friend class StringWeightIterator; friend class StringWeightReverseIterator; StringWeight() {} template StringWeight(const Iterator &begin, const Iterator &end) { for (auto iter = begin; iter != end; ++iter) PushBack(*iter); } explicit StringWeight(Label label) { PushBack(label); } static const StringWeight &Zero() { static const auto *const zero = new StringWeight(Label(kStringInfinity)); return *zero; } static const StringWeight &One() { static const auto *const one = new StringWeight(); return *one; } static const StringWeight &NoWeight() { static const auto *const no_weight = new StringWeight(Label(kStringBad)); return *no_weight; } static const string &Type() { static const string *const type = new string( S == STRING_LEFT ? "left_string" : (S == STRING_RIGHT ? "right_string" : "restricted_string")); return *type; } bool Member() const; std::istream &Read(std::istream &strm); std::ostream &Write(std::ostream &strm) const; size_t Hash() const; StringWeight Quantize(float delta = kDelta) const { return *this; } ReverseWeight Reverse() const; static constexpr uint64 Properties() { return kIdempotent | (S == STRING_LEFT ? kLeftSemiring : (S == STRING_RIGHT ? kRightSemiring : /* S == STRING_RESTRICT */ kLeftSemiring | kRightSemiring)); } // These operations combined with the StringWeightIterator and // StringWeightReverseIterator provide the access and mutation of the string // internal elements. // Clear existing StringWeight. void Clear() { first_ = 0; rest_.clear(); } size_t Size() const { return first_ ? rest_.size() + 1 : 0; } void PushFront(Label label) { if (first_) rest_.push_front(first_); first_ = label; } void PushBack(Label label) { if (!first_) { first_ = label; } else { rest_.push_back(label); } } private: Label first_ = 0; // First label in string (0 if empty). std::list