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