14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// encode.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// Class to encode and decoder an fst.
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef FST_LIB_ENCODE_H__
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define FST_LIB_ENCODE_H__
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/map.h"
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/rmfinalepsilon.h"
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectnamespace fst {
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const uint32 kEncodeLabels = 0x00001;
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const uint32 kEncodeWeights  = 0x00002;
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectenum EncodeType { ENCODE = 1, DECODE = 2 };
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Identifies stream data as an encode table (and its endianity)
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const int32 kEncodeMagicNumber = 2129983209;
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// The following class encapsulates implementation details for the
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// encoding and decoding of label/weight tuples used for encoding
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// and decoding of Fsts. The EncodeTable is bidirectional. I.E it
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// stores both the Tuple of encode labels and weights to a unique
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// label, and the reverse.
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>  class EncodeTable {
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Label Label;
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Weight Weight;
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Encoded data consists of arc input/output labels and arc weight
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  struct Tuple {
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Tuple() {}
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Tuple(Label ilabel_, Label olabel_, Weight weight_)
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        : ilabel(ilabel_), olabel(olabel_), weight(weight_) {}
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Tuple(const Tuple& tuple)
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        : ilabel(tuple.ilabel), olabel(tuple.olabel), weight(tuple.weight) {}
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Label ilabel;
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Label olabel;
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Weight weight;
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  };
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Comparison object for hashing EncodeTable Tuple(s).
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  class TupleEqual {
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project   public:
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    bool operator()(const Tuple* x, const Tuple* y) const {
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return (x->ilabel == y->ilabel &&
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project              x->olabel == y->olabel &&
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project              x->weight == y->weight);
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  };
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Hash function for EncodeTabe Tuples. Based on the encode flags
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // we either hash the labels, weights or compbination of them.
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  class TupleKey {
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    static const int kPrime = 7853;
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project   public:
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    TupleKey()
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        : encode_flags_(kEncodeLabels | kEncodeWeights) {}
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    TupleKey(const TupleKey& key)
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        : encode_flags_(key.encode_flags_) {}
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    explicit TupleKey(uint32 encode_flags)
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        : encode_flags_(encode_flags) {}
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    size_t operator()(const Tuple* x) const {
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      int lshift = x->ilabel % kPrime;
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      int rshift = sizeof(size_t) - lshift;
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      size_t hash = x->ilabel << lshift;
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (encode_flags_ & kEncodeLabels) hash ^= x->olabel >> rshift;
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (encode_flags_ & kEncodeWeights)  hash ^= x->weight.Hash();
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return hash;
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project   private:
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int32 encode_flags_;
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  };
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
9673018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers  typedef std::unordered_map<const Tuple*, Label, TupleKey, TupleEqual> EncodeHash;
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit EncodeTable(uint32 encode_flags)
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : flags_(encode_flags),
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        encode_hash_(1024, TupleKey(encode_flags)) {}
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ~EncodeTable() {
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (size_t i = 0; i < encode_tuples_.size(); ++i) {
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      delete encode_tuples_[i];
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Given an arc encode either input/ouptut labels or input/costs or both
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Label Encode(const A &arc) {
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const Tuple tuple(arc.ilabel,
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                      flags_ & kEncodeLabels ? arc.olabel : 0,
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                      flags_ & kEncodeWeights ? arc.weight : Weight::One());
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    typename EncodeHash::const_iterator it = encode_hash_.find(&tuple);
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (it == encode_hash_.end()) {
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      encode_tuples_.push_back(new Tuple(tuple));
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      encode_hash_[encode_tuples_.back()] = encode_tuples_.size();
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return encode_tuples_.size();
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    } else {
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return it->second;
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Given an encode arc Label decode back to input/output labels and costs
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const Tuple* Decode(Label key) {
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return key <= (Label)encode_tuples_.size() ? encode_tuples_[key - 1] : 0;
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool Write(ostream &strm, const string &source) const {
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    WriteType(strm, kEncodeMagicNumber);
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    WriteType(strm, flags_);
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int64 size = encode_tuples_.size();
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    WriteType(strm, size);
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (size_t i = 0;  i < size; ++i) {
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      const Tuple* tuple = encode_tuples_[i];
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      WriteType(strm, tuple->ilabel);
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      WriteType(strm, tuple->olabel);
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      tuple->weight.Write(strm);
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    strm.flush();
14031124d583cfcd1ea9407856747c178d0125c1070Ian Rogers    if (!strm) {
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      LOG(ERROR) << "EncodeTable::Write: write failed: " << source;
14231124d583cfcd1ea9407856747c178d0125c1070Ian Rogers      return false;
14331124d583cfcd1ea9407856747c178d0125c1070Ian Rogers    }
14431124d583cfcd1ea9407856747c178d0125c1070Ian Rogers    return true;
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool Read(istream &strm, const string &source) {
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    encode_tuples_.clear();
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    encode_hash_.clear();
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int32 magic_number = 0;
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ReadType(strm, &magic_number);
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (magic_number != kEncodeMagicNumber) {
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      LOG(ERROR) << "EncodeTable::Read: Bad encode table header: " << source;
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return false;
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ReadType(strm, &flags_);
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int64 size;
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ReadType(strm, &size);
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!strm) {
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      LOG(ERROR) << "EncodeTable::Read: read failed: " << source;
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return false;
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (size_t i = 0; i < size; ++i) {
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      Tuple* tuple = new Tuple();
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ReadType(strm, &tuple->ilabel);
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ReadType(strm, &tuple->olabel);
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      tuple->weight.Read(strm);
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      encode_tuples_.push_back(tuple);
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      encode_hash_[encode_tuples_.back()] = encode_tuples_.size();
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
17131124d583cfcd1ea9407856747c178d0125c1070Ian Rogers    if (!strm) {
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      LOG(ERROR) << "EncodeTable::Read: read failed: " << source;
17331124d583cfcd1ea9407856747c178d0125c1070Ian Rogers      return false;
17431124d583cfcd1ea9407856747c178d0125c1070Ian Rogers    }
17531124d583cfcd1ea9407856747c178d0125c1070Ian Rogers    return true;
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
17873018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers  uint32 flags() const { return flags_; }
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  uint32 flags_;
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  vector<Tuple*> encode_tuples_;
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  EncodeHash encode_hash_;
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(EncodeTable);
1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// A mapper to encode/decode weighted transducers. Encoding of an
1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Fst is useful for performing classical determinization or minimization
1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// on a weighted transducer by treating it as an unweighted acceptor over
1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// encoded labels.
1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// The Encode mapper stores the encoding in a local hash table (EncodeTable)
1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// This table is shared (and reference counted) between the encoder and
1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// decoder. A decoder has read only access to the EncodeTable.
1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// The EncodeMapper allows on the fly encoding of the machine. As the
1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// EncodeTable is generated the same table may by used to decode the machine
1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// on the fly. For example in the following sequence of operations
2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//  Encode -> Determinize -> Decode
2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// we will use the encoding table generated during the encode step in the
2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// decode, even though the encoding is not complete.
2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A> class EncodeMapper {
2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Weight Weight;
2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Label  Label;
2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  EncodeMapper(uint32 flags, EncodeType type)
2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : ref_count_(1), flags_(flags), type_(type),
2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      table_(new EncodeTable<A>(flags)) {}
2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  EncodeMapper(const EncodeMapper& mapper)
2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : ref_count_(mapper.ref_count_ + 1),
2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        flags_(mapper.flags_),
2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        type_(mapper.type_),
2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        table_(mapper.table_) { }
2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Copy constructor but setting the type, typically to DECODE
2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  EncodeMapper(const EncodeMapper& mapper, EncodeType type)
2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : ref_count_(mapper.ref_count_ + 1),
2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        flags_(mapper.flags_),
2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        type_(type),
2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        table_(mapper.table_) { }
2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ~EncodeMapper() {
2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (--ref_count_ == 0) delete table_;
2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  A operator()(const A &arc) {
2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (type_ == ENCODE) {  // labels and/or weights to single label
2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if ((arc.nextstate == kNoStateId && !(flags_ & kEncodeWeights)) ||
2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          (arc.nextstate == kNoStateId && (flags_ & kEncodeWeights) &&
2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project           arc.weight == Weight::Zero())) {
2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return arc;
2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      } else {
2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        Label label = table_->Encode(arc);
2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return A(label,
2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 flags_ & kEncodeLabels ? label : arc.olabel,
2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 flags_ & kEncodeWeights ? Weight::One() : arc.weight,
2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 arc.nextstate);
2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    } else {
2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arc.nextstate == kNoStateId) {
2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return arc;
2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      } else {
2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        const typename EncodeTable<A>::Tuple* tuple =
2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          table_->Decode(arc.ilabel);
2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return A(tuple->ilabel,
2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 flags_ & kEncodeLabels ? tuple->olabel : arc.olabel,
2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 flags_ & kEncodeWeights ? tuple->weight : arc.weight,
2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 arc.nextstate);;
2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  uint64 Properties(uint64 props) {
2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    uint64 mask = kFstProperties;
2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (flags_ & kEncodeLabels)
2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      mask &= kILabelInvariantProperties & kOLabelInvariantProperties;
2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (flags_ & kEncodeWeights)
2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      mask &= kILabelInvariantProperties & kWeightInvariantProperties &
2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          (type_ == ENCODE ? kAddSuperFinalProperties :
2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project           kRmSuperFinalProperties);
2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return props & mask;
2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  MapFinalAction FinalAction() const {
2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return (type_ == ENCODE && (flags_ & kEncodeWeights)) ?
2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                   MAP_REQUIRE_SUPERFINAL : MAP_NO_SUPERFINAL;
2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
27573018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers  uint32 flags() const { return flags_; }
27673018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers  EncodeType type() const { return type_; }
2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool Write(ostream &strm, const string& source) {
2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return table_->Write(strm, source);
2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool Write(const string& filename) {
2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ofstream strm(filename.c_str());
2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!strm) {
2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      LOG(ERROR) << "EncodeMap: Can't open file: " << filename;
2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return false;
2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return Write(strm, filename);
2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static EncodeMapper<A> *Read(istream &strm,
2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                               const string& source, EncodeType type) {
2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    EncodeTable<A> *table = new EncodeTable<A>(0);
2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    bool r = table->Read(strm, source);
2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return r ? new EncodeMapper(table->flags(), type, table) : 0;
2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static EncodeMapper<A> *Read(const string& filename, EncodeType type) {
2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ifstream strm(filename.c_str());
3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!strm) {
3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      LOG(ERROR) << "EncodeMap: Can't open file: " << filename;
3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return false;
3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return Read(strm, filename, type);
3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  uint32  ref_count_;
3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  uint32  flags_;
3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  EncodeType type_;
3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  EncodeTable<A>* table_;
3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit EncodeMapper(uint32 flags, EncodeType type, EncodeTable<A> *table)
3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : ref_count_(1), flags_(flags), type_(type), table_(table) {}
3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void operator=(const EncodeMapper &);  // Disallow.
3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Complexity: O(nstates + narcs)
3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class A> inline
3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid Encode(MutableFst<A> *fst, EncodeMapper<A>* mapper) {
3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Map(fst, mapper);
3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class A> inline
3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid Decode(MutableFst<A>* fst, const EncodeMapper<A>& mapper) {
3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Map(fst, EncodeMapper<A>(mapper, DECODE));
3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  RmFinalEpsilon(fst);
3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// On the fly label and/or weight encoding of input Fst
3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Complexity:
3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// - Constructor: O(1)
3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// - Traversal: O(nstates_visited + narcs_visited), assuming constant
3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//   time to visit an input state or arc.
3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass EncodeFst : public MapFst<A, A, EncodeMapper<A> > {
3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef A Arc;
3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef EncodeMapper<A> C;
3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  EncodeFst(const Fst<A> &fst, EncodeMapper<A>* encoder)
3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : MapFst<A, A, C>(fst, encoder, MapFstOptions()) {}
3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  EncodeFst(const Fst<A> &fst, const EncodeMapper<A>& encoder)
3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : MapFst<A, A, C>(fst, encoder, MapFstOptions()) {}
3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  EncodeFst(const EncodeFst<A> &fst)
3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : MapFst<A, A, C>(fst) {}
3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual EncodeFst<A> *Copy() const { return new EncodeFst(*this); }
3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// On the fly label and/or weight encoding of input Fst
3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Complexity:
3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// - Constructor: O(1)
3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// - Traversal: O(nstates_visited + narcs_visited), assuming constant
3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//   time to visit an input state or arc.
3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass DecodeFst : public MapFst<A, A, EncodeMapper<A> > {
3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef A Arc;
3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef EncodeMapper<A> C;
3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DecodeFst(const Fst<A> &fst, const EncodeMapper<A>& encoder)
3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : MapFst<A, A, C>(fst,
3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            EncodeMapper<A>(encoder, DECODE),
3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                            MapFstOptions()) {}
3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DecodeFst(const EncodeFst<A> &fst)
3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : MapFst<A, A, C>(fst) {}
3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual DecodeFst<A> *Copy() const { return new DecodeFst(*this); }
3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Specialization for EncodeFst.
3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass StateIterator< EncodeFst<A> >
3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : public StateIterator< MapFst<A, A, EncodeMapper<A> > > {
3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit StateIterator(const EncodeFst<A> &fst)
3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : StateIterator< MapFst<A, A, EncodeMapper<A> > >(fst) {}
3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Specialization for EncodeFst.
3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass ArcIterator< EncodeFst<A> >
3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : public ArcIterator< MapFst<A, A, EncodeMapper<A> > > {
3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
3974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ArcIterator(const EncodeFst<A> &fst, typename A::StateId s)
3984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : ArcIterator< MapFst<A, A, EncodeMapper<A> > >(fst, s) {}
3994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
4004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Specialization for DecodeFst.
4034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
4044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass StateIterator< DecodeFst<A> >
4054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : public StateIterator< MapFst<A, A, EncodeMapper<A> > > {
4064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
4074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit StateIterator(const DecodeFst<A> &fst)
4084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : StateIterator< MapFst<A, A, EncodeMapper<A> > >(fst) {}
4094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
4104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Specialization for DecodeFst.
4134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
4144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass ArcIterator< DecodeFst<A> >
4154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : public ArcIterator< MapFst<A, A, EncodeMapper<A> > > {
4164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
4174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ArcIterator(const DecodeFst<A> &fst, typename A::StateId s)
4184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : ArcIterator< MapFst<A, A, EncodeMapper<A> > >(fst, s) {}
4194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
4204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Useful aliases when using StdArc.
4234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef EncodeFst<StdArc> StdEncodeFst;
4244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef DecodeFst<StdArc> StdDecodeFst;
4264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif  // FST_LIB_ENCODE_H__
430