1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// relabel.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// Functions and classes to relabel an Fst (either on input or output)
20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_RELABEL_H__
22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_RELABEL_H__
23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
243da1eb108d36da35333b2d655202791af854996bPrzemyslaw Szczepaniak#include <tr1/unordered_map>
25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_map;
26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_multimap;
27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <string>
28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <utility>
29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::pair; using std::make_pair;
30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <vector>
31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::vector;
32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/cache.h>
34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/test-properties.h>
35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
375b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin#include <tr1/unordered_map>
385b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkinusing std::tr1::unordered_map;
395b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkinusing std::tr1::unordered_multimap;
405b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin
41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst {
42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Relabels either the input labels or output labels. The old to
45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// new labels are specified using a vector of pair<Label,Label>.
46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Any label associations not specified are assumed to be identity
47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// mapping.
48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \param fst input fst, must be mutable
50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \param ipairs vector of input label pairs indicating old to new mapping
51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \param opairs vector of output label pairs indicating old to new mapping
52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid Relabel(
55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    MutableFst<A> *fst,
56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    const vector<pair<typename A::Label, typename A::Label> >& ipairs,
57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    const vector<pair<typename A::Label, typename A::Label> >& opairs) {
58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Label   Label;
60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 props = fst->Properties(kFstProperties, false);
62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // construct label to label hash.
64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  unordered_map<Label, Label> input_map;
65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (size_t i = 0; i < ipairs.size(); ++i) {
66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    input_map[ipairs[i].first] = ipairs[i].second;
67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  unordered_map<Label, Label> output_map;
70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (size_t i = 0; i < opairs.size(); ++i) {
71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    output_map[opairs[i].first] = opairs[i].second;
72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (StateIterator<MutableFst<A> > siter(*fst);
75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson       !siter.Done(); siter.Next()) {
76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    StateId s = siter.Value();
77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (MutableArcIterator<MutableFst<A> > aiter(fst, s);
78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         !aiter.Done(); aiter.Next()) {
79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      A arc = aiter.Value();
80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      // relabel input
82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      // only relabel if relabel pair defined
83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      typename unordered_map<Label, Label>::iterator it =
84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        input_map.find(arc.ilabel);
85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (it != input_map.end()) {
86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (it->second == kNoLabel) {
87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          FSTERROR() << "Input symbol id " << arc.ilabel
88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                     << " missing from target vocabulary";
89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          fst->SetProperties(kError, kError);
90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          return;
91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        arc.ilabel = it->second;
93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      // relabel output
96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      it = output_map.find(arc.olabel);
97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (it != output_map.end()) {
98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (it->second == kNoLabel) {
99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          FSTERROR() << "Output symbol id " << arc.olabel
100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                     << " missing from target vocabulary";
101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          fst->SetProperties(kError, kError);
102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          return;
103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        arc.olabel = it->second;
105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      aiter.SetValue(arc);
108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  fst->SetProperties(RelabelProperties(props), kFstProperties);
112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Relabels either the input labels or output labels. The old to
116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// new labels mappings are specified using an input Symbol set.
117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Any label associations not specified are assumed to be identity
118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// mapping.
119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \param fst input fst, must be mutable
121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \param new_isymbols symbol set indicating new mapping of input symbols
122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \param new_osymbols symbol set indicating new mapping of output symbols
123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class A>
125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid Relabel(MutableFst<A> *fst,
126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_isymbols,
127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_osymbols) {
128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Relabel(fst,
129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          fst->InputSymbols(), new_isymbols, true,
130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          fst->OutputSymbols(), new_osymbols, true);
131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class A>
134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid Relabel(MutableFst<A> *fst,
135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* old_isymbols,
136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_isymbols,
137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             bool attach_new_isymbols,
138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* old_osymbols,
139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_osymbols,
140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             bool attach_new_osymbols) {
141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Label   Label;
143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  vector<pair<Label, Label> > ipairs;
145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (old_isymbols && new_isymbols) {
146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (SymbolTableIterator syms_iter(*old_isymbols); !syms_iter.Done();
147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         syms_iter.Next()) {
148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      string isymbol = syms_iter.Symbol();
149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      int isymbol_val = syms_iter.Value();
150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      int new_isymbol_val = new_isymbols->Find(isymbol);
151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ipairs.push_back(make_pair(isymbol_val, new_isymbol_val));
152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (attach_new_isymbols)
154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      fst->SetInputSymbols(new_isymbols);
155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  vector<pair<Label, Label> > opairs;
158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (old_osymbols && new_osymbols) {
159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (SymbolTableIterator syms_iter(*old_osymbols); !syms_iter.Done();
160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         syms_iter.Next()) {
161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      string osymbol = syms_iter.Symbol();
162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      int osymbol_val = syms_iter.Value();
163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      int new_osymbol_val = new_osymbols->Find(osymbol);
164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      opairs.push_back(make_pair(osymbol_val, new_osymbol_val));
165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (attach_new_osymbols)
167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      fst->SetOutputSymbols(new_osymbols);
168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // call relabel using vector of relabel pairs.
171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Relabel(fst, ipairs, opairs);
172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef CacheOptions RelabelFstOptions;
176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> class RelabelFst;
178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \class RelabelFstImpl
181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \brief Implementation for delayed relabeling
182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Relabels an FST from one symbol set to another. Relabeling
184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// can either be on input or output space. RelabelFst implements
185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// a delayed version of the relabel. Arcs are relabeled on the fly
186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// and not cached. I.e each request is recomputed.
187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class A>
189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass RelabelFstImpl : public CacheImpl<A> {
190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  friend class StateIterator< RelabelFst<A> >;
191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<A>::SetType;
193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<A>::SetProperties;
194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<A>::WriteHeader;
195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<A>::SetInputSymbols;
196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<A>::SetOutputSymbols;
197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<A>::PushArc;
199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<A>::HasArcs;
200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<A>::HasFinal;
201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<A>::HasStart;
202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<A>::SetArcs;
203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<A>::SetFinal;
204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<A>::SetStart;
205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A Arc;
207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Label   Label;
208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight  Weight;
209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef CacheState<A> State;
211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RelabelFstImpl(const Fst<A>& fst,
213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 const vector<pair<Label, Label> >& ipairs,
214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 const vector<pair<Label, Label> >& opairs,
215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 const RelabelFstOptions &opts)
216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : CacheImpl<A>(opts), fst_(fst.Copy()),
217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        relabel_input_(false), relabel_output_(false) {
218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    uint64 props = fst.Properties(kCopyProperties, false);
219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(RelabelProperties(props));
220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetType("relabel");
221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // create input label map
223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (ipairs.size() > 0) {
224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      for (size_t i = 0; i < ipairs.size(); ++i) {
225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        input_map_[ipairs[i].first] = ipairs[i].second;
226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      relabel_input_ = true;
228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // create output label map
231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (opairs.size() > 0) {
232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      for (size_t i = 0; i < opairs.size(); ++i) {
233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        output_map_[opairs[i].first] = opairs[i].second;
234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      relabel_output_ = true;
236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RelabelFstImpl(const Fst<A>& fst,
240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 const SymbolTable* old_isymbols,
241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 const SymbolTable* new_isymbols,
242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 const SymbolTable* old_osymbols,
243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 const SymbolTable* new_osymbols,
244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 const RelabelFstOptions &opts)
245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : CacheImpl<A>(opts), fst_(fst.Copy()),
246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        relabel_input_(false), relabel_output_(false) {
247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetType("relabel");
248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    uint64 props = fst.Properties(kCopyProperties, false);
250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(RelabelProperties(props));
251f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetInputSymbols(old_isymbols);
252f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetOutputSymbols(old_osymbols);
253f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
254f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (old_isymbols && new_isymbols &&
255f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        old_isymbols->LabeledCheckSum() != new_isymbols->LabeledCheckSum()) {
256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      for (SymbolTableIterator syms_iter(*old_isymbols); !syms_iter.Done();
257f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson           syms_iter.Next()) {
258f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        input_map_[syms_iter.Value()] = new_isymbols->Find(syms_iter.Symbol());
259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetInputSymbols(new_isymbols);
261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      relabel_input_ = true;
262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
264f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (old_osymbols && new_osymbols &&
265f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        old_osymbols->LabeledCheckSum() != new_osymbols->LabeledCheckSum()) {
266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      for (SymbolTableIterator syms_iter(*old_osymbols); !syms_iter.Done();
267f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson           syms_iter.Next()) {
268f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        output_map_[syms_iter.Value()] =
269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          new_osymbols->Find(syms_iter.Symbol());
270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
271f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetOutputSymbols(new_osymbols);
272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      relabel_output_ = true;
273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
274f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
275f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
276f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RelabelFstImpl(const RelabelFstImpl<A>& impl)
277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : CacheImpl<A>(impl),
278f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        fst_(impl.fst_->Copy(true)),
279f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        input_map_(impl.input_map_),
280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        output_map_(impl.output_map_),
281f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        relabel_input_(impl.relabel_input_),
282f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        relabel_output_(impl.relabel_output_) {
283f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetType("relabel");
284f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(impl.Properties(), kCopyProperties);
285f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetInputSymbols(impl.InputSymbols());
286f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetOutputSymbols(impl.OutputSymbols());
287f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
288f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
289f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ~RelabelFstImpl() { delete fst_; }
290f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
291f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId Start() {
292f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasStart()) {
293f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      StateId s = fst_->Start();
294f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetStart(s);
295f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
296f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return CacheImpl<A>::Start();
297f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
298f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
299f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight Final(StateId s) {
300f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasFinal(s)) {
301f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetFinal(s, fst_->Final(s));
302f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
303f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return CacheImpl<A>::Final(s);
304f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
305f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
306f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t NumArcs(StateId s) {
307f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasArcs(s)) {
308f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Expand(s);
309f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
310f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return CacheImpl<A>::NumArcs(s);
311f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
312f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
313f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t NumInputEpsilons(StateId s) {
314f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasArcs(s)) {
315f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Expand(s);
316f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
317f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return CacheImpl<A>::NumInputEpsilons(s);
318f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
319f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
320f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t NumOutputEpsilons(StateId s) {
321f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasArcs(s)) {
322f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Expand(s);
323f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
324f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return CacheImpl<A>::NumOutputEpsilons(s);
325f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
326f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
327f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties() const { return Properties(kFstProperties); }
328f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
329f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Set error if found; return FST impl properties.
330f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 mask) const {
331f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if ((mask & kError) && fst_->Properties(kError, false))
332f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetProperties(kError, kError);
333f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return FstImpl<Arc>::Properties(mask);
334f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
335f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
336f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void InitArcIterator(StateId s, ArcIteratorData<A>* data) {
337f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasArcs(s)) {
338f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Expand(s);
339f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
340f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CacheImpl<A>::InitArcIterator(s, data);
341f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
342f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
343f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Expand(StateId s) {
344f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (ArcIterator<Fst<A> > aiter(*fst_, s); !aiter.Done(); aiter.Next()) {
345f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      A arc = aiter.Value();
346f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
347f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      // relabel input
348f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (relabel_input_) {
349f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        typename unordered_map<Label, Label>::iterator it =
350f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          input_map_.find(arc.ilabel);
351f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (it != input_map_.end()) { arc.ilabel = it->second; }
352f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
353f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
354f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      // relabel output
355f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (relabel_output_) {
356f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        typename unordered_map<Label, Label>::iterator it =
357f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          output_map_.find(arc.olabel);
358f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (it != output_map_.end()) { arc.olabel = it->second; }
359f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
360f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
361f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      PushArc(s, arc);
362f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
363f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetArcs(s);
364f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
365f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
366f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
367f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
368f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const Fst<A> *fst_;
369f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
370f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  unordered_map<Label, Label> input_map_;
371f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  unordered_map<Label, Label> output_map_;
372f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool relabel_input_;
373f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool relabel_output_;
374f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
375f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void operator=(const RelabelFstImpl<A> &);  // disallow
376f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
377f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
378f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
379f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
380f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \class RelabelFst
381f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \brief Delayed implementation of arc relabeling
382f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
383f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This class attaches interface to implementation and handles
384f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// reference counting, delegating most methods to ImplToFst.
385f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
386f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass RelabelFst : public ImplToFst< RelabelFstImpl<A> > {
387f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
388f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  friend class ArcIterator< RelabelFst<A> >;
389f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  friend class StateIterator< RelabelFst<A> >;
390f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
391f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A Arc;
392f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Label   Label;
393f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight  Weight;
394f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
395f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef CacheState<A> State;
396f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef RelabelFstImpl<A> Impl;
397f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
398f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RelabelFst(const Fst<A>& fst,
399f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const vector<pair<Label, Label> >& ipairs,
400f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const vector<pair<Label, Label> >& opairs)
401f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ImplToFst<Impl>(new Impl(fst, ipairs, opairs, RelabelFstOptions())) {}
402f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
403f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RelabelFst(const Fst<A>& fst,
404f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const vector<pair<Label, Label> >& ipairs,
405f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const vector<pair<Label, Label> >& opairs,
406f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const RelabelFstOptions &opts)
407f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ImplToFst<Impl>(new Impl(fst, ipairs, opairs, opts)) {}
408f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
409f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RelabelFst(const Fst<A>& fst,
410f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_isymbols,
411f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_osymbols)
412f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ImplToFst<Impl>(new Impl(fst, fst.InputSymbols(), new_isymbols,
413f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                                 fst.OutputSymbols(), new_osymbols,
414f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                                 RelabelFstOptions())) {}
415f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
416f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RelabelFst(const Fst<A>& fst,
417f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_isymbols,
418f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_osymbols,
419f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const RelabelFstOptions &opts)
420f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ImplToFst<Impl>(new Impl(fst, fst.InputSymbols(), new_isymbols,
421f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                                 fst.OutputSymbols(), new_osymbols, opts)) {}
422f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
423f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RelabelFst(const Fst<A>& fst,
424f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* old_isymbols,
425f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_isymbols,
426f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* old_osymbols,
427f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_osymbols)
428f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : ImplToFst<Impl>(new Impl(fst, old_isymbols, new_isymbols, old_osymbols,
429f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                               new_osymbols, RelabelFstOptions())) {}
430f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
431f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RelabelFst(const Fst<A>& fst,
432f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* old_isymbols,
433f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_isymbols,
434f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* old_osymbols,
435f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const SymbolTable* new_osymbols,
436f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson             const RelabelFstOptions &opts)
437f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : ImplToFst<Impl>(new Impl(fst, old_isymbols, new_isymbols, old_osymbols,
438f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                               new_osymbols, opts)) {}
439f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
440f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // See Fst<>::Copy() for doc.
441f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  RelabelFst(const RelabelFst<A> &fst, bool safe = false)
442f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : ImplToFst<Impl>(fst, safe) {}
443f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
444f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Get a copy of this RelabelFst. See Fst<>::Copy() for further doc.
445f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual RelabelFst<A> *Copy(bool safe = false) const {
446f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return new RelabelFst<A>(*this, safe);
447f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
448f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
449f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual void InitStateIterator(StateIteratorData<A> *data) const;
450f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
451f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual void InitArcIterator(StateId s, ArcIteratorData<A> *data) const {
452f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return GetImpl()->InitArcIterator(s, data);
453f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
454f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
455f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
456f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Makes visible to friends.
457f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Impl *GetImpl() const { return ImplToFst<Impl>::GetImpl(); }
458f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
459f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void operator=(const RelabelFst<A> &fst);  // disallow
460f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
461f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
462f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for RelabelFst.
463f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class A>
464f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass StateIterator< RelabelFst<A> > : public StateIteratorBase<A> {
465f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
466f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
467f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
468f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit StateIterator(const RelabelFst<A> &fst)
469f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : impl_(fst.GetImpl()), siter_(*impl_->fst_), s_(0) {}
470f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
471f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool Done() const { return siter_.Done(); }
472f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
473f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId Value() const { return s_; }
474f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
475f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Next() {
476f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!siter_.Done()) {
477f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ++s_;
478f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      siter_.Next();
479f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
480f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
481f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
482f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Reset() {
483f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    s_ = 0;
484f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    siter_.Reset();
485f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
486f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
487f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
488f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool Done_() const { return Done(); }
489f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId Value_() const { return Value(); }
490f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Next_() { Next(); }
491f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Reset_() { Reset(); }
492f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
493f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const RelabelFstImpl<A> *impl_;
494f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateIterator< Fst<A> > siter_;
495f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId s_;
496f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
497f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(StateIterator);
498f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
499f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
500f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
501f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for RelabelFst.
502f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
503f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass ArcIterator< RelabelFst<A> >
504f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : public CacheArcIterator< RelabelFst<A> > {
505f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
506f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
507f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
508f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcIterator(const RelabelFst<A> &fst, StateId s)
509f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : CacheArcIterator< RelabelFst<A> >(fst.GetImpl(), s) {
510f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!fst.GetImpl()->HasArcs(s))
511f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      fst.GetImpl()->Expand(s);
512f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
513f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
514f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
515f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(ArcIterator);
516f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
517f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
518f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> inline
519f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid RelabelFst<A>::InitStateIterator(StateIteratorData<A> *data) const {
520f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  data->base = new StateIterator< RelabelFst<A> >(*this);
521f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
522f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
523f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Useful alias when using StdArc.
524f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef RelabelFst<StdArc> StdRelabelFst;
525f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
526f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}  // namespace fst
527f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
528f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif  // FST_LIB_RELABEL_H__
529