FST  openfst-1.7.1
OpenFst Library
rand-fst.h
Go to the documentation of this file.
1 #ifndef FST_TEST_RAND_FST_H_
2 #define FST_TEST_RAND_FST_H_
3 
4 #include <fst/log.h>
5 #include <fst/mutable-fst.h>
6 #include <fst/verify.h>
7 
8 namespace fst {
9 
10 // Generates a random FST.
11 template <class Arc, class WeightGenerator>
12 void RandFst(const int num_random_states, const int num_random_arcs,
13  const int num_random_labels, const float acyclic_prob,
14  WeightGenerator *weight_generator, MutableFst<Arc> *fst) {
15  typedef typename Arc::Label Label;
16  typedef typename Arc::StateId StateId;
17  typedef typename Arc::Weight Weight;
18 
19  // Determines direction of the arcs wrt state numbering. This way we
20  // can force acyclicity when desired.
21  enum ArcDirection {
22  ANY_DIRECTION = 0,
23  FORWARD_DIRECTION = 1,
24  REVERSE_DIRECTION = 2,
25  NUM_DIRECTIONS = 3
26  };
27 
28  ArcDirection arc_direction = ANY_DIRECTION;
29  if (rand() / (RAND_MAX + 1.0) < acyclic_prob)
30  arc_direction = rand() % 2 ? FORWARD_DIRECTION : REVERSE_DIRECTION;
31 
32  fst->DeleteStates();
33  StateId ns = rand() % num_random_states;
34 
35  if (ns == 0) return;
36  for (StateId s = 0; s < ns; ++s) fst->AddState();
37 
38  StateId start = rand() % ns;
39  fst->SetStart(start);
40 
41  size_t na = rand() % num_random_arcs;
42  for (size_t n = 0; n < na; ++n) {
43  StateId s = rand() % ns;
44  Arc arc;
45  arc.ilabel = rand() % num_random_labels;
46  arc.olabel = rand() % num_random_labels;
47  arc.weight = (*weight_generator)();
48  arc.nextstate = rand() % ns;
49 
50  if ((arc_direction == FORWARD_DIRECTION ||
51  arc_direction == REVERSE_DIRECTION) &&
52  s == arc.nextstate) {
53  continue; // skips self-loops
54  }
55 
56  if ((arc_direction == FORWARD_DIRECTION && s > arc.nextstate) ||
57  (arc_direction == REVERSE_DIRECTION && s < arc.nextstate)) {
58  StateId t = s; // reverses arcs
59  s = arc.nextstate;
60  arc.nextstate = t;
61  }
62 
63  fst->AddArc(s, arc);
64  }
65 
66  StateId nf = rand() % (ns + 1);
67  for (StateId n = 0; n < nf; ++n) {
68  StateId s = rand() % ns;
69  Weight final = (*weight_generator)();
70  fst->SetFinal(s, final);
71  }
72  VLOG(1) << "Check FST for sanity (including property bits).";
73  CHECK(Verify(*fst));
74 
75  // Get/compute all properties.
76  uint64 props = fst->Properties(kFstProperties, true);
77 
78  // Select random set of properties to be unknown.
79  uint64 mask = 0;
80  for (int n = 0; n < 8; ++n) {
81  mask |= rand() & 0xff;
82  mask <<= 8;
83  }
84  mask &= ~kTrinaryProperties;
85  fst->SetProperties(props & ~mask, mask);
86 }
87 
88 } // namespace fst
89 
90 #endif // FST_TEST_RAND_FST_H_
uint64_t uint64
Definition: types.h:32
virtual void AddArc(StateId, const Arc &arc)=0
virtual void SetStart(StateId)=0
constexpr uint64 kFstProperties
Definition: properties.h:301
virtual uint64 Properties(uint64 mask, bool test) const =0
virtual void SetFinal(StateId, Weight)=0
void RandFst(const int num_random_states, const int num_random_arcs, const int num_random_labels, const float acyclic_prob, WeightGenerator *weight_generator, MutableFst< Arc > *fst)
Definition: rand-fst.h:12
constexpr uint64 kTrinaryProperties
Definition: properties.h:288
#define VLOG(level)
Definition: log.h:49
bool Verify(const Fst< Arc > &fst, bool allow_negative_labels=false)
Definition: verify.h:19
virtual StateId AddState()=0
virtual void DeleteStates(const std::vector< StateId > &)=0
#define CHECK(x)
Definition: log.h:61
virtual void SetProperties(uint64 props, uint64 mask)=0