Blame view

tools/openfst-1.6.7/include/fst/verify.h 3.66 KB
8dcb6dfcb   Yannick Estève   first commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  // See www.openfst.org for extensive documentation on this weighted
  // finite-state transducer library.
  //
  // Function to verify an FST's contents.
  
  #ifndef FST_VERIFY_H_
  #define FST_VERIFY_H_
  
  #include <fst/log.h>
  
  #include <fst/fst.h>
  #include <fst/test-properties.h>
  
  
  namespace fst {
  
  // Verifies that an Fst's contents are sane.
  template <class Arc>
  bool Verify(const Fst<Arc> &fst, bool allow_negative_labels = false) {
    using Label = typename Arc::Label;
    using StateId = typename Arc::StateId;
    using Weight = typename Arc::Weight;
    const auto start = fst.Start();
    const auto *isyms = fst.InputSymbols();
    const auto *osyms = fst.OutputSymbols();
    // Count states
    StateId ns = 0;
    for (StateIterator<Fst<Arc>> siter(fst); !siter.Done(); siter.Next()) ++ns;
    if (start == kNoStateId && ns > 0) {
      LOG(ERROR) << "Verify: FST start state ID not set";
      return false;
    } else if (start >= ns) {
      LOG(ERROR) << "Verify: FST start state ID exceeds number of states";
      return false;
    }
    for (StateIterator<Fst<Arc>> siter(fst); !siter.Done(); siter.Next()) {
      auto state = siter.Value();
      size_t na = 0;
      for (ArcIterator<Fst<Arc>> aiter(fst, state); !aiter.Done(); aiter.Next()) {
        const auto &arc = aiter.Value();
        if (!allow_negative_labels && arc.ilabel < 0) {
          LOG(ERROR) << "Verify: FST input label ID of arc at position " << na
                     << " of state " << state << " is negative";
          return false;
        } else if (isyms && isyms->Find(arc.ilabel) == "") {
          LOG(ERROR) << "Verify: FST input label ID " << arc.ilabel
                     << " of arc at position " << na << " of state " << state
                     << " is missing from input symbol table \"" << isyms->Name()
                     << "\"";
          return false;
        } else if (!allow_negative_labels && arc.olabel < 0) {
          LOG(ERROR) << "Verify: FST output label ID of arc at position " << na
                     << " of state " << state << " is negative";
          return false;
        } else if (osyms && osyms->Find(arc.olabel) == "") {
          LOG(ERROR) << "Verify: FST output label ID " << arc.olabel
                     << " of arc at position " << na << " of state " << state
                     << " is missing from output symbol table \"" << osyms->Name()
                     << "\"";
          return false;
        } else if (!arc.weight.Member()) {
          LOG(ERROR) << "Verify: FST weight of arc at position " << na
                     << " of state " << state << " is invalid";
          return false;
        } else if (arc.nextstate < 0) {
          LOG(ERROR) << "Verify: FST destination state ID of arc at position "
                     << na << " of state " << state << " is negative";
          return false;
        } else if (arc.nextstate >= ns) {
          LOG(ERROR) << "Verify: FST destination state ID of arc at position "
                     << na << " of state " << state
                     << " exceeds number of states";
          return false;
        }
        ++na;
      }
      if (!fst.Final(state).Member()) {
        LOG(ERROR) << "Verify: FST final weight of state " << state
                   << " is invalid";
        return false;
      }
    }
    const auto fst_props = fst.Properties(kFstProperties, false);
    if (fst_props & kError) {
      LOG(ERROR) << "Verify: FST error property is set";
      return false;
    }
    uint64 known_props;
    uint64 test_props =
        ComputeProperties(fst, kFstProperties, &known_props, false);
    if (!CompatProperties(fst_props, test_props)) {
      LOG(ERROR) << "Verify: Stored FST properties incorrect "
                 << "(props1 = stored props, props2 = tested)";
      return false;
    } else {
      return true;
    }
  }
  
  }  // namespace fst
  
  #endif  // FST_VERIFY_H_