FST  openfst-1.8.2
OpenFst Library
lexicographic-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 // Lexicographic weight set and associated semiring operation definitions.
19 //
20 // A lexicographic weight is a sequence of weights, each of which must have the
21 // path property and Times() must be (strongly) cancellative
22 // (for all a,b,c != Zero(): Times(c, a) = Times(c, b) => a = b,
23 // Times(a, c) = Times(b, c) => a = b).
24 // The + operation on two weights a and b is the lexicographically
25 // prior of a and b.
26 
27 #ifndef FST_LEXICOGRAPHIC_WEIGHT_H_
28 #define FST_LEXICOGRAPHIC_WEIGHT_H_
29 
30 #include <cstdint>
31 #include <random>
32 #include <string>
33 
34 #include <fst/log.h>
35 
36 #include <fst/pair-weight.h>
37 #include <fst/weight.h>
38 
39 
40 namespace fst {
41 
42 template <class W1, class W2>
43 class LexicographicWeight : public PairWeight<W1, W2> {
44  public:
45  static_assert(IsPath<W1>::value, "W1 must have path property.");
46  static_assert(IsPath<W2>::value, "W2 must have path property.");
47 
48  using ReverseWeight = LexicographicWeight<typename W1::ReverseWeight,
49  typename W2::ReverseWeight>;
50 
60 
62 
64  : PairWeight<W1, W2>(w) {}
65 
66  LexicographicWeight(W1 w1, W2 w2) : PairWeight<W1, W2>(w1, w2) {}
67 
68  static const LexicographicWeight &Zero() {
69  static const LexicographicWeight zero(PairWeight<W1, W2>::Zero());
70  return zero;
71  }
72 
73  static const LexicographicWeight &One() {
74  static const LexicographicWeight one(PairWeight<W1, W2>::One());
75  return one;
76  }
77 
78  static const LexicographicWeight &NoWeight() {
79  static const LexicographicWeight no_weight(PairWeight<W1, W2>::NoWeight());
80  return no_weight;
81  }
82 
83  static const std::string &Type() {
84  static const std::string *const type =
85  new std::string(W1::Type() + "_LT_" + W2::Type());
86  return *type;
87  }
88 
89  bool Member() const {
90  if (!Value1().Member() || !Value2().Member()) return false;
91  // Lexicographic weights cannot mix zeroes and non-zeroes.
92  if (Value1() == W1::Zero() && Value2() == W2::Zero()) return true;
93  if (Value1() != W1::Zero() && Value2() != W2::Zero()) return true;
94  return false;
95  }
96 
97  LexicographicWeight Quantize(float delta = kDelta) const {
99  }
100 
103  }
104 
105  static constexpr uint64_t Properties() {
106  return W1::Properties() & W2::Properties() &
108  kCommutative);
109  }
110 };
111 
112 template <class W1, class W2>
114  const LexicographicWeight<W1, W2> &v) {
115  if (!w.Member() || !v.Member()) {
117  }
118  NaturalLess<W1> less1;
119  NaturalLess<W2> less2;
120  if (less1(w.Value1(), v.Value1())) return w;
121  if (less1(v.Value1(), w.Value1())) return v;
122  if (less2(w.Value2(), v.Value2())) return w;
123  if (less2(v.Value2(), w.Value2())) return v;
124  return w;
125 }
126 
127 template <class W1, class W2>
129  const LexicographicWeight<W1, W2> &v) {
131  Times(w.Value2(), v.Value2()));
132 }
133 
134 template <class W1, class W2>
137  DivideType typ = DIVIDE_ANY) {
138  return LexicographicWeight<W1, W2>(Divide(w.Value1(), v.Value1(), typ),
139  Divide(w.Value2(), v.Value2(), typ));
140 }
141 
142 // This function object generates weights by calling the underlying generators
143 // for the templated weight types, like all other pair weight types. However,
144 // for lexicographic weights, we cannot generate zeroes for the two subweights
145 // separately: weights are members iff both members are zero or both members
146 // are non-zero. This is intended primarily for testing.
147 template <class W1, class W2>
149  public:
153 
154  explicit WeightGenerate(uint64_t seed = std::random_device()(),
155  bool allow_zero = true,
156  size_t num_random_weights = kNumRandomWeights)
157  : rand_(seed),
158  allow_zero_(allow_zero),
159  num_random_weights_(num_random_weights),
160  generator1_(seed, false, num_random_weights),
161  generator2_(seed, false, num_random_weights) {}
162 
163  Weight operator()() const {
164  if (allow_zero_) {
165  const int sample =
166  std::uniform_int_distribution<>(0, num_random_weights_)(rand_);
167  if (sample == num_random_weights_) return Weight(W1::Zero(), W2::Zero());
168  }
169  return Weight(generator1_(), generator2_());
170  }
171 
172  private:
173  mutable std::mt19937_64 rand_;
174  const bool allow_zero_;
175  const size_t num_random_weights_;
176  const Generate1 generator1_;
177  const Generate2 generator2_;
178 };
179 
180 } // namespace fst
181 
182 #endif // FST_LEXICOGRAPHIC_WEIGHT_H_
LexicographicWeight(const PairWeight< W1, W2 > &w)
static constexpr uint64_t Properties()
LexicographicWeight< typename W1::ReverseWeight, typename W2::ReverseWeight > ReverseWeight
ErrorWeight Plus(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:60
static const std::string & Type()
ErrorWeight Times(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:63
const W2 & Value2() const
Definition: pair-weight.h:93
constexpr uint64_t kIdempotent
Definition: weight.h:144
constexpr uint64_t kRightSemiring
Definition: weight.h:136
WeightGenerate(uint64_t seed=std::random_device()(), bool allow_zero=true, size_t num_random_weights=kNumRandomWeights)
static const LexicographicWeight & One()
static const LexicographicWeight & Zero()
constexpr uint64_t kCommutative
Definition: weight.h:141
LexicographicWeight Quantize(float delta=kDelta) const
ReverseWeight Reverse() const
constexpr uint64_t kPath
Definition: weight.h:147
static const LexicographicWeight & NoWeight()
ErrorWeight Divide(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:66
constexpr size_t kNumRandomWeights
Definition: weight.h:151
DivideType
Definition: weight.h:162
constexpr uint64_t kLeftSemiring
Definition: weight.h:133
constexpr float kDelta
Definition: weight.h:130
std::bool_constant<(W::Properties()&kPath)!=0 > IsPath
Definition: weight.h:159
const W1 & Value1() const
Definition: pair-weight.h:91