FST  openfst-1.8.2.post1
OpenFst Library
string-weight.h
Go to the documentation of this file.
1 // Copyright 2005-2020 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 <cstdint>
24 #include <list>
25 #include <random>
26 #include <string>
27 #include <vector>
28 
29 #include <fst/product-weight.h>
30 #include <fst/union-weight.h>
31 #include <fst/weight.h>
32 #include <string_view>
33 
34 
35 namespace fst {
36 
37 inline constexpr int kStringInfinity = -1; // Label for the infinite string.
38 inline constexpr int kStringBad = -2; // Label for a non-string.
39 inline constexpr char kStringSeparator = '_'; // Label separator in strings.
40 
41 // Determines whether to use left or right string semiring. Includes a
42 // 'restricted' version that signals an error if proper prefixes/suffixes
43 // would otherwise be returned by Plus, useful with various
44 // algorithms that require functional transducer input with the
45 // string semirings.
47 
49  return s == STRING_LEFT ? STRING_RIGHT
51 }
52 
53 template <class>
55 template <class>
57 
58 // String semiring: (longest_common_prefix/suffix, ., Infinity, Epsilon)
59 template <typename L, StringType S = STRING_LEFT>
60 class StringWeight {
61  public:
62  using Label = L;
66 
69 
71 
72  template <typename Iterator>
73  StringWeight(const Iterator begin, const Iterator end) {
74  for (auto iter = begin; iter != end; ++iter) PushBack(*iter);
75  }
76 
77  explicit StringWeight(Label label) { PushBack(label); }
78 
79  static const StringWeight &Zero() {
80  static const auto *const zero = new StringWeight(Label(kStringInfinity));
81  return *zero;
82  }
83 
84  static const StringWeight &One() {
85  static const auto *const one = new StringWeight();
86  return *one;
87  }
88 
89  static const StringWeight &NoWeight() {
90  static const auto *const no_weight = new StringWeight(Label(kStringBad));
91  return *no_weight;
92  }
93 
94  static const std::string &Type() {
95  static const std::string *const type = new std::string(
96  S == STRING_LEFT
97  ? "left_string"
98  : (S == STRING_RIGHT ? "right_string" : "restricted_string"));
99  return *type;
100  }
101 
102  bool Member() const;
103 
104  std::istream &Read(std::istream &strm);
105 
106  std::ostream &Write(std::ostream &strm) const;
107 
108  size_t Hash() const;
109 
110  StringWeight Quantize(float delta = kDelta) const { return *this; }
111 
112  ReverseWeight Reverse() const;
113 
114  static constexpr uint64_t Properties() {
115  return kIdempotent |
116  (S == STRING_LEFT ? kLeftSemiring
117  : (S == STRING_RIGHT
119  : /* S == STRING_RESTRICT */ kLeftSemiring |
120  kRightSemiring));
121  }
122 
123  // These operations combined with the StringWeightIterator and
124  // StringWeightReverseIterator provide the access and mutation of the string
125  // internal elements.
126 
127  // Clear existing StringWeight.
128  void Clear() {
129  first_ = 0;
130  rest_.clear();
131  }
132 
133  size_t Size() const { return first_ ? rest_.size() + 1 : 0; }
134 
135  void PushFront(Label label) {
136  if (first_) rest_.push_front(first_);
137  first_ = label;
138  }
139 
140  void PushBack(Label label) {
141  if (!first_) {
142  first_ = label;
143  } else {
144  rest_.push_back(label);
145  }
146  }
147 
148  private:
149  Label first_ = 0; // First label in string (0 if empty).
150  std::list<Label> rest_; // Remaining labels in string.
151 };
152 
153 // Traverses string in forward direction.
154 template <class StringWeight_>
155 class StringWeightIterator {
156  public:
157  using Weight = StringWeight_;
158  using Label = typename Weight::Label;
159 
160  explicit StringWeightIterator(const Weight &w)
161  : first_(w.first_), rest_(w.rest_), init_(true), iter_(rest_.begin()) {}
162 
163  bool Done() const {
164  if (init_) {
165  return first_ == 0;
166  } else {
167  return iter_ == rest_.end();
168  }
169  }
170 
171  const Label &Value() const { return init_ ? first_ : *iter_; }
172 
173  void Next() {
174  if (init_) {
175  init_ = false;
176  } else {
177  ++iter_;
178  }
179  }
180 
181  void Reset() {
182  init_ = true;
183  iter_ = rest_.begin();
184  }
185 
186  private:
187  const Label &first_;
188  const decltype(Weight::rest_) &rest_;
189  bool init_; // In the initialized state?
190  typename decltype(Weight::rest_)::const_iterator iter_;
191 };
192 
193 // Traverses string in backward direction.
194 template <class StringWeight_>
196  public:
197  using Weight = StringWeight_;
198  using Label = typename Weight::Label;
199 
201  : first_(w.first_),
202  rest_(w.rest_),
203  fin_(first_ == Label()),
204  iter_(rest_.rbegin()) {}
205 
206  bool Done() const { return fin_; }
207 
208  const Label &Value() const { return iter_ == rest_.rend() ? first_ : *iter_; }
209 
210  void Next() {
211  if (iter_ == rest_.rend()) {
212  fin_ = true;
213  } else {
214  ++iter_;
215  }
216  }
217 
218  void Reset() {
219  fin_ = false;
220  iter_ = rest_.rbegin();
221  }
222 
223  private:
224  const Label &first_;
225  const decltype(Weight::rest_) &rest_;
226  bool fin_; // In the final state?
227  typename decltype(Weight::rest_)::const_reverse_iterator iter_;
228 };
229 
230 // StringWeight member functions follow that require
231 // StringWeightIterator or StringWeightReverseIterator.
232 
233 template <typename Label, StringType S>
234 inline std::istream &StringWeight<Label, S>::Read(std::istream &strm) {
235  Clear();
236  int32_t size;
237  ReadType(strm, &size);
238  for (int32_t i = 0; i < size; ++i) {
239  Label label;
240  ReadType(strm, &label);
241  PushBack(label);
242  }
243  return strm;
244 }
245 
246 template <typename Label, StringType S>
247 inline std::ostream &StringWeight<Label, S>::Write(std::ostream &strm) const {
248  const int32_t size = Size();
249  WriteType(strm, size);
250  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
251  WriteType(strm, iter.Value());
252  }
253  return strm;
254 }
255 
256 template <typename Label, StringType S>
257 inline bool StringWeight<Label, S>::Member() const {
258  Iterator iter(*this);
259  return iter.Value() != Label(kStringBad);
260 }
261 
262 template <typename Label, StringType S>
265  ReverseWeight rweight;
266  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
267  rweight.PushFront(iter.Value());
268  }
269  return rweight;
270 }
271 
272 template <typename Label, StringType S>
273 inline size_t StringWeight<Label, S>::Hash() const {
274  size_t h = 0;
275  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
276  h ^= h << 1 ^ iter.Value();
277  }
278  return h;
279 }
280 
281 template <typename Label, StringType S>
282 inline bool operator==(const StringWeight<Label, S> &w1,
283  const StringWeight<Label, S> &w2) {
284  if (w1.Size() != w2.Size()) return false;
286  Iterator iter1(w1);
287  Iterator iter2(w2);
288  for (; !iter1.Done(); iter1.Next(), iter2.Next()) {
289  if (iter1.Value() != iter2.Value()) return false;
290  }
291  return true;
292 }
293 
294 template <typename Label, StringType S>
295 inline bool operator!=(const StringWeight<Label, S> &w1,
296  const StringWeight<Label, S> &w2) {
297  return !(w1 == w2);
298 }
299 
300 template <typename Label, StringType S>
301 inline bool ApproxEqual(const StringWeight<Label, S> &w1,
302  const StringWeight<Label, S> &w2,
303  float delta = kDelta) {
304  return w1 == w2;
305 }
306 
307 template <typename Label, StringType S>
308 inline std::ostream &operator<<(std::ostream &strm,
309  const StringWeight<Label, S> &weight) {
310  typename StringWeight<Label, S>::Iterator iter(weight);
311  if (iter.Done()) {
312  return strm << "Epsilon";
313  } else if (iter.Value() == Label(kStringInfinity)) {
314  return strm << "Infinity";
315  } else if (iter.Value() == Label(kStringBad)) {
316  return strm << "BadString";
317  } else {
318  for (size_t i = 0; !iter.Done(); ++i, iter.Next()) {
319  if (i > 0) strm << kStringSeparator;
320  strm << iter.Value();
321  }
322  }
323  return strm;
324 }
325 
326 template <typename Label, StringType S>
327 inline std::istream &operator>>(std::istream &strm,
328  StringWeight<Label, S> &weight) {
329  std::string str;
330  strm >> str;
331  using Weight = StringWeight<Label, S>;
332  if (str == "Infinity") {
333  weight = Weight::Zero();
334  } else if (str == "Epsilon") {
335  weight = Weight::One();
336  } else {
337  weight.Clear();
338  for (std::string_view sv : StrSplit(str, kStringSeparator)) {
339  auto maybe_label = ParseInt64(sv);
340  if (!maybe_label.has_value()) {
341  strm.clear(std::ios::badbit);
342  break;
343  }
344  weight.PushBack(*maybe_label);
345  }
346  }
347  return strm;
348 }
349 
350 // Default is for the restricted string semiring. String equality is required
351 // (for non-Zero() input). The restriction is used (e.g., in determinization)
352 // to ensure the input is functional.
353 template <typename Label, StringType S>
355  const StringWeight<Label, S> &w2) {
356  using Weight = StringWeight<Label, S>;
357  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
358  if (w1 == Weight::Zero()) return w2;
359  if (w2 == Weight::Zero()) return w1;
360  if (w1 != w2) {
361  FSTERROR() << "StringWeight::Plus: Unequal arguments "
362  << "(non-functional FST?)"
363  << " w1 = " << w1 << " w2 = " << w2;
364  return Weight::NoWeight();
365  }
366  return w1;
367 }
368 
369 // Longest common prefix for left string semiring.
370 template <typename Label>
374  using Weight = StringWeight<Label, STRING_LEFT>;
375  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
376  if (w1 == Weight::Zero()) return w2;
377  if (w2 == Weight::Zero()) return w1;
378  Weight sum;
379  typename Weight::Iterator iter1(w1);
380  typename Weight::Iterator iter2(w2);
381  for (; !iter1.Done() && !iter2.Done() && iter1.Value() == iter2.Value();
382  iter1.Next(), iter2.Next()) {
383  sum.PushBack(iter1.Value());
384  }
385  return sum;
386 }
387 
388 // Longest common suffix for right string semiring.
389 template <typename Label>
393  using Weight = StringWeight<Label, STRING_RIGHT>;
394  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
395  if (w1 == Weight::Zero()) return w2;
396  if (w2 == Weight::Zero()) return w1;
397  Weight sum;
398  typename Weight::ReverseIterator iter1(w1);
399  typename Weight::ReverseIterator iter2(w2);
400  for (; !iter1.Done() && !iter2.Done() && iter1.Value() == iter2.Value();
401  iter1.Next(), iter2.Next()) {
402  sum.PushFront(iter1.Value());
403  }
404  return sum;
405 }
406 
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 (w1 == Weight::Zero() || w2 == Weight::Zero()) return Weight::Zero();
413  Weight product(w1);
414  for (typename Weight::Iterator iter(w2); !iter.Done(); iter.Next()) {
415  product.PushBack(iter.Value());
416  }
417  return product;
418 }
419 
420 // Left division in a left string semiring.
421 template <typename Label, StringType S>
423  const StringWeight<Label, S> &w2) {
424  using Weight = StringWeight<Label, S>;
425  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
426  if (w2 == Weight::Zero()) {
427  return Weight(Label(kStringBad));
428  } else if (w1 == Weight::Zero()) {
429  return Weight::Zero();
430  }
431  Weight result;
432  typename Weight::Iterator iter(w1);
433  size_t i = 0;
434  for (; !iter.Done() && i < w2.Size(); iter.Next(), ++i) {
435  }
436  for (; !iter.Done(); iter.Next()) result.PushBack(iter.Value());
437  return result;
438 }
439 
440 // Right division in a right string semiring.
441 template <typename Label, StringType S>
443  const StringWeight<Label, S> &w2) {
444  using Weight = StringWeight<Label, S>;
445  if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
446  if (w2 == Weight::Zero()) {
447  return Weight(Label(kStringBad));
448  } else if (w1 == Weight::Zero()) {
449  return Weight::Zero();
450  }
451  Weight result;
452  typename Weight::ReverseIterator iter(w1);
453  size_t i = 0;
454  for (; !iter.Done() && i < w2.Size(); iter.Next(), ++i) {
455  }
456  for (; !iter.Done(); iter.Next()) result.PushFront(iter.Value());
457  return result;
458 }
459 
460 // Default is the restricted string semiring.
461 template <typename Label, StringType S>
463  const StringWeight<Label, S> &w2,
464  DivideType divide_type) {
465  using Weight = StringWeight<Label, S>;
466  if (divide_type == DIVIDE_LEFT) {
467  return DivideLeft(w1, w2);
468  } else if (divide_type == DIVIDE_RIGHT) {
469  return DivideRight(w1, w2);
470  } else {
471  FSTERROR() << "StringWeight::Divide: "
472  << "Only explicit left or right division is defined "
473  << "for the " << Weight::Type() << " semiring";
474  return Weight::NoWeight();
475  }
476 }
477 
478 // Left division in the left string semiring.
479 template <typename Label>
482  const StringWeight<Label, STRING_LEFT> &w2, DivideType divide_type) {
483  if (divide_type != DIVIDE_LEFT) {
484  FSTERROR() << "StringWeight::Divide: Only left division is defined "
485  << "for the left string semiring";
487  }
488  return DivideLeft(w1, w2);
489 }
490 
491 // Right division in the right string semiring.
492 template <typename Label>
495  const StringWeight<Label, STRING_RIGHT> &w2, DivideType divide_type) {
496  if (divide_type != DIVIDE_RIGHT) {
497  FSTERROR() << "StringWeight::Divide: Only right division is defined "
498  << "for the right string semiring";
500  }
501  return DivideRight(w1, w2);
502 }
503 
504 // This function object generates StringWeights that are random integer strings
505 // from {1, ... , alphabet_size)^{0, max_string_length} U { Zero }. This is
506 // intended primarily for testing.
507 template <class Label, StringType S>
509  public:
511 
512  explicit WeightGenerate(uint64_t seed = std::random_device()(),
513  bool allow_zero = true,
514  size_t alphabet_size = kNumRandomWeights,
515  size_t max_string_length = kNumRandomWeights)
516  : rand_(seed),
517  allow_zero_(allow_zero),
518  alphabet_size_(alphabet_size),
519  max_string_length_(max_string_length) {}
520 
521  Weight operator()() const {
522  const int n = std::uniform_int_distribution<>(
523  0, max_string_length_ + allow_zero_)(rand_);
524  if (allow_zero_ && n == max_string_length_) return Weight::Zero();
525  std::vector<Label> labels;
526  labels.reserve(n);
527  for (int i = 0; i < n; ++i) {
528  labels.push_back(
529  std::uniform_int_distribution<>(1, alphabet_size_)(rand_));
530  }
531  return Weight(labels.begin(), labels.end());
532  }
533 
534  private:
535  mutable std::mt19937_64 rand_;
536  const bool allow_zero_;
537  const size_t alphabet_size_;
538  const size_t max_string_length_;
539 };
540 
541 // Determines whether to use left, right, or (general) gallic semiring. Includes
542 // a restricted version that signals an error if proper string prefixes or
543 // suffixes would otherwise be returned by string Plus. This is useful with
544 // algorithms that require functional transducer input. Also includes min
545 // version that changes the Plus to keep only the lowest W weight string.
551  GALLIC = 4
552 };
553 
555  return g == GALLIC_LEFT
556  ? STRING_LEFT
558 }
559 
561  return g == GALLIC_LEFT
562  ? GALLIC_RIGHT
563  : (g == GALLIC_RIGHT
564  ? GALLIC_LEFT
565  : (g == GALLIC_RESTRICT
567  : (g == GALLIC_MIN ? GALLIC_MIN : GALLIC)));
568 }
569 
570 // Product of string weight and an arbitraryy weight.
571 template <class Label, class W, GallicType G = GALLIC_LEFT>
573  : public ProductWeight<StringWeight<Label, GallicStringType(G)>, W> {
574  using ReverseWeight =
577 
579 
581 
582  GallicWeight(SW w1, W w2) : ProductWeight<SW, W>(w1, w2) {}
583 
584  explicit GallicWeight(const std::string &s, int *nread = nullptr)
585  : ProductWeight<SW, W>(s, nread) {}
586 
588  : ProductWeight<SW, W>(w) {}
589 
590  static const GallicWeight &Zero() {
591  static const GallicWeight zero(ProductWeight<SW, W>::Zero());
592  return zero;
593  }
594 
595  static const GallicWeight &One() {
596  static const GallicWeight one(ProductWeight<SW, W>::One());
597  return one;
598  }
599 
600  static const GallicWeight &NoWeight() {
601  static const GallicWeight no_weight(ProductWeight<SW, W>::NoWeight());
602  return no_weight;
603  }
604 
605  static const std::string &Type() {
606  static const std::string *const type = new std::string(
607  G == GALLIC_LEFT
608  ? "left_gallic"
609  : (G == GALLIC_RIGHT
610  ? "right_gallic"
611  : (G == GALLIC_RESTRICT
612  ? "restricted_gallic"
613  : (G == GALLIC_MIN ? "min_gallic" : "gallic"))));
614  return *type;
615  }
616 
617  GallicWeight Quantize(float delta = kDelta) const {
619  }
620 
623  }
624 };
625 
626 // Default plus.
627 template <class Label, class W, GallicType G>
629  const GallicWeight<Label, W, G> &v) {
630  return GallicWeight<Label, W, G>(Plus(w.Value1(), v.Value1()),
631  Plus(w.Value2(), v.Value2()));
632 }
633 
634 // Min gallic plus.
635 template <class Label, class W>
639  static const NaturalLess<W> less;
640  return less(w1.Value2(), w2.Value2()) ? w1 : w2;
641 }
642 
643 template <class Label, class W, GallicType G>
645  const GallicWeight<Label, W, G> &v) {
646  return GallicWeight<Label, W, G>(Times(w.Value1(), v.Value1()),
647  Times(w.Value2(), v.Value2()));
648 }
649 
650 template <class Label, class W, GallicType G>
652  const GallicWeight<Label, W, G> &v,
653  DivideType divide_type = DIVIDE_ANY) {
654  return GallicWeight<Label, W, G>(Divide(w.Value1(), v.Value1(), divide_type),
655  Divide(w.Value2(), v.Value2(), divide_type));
656 }
657 
658 // This function object generates gallic weights by calling an underlying
659 // product weight generator. This is intended primarily for testing.
660 template <class Label, class W, GallicType G>
662  : public WeightGenerate<
663  ProductWeight<StringWeight<Label, GallicStringType(G)>, W>> {
664  public:
666  using Generate = WeightGenerate<
668 
669  explicit WeightGenerate(uint64_t seed = std::random_device()(),
670  bool allow_zero = true)
671  : generate_(seed, allow_zero) {}
672 
673  Weight operator()() const { return Weight(generate_()); }
674 
675  private:
676  const Generate generate_;
677 };
678 
679 // Union weight options for (general) GALLIC type.
680 template <class Label, class W>
686 
687  // Military order.
688  struct Compare {
689  bool operator()(const GW &w1, const GW &w2) const {
690  const SW &s1 = w1.Value1();
691  const SW &s2 = w2.Value1();
692  if (s1.Size() < s2.Size()) return true;
693  if (s1.Size() > s2.Size()) return false;
694  SI iter1(s1);
695  SI iter2(s2);
696  while (!iter1.Done()) {
697  const auto l1 = iter1.Value();
698  const auto l2 = iter2.Value();
699  if (l1 < l2) return true;
700  if (l1 > l2) return false;
701  iter1.Next();
702  iter2.Next();
703  }
704  return false;
705  }
706  };
707 
708  // Adds W weights when string part equal.
709  struct Merge {
710  GW operator()(const GW &w1, const GW &w2) const {
711  return GW(w1.Value1(), Plus(w1.Value2(), w2.Value2()));
712  }
713  };
714 };
715 
716 // Specialization for the (general) GALLIC type.
717 template <class Label, class W>
719  : public UnionWeight<GallicWeight<Label, W, GALLIC_RESTRICT>,
720  GallicUnionWeightOptions<Label, W>> {
727 
728  using UW::Properties;
729 
731 
732  // Copy constructor.
733  // NOLINTNEXTLINE(google-explicit-constructor)
734  GallicWeight(const UW &weight) : UW(weight) {}
735 
736  // Singleton constructors: create a GALLIC weight containing a single
737  // GALLIC_RESTRICT weight. Takes as argument (1) a GALLIC_RESTRICT weight or
738  // (2) the two components of a GALLIC_RESTRICT weight.
739  explicit GallicWeight(const GW &weight) : UW(weight) {}
740 
741  GallicWeight(SW w1, W w2) : UW(GW(w1, w2)) {}
742 
743  explicit GallicWeight(const std::string &str, int *nread = nullptr)
744  : UW(str, nread) {}
745 
747  static const GallicWeight<Label, W, GALLIC> zero(UW::Zero());
748  return zero;
749  }
750 
752  static const GallicWeight<Label, W, GALLIC> one(UW::One());
753  return one;
754  }
755 
757  static const GallicWeight<Label, W, GALLIC> no_weight(UW::NoWeight());
758  return no_weight;
759  }
760 
761  static const std::string &Type() {
762  static const std::string *const type = new std::string("gallic");
763  return *type;
764  }
765 
767  return UW::Quantize(delta);
768  }
769 
770  ReverseWeight Reverse() const { return UW::Reverse(); }
771 };
772 
773 // (General) gallic plus.
774 template <class Label, class W>
777  const GallicWeight<Label, W, GALLIC> &w2) {
780  return Plus(static_cast<UW>(w1), static_cast<UW>(w2));
781 }
782 
783 // (General) gallic times.
784 template <class Label, class W>
787  const GallicWeight<Label, W, GALLIC> &w2) {
790  return Times(static_cast<UW>(w1), static_cast<UW>(w2));
791 }
792 
793 // (General) gallic divide.
794 template <class Label, class W>
798  DivideType divide_type = DIVIDE_ANY) {
801  return Divide(static_cast<UW>(w1), static_cast<UW>(w2), divide_type);
802 }
803 
804 // This function object generates gallic weights by calling an underlying
805 // union weight generator. This is intended primarily for testing.
806 template <class Label, class W>
808  : public WeightGenerate<UnionWeight<GallicWeight<Label, W, GALLIC_RESTRICT>,
809  GallicUnionWeightOptions<Label, W>>> {
810  public:
812  using Generate =
815 
816  explicit WeightGenerate(uint64_t seed = std::random_device()(),
817  bool allow_zero = true)
818  : generate_(seed, allow_zero) {}
819 
820  Weight operator()() const { return Weight(generate_()); }
821 
822  private:
823  const Generate generate_;
824 };
825 
826 } // namespace fst
827 
828 #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:63
static const GallicWeight & Zero()
static const StringWeight & One()
Definition: string-weight.h:84
StringWeight< Label, S > DivideLeft(const StringWeight< Label, S > &w1, const StringWeight< Label, S > &w2)
ErrorWeight Plus(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:60
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:70
const Label & Value() const
StringWeight(const Iterator begin, const Iterator end)
Definition: string-weight.h:73
static constexpr uint64_t Properties()
StringWeightIterator< StringWeight > Iterator
Definition: string-weight.h:64
constexpr int kStringBad
Definition: string-weight.h:38
size_t Hash() const
constexpr GallicType ReverseGallicType(GallicType g)
ErrorWeight Times(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:63
static const GallicWeight< Label, W, GALLIC > & One()
bool Member() const
GallicWeight(const std::string &str, int *nread=nullptr)
constexpr uint64_t kIdempotent
Definition: weight.h:144
typename Weight::Label Label
GallicWeight(SW w1, W w2)
static const StringWeight & Zero()
Definition: string-weight.h:79
constexpr char kStringSeparator
Definition: string-weight.h:39
internal::StringSplitter StrSplit(std::string_view full, ByAnyChar delim)
Definition: compat.cc:81
const Label & Value() const
static const StringWeight & NoWeight()
Definition: string-weight.h:89
constexpr uint64_t kRightSemiring
Definition: weight.h:136
std::ostream & WriteType(std::ostream &strm, const T t)
Definition: util.h:214
#define FSTERROR()
Definition: util.h:53
static const std::string & Type()
std::optional< int64_t > ParseInt64(std::string_view s, int base=10)
Definition: util.cc:42
constexpr int kStringInfinity
Definition: string-weight.h:37
std::istream & operator>>(std::istream &strm, FloatWeightTpl< T > &w)
Definition: float-weight.h:181
bool operator!=(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:53
static const std::string & Type()
constexpr StringType ReverseStringType(StringType s)
Definition: string-weight.h:48
std::ostream & operator<<(std::ostream &strm, const ErrorWeight &)
Definition: error-weight.h:70
StringWeight(Label label)
Definition: string-weight.h:77
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)
GallicWeight(const std::string &s, int *nread=nullptr)
std::istream & Read(std::istream &strm)
GallicWeight(const ProductWeight< SW, W > &w)
std::ostream & Write(std::ostream &strm) const
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:46
size_t Size() const
ErrorWeight Divide(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:66
bool operator==(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:50
constexpr size_t kNumRandomWeights
Definition: weight.h:151
std::istream & ReadType(std::istream &strm, T *t)
Definition: util.h:68
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:162
void PushFront(Label label)
constexpr uint64_t kLeftSemiring
Definition: weight.h:133
constexpr float kDelta
Definition: weight.h:130
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:57
StringWeight Quantize(float delta=kDelta) const
ReverseWeight Reverse() const
const StringWeight< Label, GallicStringType(G)> & Value1() const
Definition: pair-weight.h:91
constexpr StringType GallicStringType(GallicType g)
static const std::string & Type()
Definition: string-weight.h:94