FST  openfst-1.7.2
OpenFst Library
string-weight.h
Go to the documentation of this file.
1 // See www.openfst.org for extensive documentation on this weighted
2 // finite-state transducer library.
3 //
4 // String weight set and associated semiring operation definitions.
5 
6 #ifndef FST_STRING_WEIGHT_H_
7 #define FST_STRING_WEIGHT_H_
8 
9 #include <cstdlib>
10 
11 #include <list>
12 #include <string>
13 #include <vector>
14 
15 #include <fst/product-weight.h>
16 #include <fst/union-weight.h>
17 #include <fst/weight.h>
18 
19 
20 namespace fst {
21 
22 constexpr int kStringInfinity = -1; // Label for the infinite string.
23 constexpr int kStringBad = -2; // Label for a non-string.
24 constexpr char kStringSeparator = '_'; // Label separator in strings.
25 
26 // Determines whether to use left or right string semiring. Includes a
27 // 'restricted' version that signals an error if proper prefixes/suffixes
28 // would otherwise be returned by Plus, useful with various
29 // algorithms that require functional transducer input with the
30 // string semirings.
32 
34  return s == STRING_LEFT ? STRING_RIGHT
36 }
37 
38 template <class>
40 template <class>
42 
43 // String semiring: (longest_common_prefix/suffix, ., Infinity, Epsilon)
44 template <typename Label_, StringType S = STRING_LEFT>
45 class StringWeight {
46  public:
47  using Label = Label_;
51 
54 
56 
57  template <typename Iterator>
58  StringWeight(const Iterator &begin, const Iterator &end) {
59  for (auto iter = begin; iter != end; ++iter) PushBack(*iter);
60  }
61 
62  explicit StringWeight(Label label) { PushBack(label); }
63 
64  static const StringWeight &Zero() {
65  static const auto *const zero = new StringWeight(Label(kStringInfinity));
66  return *zero;
67  }
68 
69  static const StringWeight &One() {
70  static const auto *const one = new StringWeight();
71  return *one;
72  }
73 
74  static const StringWeight &NoWeight() {
75  static const auto *const no_weight = new StringWeight(Label(kStringBad));
76  return *no_weight;
77  }
78 
79  static const string &Type() {
80  static const string *const type = new string(
81  S == STRING_LEFT
82  ? "left_string"
83  : (S == STRING_RIGHT ? "right_string" : "restricted_string"));
84  return *type;
85  }
86 
87  bool Member() const;
88 
89  std::istream &Read(std::istream &strm);
90 
91  std::ostream &Write(std::ostream &strm) const;
92 
93  size_t Hash() const;
94 
95  StringWeight Quantize(float delta = kDelta) const { return *this; }
96 
97  ReverseWeight Reverse() const;
98 
99  static constexpr uint64 Properties() {
100  return kIdempotent |
101  (S == STRING_LEFT ? kLeftSemiring
102  : (S == STRING_RIGHT
104  : /* S == STRING_RESTRICT */ kLeftSemiring |
105  kRightSemiring));
106  }
107 
108  // These operations combined with the StringWeightIterator and
109  // StringWeightReverseIterator provide the access and mutation of the string
110  // internal elements.
111 
112  // Clear existing StringWeight.
113  void Clear() {
114  first_ = 0;
115  rest_.clear();
116  }
117 
118  size_t Size() const { return first_ ? rest_.size() + 1 : 0; }
119 
120  void PushFront(Label label) {
121  if (first_) rest_.push_front(first_);
122  first_ = label;
123  }
124 
125  void PushBack(Label label) {
126  if (!first_) {
127  first_ = label;
128  } else {
129  rest_.push_back(label);
130  }
131  }
132 
133  private:
134  Label first_ = 0; // First label in string (0 if empty).
135  std::list<Label> rest_; // Remaining labels in string.
136 };
137 
138 // Traverses string in forward direction.
139 template <class StringWeight_>
140 class StringWeightIterator {
141  public:
142  using Weight = StringWeight_;
143  using Label = typename Weight::Label;
144 
145  explicit StringWeightIterator(const Weight &w)
146  : first_(w.first_), rest_(w.rest_), init_(true), iter_(rest_.begin()) {}
147 
148  bool Done() const {
149  if (init_) {
150  return first_ == 0;
151  } else {
152  return iter_ == rest_.end();
153  }
154  }
155 
156  const Label &Value() const { return init_ ? first_ : *iter_; }
157 
158  void Next() {
159  if (init_) {
160  init_ = false;
161  } else {
162  ++iter_;
163  }
164  }
165 
166  void Reset() {
167  init_ = true;
168  iter_ = rest_.begin();
169  }
170 
171  private:
172  const Label &first_;
173  const decltype(Weight::rest_) &rest_;
174  bool init_; // In the initialized state?
175  typename decltype(Weight::rest_)::const_iterator iter_;
176 };
177 
178 // Traverses string in backward direction.
179 template <class StringWeight_>
181  public:
182  using Weight = StringWeight_;
183  using Label = typename Weight::Label;
184 
186  : first_(w.first_),
187  rest_(w.rest_),
188  fin_(first_ == Label()),
189  iter_(rest_.rbegin()) {}
190 
191  bool Done() const { return fin_; }
192 
193  const Label &Value() const { return iter_ == rest_.rend() ? first_ : *iter_; }
194 
195  void Next() {
196  if (iter_ == rest_.rend()) {
197  fin_ = true;
198  } else {
199  ++iter_;
200  }
201  }
202 
203  void Reset() {
204  fin_ = false;
205  iter_ = rest_.rbegin();
206  }
207 
208  private:
209  const Label &first_;
210  const decltype(Weight::rest_) &rest_;
211  bool fin_; // In the final state?
212  typename decltype(Weight::rest_)::const_reverse_iterator iter_;
213 };
214 
215 // StringWeight member functions follow that require
216 // StringWeightIterator or StringWeightReverseIterator.
217 
218 template <typename Label, StringType S>
219 inline std::istream &StringWeight<Label, S>::Read(std::istream &strm) {
220  Clear();
221  int32 size;
222  ReadType(strm, &size);
223  for (int32 i = 0; i < size; ++i) {
224  Label label;
225  ReadType(strm, &label);
226  PushBack(label);
227  }
228  return strm;
229 }
230 
231 template <typename Label, StringType S>
232 inline std::ostream &StringWeight<Label, S>::Write(std::ostream &strm) const {
233  const int32 size = Size();
234  WriteType(strm, size);
235  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
236  WriteType(strm, iter.Value());
237  }
238  return strm;
239 }
240 
241 template <typename Label, StringType S>
242 inline bool StringWeight<Label, S>::Member() const {
243  Iterator iter(*this);
244  return iter.Value() != Label(kStringBad);
245 }
246 
247 template <typename Label, StringType S>
250  ReverseWeight rweight;
251  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
252  rweight.PushFront(iter.Value());
253  }
254  return rweight;
255 }
256 
257 template <typename Label, StringType S>
258 inline size_t StringWeight<Label, S>::Hash() const {
259  size_t h = 0;
260  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
261  h ^= h << 1 ^ iter.Value();
262  }
263  return h;
264 }
265 
266 template <typename Label, StringType S>
267 inline bool operator==(const StringWeight<Label, S> &w1,
268  const StringWeight<Label, S> &w2) {
269  if (w1.Size() != w2.Size()) return false;
271  Iterator iter1(w1);
272  Iterator iter2(w2);
273  for (; !iter1.Done(); iter1.Next(), iter2.Next()) {
274  if (iter1.Value() != iter2.Value()) return false;
275  }
276  return true;
277 }
278 
279 template <typename Label, StringType S>
280 inline bool operator!=(const StringWeight<Label, S> &w1,
281  const StringWeight<Label, S> &w2) {
282  return !(w1 == w2);
283 }
284 
285 template <typename Label, StringType S>
286 inline bool ApproxEqual(const StringWeight<Label, S> &w1,
287  const StringWeight<Label, S> &w2,
288  float delta = kDelta) {
289  return w1 == w2;
290 }
291 
292 template <typename Label, StringType S>
293 inline std::ostream &operator<<(std::ostream &strm,
294  const StringWeight<Label, S> &weight) {
295  typename StringWeight<Label, S>::Iterator iter(weight);
296  if (iter.Done()) {
297  return strm << "Epsilon";
298  } else if (iter.Value() == Label(kStringInfinity)) {
299  return strm << "Infinity";
300  } else if (iter.Value() == Label(kStringBad)) {
301  return strm << "BadString";
302  } else {
303  for (size_t i = 0; !iter.Done(); ++i, iter.Next()) {
304  if (i > 0) strm << kStringSeparator;
305  strm << iter.Value();
306  }
307  }
308  return strm;
309 }
310 
311 template <typename Label, StringType S>
312 inline std::istream &operator>>(std::istream &strm,
313  StringWeight<Label, S> &weight) {
314  string str;
315  strm >> str;
316  using Weight = StringWeight<Label, S>;
317  if (str == "Infinity") {
318  weight = Weight::Zero();
319  } else if (str == "Epsilon") {
320  weight = Weight::One();
321  } else {
322  weight.Clear();
323  char *p = nullptr;
324  for (const char *cs = str.c_str(); !p || *p != '\0'; cs = p + 1) {
325  const Label label = strtoll(cs, &p, 10);
326  if (p == cs || (*p != 0 && *p != kStringSeparator)) {
327  strm.clear(std::ios::badbit);
328  break;
329  }
330  weight.PushBack(label);
331  }
332  }
333  return strm;
334 }
335 
336 // Default is for the restricted string semiring. String equality is required
337 // (for non-Zero() input). The restriction is used (e.g., in determinization)
338 // to ensure the input is functional.
339 template <typename Label, StringType S>
341  const StringWeight<Label, S> &w2) {
342  using Weight = StringWeight<Label, S>;
343  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
344  if (w1 == Weight::Zero()) return w2;
345  if (w2 == Weight::Zero()) return w1;
346  if (w1 != w2) {
347  FSTERROR() << "StringWeight::Plus: Unequal arguments "
348  << "(non-functional FST?)"
349  << " w1 = " << w1 << " w2 = " << w2;
350  return Weight::NoWeight();
351  }
352  return w1;
353 }
354 
355 // Longest common prefix for left string semiring.
356 template <typename Label>
360  using Weight = StringWeight<Label, STRING_LEFT>;
361  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
362  if (w1 == Weight::Zero()) return w2;
363  if (w2 == Weight::Zero()) return w1;
364  Weight sum;
365  typename Weight::Iterator iter1(w1);
366  typename Weight::Iterator iter2(w2);
367  for (; !iter1.Done() && !iter2.Done() && iter1.Value() == iter2.Value();
368  iter1.Next(), iter2.Next()) {
369  sum.PushBack(iter1.Value());
370  }
371  return sum;
372 }
373 
374 // Longest common suffix for right string semiring.
375 template <typename Label>
379  using Weight = StringWeight<Label, STRING_RIGHT>;
380  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
381  if (w1 == Weight::Zero()) return w2;
382  if (w2 == Weight::Zero()) return w1;
383  Weight sum;
384  typename Weight::ReverseIterator iter1(w1);
385  typename Weight::ReverseIterator iter2(w2);
386  for (; !iter1.Done() && !iter2.Done() && iter1.Value() == iter2.Value();
387  iter1.Next(), iter2.Next()) {
388  sum.PushFront(iter1.Value());
389  }
390  return sum;
391 }
392 
393 template <typename Label, StringType S>
395  const StringWeight<Label, S> &w2) {
396  using Weight = StringWeight<Label, S>;
397  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
398  if (w1 == Weight::Zero() || w2 == Weight::Zero()) return Weight::Zero();
399  Weight product(w1);
400  for (typename Weight::Iterator iter(w2); !iter.Done(); iter.Next()) {
401  product.PushBack(iter.Value());
402  }
403  return product;
404 }
405 
406 // Left division in a left string semiring.
407 template <typename Label, StringType S>
409  const StringWeight<Label, S> &w2) {
410  using Weight = StringWeight<Label, S>;
411  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
412  if (w2 == Weight::Zero()) {
413  return Weight(Label(kStringBad));
414  } else if (w1 == Weight::Zero()) {
415  return Weight::Zero();
416  }
417  Weight result;
418  typename Weight::Iterator iter(w1);
419  size_t i = 0;
420  for (; !iter.Done() && i < w2.Size(); iter.Next(), ++i) {
421  }
422  for (; !iter.Done(); iter.Next()) result.PushBack(iter.Value());
423  return result;
424 }
425 
426 // Right division in a right string semiring.
427 template <typename Label, StringType S>
429  const StringWeight<Label, S> &w2) {
430  using Weight = StringWeight<Label, S>;
431  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
432  if (w2 == Weight::Zero()) {
433  return Weight(Label(kStringBad));
434  } else if (w1 == Weight::Zero()) {
435  return Weight::Zero();
436  }
437  Weight result;
438  typename Weight::ReverseIterator iter(w1);
439  size_t i = 0;
440  for (; !iter.Done() && i < w2.Size(); iter.Next(), ++i) {
441  }
442  for (; !iter.Done(); iter.Next()) result.PushFront(iter.Value());
443  return result;
444 }
445 
446 // Default is the restricted string semiring.
447 template <typename Label, StringType S>
449  const StringWeight<Label, S> &w2,
450  DivideType divide_type) {
451  using Weight = StringWeight<Label, S>;
452  if (divide_type == DIVIDE_LEFT) {
453  return DivideLeft(w1, w2);
454  } else if (divide_type == DIVIDE_RIGHT) {
455  return DivideRight(w1, w2);
456  } else {
457  FSTERROR() << "StringWeight::Divide: "
458  << "Only explicit left or right division is defined "
459  << "for the " << Weight::Type() << " semiring";
460  return Weight::NoWeight();
461  }
462 }
463 
464 // Left division in the left string semiring.
465 template <typename Label>
468  const StringWeight<Label, STRING_LEFT> &w2, DivideType divide_type) {
469  if (divide_type != DIVIDE_LEFT) {
470  FSTERROR() << "StringWeight::Divide: Only left division is defined "
471  << "for the left string semiring";
473  }
474  return DivideLeft(w1, w2);
475 }
476 
477 // Right division in the right string semiring.
478 template <typename Label>
481  const StringWeight<Label, STRING_RIGHT> &w2, DivideType divide_type) {
482  if (divide_type != DIVIDE_RIGHT) {
483  FSTERROR() << "StringWeight::Divide: Only right division is defined "
484  << "for the right string semiring";
486  }
487  return DivideRight(w1, w2);
488 }
489 
490 // This function object generates StringWeights that are random integer strings
491 // from {1, ... , alphabet_size)^{0, max_string_length} U { Zero }. This is
492 // intended primarily for testing.
493 template <class Label, StringType S>
495  public:
497 
498  explicit WeightGenerate(bool allow_zero = true,
499  size_t alphabet_size = kNumRandomWeights,
500  size_t max_string_length = kNumRandomWeights)
501  : allow_zero_(allow_zero),
502  alphabet_size_(alphabet_size),
503  max_string_length_(max_string_length) {}
504 
505  Weight operator()() const {
506  size_t n = rand() % (max_string_length_ + allow_zero_); // NOLINT
507  if (allow_zero_ && n == max_string_length_) return Weight::Zero();
508  std::vector<Label> labels;
509  labels.reserve(n);
510  for (size_t i = 0; i < n; ++i) {
511  labels.push_back(rand() % alphabet_size_ + 1); // NOLINT
512  }
513  return Weight(labels.begin(), labels.end());
514  }
515 
516  private:
517  // Permits Zero() and zero divisors.
518  const bool allow_zero_;
519  // Alphabet size for random weights.
520  const size_t alphabet_size_;
521  // Number of alternative random weights.
522  const size_t max_string_length_;
523 };
524 
525 // Determines whether to use left, right, or (general) gallic semiring. Includes
526 // a restricted version that signals an error if proper string prefixes or
527 // suffixes would otherwise be returned by string Plus. This is useful with
528 // algorithms that require functional transducer input. Also includes min
529 // version that changes the Plus to keep only the lowest W weight string.
535  GALLIC = 4
536 };
537 
539  return g == GALLIC_LEFT
540  ? STRING_LEFT
542 }
543 
545  return g == GALLIC_LEFT
546  ? GALLIC_RIGHT
547  : (g == GALLIC_RIGHT
548  ? GALLIC_LEFT
549  : (g == GALLIC_RESTRICT
551  : (g == GALLIC_MIN ? GALLIC_MIN : GALLIC)));
552 }
553 
554 // Product of string weight and an arbitraryy weight.
555 template <class Label, class W, GallicType G = GALLIC_LEFT>
557  : public ProductWeight<StringWeight<Label, GallicStringType(G)>, W> {
558  using ReverseWeight =
561 
563 
565 
566  GallicWeight(SW w1, W w2) : ProductWeight<SW, W>(w1, w2) {}
567 
568  explicit GallicWeight(const string &s, int *nread = nullptr)
569  : ProductWeight<SW, W>(s, nread) {}
570 
572  : ProductWeight<SW, W>(w) {}
573 
574  static const GallicWeight &Zero() {
575  static const GallicWeight zero(ProductWeight<SW, W>::Zero());
576  return zero;
577  }
578 
579  static const GallicWeight &One() {
580  static const GallicWeight one(ProductWeight<SW, W>::One());
581  return one;
582  }
583 
584  static const GallicWeight &NoWeight() {
585  static const GallicWeight no_weight(ProductWeight<SW, W>::NoWeight());
586  return no_weight;
587  }
588 
589  static const string &Type() {
590  static const string *const type = new string(
591  G == GALLIC_LEFT
592  ? "left_gallic"
593  : (G == GALLIC_RIGHT
594  ? "right_gallic"
595  : (G == GALLIC_RESTRICT
596  ? "restricted_gallic"
597  : (G == GALLIC_MIN ? "min_gallic" : "gallic"))));
598  return *type;
599  }
600 
601  GallicWeight Quantize(float delta = kDelta) const {
603  }
604 
607  }
608 };
609 
610 // Default plus.
611 template <class Label, class W, GallicType G>
613  const GallicWeight<Label, W, G> &v) {
614  return GallicWeight<Label, W, G>(Plus(w.Value1(), v.Value1()),
615  Plus(w.Value2(), v.Value2()));
616 }
617 
618 // Min gallic plus.
619 template <class Label, class W>
623  static const NaturalLess<W> less;
624  return less(w1.Value2(), w2.Value2()) ? w1 : w2;
625 }
626 
627 template <class Label, class W, GallicType G>
629  const GallicWeight<Label, W, G> &v) {
630  return GallicWeight<Label, W, G>(Times(w.Value1(), v.Value1()),
631  Times(w.Value2(), v.Value2()));
632 }
633 
634 template <class Label, class W, GallicType G>
636  const GallicWeight<Label, W, G> &v,
637  DivideType divide_type = DIVIDE_ANY) {
638  return GallicWeight<Label, W, G>(Divide(w.Value1(), v.Value1(), divide_type),
639  Divide(w.Value2(), v.Value2(), divide_type));
640 }
641 
642 // This function object generates gallic weights by calling an underlying
643 // product weight generator. This is intended primarily for testing.
644 template <class Label, class W, GallicType G>
646  : public WeightGenerate<
647  ProductWeight<StringWeight<Label, GallicStringType(G)>, W>> {
648  public:
650  using Generate = WeightGenerate<
652 
653  explicit WeightGenerate(bool allow_zero = true) : generate_(allow_zero) {}
654 
655  Weight operator()() const { return Weight(generate_()); }
656 
657  private:
658  const Generate generate_;
659 };
660 
661 // Union weight options for (general) GALLIC type.
662 template <class Label, class W>
668 
669  // Military order.
670  struct Compare {
671  bool operator()(const GW &w1, const GW &w2) const {
672  const SW &s1 = w1.Value1();
673  const SW &s2 = w2.Value1();
674  if (s1.Size() < s2.Size()) return true;
675  if (s1.Size() > s2.Size()) return false;
676  SI iter1(s1);
677  SI iter2(s2);
678  while (!iter1.Done()) {
679  const auto l1 = iter1.Value();
680  const auto l2 = iter2.Value();
681  if (l1 < l2) return true;
682  if (l1 > l2) return false;
683  iter1.Next();
684  iter2.Next();
685  }
686  return false;
687  }
688  };
689 
690  // Adds W weights when string part equal.
691  struct Merge {
692  GW operator()(const GW &w1, const GW &w2) const {
693  return GW(w1.Value1(), Plus(w1.Value2(), w2.Value2()));
694  }
695  };
696 };
697 
698 // Specialization for the (general) GALLIC type.
699 template <class Label, class W>
701  : public UnionWeight<GallicWeight<Label, W, GALLIC_RESTRICT>,
702  GallicUnionWeightOptions<Label, W>> {
709 
710  using UW::Properties;
711 
713 
714  // Copy constructor.
715  GallicWeight(const UW &weight) : UW(weight) {} // NOLINT
716 
717  // Singleton constructors: create a GALLIC weight containing a single
718  // GALLIC_RESTRICT weight. Takes as argument (1) a GALLIC_RESTRICT weight or
719  // (2) the two components of a GALLIC_RESTRICT weight.
720  explicit GallicWeight(const GW &weight) : UW(weight) {}
721 
722  GallicWeight(SW w1, W w2) : UW(GW(w1, w2)) {}
723 
724  explicit GallicWeight(const string &str, int *nread = nullptr)
725  : UW(str, nread) {}
726 
728  static const GallicWeight<Label, W, GALLIC> zero(UW::Zero());
729  return zero;
730  }
731 
733  static const GallicWeight<Label, W, GALLIC> one(UW::One());
734  return one;
735  }
736 
738  static const GallicWeight<Label, W, GALLIC> no_weight(UW::NoWeight());
739  return no_weight;
740  }
741 
742  static const string &Type() {
743  static const string *const type = new string("gallic");
744  return *type;
745  }
746 
748  return UW::Quantize(delta);
749  }
750 
751  ReverseWeight Reverse() const { return UW::Reverse(); }
752 };
753 
754 // (General) gallic plus.
755 template <class Label, class W>
758  const GallicWeight<Label, W, GALLIC> &w2) {
761  return Plus(static_cast<UW>(w1), static_cast<UW>(w2));
762 }
763 
764 // (General) gallic times.
765 template <class Label, class W>
768  const GallicWeight<Label, W, GALLIC> &w2) {
771  return Times(static_cast<UW>(w1), static_cast<UW>(w2));
772 }
773 
774 // (General) gallic divide.
775 template <class Label, class W>
779  DivideType divide_type = DIVIDE_ANY) {
782  return Divide(static_cast<UW>(w1), static_cast<UW>(w2), divide_type);
783 }
784 
785 // This function object generates gallic weights by calling an underlying
786 // union weight generator. This is intended primarily for testing.
787 template <class Label, class W>
789  : public WeightGenerate<UnionWeight<GallicWeight<Label, W, GALLIC_RESTRICT>,
790  GallicUnionWeightOptions<Label, W>>> {
791  public:
793  using Generate =
796 
797  explicit WeightGenerate(bool allow_zero = true) : generate_(allow_zero) {}
798 
799  Weight operator()() const { return Weight(generate_()); }
800 
801  private:
802  const Generate generate_;
803 };
804 
805 } // namespace fst
806 
807 #endif // FST_STRING_WEIGHT_H_
GallicWeight< Label, W, GALLIC > Quantize(float delta=kDelta) const
StringWeightIterator(const Weight &w)
GW operator()(const GW &w1, const GW &w2) const
WeightGenerate(bool allow_zero=true, size_t alphabet_size=kNumRandomWeights, size_t max_string_length=kNumRandomWeights)
ExpectationWeight< X1, X2 > Divide(const ExpectationWeight< X1, X2 > &w1, const ExpectationWeight< X1, X2 > &w2, DivideType typ=DIVIDE_ANY)
static const GallicWeight & Zero()
StringWeight(const Iterator &begin, const Iterator &end)
Definition: string-weight.h:58
uint64_t uint64
Definition: types.h:32
static const StringWeight & NoWeight()
Definition: string-weight.h:74
StringWeight< Label, S > DivideLeft(const StringWeight< Label, S > &w1, const StringWeight< Label, S > &w2)
const Label & Value() const
constexpr int kStringBad
Definition: string-weight.h:23
size_t Hash() const
constexpr uint64 kRightSemiring
Definition: weight.h:115
constexpr GallicType ReverseGallicType(GallicType g)
GallicWeight(const string &str, int *nread=nullptr)
static const StringWeight & Zero()
Definition: string-weight.h:64
static const GallicWeight< Label, W, GALLIC > & One()
void PushBack(Label label)
bool Member() const
ExpectationWeight< X1, X2 > Times(const ExpectationWeight< X1, X2 > &w1, const ExpectationWeight< X1, X2 > &w2)
GallicWeight(const string &s, int *nread=nullptr)
typename Weight::Label Label
GallicWeight(SW w1, W w2)
constexpr uint64 kLeftSemiring
Definition: weight.h:112
constexpr char kStringSeparator
Definition: string-weight.h:24
const Label & Value() const
void Reverse(const Fst< Arc > &ifst, const std::vector< std::pair< typename Arc::Label, typename Arc::Label >> &parens, std::vector< typename Arc::Label > *assignments, MutableFst< RevArc > *ofst)
Definition: reverse.h:20
std::ostream & WriteType(std::ostream &strm, const T t)
Definition: util.h:155
#define FSTERROR()
Definition: util.h:35
static const string & Type()
Definition: string-weight.h:79
constexpr int kStringInfinity
Definition: string-weight.h:22
StringWeightIterator< StringWeight > Iterator
Definition: string-weight.h:49
std::istream & operator>>(std::istream &strm, FloatWeightTpl< T > &w)
Definition: float-weight.h:160
bool operator==(const PdtStateTuple< S, K > &x, const PdtStateTuple< S, K > &y)
Definition: pdt.h:133
StringWeight< Label, ReverseStringType(S)> ReverseWeight
Definition: string-weight.h:48
constexpr StringType ReverseStringType(StringType s)
Definition: string-weight.h:33
constexpr uint64 kIdempotent
Definition: weight.h:123
StringWeight Quantize(float delta=kDelta) const
Definition: string-weight.h:95
ExpectationWeight< X1, X2 > Plus(const ExpectationWeight< X1, X2 > &w1, const ExpectationWeight< X1, X2 > &w2)
static const GallicWeight & One()
StringWeight< Label, S > DivideRight(const StringWeight< Label, S > &w1, const StringWeight< Label, S > &w2)
std::ostream & operator<<(std::ostream &strm, const FloatWeightTpl< T > &w)
Definition: float-weight.h:146
GallicWeight Quantize(float delta=kDelta) const
constexpr bool operator!=(const FloatWeightTpl< T > &w1, const FloatWeightTpl< T > &w2)
Definition: float-weight.h:119
std::istream & Read(std::istream &strm)
GallicWeight(const ProductWeight< SW, W > &w)
std::ostream & Write(std::ostream &strm) const
typename Weight::Label Label
StringWeight(Label label)
Definition: string-weight.h:62
bool operator()(const GW &w1, const GW &w2) const
static const GallicWeight< Label, W, GALLIC > & Zero()
static const StringWeight & One()
Definition: string-weight.h:69
static const string & Type()
int32_t int32
Definition: types.h:26
StringType
Definition: string-weight.h:31
constexpr bool ApproxEqual(const FloatWeightTpl< T > &w1, const FloatWeightTpl< T > &w2, float delta=kDelta)
Definition: float-weight.h:140
size_t Size() const
constexpr size_t kNumRandomWeights
Definition: weight.h:130
static constexpr uint64 Properties()
Definition: string-weight.h:99
std::istream & ReadType(std::istream &strm, T *t)
Definition: util.h:47
static const GallicWeight & NoWeight()
DivideType
Definition: weight.h:142
constexpr float kDelta
Definition: weight.h:109
StringWeightReverseIterator(const Weight &w)
void PushFront(Label label)
static const GallicWeight< Label, W, GALLIC > & NoWeight()
ReverseWeight Reverse() const
ReverseWeight Reverse() const
const StringWeight< Label, GallicStringType(G)> & Value1() const
Definition: pair-weight.h:76
constexpr StringType GallicStringType(GallicType g)