// See www.openfst.org for extensive documentation on this weighted // finite-state transducer library. // // Product weight set and associated semiring operation definitions. #ifndef FST_PRODUCT_WEIGHT_H_ #define FST_PRODUCT_WEIGHT_H_ #include #include #include #include namespace fst { // Product semiring: W1 * W2. template class ProductWeight : public PairWeight { public: using ReverseWeight = ProductWeight; ProductWeight() {} explicit ProductWeight(const PairWeight &weight) : PairWeight(weight) {} ProductWeight(W1 w1, W2 w2) : PairWeight(std::move(w1), std::move(w2)) {} static const ProductWeight &Zero() { static const ProductWeight zero(PairWeight::Zero()); return zero; } static const ProductWeight &One() { static const ProductWeight one(PairWeight::One()); return one; } static const ProductWeight &NoWeight() { static const ProductWeight no_weight(PairWeight::NoWeight()); return no_weight; } static const string &Type() { static const string *const type = new string(W1::Type() + "_X_" + W2::Type()); return *type; } static constexpr uint64 Properties() { return W1::Properties() & W2::Properties() & (kLeftSemiring | kRightSemiring | kCommutative | kIdempotent); } ProductWeight Quantize(float delta = kDelta) const { return ProductWeight(PairWeight::Quantize(delta)); } ReverseWeight Reverse() const { return ReverseWeight(PairWeight::Reverse()); } }; template inline ProductWeight Plus(const ProductWeight &w1, const ProductWeight &w2) { return ProductWeight(Plus(w1.Value1(), w2.Value1()), Plus(w1.Value2(), w2.Value2())); } template inline ProductWeight Times(const ProductWeight &w1, const ProductWeight &w2) { return ProductWeight(Times(w1.Value1(), w2.Value1()), Times(w1.Value2(), w2.Value2())); } template inline ProductWeight Divide(const ProductWeight &w1, const ProductWeight &w2, DivideType typ = DIVIDE_ANY) { return ProductWeight(Divide(w1.Value1(), w2.Value1(), typ), Divide(w1.Value2(), w2.Value2(), typ)); } // This function object generates weights by calling the underlying generators // for the template weight types, like all other pair weight types. This is // intended primarily for testing. template class WeightGenerate> : public WeightGenerate> { public: using Weight = ProductWeight; using Generate = WeightGenerate>; explicit WeightGenerate(bool allow_zero = true) : Generate(allow_zero) {} Weight operator()() const { return Weight(Generate::operator()()); } }; } // namespace fst #endif // FST_PRODUCT_WEIGHT_H_