Home | History | Annotate | Download | only in lib
      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