Home | History | Annotate | Download | only in fst
      1 // expanded-fst.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 // Generic FST augmented with state count - interface class definition.
     20 //
     21 
     22 #ifndef FST_LIB_EXPANDED_FST_H__
     23 #define FST_LIB_EXPANDED_FST_H__
     24 
     25 #include <sys/types.h>
     26 #include <string>
     27 
     28 #include <fst/fst.h>
     29 
     30 
     31 namespace fst {
     32 
     33 // A generic FST plus state count.
     34 template <class A>
     35 class ExpandedFst : public Fst<A> {
     36  public:
     37   typedef A Arc;
     38   typedef typename A::StateId StateId;
     39 
     40   virtual StateId NumStates() const = 0;  // State count
     41 
     42   // Get a copy of this ExpandedFst. See Fst<>::Copy() for further doc.
     43   virtual ExpandedFst<A> *Copy(bool safe = false) const = 0;
     44 
     45   // Read an ExpandedFst from an input stream; return NULL on error.
     46   static ExpandedFst<A> *Read(istream &strm, const FstReadOptions &opts) {
     47     FstReadOptions ropts(opts);
     48     FstHeader hdr;
     49     if (ropts.header)
     50       hdr = *opts.header;
     51     else {
     52       if (!hdr.Read(strm, opts.source))
     53         return 0;
     54       ropts.header = &hdr;
     55     }
     56     if (!(hdr.Properties() & kExpanded)) {
     57       LOG(ERROR) << "ExpandedFst::Read: Not an ExpandedFst: " << ropts.source;
     58       return 0;
     59     }
     60     FstRegister<A> *registr = FstRegister<A>::GetRegister();
     61     const typename FstRegister<A>::Reader reader =
     62       registr->GetReader(hdr.FstType());
     63     if (!reader) {
     64       LOG(ERROR) << "ExpandedFst::Read: Unknown FST type \"" << hdr.FstType()
     65                  << "\" (arc type = \"" << A::Type()
     66                  << "\"): " << ropts.source;
     67       return 0;
     68     }
     69     Fst<A> *fst = reader(strm, ropts);
     70     if (!fst) return 0;
     71     return static_cast<ExpandedFst<A> *>(fst);
     72   }
     73 
     74   // Read an ExpandedFst from a file; return NULL on error.
     75   // Empty filename reads from standard input.
     76   static ExpandedFst<A> *Read(const string &filename) {
     77     if (!filename.empty()) {
     78       ifstream strm(filename.c_str(), ifstream::in | ifstream::binary);
     79       if (!strm) {
     80         LOG(ERROR) << "ExpandedFst::Read: Can't open file: " << filename;
     81         return 0;
     82       }
     83       return Read(strm, FstReadOptions(filename));
     84     } else {
     85       return Read(cin, FstReadOptions("standard input"));
     86     }
     87   }
     88 };
     89 
     90 
     91 namespace internal {
     92 
     93 //  ExpandedFst<A> case - abstract methods.
     94 template <class A> inline
     95 typename A::Weight Final(const ExpandedFst<A> &fst, typename A::StateId s) {
     96   return fst.Final(s);
     97 }
     98 
     99 template <class A> inline
    100 ssize_t NumArcs(const ExpandedFst<A> &fst, typename A::StateId s) {
    101   return fst.NumArcs(s);
    102 }
    103 
    104 template <class A> inline
    105 ssize_t NumInputEpsilons(const ExpandedFst<A> &fst, typename A::StateId s) {
    106   return fst.NumInputEpsilons(s);
    107 }
    108 
    109 template <class A> inline
    110 ssize_t NumOutputEpsilons(const ExpandedFst<A> &fst, typename A::StateId s) {
    111   return fst.NumOutputEpsilons(s);
    112 }
    113 
    114 }  // namespace internal
    115 
    116 
    117 // A useful alias when using StdArc.
    118 typedef ExpandedFst<StdArc> StdExpandedFst;
    119 
    120 
    121 // This is a helper class template useful for attaching an ExpandedFst
    122 // interface to its implementation, handling reference counting. It
    123 // delegates to ImplToFst the handling of the Fst interface methods.
    124 template < class I, class F = ExpandedFst<typename I::Arc> >
    125 class ImplToExpandedFst : public ImplToFst<I, F> {
    126  public:
    127   typedef typename I::Arc Arc;
    128   typedef typename Arc::Weight Weight;
    129   typedef typename Arc::StateId StateId;
    130 
    131   using ImplToFst<I, F>::GetImpl;
    132 
    133   virtual StateId NumStates() const { return GetImpl()->NumStates(); }
    134 
    135  protected:
    136   ImplToExpandedFst() : ImplToFst<I, F>() {}
    137 
    138   ImplToExpandedFst(I *impl) : ImplToFst<I, F>(impl) {}
    139 
    140   ImplToExpandedFst(const ImplToExpandedFst<I, F> &fst)
    141       : ImplToFst<I, F>(fst) {}
    142 
    143   ImplToExpandedFst(const ImplToExpandedFst<I, F> &fst, bool safe)
    144       : ImplToFst<I, F>(fst, safe) {}
    145 
    146   // Read FST implementation from a file; return NULL on error.
    147   // Empty filename reads from standard input.
    148   static I *Read(const string &filename) {
    149     if (!filename.empty()) {
    150       ifstream strm(filename.c_str(), ifstream::in | ifstream::binary);
    151       if (!strm) {
    152         LOG(ERROR) << "ExpandedFst::Read: Can't open file: " << filename;
    153         return 0;
    154       }
    155       return I::Read(strm, FstReadOptions(filename));
    156     } else {
    157       return I::Read(cin, FstReadOptions("standard input"));
    158     }
    159   }
    160 
    161  private:
    162   // Disallow
    163   ImplToExpandedFst<I, F> &operator=(const ImplToExpandedFst<I, F> &fst);
    164 
    165   ImplToExpandedFst<I, F> &operator=(const Fst<Arc> &fst) {
    166     FSTERROR() << "ImplToExpandedFst: Assignment operator disallowed";
    167     GetImpl()->SetProperties(kError, kError);
    168     return *this;
    169   }
    170 };
    171 
    172 // Function to return the number of states in an FST, counting them
    173 // if necessary.
    174 template <class Arc>
    175 typename Arc::StateId CountStates(const Fst<Arc> &fst) {
    176   if (fst.Properties(kExpanded, false)) {
    177     const ExpandedFst<Arc> *efst = static_cast<const ExpandedFst<Arc> *>(&fst);
    178     return efst->NumStates();
    179   } else {
    180     typename Arc::StateId nstates = 0;
    181     for (StateIterator< Fst<Arc> > siter(fst); !siter.Done(); siter.Next())
    182       ++nstates;
    183     return nstates;
    184   }
    185 }
    186 
    187 }  // namespace fst
    188 
    189 #endif  // FST_LIB_EXPANDED_FST_H__
    190