14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// verify.h 24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Licensed under the Apache License, Version 2.0 (the "License"); 44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// you may not use this file except in compliance with the License. 54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// You may obtain a copy of the License at 64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// http://www.apache.org/licenses/LICENSE-2.0 84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Unless required by applicable law or agreed to in writing, software 104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// distributed under the License is distributed on an "AS IS" BASIS, 114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// See the License for the specific language governing permissions and 134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// limitations under the License. 144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \file 174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Function to test property bits 184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef FST_LIB_VERIFY_H__ 204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define FST_LIB_VERIFY_H__ 214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/fst.h" 234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/test-properties.h" 244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectnamespace fst { 264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Verifies that an Fst's contents are sane. 284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class Arc> 294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectbool Verify(const Fst<Arc> &fst) { 304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project typedef typename Arc::Label Label; 314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project typedef typename Arc::Weight Weight; 324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project typedef typename Arc::StateId StateId; 334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project StateId start = fst.Start(); 354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const SymbolTable *isyms = fst.InputSymbols(); 364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const SymbolTable *osyms = fst.OutputSymbols(); 374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Count states 394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project StateId ns = 0; 404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (StateIterator< Fst<Arc> > siter(fst); 414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !siter.Done(); 424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project siter.Next()) 434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ++ns; 444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (start == kNoStateId && ns > 0) { 464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "Verify: Fst start state ID unset"; 474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else if (start >= ns) { 494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "Verify: Fst start state ID exceeds number of states"; 504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (StateIterator< Fst<Arc> > siter(fst); 544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !siter.Done(); 554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project siter.Next()) { 564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project StateId s = siter.Value(); 574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project size_t na = 0; 584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (ArcIterator< Fst<Arc> > aiter(fst, s); 594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !aiter.Done(); 604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project aiter.Next()) { 614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const Arc &arc =aiter.Value(); 624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (arc.ilabel < 0) { 634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "Verify: Fst input label ID of arc at position " 644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << na << " of state " << s << " is negative"; 654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else if (isyms && isyms->Find(arc.ilabel) == "") { 674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "Verify: Fst input label ID " << arc.ilabel 684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << " of arc at position " << na << " of state " << s 694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << " is missing from input symbol table \"" 704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << isyms->Name() << "\""; 714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else if (arc.olabel < 0) { 734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "Verify: Fst output label ID of arc at position " 744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << na << " of state " << s << " is negative"; 754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else if (osyms && osyms->Find(arc.olabel) == "") { 774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "Verify: Fst output label ID " << arc.olabel 784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << " of arc at position " << na << " of state " << s 794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << " is missing from output symbol table \"" 804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << osyms->Name() << "\""; 814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else if (!arc.weight.Member() || arc.weight == Weight::Zero()) { 834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "Verify: Fst weight of arc at position " 844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << na << " of state " << s << " is invalid"; 854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else if (arc.nextstate < 0) { 874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "Verify: Fst destination state ID of arc at position " 884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << na << " of state " << s << " is negative"; 894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else if (arc.nextstate >= ns) { 914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "Verify: Fst destination state ID of arc at position " 924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << na << " of state " << s 934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << " exceeds number of states"; 944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ++na; 974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!fst.Final(s).Member()) { 994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "Verify: Fst final weight of state " << s << " is invalid"; 1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 fst_props = fst.Properties(kFstProperties, false); 1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 known_props; 1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 test_props = ComputeProperties(fst, kFstProperties, &known_props, 1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project false); 1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!CompatProperties(fst_props, test_props)) { 1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "Verify: stored Fst properties incorrect " 1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << "(props1 = stored props, props2 = tested)"; 1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { 1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return true; 1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} // namespace fst 1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif // FST_LIB_VERIFY_H__ 119