FST  openfst-1.8.3
OpenFst Library
rand-fst.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 #ifndef FST_TEST_RAND_FST_H_
16 #define FST_TEST_RAND_FST_H_
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <random>
21 
22 #include <fst/log.h>
23 #include <fst/mutable-fst.h>
24 #include <fst/properties.h>
25 #include <fst/verify.h>
26 
27 namespace fst {
28 
29 // Generates a random FST.
30 template <class Arc, class Generate>
31 void RandFst(const int num_random_states, const int num_random_arcs,
32  const int num_random_labels, const float acyclic_prob,
33  Generate generate, uint64_t seed, MutableFst<Arc> *fst) {
34  using Label = typename Arc::Label;
35  using StateId = typename Arc::StateId;
36  using Weight = typename Arc::Weight;
37 
38  // Determines direction of the arcs wrt state numbering. This way we
39  // can force acyclicity when desired.
40  enum ArcDirection {
41  ANY_DIRECTION = 0,
42  FORWARD_DIRECTION = 1,
43  REVERSE_DIRECTION = 2,
44  NUM_DIRECTIONS = 3
45  };
46 
47  std::mt19937_64 rand(seed);
48  const StateId ns =
49  std::uniform_int_distribution<>(0, num_random_states - 1)(rand);
50  std::uniform_int_distribution<size_t> arc_dist(0, num_random_arcs - 1);
51  std::uniform_int_distribution<Label> label_dist(0, num_random_labels - 1);
52  std::uniform_int_distribution<StateId> ns_dist(0, ns - 1);
53 
54  ArcDirection arc_direction = ANY_DIRECTION;
55  if (!std::bernoulli_distribution(acyclic_prob)(rand)) {
56  arc_direction = std::bernoulli_distribution(.5)(rand) ? FORWARD_DIRECTION
57  : REVERSE_DIRECTION;
58  }
59 
60  fst->DeleteStates();
61 
62  if (ns == 0) return;
63  fst->AddStates(ns);
64 
65  const StateId start = ns_dist(rand);
66  fst->SetStart(start);
67 
68  const size_t na = arc_dist(rand);
69  for (size_t n = 0; n < na; ++n) {
70  StateId s = ns_dist(rand);
71  Arc arc;
72  arc.ilabel = label_dist(rand);
73  arc.olabel = label_dist(rand);
74  arc.weight = generate();
75  arc.nextstate = ns_dist(rand);
76  if ((arc_direction == FORWARD_DIRECTION ||
77  arc_direction == REVERSE_DIRECTION) &&
78  s == arc.nextstate) {
79  continue; // Skips self-loops.
80  }
81 
82  if ((arc_direction == FORWARD_DIRECTION && s > arc.nextstate) ||
83  (arc_direction == REVERSE_DIRECTION && s < arc.nextstate)) {
84  StateId t = s; // reverses arcs
85  s = arc.nextstate;
86  arc.nextstate = t;
87  }
88 
89  fst->AddArc(s, arc);
90  }
91 
92  const StateId nf = std::uniform_int_distribution<>(0, ns)(rand);
93  for (StateId n = 0; n < nf; ++n) {
94  const StateId s = ns_dist(rand);
95  fst->SetFinal(s, generate());
96  }
97  VLOG(1) << "Check FST for sanity (including property bits).";
98  CHECK(Verify(*fst));
99 
100  // Get/compute all properties.
101  const uint64_t props = fst->Properties(kFstProperties, true);
102 
103  // Select random set of properties to be unknown.
104  uint64_t mask = 0;
105  for (int n = 0; n < 8; ++n) {
106  mask |= std::uniform_int_distribution<>(0, 0xff)(rand);
107  mask <<= 8;
108  }
109  mask &= ~kTrinaryProperties;
110  fst->SetProperties(props & ~mask, mask);
111 }
112 
113 } // namespace fst
114 
115 #endif // FST_TEST_RAND_FST_H_
virtual uint64_t Properties(uint64_t mask, bool test) const =0
constexpr uint64_t kTrinaryProperties
Definition: properties.h:313
virtual void SetStart(StateId)=0
virtual void SetProperties(uint64_t props, uint64_t mask)=0
void RandFst(const int num_random_states, const int num_random_arcs, const int num_random_labels, const float acyclic_prob, Generate generate, uint64_t seed, MutableFst< Arc > *fst)
Definition: rand-fst.h:31
#define VLOG(level)
Definition: log.h:54
bool Verify(const Fst< Arc > &fst, bool allow_negative_labels=false)
Definition: verify.h:36
constexpr uint64_t kFstProperties
Definition: properties.h:326
virtual void AddArc(StateId, const Arc &)=0
virtual void SetFinal(StateId s, Weight weight=Weight::One())=0
virtual void DeleteStates(const std::vector< StateId > &)=0
#define CHECK(x)
Definition: log.h:65
virtual void AddStates(size_t)=0