1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// encode.h
2f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
3f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Licensed under the Apache License, Version 2.0 (the "License");
4f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// you may not use this file except in compliance with the License.
5f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// You may obtain a copy of the License at
6f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
7f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//     http://www.apache.org/licenses/LICENSE-2.0
8f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
9f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Unless required by applicable law or agreed to in writing, software
10f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// distributed under the License is distributed on an "AS IS" BASIS,
11f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// See the License for the specific language governing permissions and
13f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// limitations under the License.
14f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
15f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Copyright 2005-2010 Google, Inc.
16f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Author: johans@google.com (Johan Schalkwyk)
17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \file
19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Class to encode and decoder an fst.
20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_ENCODE_H__
22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_ENCODE_H__
23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <climits>
25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <unordered_map>
26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_map;
27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_multimap;
28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <string>
29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <vector>
30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::vector;
31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/arc-map.h>
33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/rmfinalepsilon.h>
34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst {
37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstatic const uint32 kEncodeLabels      = 0x0001;
39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstatic const uint32 kEncodeWeights     = 0x0002;
40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstatic const uint32 kEncodeFlags       = 0x0003;  // All non-internal flags
41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstatic const uint32 kEncodeHasISymbols = 0x0004;  // For internal use
43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstatic const uint32 kEncodeHasOSymbols = 0x0008;  // For internal use
44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonenum EncodeType { ENCODE = 1, DECODE = 2 };
46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Identifies stream data as an encode table (and its endianity)
48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstatic const int32 kEncodeMagicNumber = 2129983209;
49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The following class encapsulates implementation details for the
52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// encoding and decoding of label/weight tuples used for encoding
53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// and decoding of Fsts. The EncodeTable is bidirectional. I.E it
54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// stores both the Tuple of encode labels and weights to a unique
55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// label, and the reverse.
56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>  class EncodeTable {
57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Label Label;
59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight Weight;
60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Encoded data consists of arc input/output labels and arc weight
62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  struct Tuple {
63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Tuple() {}
64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Tuple(Label ilabel_, Label olabel_, Weight weight_)
65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        : ilabel(ilabel_), olabel(olabel_), weight(weight_) {}
66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Tuple(const Tuple& tuple)
67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        : ilabel(tuple.ilabel), olabel(tuple.olabel), weight(tuple.weight) {}
68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Label ilabel;
70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Label olabel;
71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Weight weight;
72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  };
73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Comparison object for hashing EncodeTable Tuple(s).
75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  class TupleEqual {
76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson   public:
77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    bool operator()(const Tuple* x, const Tuple* y) const {
78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return (x->ilabel == y->ilabel &&
79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson              x->olabel == y->olabel &&
80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson              x->weight == y->weight);
81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  };
83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Hash function for EncodeTabe Tuples. Based on the encode flags
85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // we either hash the labels, weights or combination of them.
86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  class TupleKey {
87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson   public:
88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    TupleKey()
89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        : encode_flags_(kEncodeLabels | kEncodeWeights) {}
90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    TupleKey(const TupleKey& key)
92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        : encode_flags_(key.encode_flags_) {}
93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    explicit TupleKey(uint32 encode_flags)
95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        : encode_flags_(encode_flags) {}
96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    size_t operator()(const Tuple* x) const {
98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      size_t hash = x->ilabel;
99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      const int lshift = 5;
100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      const int rshift = CHAR_BIT * sizeof(size_t) - 5;
101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (encode_flags_ & kEncodeLabels)
102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        hash = hash << lshift ^ hash >> rshift ^ x->olabel;
103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (encode_flags_ & kEncodeWeights)
104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        hash = hash << lshift ^ hash >> rshift ^ x->weight.Hash();
105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return hash;
106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson   private:
109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    int32 encode_flags_;
110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  };
111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef unordered_map<const Tuple*,
113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                   Label,
114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                   TupleKey,
115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                   TupleEqual> EncodeHash;
116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit EncodeTable(uint32 encode_flags)
118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : flags_(encode_flags),
119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        encode_hash_(1024, TupleKey(encode_flags)),
120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        isymbols_(0), osymbols_(0) {}
121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ~EncodeTable() {
123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (size_t i = 0; i < encode_tuples_.size(); ++i) {
124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      delete encode_tuples_[i];
125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    delete isymbols_;
127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    delete osymbols_;
128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Given an arc encode either input/ouptut labels or input/costs or both
131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Label Encode(const A &arc) {
132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    const Tuple tuple(arc.ilabel,
133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                      flags_ & kEncodeLabels ? arc.olabel : 0,
134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                      flags_ & kEncodeWeights ? arc.weight : Weight::One());
135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    typename EncodeHash::const_iterator it = encode_hash_.find(&tuple);
136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (it == encode_hash_.end()) {
137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      encode_tuples_.push_back(new Tuple(tuple));
138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      encode_hash_[encode_tuples_.back()] = encode_tuples_.size();
139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return encode_tuples_.size();
140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else {
141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return it->second;
142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Given an arc, look up its encoded label. Returns kNoLabel if not found.
146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Label GetLabel(const A &arc) const {
147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    const Tuple tuple(arc.ilabel,
148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                      flags_ & kEncodeLabels ? arc.olabel : 0,
149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                      flags_ & kEncodeWeights ? arc.weight : Weight::One());
150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    typename EncodeHash::const_iterator it = encode_hash_.find(&tuple);
151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (it == encode_hash_.end()) {
152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return kNoLabel;
153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else {
154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return it->second;
155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Given an encode arc Label decode back to input/output labels and costs
159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const Tuple* Decode(Label key) const {
160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (key < 1 || key > encode_tuples_.size()) {
161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      LOG(ERROR) << "EncodeTable::Decode: unknown decode key: " << key;
162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return 0;
163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return encode_tuples_[key - 1];
165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t Size() const { return encode_tuples_.size(); }
168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool Write(ostream &strm, const string &source) const;
170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static EncodeTable<A> *Read(istream &strm, const string &source);
172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const uint32 flags() const { return flags_ & kEncodeFlags; }
174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int RefCount() const { return ref_count_.count(); }
176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int IncrRefCount() { return ref_count_.Incr(); }
177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int DecrRefCount() { return ref_count_.Decr(); }
178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SymbolTable *InputSymbols() const { return isymbols_; }
181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SymbolTable *OutputSymbols() const { return osymbols_; }
183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetInputSymbols(const SymbolTable* syms) {
185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (isymbols_) delete isymbols_;
186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (syms) {
187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      isymbols_ = syms->Copy();
188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      flags_ |= kEncodeHasISymbols;
189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else {
190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      isymbols_ = 0;
191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      flags_ &= ~kEncodeHasISymbols;
192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetOutputSymbols(const SymbolTable* syms) {
196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (osymbols_) delete osymbols_;
197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (syms) {
198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      osymbols_ = syms->Copy();
199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      flags_ |= kEncodeHasOSymbols;
200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else {
201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      osymbols_ = 0;
202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      flags_ &= ~kEncodeHasOSymbols;
203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint32 flags_;
208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  vector<Tuple*> encode_tuples_;
209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  EncodeHash encode_hash_;
210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RefCounter ref_count_;
211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SymbolTable *isymbols_;       // Pre-encoded ilabel symbol table
212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SymbolTable *osymbols_;       // Pre-encoded olabel symbol table
213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(EncodeTable);
215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> inline
218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonbool EncodeTable<A>::Write(ostream &strm, const string &source) const {
219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  WriteType(strm, kEncodeMagicNumber);
220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  WriteType(strm, flags_);
221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 size = encode_tuples_.size();
222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  WriteType(strm, size);
223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (size_t i = 0;  i < size; ++i) {
224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    const Tuple* tuple = encode_tuples_[i];
225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    WriteType(strm, tuple->ilabel);
226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    WriteType(strm, tuple->olabel);
227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    tuple->weight.Write(strm);
228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (flags_ & kEncodeHasISymbols)
231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    isymbols_->Write(strm);
232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (flags_ & kEncodeHasOSymbols)
234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    osymbols_->Write(strm);
235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  strm.flush();
237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (!strm) {
238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    LOG(ERROR) << "EncodeTable::Write: write failed: " << source;
239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return false;
240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return true;
242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> inline
245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonEncodeTable<A> *EncodeTable<A>::Read(istream &strm, const string &source) {
246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int32 magic_number = 0;
247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ReadType(strm, &magic_number);
248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (magic_number != kEncodeMagicNumber) {
249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    LOG(ERROR) << "EncodeTable::Read: Bad encode table header: " << source;
250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return 0;
251f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
252f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint32 flags;
253f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ReadType(strm, &flags);
254f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  EncodeTable<A> *table = new EncodeTable<A>(flags);
255f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 size;
257f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ReadType(strm, &size);
258f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (!strm) {
259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    LOG(ERROR) << "EncodeTable::Read: read failed: " << source;
260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return 0;
261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (size_t i = 0; i < size; ++i) {
264f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Tuple* tuple = new Tuple();
265f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ReadType(strm, &tuple->ilabel);
266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ReadType(strm, &tuple->olabel);
267f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    tuple->weight.Read(strm);
268f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!strm) {
269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      LOG(ERROR) << "EncodeTable::Read: read failed: " << source;
270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return 0;
271f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    table->encode_tuples_.push_back(tuple);
273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    table->encode_hash_[table->encode_tuples_.back()] =
274f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        table->encode_tuples_.size();
275f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
276f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (flags & kEncodeHasISymbols)
278f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    table->isymbols_ = SymbolTable::Read(strm, source);
279f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (flags & kEncodeHasOSymbols)
281f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    table->osymbols_ = SymbolTable::Read(strm, source);
282f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
283f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return table;
284f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
285f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
286f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
287f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// A mapper to encode/decode weighted transducers. Encoding of an
288f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Fst is useful for performing classical determinization or minimization
289f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// on a weighted transducer by treating it as an unweighted acceptor over
290f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// encoded labels.
291f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
292f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The Encode mapper stores the encoding in a local hash table (EncodeTable)
293f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This table is shared (and reference counted) between the encoder and
294f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// decoder. A decoder has read only access to the EncodeTable.
295f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
296f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The EncodeMapper allows on the fly encoding of the machine. As the
297f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// EncodeTable is generated the same table may by used to decode the machine
298f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// on the fly. For example in the following sequence of operations
299f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
300f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//  Encode -> Determinize -> Decode
301f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
302f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// we will use the encoding table generated during the encode step in the
303f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// decode, even though the encoding is not complete.
304f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
305f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> class EncodeMapper {
306f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight Weight;
307f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Label  Label;
308f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
309f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  EncodeMapper(uint32 flags, EncodeType type)
310f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : flags_(flags),
311f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      type_(type),
312f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      table_(new EncodeTable<A>(flags)),
313f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      error_(false) {}
314f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
315f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  EncodeMapper(const EncodeMapper& mapper)
316f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : flags_(mapper.flags_),
317f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        type_(mapper.type_),
318f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        table_(mapper.table_),
319f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        error_(false) {
320f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    table_->IncrRefCount();
321f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
322f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
323f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Copy constructor but setting the type, typically to DECODE
324f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  EncodeMapper(const EncodeMapper& mapper, EncodeType type)
325f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : flags_(mapper.flags_),
326f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        type_(type),
327f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        table_(mapper.table_),
328f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        error_(mapper.error_) {
329f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    table_->IncrRefCount();
330f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
331f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
332f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ~EncodeMapper() {
333f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!table_->DecrRefCount()) delete table_;
334f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
335f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
336f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  A operator()(const A &arc);
337f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
338f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const {
339f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return (type_ == ENCODE && (flags_ & kEncodeWeights)) ?
340f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                   MAP_REQUIRE_SUPERFINAL : MAP_NO_SUPERFINAL;
341f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
342f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
343f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_CLEAR_SYMBOLS; }
344f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
345f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_CLEAR_SYMBOLS;}
346f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
347f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 inprops) {
348f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    uint64 outprops = inprops;
349f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (error_) outprops |= kError;
350f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
351f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    uint64 mask = kFstProperties;
352f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (flags_ & kEncodeLabels)
353f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      mask &= kILabelInvariantProperties & kOLabelInvariantProperties;
354f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (flags_ & kEncodeWeights)
355f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      mask &= kILabelInvariantProperties & kWeightInvariantProperties &
356f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          (type_ == ENCODE ? kAddSuperFinalProperties :
357f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson           kRmSuperFinalProperties);
358f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
359f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return outprops & mask;
360f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
361f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
362f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const uint32 flags() const { return flags_; }
363f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const EncodeType type() const { return type_; }
364f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const EncodeTable<A> &table() const { return *table_; }
365f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
366f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool Write(ostream &strm, const string& source) {
367f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return table_->Write(strm, source);
368f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
369f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
370f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool Write(const string& filename) {
371f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ofstream strm(filename.c_str(), ofstream::out | ofstream::binary);
372f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!strm) {
373f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      LOG(ERROR) << "EncodeMap: Can't open file: " << filename;
374f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return false;
375f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
376f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return Write(strm, filename);
377f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
378f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
379f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static EncodeMapper<A> *Read(istream &strm,
380f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                               const string& source,
381f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                               EncodeType type = ENCODE) {
382f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    EncodeTable<A> *table = EncodeTable<A>::Read(strm, source);
383f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return table ? new EncodeMapper(table->flags(), type, table) : 0;
384f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
385f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
386f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static EncodeMapper<A> *Read(const string& filename,
387f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                               EncodeType type = ENCODE) {
388f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ifstream strm(filename.c_str(), ifstream::in | ifstream::binary);
389f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!strm) {
390f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      LOG(ERROR) << "EncodeMap: Can't open file: " << filename;
391f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return NULL;
392f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
393f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return Read(strm, filename, type);
394f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
395f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
396f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SymbolTable *InputSymbols() const { return table_->InputSymbols(); }
397f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
398f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SymbolTable *OutputSymbols() const { return table_->OutputSymbols(); }
399f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
400f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetInputSymbols(const SymbolTable* syms) {
401f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    table_->SetInputSymbols(syms);
402f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
403f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
404f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetOutputSymbols(const SymbolTable* syms) {
405f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    table_->SetOutputSymbols(syms);
406f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
407f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
408f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
409f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint32 flags_;
410f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  EncodeType type_;
411f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  EncodeTable<A>* table_;
412f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool error_;
413f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
414f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit EncodeMapper(uint32 flags, EncodeType type, EncodeTable<A> *table)
415f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : flags_(flags), type_(type), table_(table) {}
416f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void operator=(const EncodeMapper &);  // Disallow.
417f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
418f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
419f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> inline
420f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonA EncodeMapper<A>::operator()(const A &arc) {
421f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (type_ == ENCODE) {  // labels and/or weights to single label
422f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if ((arc.nextstate == kNoStateId && !(flags_ & kEncodeWeights)) ||
423f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        (arc.nextstate == kNoStateId && (flags_ & kEncodeWeights) &&
424f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         arc.weight == Weight::Zero())) {
425f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return arc;
426f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else {
427f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Label label = table_->Encode(arc);
428f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return A(label,
429f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson               flags_ & kEncodeLabels ? label : arc.olabel,
430f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson               flags_ & kEncodeWeights ? Weight::One() : arc.weight,
431f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson               arc.nextstate);
432f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
433f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  } else {  // type_ == DECODE
434f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.nextstate == kNoStateId) {
435f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return arc;
436f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else {
437f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (arc.ilabel == 0) return arc;
438f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (flags_ & kEncodeLabels && arc.ilabel != arc.olabel) {
439f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        FSTERROR() << "EncodeMapper: Label-encoded arc has different "
440f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            "input and output labels";
441f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        error_ = true;
442f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
443f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (flags_ & kEncodeWeights && arc.weight != Weight::One()) {
444f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        FSTERROR() <<
445f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            "EncodeMapper: Weight-encoded arc has non-trivial weight";
446f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        error_ = true;
447f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
448f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      const typename EncodeTable<A>::Tuple* tuple = table_->Decode(arc.ilabel);
449f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (!tuple) {
450f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        FSTERROR() << "EncodeMapper: decode failed";
451f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        error_ = true;
452f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        return A(kNoLabel, kNoLabel, Weight::NoWeight(), arc.nextstate);
453f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else {
454f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        return A(tuple->ilabel,
455f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 flags_ & kEncodeLabels ? tuple->olabel : arc.olabel,
456f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 flags_ & kEncodeWeights ? tuple->weight : arc.weight,
457f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 arc.nextstate);
458f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
459f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
460f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
461f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
462f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
463f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
464f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Complexity: O(nstates + narcs)
465f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class A> inline
466f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid Encode(MutableFst<A> *fst, EncodeMapper<A>* mapper) {
467f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  mapper->SetInputSymbols(fst->InputSymbols());
468f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  mapper->SetOutputSymbols(fst->OutputSymbols());
469f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMap(fst, mapper);
470f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
471f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
472f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class A> inline
473f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid Decode(MutableFst<A>* fst, const EncodeMapper<A>& mapper) {
474f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMap(fst, EncodeMapper<A>(mapper, DECODE));
475f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RmFinalEpsilon(fst);
476f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  fst->SetInputSymbols(mapper.InputSymbols());
477f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  fst->SetOutputSymbols(mapper.OutputSymbols());
478f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
479f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
480f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
481f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// On the fly label and/or weight encoding of input Fst
482f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
483f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Complexity:
484f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// - Constructor: O(1)
485f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// - Traversal: O(nstates_visited + narcs_visited), assuming constant
486f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   time to visit an input state or arc.
487f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
488f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass EncodeFst : public ArcMapFst<A, A, EncodeMapper<A> > {
489f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
490f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A Arc;
491f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef EncodeMapper<A> C;
492f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef ArcMapFstImpl< A, A, EncodeMapper<A> > Impl;
493f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using ImplToFst<Impl>::GetImpl;
494f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
495f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  EncodeFst(const Fst<A> &fst, EncodeMapper<A>* encoder)
496f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ArcMapFst<A, A, C>(fst, encoder, ArcMapFstOptions()) {
497f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    encoder->SetInputSymbols(fst.InputSymbols());
498f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    encoder->SetOutputSymbols(fst.OutputSymbols());
499f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
500f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
501f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  EncodeFst(const Fst<A> &fst, const EncodeMapper<A>& encoder)
502f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ArcMapFst<A, A, C>(fst, encoder, ArcMapFstOptions()) {}
503f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
504f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // See Fst<>::Copy() for doc.
505f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  EncodeFst(const EncodeFst<A> &fst, bool copy = false)
506f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ArcMapFst<A, A, C>(fst, copy) {}
507f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
508f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Get a copy of this EncodeFst. See Fst<>::Copy() for further doc.
509f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual EncodeFst<A> *Copy(bool safe = false) const {
510f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (safe) {
511f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      FSTERROR() << "EncodeFst::Copy(true): not allowed.";
512f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      GetImpl()->SetProperties(kError, kError);
513f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
514f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return new EncodeFst(*this);
515f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
516f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
517f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
518f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
519f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// On the fly label and/or weight encoding of input Fst
520f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
521f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Complexity:
522f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// - Constructor: O(1)
523f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// - Traversal: O(nstates_visited + narcs_visited), assuming constant
524f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   time to visit an input state or arc.
525f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
526f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass DecodeFst : public ArcMapFst<A, A, EncodeMapper<A> > {
527f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
528f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A Arc;
529f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef EncodeMapper<A> C;
530f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef ArcMapFstImpl< A, A, EncodeMapper<A> > Impl;
531f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using ImplToFst<Impl>::GetImpl;
532f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
533f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DecodeFst(const Fst<A> &fst, const EncodeMapper<A>& encoder)
534f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ArcMapFst<A, A, C>(fst,
535f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                            EncodeMapper<A>(encoder, DECODE),
536f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                            ArcMapFstOptions()) {
537f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    GetImpl()->SetInputSymbols(encoder.InputSymbols());
538f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    GetImpl()->SetOutputSymbols(encoder.OutputSymbols());
539f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
540f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
541f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // See Fst<>::Copy() for doc.
542f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DecodeFst(const DecodeFst<A> &fst, bool safe = false)
543f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ArcMapFst<A, A, C>(fst, safe) {}
544f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
545f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Get a copy of this DecodeFst. See Fst<>::Copy() for further doc.
546f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual DecodeFst<A> *Copy(bool safe = false) const {
547f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return new DecodeFst(*this, safe);
548f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
549f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
550f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
551f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
552f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for EncodeFst.
553f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
554f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass StateIterator< EncodeFst<A> >
555f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : public StateIterator< ArcMapFst<A, A, EncodeMapper<A> > > {
556f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
557f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit StateIterator(const EncodeFst<A> &fst)
558f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : StateIterator< ArcMapFst<A, A, EncodeMapper<A> > >(fst) {}
559f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
560f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
561f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
562f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for EncodeFst.
563f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
564f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass ArcIterator< EncodeFst<A> >
565f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : public ArcIterator< ArcMapFst<A, A, EncodeMapper<A> > > {
566f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
567f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcIterator(const EncodeFst<A> &fst, typename A::StateId s)
568f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ArcIterator< ArcMapFst<A, A, EncodeMapper<A> > >(fst, s) {}
569f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
570f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
571f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
572f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for DecodeFst.
573f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
574f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass StateIterator< DecodeFst<A> >
575f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : public StateIterator< ArcMapFst<A, A, EncodeMapper<A> > > {
576f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
577f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit StateIterator(const DecodeFst<A> &fst)
578f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : StateIterator< ArcMapFst<A, A, EncodeMapper<A> > >(fst) {}
579f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
580f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
581f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
582f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for DecodeFst.
583f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
584f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass ArcIterator< DecodeFst<A> >
585f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : public ArcIterator< ArcMapFst<A, A, EncodeMapper<A> > > {
586f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
587f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcIterator(const DecodeFst<A> &fst, typename A::StateId s)
588f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ArcIterator< ArcMapFst<A, A, EncodeMapper<A> > >(fst, s) {}
589f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
590f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
591f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
592f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Useful aliases when using StdArc.
593f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef EncodeFst<StdArc> StdEncodeFst;
594f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
595f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef DecodeFst<StdArc> StdDecodeFst;
596f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
597f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}  // namespace fst
598f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
599f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif  // FST_LIB_ENCODE_H__
600