14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// relabel.h
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Licensed under the Apache License, Version 2.0 (the "License");
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// you may not use this file except in compliance with the License.
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// You may obtain a copy of the License at
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//      http://www.apache.org/licenses/LICENSE-2.0
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Unless required by applicable law or agreed to in writing, software
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// distributed under the License is distributed on an "AS IS" BASIS,
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// See the License for the specific language governing permissions and
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// limitations under the License.
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \file
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Functions and classes to relabel an Fst (either on input or output)
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef FST_LIB_RELABEL_H__
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define FST_LIB_RELABEL_H__
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2273018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers#include <unordered_map>
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/cache.h"
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/test-properties.h"
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectnamespace fst {
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Relabels either the input labels or output labels. The old to
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// new labels are specified using a vector of pair<Label,Label>.
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Any label associations not specified are assumed to be identity
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// mapping.
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \param fst input fst, must be mutable
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \param relabel_pairs vector of pairs indicating old to new mapping
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \param relabel_flags whether to relabel input or output
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid Relabel(
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutableFst<A> *fst,
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const vector<pair<typename A::Label, typename A::Label> >& ipairs,
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const vector<pair<typename A::Label, typename A::Label> >& opairs) {
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Label   Label;
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  uint64 props = fst->Properties(kFstProperties, false);
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // construct label to label hash. Could
5173018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers  std::unordered_map<Label, Label> input_map;
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (size_t i = 0; i < ipairs.size(); ++i) {
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    input_map[ipairs[i].first] = ipairs[i].second;
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5673018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers  std::unordered_map<Label, Label> output_map;
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (size_t i = 0; i < opairs.size(); ++i) {
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    output_map[opairs[i].first] = opairs[i].second;
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (StateIterator<MutableFst<A> > siter(*fst);
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       !siter.Done(); siter.Next()) {
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    StateId s = siter.Value();
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (MutableArcIterator<MutableFst<A> > aiter(fst, s);
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         !aiter.Done(); aiter.Next()) {
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      A arc = aiter.Value();
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      // relabel input
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      // only relabel if relabel pair defined
7073018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers      typename std::unordered_map<Label, Label>::iterator it =
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        input_map.find(arc.ilabel);
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (it != input_map.end()) {arc.ilabel = it->second; }
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      // relabel output
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      it = output_map.find(arc.olabel);
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (it != output_map.end()) { arc.olabel = it->second; }
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      aiter.SetValue(arc);
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  fst->SetProperties(RelabelProperties(props), kFstProperties);
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Relabels either the input labels or output labels. The old to
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// new labels mappings are specified using an input Symbol set.
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Any label associations not specified are assumed to be identity
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// mapping.
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \param fst input fst, must be mutable
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \param new_symbols symbol set indicating new mapping
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \param relabel_flags whether to relabel input or output
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class A>
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid Relabel(MutableFst<A> *fst,
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const SymbolTable* new_isymbols,
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const SymbolTable* new_osymbols) {
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Label   Label;
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const SymbolTable* old_isymbols = fst->InputSymbols();
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const SymbolTable* old_osymbols = fst->OutputSymbols();
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  vector<pair<Label, Label> > ipairs;
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (old_isymbols && new_isymbols) {
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (SymbolTableIterator syms_iter(*old_isymbols); !syms_iter.Done();
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         syms_iter.Next()) {
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ipairs.push_back(make_pair(syms_iter.Value(),
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                 new_isymbols->Find(syms_iter.Symbol())));
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    fst->SetInputSymbols(new_isymbols);
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  vector<pair<Label, Label> > opairs;
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (old_osymbols && new_osymbols) {
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (SymbolTableIterator syms_iter(*old_osymbols); !syms_iter.Done();
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         syms_iter.Next()) {
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      opairs.push_back(make_pair(syms_iter.Value(),
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                 new_osymbols->Find(syms_iter.Symbol())));
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    fst->SetOutputSymbols(new_osymbols);
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // call relabel using vector of relabel pairs.
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Relabel(fst, ipairs, opairs);
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef CacheOptions RelabelFstOptions;
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A> class RelabelFst;
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \class RelabelFstImpl
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \brief Implementation for delayed relabeling
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Relabels an FST from one symbol set to another. Relabeling
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// can either be on input or output space. RelabelFst implements
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// a delayed version of the relabel. Arcs are relabeled on the fly
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// and not cached. I.e each request is recomputed.
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class A>
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass RelabelFstImpl : public CacheImpl<A> {
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  friend class StateIterator< RelabelFst<A> >;
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::SetType;
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::SetProperties;
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::Properties;
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::SetInputSymbols;
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::SetOutputSymbols;
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using CacheImpl<A>::HasStart;
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using CacheImpl<A>::HasArcs;
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Label   Label;
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Weight  Weight;
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef CacheState<A> State;
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  RelabelFstImpl(const Fst<A>& fst,
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 const vector<pair<Label, Label> >& ipairs,
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 const vector<pair<Label, Label> >& opairs,
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 const RelabelFstOptions &opts)
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : CacheImpl<A>(opts), fst_(fst.Copy()),
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        relabel_input_(false), relabel_output_(false) {
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    uint64 props = fst.Properties(kCopyProperties, false);
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(RelabelProperties(props));
1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetType("relabel");
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // create input label map
1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (ipairs.size() > 0) {
1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      for (size_t i = 0; i < ipairs.size(); ++i) {
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        input_map_[ipairs[i].first] = ipairs[i].second;
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      relabel_input_ = true;
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // create output label map
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (opairs.size() > 0) {
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      for (size_t i = 0; i < opairs.size(); ++i) {
1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        output_map_[opairs[i].first] = opairs[i].second;
1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      relabel_output_ = true;
1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  RelabelFstImpl(const Fst<A>& fst,
1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 const SymbolTable* new_isymbols,
1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 const SymbolTable* new_osymbols,
1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 const RelabelFstOptions &opts)
1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : CacheImpl<A>(opts), fst_(fst.Copy()),
1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        relabel_input_(false), relabel_output_(false) {
1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetType("relabel");
1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    uint64 props = fst.Properties(kCopyProperties, false);
1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(RelabelProperties(props));
2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetInputSymbols(fst.InputSymbols());
2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetOutputSymbols(fst.OutputSymbols());
2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const SymbolTable* old_isymbols = fst.InputSymbols();
2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const SymbolTable* old_osymbols = fst.OutputSymbols();
2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (old_isymbols && new_isymbols &&
2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        old_isymbols->CheckSum() != new_isymbols->CheckSum()) {
2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      for (SymbolTableIterator syms_iter(*old_isymbols); !syms_iter.Done();
2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project           syms_iter.Next()) {
2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        input_map_[syms_iter.Value()] = new_isymbols->Find(syms_iter.Symbol());
2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetInputSymbols(new_isymbols);
2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      relabel_input_ = true;
2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (old_osymbols && new_osymbols &&
2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        old_osymbols->CheckSum() != new_osymbols->CheckSum()) {
2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      for (SymbolTableIterator syms_iter(*old_osymbols); !syms_iter.Done();
2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project           syms_iter.Next()) {
2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        output_map_[syms_iter.Value()] =
2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          new_osymbols->Find(syms_iter.Symbol());
2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetOutputSymbols(new_osymbols);
2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      relabel_output_ = true;
2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ~RelabelFstImpl() { delete fst_; }
2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId Start() {
2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!HasStart()) {
2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      StateId s = fst_->Start();
2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetStart(s);
2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return CacheImpl<A>::Start();
2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Weight Final(StateId s) {
2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!HasFinal(s)) {
2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetFinal(s, fst_->Final(s));
2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return CacheImpl<A>::Final(s);
2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t NumArcs(StateId s) {
2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!HasArcs(s)) {
2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      Expand(s);
2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return CacheImpl<A>::NumArcs(s);
2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t NumInputEpsilons(StateId s) {
2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!HasArcs(s)) {
2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      Expand(s);
2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return CacheImpl<A>::NumInputEpsilons(s);
2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t NumOutputEpsilons(StateId s) {
2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!HasArcs(s)) {
2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      Expand(s);
2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return CacheImpl<A>::NumOutputEpsilons(s);
2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void InitArcIterator(StateId s, ArcIteratorData<A>* data) {
2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!HasArcs(s)) {
2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      Expand(s);
2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    CacheImpl<A>::InitArcIterator(s, data);
2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Expand(StateId s) {
2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ArcIterator<Fst<A> > aiter(*fst_, s); !aiter.Done(); aiter.Next()) {
2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      A arc = aiter.Value();
2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      // relabel input
2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (relabel_input_) {
27973018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers        typename std::unordered_map<Label, Label>::iterator it =
2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          input_map_.find(arc.ilabel);
2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (it != input_map_.end()) { arc.ilabel = it->second; }
2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      // relabel output
2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (relabel_output_) {
28673018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers        typename std::unordered_map<Label, Label>::iterator it =
2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          output_map_.find(arc.olabel);
2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (it != output_map_.end()) { arc.olabel = it->second; }
2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      AddArc(s, arc);
2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetArcs(s);
2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const Fst<A> *fst_;
2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
30073018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers  std::unordered_map<Label, Label> input_map_;
30173018b4a1d088cdda0e7bd059fddf1f308a8195aIan Rogers  std::unordered_map<Label, Label> output_map_;
3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool relabel_input_;
3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool relabel_output_;
3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(RelabelFstImpl);
3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \class RelabelFst
3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \brief Delayed implementation of arc relabeling
3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// This class attaches interface to implementation and handles
3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// reference counting.
3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass RelabelFst : public Fst<A> {
3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  friend class ArcIterator< RelabelFst<A> >;
3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  friend class StateIterator< RelabelFst<A> >;
3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  friend class CacheArcIterator< RelabelFst<A> >;
3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef A Arc;
3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Label   Label;
3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Weight  Weight;
3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef CacheState<A> State;
3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  RelabelFst(const Fst<A>& fst,
3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const vector<pair<Label, Label> >& ipairs,
3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const vector<pair<Label, Label> >& opairs) :
3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      impl_(new RelabelFstImpl<A>(fst, ipairs, opairs, RelabelFstOptions())) {}
3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  RelabelFst(const Fst<A>& fst,
3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const vector<pair<Label, Label> >& ipairs,
3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const vector<pair<Label, Label> >& opairs,
3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const RelabelFstOptions &opts)
3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : impl_(new RelabelFstImpl<A>(fst, ipairs, opairs, opts)) {}
3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  RelabelFst(const Fst<A>& fst,
3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const SymbolTable* new_isymbols,
3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const SymbolTable* new_osymbols) :
3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      impl_(new RelabelFstImpl<A>(fst, new_isymbols, new_osymbols,
3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                  RelabelFstOptions())) {}
3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  RelabelFst(const Fst<A>& fst,
3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const SymbolTable* new_isymbols,
3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const SymbolTable* new_osymbols,
3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             const RelabelFstOptions &opts)
3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : impl_(new RelabelFstImpl<A>(fst, new_isymbols, new_osymbols, opts)) {}
3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  RelabelFst(const RelabelFst<A> &fst) : impl_(fst.impl_) {
3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->IncrRefCount();
3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual ~RelabelFst() { if (!impl_->DecrRefCount()) delete impl_;  }
3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual StateId Start() const { return impl_->Start(); }
3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual Weight Final(StateId s) const { return impl_->Final(s); }
3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual size_t NumArcs(StateId s) const { return impl_->NumArcs(s); }
3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual size_t NumInputEpsilons(StateId s) const {
3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->NumInputEpsilons(s);
3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual size_t NumOutputEpsilons(StateId s) const {
3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->NumOutputEpsilons(s);
3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual uint64 Properties(uint64 mask, bool test) const {
3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (test) {
3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      uint64 known, test = TestProperties(*this, mask, &known);
3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      impl_->SetProperties(test, known);
3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return test & mask;
3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    } else {
3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return impl_->Properties(mask);
3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual const string& Type() const { return impl_->Type(); }
3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual RelabelFst<A> *Copy() const {
3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return new RelabelFst<A>(*this);
3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual const SymbolTable* InputSymbols() const {
3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->InputSymbols();
3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual const SymbolTable* OutputSymbols() const {
3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->OutputSymbols();
3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void InitStateIterator(StateIteratorData<A> *data) const;
3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void InitArcIterator(StateId s, ArcIteratorData<A> *data) const {
3984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->InitArcIterator(s, data);
3994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
4024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  RelabelFstImpl<A> *impl_;
4034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void operator=(const RelabelFst<A> &fst);  // disallow
4054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
4064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Specialization for RelabelFst.
4084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class A>
4094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass StateIterator< RelabelFst<A> > : public StateIteratorBase<A> {
4104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
4114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
4124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit StateIterator(const RelabelFst<A> &fst)
4144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : impl_(fst.impl_), siter_(*impl_->fst_), s_(0) {}
4154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool Done() const { return siter_.Done(); }
4174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId Value() const { return s_; }
4194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Next() {
4214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!siter_.Done()) {
4224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ++s_;
4234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      siter_.Next();
4244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
4254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Reset() {
4284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    s_ = 0;
4294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    siter_.Reset();
4304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
4334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const RelabelFstImpl<A> *impl_;
4344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateIterator< Fst<A> > siter_;
4354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId s_;
4364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(StateIterator);
4384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
4394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Specialization for RelabelFst.
4424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
4434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass ArcIterator< RelabelFst<A> >
4444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : public CacheArcIterator< RelabelFst<A> > {
4454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
4464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
4474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ArcIterator(const RelabelFst<A> &fst, StateId s)
4494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : CacheArcIterator< RelabelFst<A> >(fst, s) {
4504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!fst.impl_->HasArcs(s))
4514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      fst.impl_->Expand(s);
4524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
4554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(ArcIterator);
4564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
4574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A> inline
4594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid RelabelFst<A>::InitStateIterator(StateIteratorData<A> *data) const {
4604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  data->base = new StateIterator< RelabelFst<A> >(*this);
4614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Useful alias when using StdArc.
4644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef RelabelFst<StdArc> StdRelabelFst;
4654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}  // namespace fst
4674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif  // FST_LIB_RELABEL_H__
469