14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// product-weight.h 24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Licensed under the Apache License, Version 2.0 (the "License"); 44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// you may not use this file except in compliance with the License. 54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// You may obtain a copy of the License at 64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// http://www.apache.org/licenses/LICENSE-2.0 84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Unless required by applicable law or agreed to in writing, software 104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// distributed under the License is distributed on an "AS IS" BASIS, 114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// See the License for the specific language governing permissions and 134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// limitations under the License. 144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \file 174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Product weight set and associated semiring operation definitions. 184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef FST_LIB_PRODUCT_WEIGHT_H__ 204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define FST_LIB_PRODUCT_WEIGHT_H__ 214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/weight.h" 234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectDECLARE_string(fst_product_separator); 254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectnamespace fst { 274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Product semiring: W1 * W2 294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class W1, class W2> 304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass ProductWeight { 314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public: 324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project typedef ProductWeight<typename W1::ReverseWeight, typename W2::ReverseWeight> 334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ReverseWeight; 344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ProductWeight() {} 364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ProductWeight(W1 w1, W2 w2) : value1_(w1), value2_(w2) {} 384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const ProductWeight<W1, W2> &Zero() { 404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const ProductWeight<W1, W2> zero(W1::Zero(), W2::Zero()); 414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return zero; 424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const ProductWeight<W1, W2> &One() { 454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const ProductWeight<W1, W2> one(W1::One(), W2::One()); 464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return one; 474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const string &Type() { 504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static const string type = W1::Type() + "_X_" + W2::Type(); 514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return type; 524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project istream &Read(istream &strm) { 554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project value1_.Read(strm); 564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return value2_.Read(strm); 574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ostream &Write(ostream &strm) const { 604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project value1_.Write(strm); 614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return value2_.Write(strm); 624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ProductWeight<W1, W2> &operator=(const ProductWeight<W1, W2> &w) { 654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project value1_ = w.Value1(); 664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project value2_ = w.Value2(); 674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return *this; 684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bool Member() const { return value1_.Member() && value2_.Member(); } 714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ssize_t Hash() const { 734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ssize_t h1 = value1_.Hash(); 744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ssize_t h2 = value2_.Hash(); 754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int lshift = 5; 764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int rshift = sizeof(ssize_t) - 5; 774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return h1 << lshift ^ h1 >> rshift ^ h2; 784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ProductWeight<W1, W2> Quantize(float delta = kDelta) const { 814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ProductWeight<W1, W2>(value1_.Quantize(), value2_.Quantize()); 824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ReverseWeight Reverse() const { 854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ReverseWeight(value1_.Reverse(), value2_.Reverse()); 864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static uint64 Properties() { 894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 props1 = W1::Properties(); 904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 props2 = W2::Properties(); 914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return props1 & props2 & (kLeftSemiring | kRightSemiring | 924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project kCommutative | kIdempotent); 934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project W1 Value1() const { return value1_; } 964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project W2 Value2() const { return value2_; } 984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private: 1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project W1 value1_; 1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project W2 value2_; 1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}; 1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class W1, class W2> 1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline bool operator==(const ProductWeight<W1, W2> &w, 1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const ProductWeight<W1, W2> &v) { 1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return w.Value1() == v.Value1() && w.Value2() == v.Value2(); 1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class W1, class W2> 1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline bool operator!=(const ProductWeight<W1, W2> &w1, 1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const ProductWeight<W1, W2> &w2) { 1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return w1.Value1() != w2.Value1() || w1.Value2() != w2.Value2(); 1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class W1, class W2> 1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline bool ApproxEqual(const ProductWeight<W1, W2> &w1, 1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const ProductWeight<W1, W2> &w2, 1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float delta = kDelta) { 1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return w1 == w2; 1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class W1, class W2> 1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline ostream &operator<<(ostream &strm, const ProductWeight<W1, W2> &w) { 1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project CHECK(FLAGS_fst_product_separator.size() == 1); 1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char separator = FLAGS_fst_product_separator[0]; 1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return strm << w.Value1() << separator << w.Value2(); 1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class W1, class W2> 1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline istream &operator>>(istream &strm, ProductWeight<W1, W2> &w) { 1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project CHECK(FLAGS_fst_product_separator.size() == 1); 1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char separator = FLAGS_fst_product_separator[0]; 1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int c; 1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // read any initial whitespapce 1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project while (true) { 1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project c = strm.get(); 1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (c == EOF || c == separator) { 1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strm.clear(std::ios::badbit); 1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return strm; 1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!isspace(c)) 1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project break; 1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // read first element 1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project string s1; 1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project do { 1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project s1 += c; 1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project c = strm.get(); 1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (c == EOF || isspace(c)) { 1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strm.clear(std::ios::badbit); 1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return strm; 1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } while (c != separator); 1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project istringstream strm1(s1); 1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project W1 w1 = W1::Zero(); 1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strm1 >> w1; 1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // read second element 1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project W2 w2 = W2::Zero(); 1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strm >> w2; 1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project w = ProductWeight<W1, W2>(w1, w2); 1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return strm; 1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class W1, class W2> 1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline ProductWeight<W1, W2> Plus(const ProductWeight<W1, W2> &w, 1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const ProductWeight<W1, W2> &v) { 1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ProductWeight<W1, W2>(Plus(w.Value1(), v.Value1()), 1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Plus(w.Value2(), v.Value2())); 1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class W1, class W2> 1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline ProductWeight<W1, W2> Times(const ProductWeight<W1, W2> &w, 1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const ProductWeight<W1, W2> &v) { 1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ProductWeight<W1, W2>(Times(w.Value1(), v.Value1()), 1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Times(w.Value2(), v.Value2())); 1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class W1, class W2> 1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline ProductWeight<W1, W2> Divide(const ProductWeight<W1, W2> &w, 1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const ProductWeight<W1, W2> &v, 1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project DivideType typ = DIVIDE_ANY) { 1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ProductWeight<W1, W2>(Divide(w.Value1(), v.Value1(), typ), 1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Divide(w.Value2(), v.Value2(), typ)); 1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} // namespace fst; 1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif // FST_LIB_PRODUCT_WEIGHT_H__ 195