FST  openfst-1.8.3
OpenFst Library
string-weight.h
Go to the documentation of this file.
1 // Copyright 2005-2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the 'License');
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an 'AS IS' BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // See www.openfst.org for extensive documentation on this weighted
16 // finite-state transducer library.
17 //
18 // String weight set and associated semiring operation definitions.
19 
20 #ifndef FST_STRING_WEIGHT_H_
21 #define FST_STRING_WEIGHT_H_
22 
23 #include <cstddef>
24 #include <cstdint>
25 #include <ios>
26 #include <istream>
27 #include <list>
28 #include <optional>
29 #include <ostream>
30 #include <random>
31 #include <string>
32 #include <vector>
33 
34 #include <fst/log.h>
35 #include <fst/product-weight.h>
36 #include <fst/union-weight.h>
37 #include <fst/util.h>
38 #include <fst/weight.h>
39 #include <string_view>
40 
41 namespace fst {
42 
43 inline constexpr int kStringInfinity = -1; // Label for the infinite string.
44 inline constexpr int kStringBad = -2; // Label for a non-string.
45 inline constexpr char kStringSeparator = '_'; // Label separator in strings.
46 
47 // Determines whether to use left or right string semiring. Includes a
48 // 'restricted' version that signals an error if proper prefixes/suffixes
49 // would otherwise be returned by Plus, useful with various
50 // algorithms that require functional transducer input with the
51 // string semirings.
53 
55  return s == STRING_LEFT ? STRING_RIGHT
57 }
58 
59 template <class>
61 template <class>
63 
64 // String semiring: (longest_common_prefix/suffix, ., Infinity, Epsilon)
65 template <typename L, StringType S = STRING_LEFT>
66 class StringWeight {
67  public:
68  using Label = L;
72 
75 
76  StringWeight() = default;
77 
78  template <typename Iterator>
79  StringWeight(const Iterator begin, const Iterator end) {
80  for (auto iter = begin; iter != end; ++iter) PushBack(*iter);
81  }
82 
83  explicit StringWeight(Label label) { PushBack(label); }
84 
85  static const StringWeight &Zero() {
86  static const auto *const zero = new StringWeight(Label(kStringInfinity));
87  return *zero;
88  }
89 
90  static const StringWeight &One() {
91  static const auto *const one = new StringWeight();
92  return *one;
93  }
94 
95  static const StringWeight &NoWeight() {
96  static const auto *const no_weight = new StringWeight(Label(kStringBad));
97  return *no_weight;
98  }
99 
100  static const std::string &Type() {
101  static const std::string *const type = new std::string(
102  S == STRING_LEFT
103  ? "left_string"
104  : (S == STRING_RIGHT ? "right_string" : "restricted_string"));
105  return *type;
106  }
107 
108  bool Member() const;
109 
110  std::istream &Read(std::istream &strm);
111 
112  std::ostream &Write(std::ostream &strm) const;
113 
114  size_t Hash() const;
115 
116  StringWeight Quantize(float delta = kDelta) const { return *this; }
117 
118  ReverseWeight Reverse() const;
119 
120  static constexpr uint64_t Properties() {
121  return kIdempotent |
122  (S == STRING_LEFT ? kLeftSemiring
123  : (S == STRING_RIGHT
125  : /* S == STRING_RESTRICT */ kLeftSemiring |
126  kRightSemiring));
127  }
128 
129  // These operations combined with the StringWeightIterator and
130  // StringWeightReverseIterator provide the access and mutation of the string
131  // internal elements.
132 
133  // Clear existing StringWeight.
134  void Clear() {
135  first_ = 0;
136  rest_.clear();
137  }
138 
139  size_t Size() const { return first_ ? rest_.size() + 1 : 0; }
140 
141  void PushFront(Label label) {
142  if (first_) rest_.push_front(first_);
143  first_ = label;
144  }
145 
146  void PushBack(Label label) {
147  if (!first_) {
148  first_ = label;
149  } else {
150  rest_.push_back(label);
151  }
152  }
153 
154  private:
155  Label first_ = 0; // First label in string (0 if empty).
156  std::list<Label> rest_; // Remaining labels in string.
157 };
158 
159 // Traverses string in forward direction.
160 template <class StringWeight_>
161 class StringWeightIterator {
162  public:
163  using Weight = StringWeight_;
164  using Label = typename Weight::Label;
165 
166  explicit StringWeightIterator(const Weight &w)
167  : first_(w.first_), rest_(w.rest_), init_(true), iter_(rest_.begin()) {}
168 
169  bool Done() const {
170  if (init_) {
171  return first_ == 0;
172  } else {
173  return iter_ == rest_.end();
174  }
175  }
176 
177  const Label &Value() const { return init_ ? first_ : *iter_; }
178 
179  void Next() {
180  if (init_) {
181  init_ = false;
182  } else {
183  ++iter_;
184  }
185  }
186 
187  void Reset() {
188  init_ = true;
189  iter_ = rest_.begin();
190  }
191 
192  private:
193  const Label &first_;
194  const decltype(Weight::rest_) &rest_;
195  bool init_; // In the initialized state?
196  typename decltype(Weight::rest_)::const_iterator iter_;
197 };
198 
199 // Traverses string in backward direction.
200 template <class StringWeight_>
202  public:
203  using Weight = StringWeight_;
204  using Label = typename Weight::Label;
205 
207  : first_(w.first_),
208  rest_(w.rest_),
209  fin_(first_ == Label()),
210  iter_(rest_.rbegin()) {}
211 
212  bool Done() const { return fin_; }
213 
214  const Label &Value() const { return iter_ == rest_.rend() ? first_ : *iter_; }
215 
216  void Next() {
217  if (iter_ == rest_.rend()) {
218  fin_ = true;
219  } else {
220  ++iter_;
221  }
222  }
223 
224  void Reset() {
225  fin_ = false;
226  iter_ = rest_.rbegin();
227  }
228 
229  private:
230  const Label &first_;
231  const decltype(Weight::rest_) &rest_;
232  bool fin_; // In the final state?
233  typename decltype(Weight::rest_)::const_reverse_iterator iter_;
234 };
235 
236 // StringWeight member functions follow that require
237 // StringWeightIterator or StringWeightReverseIterator.
238 
239 template <typename Label, StringType S>
240 inline std::istream &StringWeight<Label, S>::Read(std::istream &strm) {
241  Clear();
242  int32_t size;
243  ReadType(strm, &size);
244  for (int32_t i = 0; i < size; ++i) {
245  Label label;
246  ReadType(strm, &label);
247  PushBack(label);
248  }
249  return strm;
250 }
251 
252 template <typename Label, StringType S>
253 inline std::ostream &StringWeight<Label, S>::Write(std::ostream &strm) const {
254  const int32_t size = Size();
255  WriteType(strm, size);
256  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
257  WriteType(strm, iter.Value());
258  }
259  return strm;
260 }
261 
262 template <typename Label, StringType S>
263 inline bool StringWeight<Label, S>::Member() const {
264  Iterator iter(*this);
265  return iter.Value() != Label(kStringBad);
266 }
267 
268 template <typename Label, StringType S>
271  ReverseWeight rweight;
272  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
273  rweight.PushFront(iter.Value());
274  }
275  return rweight;
276 }
277 
278 template <typename Label, StringType S>
279 inline size_t StringWeight<Label, S>::Hash() const {
280  size_t h = 0;
281  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
282  h ^= h << 1 ^ iter.Value();
283  }
284  return h;
285 }
286 
287 template <typename Label, StringType S>
288 inline bool operator==(const StringWeight<Label, S> &w1,
289  const StringWeight<Label, S> &w2) {
290  if (w1.Size() != w2.Size()) return false;
292  Iterator iter1(w1);
293  Iterator iter2(w2);
294  for (; !iter1.Done(); iter1.Next(), iter2.Next()) {
295  if (iter1.Value() != iter2.Value()) return false;
296  }
297  return true;
298 }
299 
300 template <typename Label, StringType S>
301 inline bool operator!=(const StringWeight<Label, S> &w1,
302  const StringWeight<Label, S> &w2) {
303  return !(w1 == w2);
304 }
305 
306 template <typename Label, StringType S>
307 inline bool ApproxEqual(const StringWeight<Label, S> &w1,
308  const StringWeight<Label, S> &w2,
309  float delta = kDelta) {
310  return w1 == w2;
311 }
312 
313 template <typename Label, StringType S>
314 inline std::ostream &operator<<(std::ostream &strm,
315  const StringWeight<Label, S> &weight) {
316  typename StringWeight<Label, S>::Iterator iter(weight);
317  if (iter.Done()) {
318  return strm << "Epsilon";
319  } else if (iter.Value() == Label(kStringInfinity)) {
320  return strm << "Infinity";
321  } else if (iter.Value() == Label(kStringBad)) {
322  return strm << "BadString";
323  } else {
324  for (size_t i = 0; !iter.Done(); ++i, iter.Next()) {
325  if (i > 0) strm << kStringSeparator;
326  strm << iter.Value();
327  }
328  }
329  return strm;
330 }
331 
332 template <typename Label, StringType S>
333 inline std::istream &operator>>(std::istream &strm,
334  StringWeight<Label, S> &weight) {
335  std::string str;
336  strm >> str;
337  using Weight = StringWeight<Label, S>;
338  if (str == "Infinity") {
339  weight = Weight::Zero();
340  } else if (str == "Epsilon") {
341  weight = Weight::One();
342  } else {
343  weight.Clear();
344  for (std::string_view sv : StrSplit(str, kStringSeparator)) {
345  auto maybe_label = ParseInt64(sv);
346  if (!maybe_label.has_value()) {
347  strm.clear(std::ios::badbit);
348  break;
349  }
350  weight.PushBack(*maybe_label);
351  }
352  }
353  return strm;
354 }
355 
356 // Default is for the restricted string semiring. String equality is required
357 // (for non-Zero() input). The restriction is used (e.g., in determinization)
358 // to ensure the input is functional.
359 template <typename Label, StringType S>
361  const StringWeight<Label, S> &w2) {
362  using Weight = StringWeight<Label, S>;
363  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
364  if (w1 == Weight::Zero()) return w2;
365  if (w2 == Weight::Zero()) return w1;
366  if (w1 != w2) {
367  FSTERROR() << "StringWeight::Plus: Unequal arguments "
368  << "(non-functional FST?)"
369  << " w1 = " << w1 << " w2 = " << w2;
370  return Weight::NoWeight();
371  }
372  return w1;
373 }
374 
375 // Longest common prefix for left string semiring.
376 template <typename Label>
380  using Weight = StringWeight<Label, STRING_LEFT>;
381  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
382  if (w1 == Weight::Zero()) return w2;
383  if (w2 == Weight::Zero()) return w1;
384  Weight sum;
385  typename Weight::Iterator iter1(w1);
386  typename Weight::Iterator iter2(w2);
387  for (; !iter1.Done() && !iter2.Done() && iter1.Value() == iter2.Value();
388  iter1.Next(), iter2.Next()) {
389  sum.PushBack(iter1.Value());
390  }
391  return sum;
392 }
393 
394 // Longest common suffix for right string semiring.
395 template <typename Label>
399  using Weight = StringWeight<Label, STRING_RIGHT>;
400  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
401  if (w1 == Weight::Zero()) return w2;
402  if (w2 == Weight::Zero()) return w1;
403  Weight sum;
404  typename Weight::ReverseIterator iter1(w1);
405  typename Weight::ReverseIterator iter2(w2);
406  for (; !iter1.Done() && !iter2.Done() && iter1.Value() == iter2.Value();
407  iter1.Next(), iter2.Next()) {
408  sum.PushFront(iter1.Value());
409  }
410  return sum;
411 }
412 
413 template <typename Label, StringType S>
415  const StringWeight<Label, S> &w2) {
416  using Weight = StringWeight<Label, S>;
417  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
418  if (w1 == Weight::Zero() || w2 == Weight::Zero()) return Weight::Zero();
419  Weight product(w1);
420  for (typename Weight::Iterator iter(w2); !iter.Done(); iter.Next()) {
421  product.PushBack(iter.Value());
422  }
423  return product;
424 }
425 
426 // Left division in a left 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::Iterator 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.PushBack(iter.Value());
443  return result;
444 }
445 
446 // Right division in a right string semiring.
447 template <typename Label, StringType S>
449  const StringWeight<Label, S> &w2) {
450  using Weight = StringWeight<Label, S>;
451  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
452  if (w2 == Weight::Zero()) {
453  return Weight(Label(kStringBad));
454  } else if (w1 == Weight::Zero()) {
455  return Weight::Zero();
456  }
457  Weight result;
458  typename Weight::ReverseIterator iter(w1);
459  size_t i = 0;
460  for (; !iter.Done() && i < w2.Size(); iter.Next(), ++i) {
461  }
462  for (; !iter.Done(); iter.Next()) result.PushFront(iter.Value());
463  return result;
464 }
465 
466 // Default is the restricted string semiring.
467 template <typename Label, StringType S>
469  const StringWeight<Label, S> &w2,
470  DivideType divide_type) {
471  using Weight = StringWeight<Label, S>;
472  if (divide_type == DIVIDE_LEFT) {
473  return DivideLeft(w1, w2);
474  } else if (divide_type == DIVIDE_RIGHT) {
475  return DivideRight(w1, w2);
476  } else {
477  FSTERROR() << "StringWeight::Divide: "
478  << "Only explicit left or right division is defined "
479  << "for the " << Weight::Type() << " semiring";
480  return Weight::NoWeight();
481  }
482 }
483 
484 // Left division in the left string semiring.
485 template <typename Label>
488  const StringWeight<Label, STRING_LEFT> &w2, DivideType divide_type) {
489  if (divide_type != DIVIDE_LEFT) {
490  FSTERROR() << "StringWeight::Divide: Only left division is defined "
491  << "for the left string semiring";
493  }
494  return DivideLeft(w1, w2);
495 }
496 
497 // Right division in the right string semiring.
498 template <typename Label>
501  const StringWeight<Label, STRING_RIGHT> &w2, DivideType divide_type) {
502  if (divide_type != DIVIDE_RIGHT) {
503  FSTERROR() << "StringWeight::Divide: Only right division is defined "
504  << "for the right string semiring";
506  }
507  return DivideRight(w1, w2);
508 }
509 
510 // This function object generates StringWeights that are random integer strings
511 // from {1, ... , alphabet_size)^{0, max_string_length} U { Zero }. This is
512 // intended primarily for testing.
513 template <class Label, StringType S>
515  public:
517 
518  explicit WeightGenerate(uint64_t seed = std::random_device()(),
519  bool allow_zero = true,
520  size_t alphabet_size = kNumRandomWeights,
521  size_t max_string_length = kNumRandomWeights)
522  : rand_(seed),
523  allow_zero_(allow_zero),
524  alphabet_size_(alphabet_size),
525  max_string_length_(max_string_length) {}
526 
527  Weight operator()() const {
528  const int n = std::uniform_int_distribution<>(
529  0, max_string_length_ + allow_zero_)(rand_);
530  if (allow_zero_ && n == max_string_length_) return Weight::Zero();
531  std::vector<Label> labels;
532  labels.reserve(n);
533  for (int i = 0; i < n; ++i) {
534  labels.push_back(
535  std::uniform_int_distribution<>(1, alphabet_size_)(rand_));
536  }
537  return Weight(labels.begin(), labels.end());
538  }
539 
540  private:
541  mutable std::mt19937_64 rand_;
542  const bool allow_zero_;
543  const size_t alphabet_size_;
544  const size_t max_string_length_;
545 };
546 
547 // Determines whether to use left, right, or (general) gallic semiring. Includes
548 // a restricted version that signals an error if proper string prefixes or
549 // suffixes would otherwise be returned by string Plus. This is useful with
550 // algorithms that require functional transducer input. Also includes min
551 // version that changes the Plus to keep only the lowest W weight string.
557  GALLIC = 4
558 };
559 
561  return g == GALLIC_LEFT
562  ? STRING_LEFT
564 }
565 
567  return g == GALLIC_LEFT
568  ? GALLIC_RIGHT
569  : (g == GALLIC_RIGHT
570  ? GALLIC_LEFT
571  : (g == GALLIC_RESTRICT
573  : (g == GALLIC_MIN ? GALLIC_MIN : GALLIC)));
574 }
575 
576 // Product of string weight and an arbitraryy weight.
577 template <class Label, class W, GallicType G = GALLIC_LEFT>
579  : public ProductWeight<StringWeight<Label, GallicStringType(G)>, W> {
580  using ReverseWeight =
583 
585 
586  GallicWeight() = default;
587 
588  GallicWeight(SW w1, W w2) : ProductWeight<SW, W>(w1, w2) {}
589 
590  explicit GallicWeight(std::string_view s, int *nread = nullptr)
591  : ProductWeight<SW, W>(s, nread) {}
592 
594  : ProductWeight<SW, W>(w) {}
595 
596  static const GallicWeight &Zero() {
597  static const GallicWeight zero(ProductWeight<SW, W>::Zero());
598  return zero;
599  }
600 
601  static const GallicWeight &One() {
602  static const GallicWeight one(ProductWeight<SW, W>::One());
603  return one;
604  }
605 
606  static const GallicWeight &NoWeight() {
607  static const GallicWeight no_weight(ProductWeight<SW, W>::NoWeight());
608  return no_weight;
609  }
610 
611  static const std::string &Type() {
612  static const std::string *const type = new std::string(
613  G == GALLIC_LEFT
614  ? "left_gallic"
615  : (G == GALLIC_RIGHT
616  ? "right_gallic"
617  : (G == GALLIC_RESTRICT
618  ? "restricted_gallic"
619  : (G == GALLIC_MIN ? "min_gallic" : "gallic"))));
620  return *type;
621  }
622 
623  GallicWeight Quantize(float delta = kDelta) const {
625  }
626 
629  }
630 };
631 
632 // Default plus.
633 template <class Label, class W, GallicType G>
635  const GallicWeight<Label, W, G> &v) {
636  return GallicWeight<Label, W, G>(Plus(w.Value1(), v.Value1()),
637  Plus(w.Value2(), v.Value2()));
638 }
639 
640 // Min gallic plus.
641 template <class Label, class W>
645  static const NaturalLess<W> less;
646  return less(w1.Value2(), w2.Value2()) ? w1 : w2;
647 }
648 
649 template <class Label, class W, GallicType G>
651  const GallicWeight<Label, W, G> &v) {
652  return GallicWeight<Label, W, G>(Times(w.Value1(), v.Value1()),
653  Times(w.Value2(), v.Value2()));
654 }
655 
656 template <class Label, class W, GallicType G>
658  const GallicWeight<Label, W, G> &v,
659  DivideType divide_type = DIVIDE_ANY) {
660  return GallicWeight<Label, W, G>(Divide(w.Value1(), v.Value1(), divide_type),
661  Divide(w.Value2(), v.Value2(), divide_type));
662 }
663 
664 // This function object generates gallic weights by calling an underlying
665 // product weight generator. This is intended primarily for testing.
666 template <class Label, class W, GallicType G>
668  : public WeightGenerate<
669  ProductWeight<StringWeight<Label, GallicStringType(G)>, W>> {
670  public:
672  using Generate = WeightGenerate<
674 
675  explicit WeightGenerate(uint64_t seed = std::random_device()(),
676  bool allow_zero = true)
677  : generate_(seed, allow_zero) {}
678 
679  Weight operator()() const { return Weight(generate_()); }
680 
681  private:
682  const Generate generate_;
683 };
684 
685 // Union weight options for (general) GALLIC type.
686 template <class Label, class W>
692 
693  // Military order.
694  struct Compare {
695  bool operator()(const GW &w1, const GW &w2) const {
696  const SW &s1 = w1.Value1();
697  const SW &s2 = w2.Value1();
698  if (s1.Size() < s2.Size()) return true;
699  if (s1.Size() > s2.Size()) return false;
700  SI iter1(s1);
701  SI iter2(s2);
702  while (!iter1.Done()) {
703  const auto l1 = iter1.Value();
704  const auto l2 = iter2.Value();
705  if (l1 < l2) return true;
706  if (l1 > l2) return false;
707  iter1.Next();
708  iter2.Next();
709  }
710  return false;
711  }
712  };
713 
714  // Adds W weights when string part equal.
715  struct Merge {
716  GW operator()(const GW &w1, const GW &w2) const {
717  return GW(w1.Value1(), Plus(w1.Value2(), w2.Value2()));
718  }
719  };
720 };
721 
722 // Specialization for the (general) GALLIC type.
723 template <class Label, class W>
725  : public UnionWeight<GallicWeight<Label, W, GALLIC_RESTRICT>,
726  GallicUnionWeightOptions<Label, W>> {
733 
734  using UW::Properties;
735 
736  GallicWeight() = default;
737 
738  // Copy constructor.
739  // NOLINTNEXTLINE(google-explicit-constructor)
740  GallicWeight(const UW &weight) : UW(weight) {}
741 
742  // Singleton constructors: create a GALLIC weight containing a single
743  // GALLIC_RESTRICT weight. Takes as argument (1) a GALLIC_RESTRICT weight or
744  // (2) the two components of a GALLIC_RESTRICT weight.
745  explicit GallicWeight(const GW &weight) : UW(weight) {}
746 
747  GallicWeight(SW w1, W w2) : UW(GW(w1, w2)) {}
748 
749  explicit GallicWeight(std::string_view str, int *nread = nullptr)
750  : UW(str, nread) {}
751 
753  static const GallicWeight<Label, W, GALLIC> zero(UW::Zero());
754  return zero;
755  }
756 
758  static const GallicWeight<Label, W, GALLIC> one(UW::One());
759  return one;
760  }
761 
763  static const GallicWeight<Label, W, GALLIC> no_weight(UW::NoWeight());
764  return no_weight;
765  }
766 
767  static const std::string &Type() {
768  static const std::string *const type = new std::string("gallic");
769  return *type;
770  }
771 
773  return UW::Quantize(delta);
774  }
775 
776  ReverseWeight Reverse() const { return UW::Reverse(); }
777 };
778 
779 // (General) gallic plus.
780 template <class Label, class W>
783  const GallicWeight<Label, W, GALLIC> &w2) {
786  return Plus(static_cast<UW>(w1), static_cast<UW>(w2));
787 }
788 
789 // (General) gallic times.
790 template <class Label, class W>
793  const GallicWeight<Label, W, GALLIC> &w2) {
796  return Times(static_cast<UW>(w1), static_cast<UW>(w2));
797 }
798 
799 // (General) gallic divide.
800 template <class Label, class W>
804  DivideType divide_type = DIVIDE_ANY) {
807  return Divide(static_cast<UW>(w1), static_cast<UW>(w2), divide_type);
808 }
809 
810 // This function object generates gallic weights by calling an underlying
811 // union weight generator. This is intended primarily for testing.
812 template <class Label, class W>
814  : public WeightGenerate<UnionWeight<GallicWeight<Label, W, GALLIC_RESTRICT>,
815  GallicUnionWeightOptions<Label, W>>> {
816  public:
818  using Generate =
821 
822  explicit WeightGenerate(uint64_t seed = std::random_device()(),
823  bool allow_zero = true)
824  : generate_(seed, allow_zero) {}
825 
826  Weight operator()() const { return Weight(generate_()); }
827 
828  private:
829  const Generate generate_;
830 };
831 
832 } // namespace fst
833 
834 #endif // FST_STRING_WEIGHT_H_
WeightGenerate(uint64_t seed=std::random_device()(), bool allow_zero=true)
GallicWeight< Label, W, GALLIC > Quantize(float delta=kDelta) const
StringWeightIterator(const Weight &w)
GW operator()(const GW &w1, const GW &w2) const
StringWeight< Label, ReverseStringType(S)> ReverseWeight
Definition: string-weight.h:69
static const GallicWeight & Zero()
static const StringWeight & One()
Definition: string-weight.h:90
StringWeight< Label, S > DivideLeft(const StringWeight< Label, S > &w1, const StringWeight< Label, S > &w2)
ErrorWeight Plus(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:61
void PushBack(Label label)
void Reverse(const FstClass &ifst, const std::vector< std::pair< int64_t, int64_t >> &parens, std::vector< int64_t > *assignments, MutableFstClass *ofst)
Definition: mpdtscript.cc:72
const Label & Value() const
StringWeight(const Iterator begin, const Iterator end)
Definition: string-weight.h:79
static constexpr uint64_t Properties()
StringWeightIterator< StringWeight > Iterator
Definition: string-weight.h:70
constexpr int kStringBad
Definition: string-weight.h:44
size_t Hash() const
constexpr GallicType ReverseGallicType(GallicType g)
ErrorWeight Times(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:64
static const GallicWeight< Label, W, GALLIC > & One()
bool Member() const
constexpr uint64_t kIdempotent
Definition: weight.h:147
typename Weight::Label Label
GallicWeight(SW w1, W w2)
static const StringWeight & Zero()
Definition: string-weight.h:85
StringWeight()=default
constexpr char kStringSeparator
Definition: string-weight.h:45
internal::StringSplitter StrSplit(std::string_view full, ByAnyChar delim)
Definition: compat.cc:77
const Label & Value() const
static const StringWeight & NoWeight()
Definition: string-weight.h:95
constexpr uint64_t kRightSemiring
Definition: weight.h:139
std::ostream & WriteType(std::ostream &strm, const T t)
Definition: util.h:228
#define FSTERROR()
Definition: util.h:56
static const std::string & Type()
std::optional< int64_t > ParseInt64(std::string_view s, int base=10)
Definition: util.cc:46
constexpr int kStringInfinity
Definition: string-weight.h:43
std::istream & operator>>(std::istream &strm, FloatWeightTpl< T > &w)
Definition: float-weight.h:185
bool operator!=(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:54
static const std::string & Type()
GallicWeight(std::string_view str, int *nread=nullptr)
constexpr StringType ReverseStringType(StringType s)
Definition: string-weight.h:54
std::ostream & operator<<(std::ostream &strm, const ErrorWeight &)
Definition: error-weight.h:71
StringWeight(Label label)
Definition: string-weight.h:83
static const GallicWeight & One()
StringWeight< Label, S > DivideRight(const StringWeight< Label, S > &w1, const StringWeight< Label, S > &w2)
GallicWeight Quantize(float delta=kDelta) const
WeightGenerate(uint64_t seed=std::random_device()(), bool allow_zero=true)
std::istream & Read(std::istream &strm)
GallicWeight(const ProductWeight< SW, W > &w)
std::ostream & Write(std::ostream &strm) const
GallicWeight(std::string_view s, int *nread=nullptr)
typename Weight::Label Label
bool operator()(const GW &w1, const GW &w2) const
static const GallicWeight< Label, W, GALLIC > & Zero()
StringType
Definition: string-weight.h:52
size_t Size() const
ErrorWeight Divide(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:67
bool operator==(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:51
constexpr size_t kNumRandomWeights
Definition: weight.h:154
std::istream & ReadType(std::istream &strm, T *t)
Definition: util.h:80
WeightGenerate(uint64_t seed=std::random_device()(), bool allow_zero=true, size_t alphabet_size=kNumRandomWeights, size_t max_string_length=kNumRandomWeights)
static const GallicWeight & NoWeight()
DivideType
Definition: weight.h:165
void PushFront(Label label)
constexpr uint64_t kLeftSemiring
Definition: weight.h:136
constexpr float kDelta
Definition: weight.h:133
StringWeightReverseIterator(const Weight &w)
static const GallicWeight< Label, W, GALLIC > & NoWeight()
ReverseWeight Reverse() const
bool ApproxEqual(const ErrorWeight &, const ErrorWeight &, float)
Definition: error-weight.h:58
StringWeight Quantize(float delta=kDelta) const
ReverseWeight Reverse() const
const StringWeight< Label, GallicStringType(G)> & Value1() const
Definition: pair-weight.h:93
constexpr StringType GallicStringType(GallicType g)
static const std::string & Type()