Home | History | Annotate | Download | only in fst
      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 (at) 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