1 // verify.h 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 // 16 // \file 17 // Function to test property bits 18 19 #ifndef FST_LIB_VERIFY_H__ 20 #define FST_LIB_VERIFY_H__ 21 22 #include "fst/lib/fst.h" 23 #include "fst/lib/test-properties.h" 24 25 namespace fst { 26 27 // Verifies that an Fst's contents are sane. 28 template<class Arc> 29 bool Verify(const Fst<Arc> &fst) { 30 typedef typename Arc::Label Label; 31 typedef typename Arc::Weight Weight; 32 typedef typename Arc::StateId StateId; 33 34 StateId start = fst.Start(); 35 const SymbolTable *isyms = fst.InputSymbols(); 36 const SymbolTable *osyms = fst.OutputSymbols(); 37 38 // Count states 39 StateId ns = 0; 40 for (StateIterator< Fst<Arc> > siter(fst); 41 !siter.Done(); 42 siter.Next()) 43 ++ns; 44 45 if (start == kNoStateId && ns > 0) { 46 LOG(ERROR) << "Verify: Fst start state ID unset"; 47 return false; 48 } else if (start >= ns) { 49 LOG(ERROR) << "Verify: Fst start state ID exceeds number of states"; 50 return false; 51 } 52 53 for (StateIterator< Fst<Arc> > siter(fst); 54 !siter.Done(); 55 siter.Next()) { 56 StateId s = siter.Value(); 57 size_t na = 0; 58 for (ArcIterator< Fst<Arc> > aiter(fst, s); 59 !aiter.Done(); 60 aiter.Next()) { 61 const Arc &arc =aiter.Value(); 62 if (arc.ilabel < 0) { 63 LOG(ERROR) << "Verify: Fst input label ID of arc at position " 64 << na << " of state " << s << " is negative"; 65 return false; 66 } else if (isyms && isyms->Find(arc.ilabel) == "") { 67 LOG(ERROR) << "Verify: Fst input label ID " << arc.ilabel 68 << " of arc at position " << na << " of state " << s 69 << " is missing from input symbol table \"" 70 << isyms->Name() << "\""; 71 return false; 72 } else if (arc.olabel < 0) { 73 LOG(ERROR) << "Verify: Fst output label ID of arc at position " 74 << na << " of state " << s << " is negative"; 75 return false; 76 } else if (osyms && osyms->Find(arc.olabel) == "") { 77 LOG(ERROR) << "Verify: Fst output label ID " << arc.olabel 78 << " of arc at position " << na << " of state " << s 79 << " is missing from output symbol table \"" 80 << osyms->Name() << "\""; 81 return false; 82 } else if (!arc.weight.Member() || arc.weight == Weight::Zero()) { 83 LOG(ERROR) << "Verify: Fst weight of arc at position " 84 << na << " of state " << s << " is invalid"; 85 return false; 86 } else if (arc.nextstate < 0) { 87 LOG(ERROR) << "Verify: Fst destination state ID of arc at position " 88 << na << " of state " << s << " is negative"; 89 return false; 90 } else if (arc.nextstate >= ns) { 91 LOG(ERROR) << "Verify: Fst destination state ID of arc at position " 92 << na << " of state " << s 93 << " exceeds number of states"; 94 return false; 95 } 96 ++na; 97 } 98 if (!fst.Final(s).Member()) { 99 LOG(ERROR) << "Verify: Fst final weight of state " << s << " is invalid"; 100 return false; 101 } 102 } 103 uint64 fst_props = fst.Properties(kFstProperties, false); 104 uint64 known_props; 105 uint64 test_props = ComputeProperties(fst, kFstProperties, &known_props, 106 false); 107 if (!CompatProperties(fst_props, test_props)) { 108 LOG(ERROR) << "Verify: stored Fst properties incorrect " 109 << "(props1 = stored props, props2 = tested)"; 110 return false; 111 } else { 112 return true; 113 } 114 } 115 116 } // namespace fst 117 118 #endif // FST_LIB_VERIFY_H__ 119