1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// arc-map.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: riley@google.com (Michael Riley)
17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \file
19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Class to map over/transform arcs e.g., change semirings or
20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// implement project/invert. Consider using when operation does
21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// not change the number of arcs (except possibly superfinal arcs).
22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_ARC_MAP_H__
24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_ARC_MAP_H__
25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
263da1eb108d36da35333b2d655202791af854996bPrzemyslaw Szczepaniak#include <tr1/unordered_map>
27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_map;
28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_multimap;
29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <string>
30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <utility>
31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::pair; using std::make_pair;
32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/cache.h>
34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/mutable-fst.h>
35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst {
38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This determines how final weights are mapped.
40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonenum MapFinalAction {
41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // A final weight is mapped into a final weight. An error
42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // is raised if this is not possible.
43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MAP_NO_SUPERFINAL,
44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // A final weight is mapped to an arc to the superfinal state
46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // when the result cannot be represented as a final weight.
47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // The superfinal state will be added only if it is needed.
48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MAP_ALLOW_SUPERFINAL,
49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // A final weight is mapped to an arc to the superfinal state
51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // unless the result can be represented as a final weight of weight
52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Zero(). The superfinal state is always added (if the input is
53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // not the empty Fst).
54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MAP_REQUIRE_SUPERFINAL
55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This determines how symbol tables are mapped.
58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonenum MapSymbolsAction {
59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Symbols should be cleared in the result by the map.
60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MAP_CLEAR_SYMBOLS,
61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Symbols should be copied from the input FST by the map.
63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MAP_COPY_SYMBOLS,
64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Symbols should not be modified in the result by the map itself.
66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // (They may set by the mapper).
67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MAP_NOOP_SYMBOLS
68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// ArcMapper Interface - class determinies how arcs and final weights
71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// are mapped. Useful for implementing operations that do not change
72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// the number of arcs (expect possibly superfinal arcs).
73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// class ArcMapper {
75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//  public:
76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   typedef A FromArc;
77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   typedef B ToArc;
78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   // Maps an arc type A to arc type B.
80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   B operator()(const A &arc);
81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   // Specifies final action the mapper requires (see above).
82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   // The mapper will be passed final weights as arcs of the
83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   // form A(0, 0, weight, kNoStateId).
84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   MapFinalAction FinalAction() const;
85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   // Specifies input symbol table action the mapper requires (see above).
86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   MapSymbolsAction InputSymbolsAction() const;
87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   // Specifies output symbol table action the mapper requires (see above).
88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   MapSymbolsAction OutputSymbolsAction() const;
89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   // This specifies the known properties of an Fst mapped by this
90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   // mapper. It takes as argument the input Fst's known properties.
91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//   uint64 Properties(uint64 props) const;
92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// };
93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The ArcMap functions and classes below will use the FinalAction()
95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// method of the mapper to determine how to treat final weights,
96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// e.g. whether to add a superfinal state. They will use the Properties()
97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// method to set the result Fst properties.
98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// We include a various map versions below. One dimension of
100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// variation is whether the mapping mutates its input, writes to a
101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// new result Fst, or is an on-the-fly Fst. Another dimension is how
102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// we pass the mapper. We allow passing the mapper by pointer
103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// for cases that we need to change the state of the user's mapper.
104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This is the case with the encode mapper, which is reused during
105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// decoding. We also include map versions that pass the mapper
106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// by value or const reference when this suffices.
107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Maps an arc type A using a mapper function object C, passed
110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// by pointer.  This version modifies its Fst input.
111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class A, class C>
112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid ArcMap(MutableFst<A> *fst, C* mapper) {
113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight Weight;
115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (mapper->InputSymbolsAction() == MAP_CLEAR_SYMBOLS)
117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    fst->SetInputSymbols(0);
118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (mapper->OutputSymbolsAction() == MAP_CLEAR_SYMBOLS)
120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    fst->SetOutputSymbols(0);
121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (fst->Start() == kNoStateId)
123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return;
124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 props = fst->Properties(kFstProperties, false);
126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction final_action = mapper->FinalAction();
128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId superfinal = kNoStateId;
129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (final_action == MAP_REQUIRE_SUPERFINAL) {
130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    superfinal = fst->AddState();
131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    fst->SetFinal(superfinal, Weight::One());
132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (StateId s = 0; s < fst->NumStates(); ++s) {
135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (MutableArcIterator< MutableFst<A> > aiter(fst, s);
136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         !aiter.Done(); aiter.Next()) {
137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      const A &arc = aiter.Value();
138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      aiter.SetValue((*mapper)(arc));
139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    switch (final_action) {
142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      case MAP_NO_SUPERFINAL:
143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      default: {
144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        A final_arc = (*mapper)(A(0, 0, fst->Final(s), kNoStateId));
145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          FSTERROR() << "ArcMap: non-zero arc labels for superfinal arc";
147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          fst->SetProperties(kError, kError);
148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        fst->SetFinal(s, final_arc.weight);
151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        break;
152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      case MAP_ALLOW_SUPERFINAL: {
154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (s != superfinal) {
155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          A final_arc = (*mapper)(A(0, 0, fst->Final(s), kNoStateId));
156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            // Add a superfinal state if not already done.
158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            if (superfinal == kNoStateId) {
159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson              superfinal = fst->AddState();
160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson              fst->SetFinal(superfinal, Weight::One());
161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            }
162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            final_arc.nextstate = superfinal;
163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            fst->AddArc(s, final_arc);
164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            fst->SetFinal(s, Weight::Zero());
165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          } else {
166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            fst->SetFinal(s, final_arc.weight);
167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          }
168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
1695b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin        break;
170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      case MAP_REQUIRE_SUPERFINAL: {
172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (s != superfinal) {
173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          A final_arc = (*mapper)(A(0, 0, fst->Final(s), kNoStateId));
174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          if (final_arc.ilabel != 0 || final_arc.olabel != 0 ||
175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson              final_arc.weight != Weight::Zero())
176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            fst->AddArc(s, A(final_arc.ilabel, final_arc.olabel,
177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                             final_arc.weight, superfinal));
178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            fst->SetFinal(s, Weight::Zero());
179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        break;
181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  fst->SetProperties(mapper->Properties(props), kFstProperties);
185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Maps an arc type A using a mapper function object C, passed
189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// by value.  This version modifies its Fst input.
190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class A, class C>
191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid ArcMap(MutableFst<A> *fst, C mapper) {
192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMap(fst, &mapper);
193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Maps an arc type A to an arc type B using mapper function
197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// object C, passed by pointer. This version writes the mapped
198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// input Fst to an output MutableFst.
199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class A, class B, class C>
200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid ArcMap(const Fst<A> &ifst, MutableFst<B> *ofst, C* mapper) {
201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight Weight;
203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ofst->DeleteStates();
205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (mapper->InputSymbolsAction() == MAP_COPY_SYMBOLS)
207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ofst->SetInputSymbols(ifst.InputSymbols());
208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  else if (mapper->InputSymbolsAction() == MAP_CLEAR_SYMBOLS)
209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ofst->SetInputSymbols(0);
210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (mapper->OutputSymbolsAction() == MAP_COPY_SYMBOLS)
212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ofst->SetOutputSymbols(ifst.OutputSymbols());
213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  else if (mapper->OutputSymbolsAction() == MAP_CLEAR_SYMBOLS)
214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ofst->SetOutputSymbols(0);
215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 iprops = ifst.Properties(kCopyProperties, false);
217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (ifst.Start() == kNoStateId) {
219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (iprops & kError) ofst->SetProperties(kError, kError);
220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return;
221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction final_action = mapper->FinalAction();
224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (ifst.Properties(kExpanded, false)) {
225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ofst->ReserveStates(CountStates(ifst) +
226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                        final_action == MAP_NO_SUPERFINAL ? 0 : 1);
227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Add all states.
230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (StateIterator< Fst<A> > siter(ifst); !siter.Done(); siter.Next())
231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ofst->AddState();
232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId superfinal = kNoStateId;
234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (final_action == MAP_REQUIRE_SUPERFINAL) {
235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    superfinal = ofst->AddState();
236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ofst->SetFinal(superfinal, B::Weight::One());
237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (StateIterator< Fst<A> > siter(ifst); !siter.Done(); siter.Next()) {
239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    StateId s = siter.Value();
240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (s == ifst.Start())
241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ofst->SetStart(s);
242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ofst->ReserveArcs(s, ifst.NumArcs(s));
244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (ArcIterator< Fst<A> > aiter(ifst, s); !aiter.Done(); aiter.Next())
245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ofst->AddArc(s, (*mapper)(aiter.Value()));
246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    switch (final_action) {
248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      case MAP_NO_SUPERFINAL:
249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      default: {
250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId));
251f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
252f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          FSTERROR() << "ArcMap: non-zero arc labels for superfinal arc";
253f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ofst->SetProperties(kError, kError);
254f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
255f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        ofst->SetFinal(s, final_arc.weight);
256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        break;
257f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
258f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      case MAP_ALLOW_SUPERFINAL: {
259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId));
260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            // Add a superfinal state if not already done.
262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          if (superfinal == kNoStateId) {
263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            superfinal = ofst->AddState();
264f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            ofst->SetFinal(superfinal, B::Weight::One());
265f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          }
266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          final_arc.nextstate = superfinal;
267f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ofst->AddArc(s, final_arc);
268f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ofst->SetFinal(s, B::Weight::Zero());
269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        } else {
270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ofst->SetFinal(s, final_arc.weight);
271f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        break;
273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
274f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      case MAP_REQUIRE_SUPERFINAL: {
275f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId));
276f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (final_arc.ilabel != 0 || final_arc.olabel != 0 ||
277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            final_arc.weight != B::Weight::Zero())
278f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ofst->AddArc(s, B(final_arc.ilabel, final_arc.olabel,
279f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                            final_arc.weight, superfinal));
280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        ofst->SetFinal(s, B::Weight::Zero());
281f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        break;
282f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
283f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
284f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
285f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 oprops = ofst->Properties(kFstProperties, false);
286f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ofst->SetProperties(mapper->Properties(iprops) | oprops, kFstProperties);
287f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
288f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
289f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Maps an arc type A to an arc type B using mapper function
290f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// object C, passed by value. This version writes the mapped input
291f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Fst to an output MutableFst.
292f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class A, class B, class C>
293f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid ArcMap(const Fst<A> &ifst, MutableFst<B> *ofst, C mapper) {
294f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMap(ifst, ofst, &mapper);
295f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
296f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
297f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
298f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct ArcMapFstOptions : public CacheOptions {
299f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // ArcMapFst default caching behaviour is to do no caching. Most
300f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // mappers are cheap and therefore we save memory by not doing
301f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // caching.
302f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMapFstOptions() : CacheOptions(true, 0) {}
303f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMapFstOptions(const CacheOptions& opts) : CacheOptions(opts) {}
304f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
305f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
306f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
307f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, class B, class C> class ArcMapFst;
308f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
309f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Implementation of delayed ArcMapFst.
310f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, class B, class C>
311f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass ArcMapFstImpl : public CacheImpl<B> {
312f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
313f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<B>::SetType;
314f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<B>::SetProperties;
315f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<B>::SetInputSymbols;
316f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<B>::SetOutputSymbols;
317f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
318f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<B>::PushArc;
319f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<B>::HasArcs;
320f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<B>::HasFinal;
321f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<B>::HasStart;
322f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<B>::SetArcs;
323f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<B>::SetFinal;
324f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using CacheImpl<B>::SetStart;
325f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
326f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  friend class StateIterator< ArcMapFst<A, B, C> >;
327f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
328f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef B Arc;
329f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename B::Weight Weight;
330f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename B::StateId StateId;
331f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
332f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMapFstImpl(const Fst<A> &fst, const C &mapper,
333f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 const ArcMapFstOptions& opts)
334f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : CacheImpl<B>(opts),
335f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        fst_(fst.Copy()),
336f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        mapper_(new C(mapper)),
337f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        own_mapper_(true),
338f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        superfinal_(kNoStateId),
339f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        nstates_(0) {
340f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Init();
341f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
342f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
343f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMapFstImpl(const Fst<A> &fst, C *mapper,
344f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 const ArcMapFstOptions& opts)
345f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : CacheImpl<B>(opts),
346f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        fst_(fst.Copy()),
347f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        mapper_(mapper),
348f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        own_mapper_(false),
349f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        superfinal_(kNoStateId),
350f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        nstates_(0) {
351f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Init();
352f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
353f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
354f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMapFstImpl(const ArcMapFstImpl<A, B, C> &impl)
355f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : CacheImpl<B>(impl),
356f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        fst_(impl.fst_->Copy(true)),
357f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        mapper_(new C(*impl.mapper_)),
358f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        own_mapper_(true),
359f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        superfinal_(kNoStateId),
360f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        nstates_(0) {
361f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Init();
362f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
363f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
364f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ~ArcMapFstImpl() {
365f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    delete fst_;
366f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (own_mapper_) delete mapper_;
367f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
368f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
369f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId Start() {
370f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasStart())
371f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetStart(FindOState(fst_->Start()));
372f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return CacheImpl<B>::Start();
373f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
374f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
375f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight Final(StateId s) {
376f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasFinal(s)) {
377f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      switch (final_action_) {
378f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        case MAP_NO_SUPERFINAL:
379f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        default: {
380f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)),
381f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                                        kNoStateId));
382f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
383f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            FSTERROR() << "ArcMapFst: non-zero arc labels for superfinal arc";
384f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            SetProperties(kError, kError);
385f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          }
386f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          SetFinal(s, final_arc.weight);
387f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          break;
388f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
389f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        case MAP_ALLOW_SUPERFINAL: {
390f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          if (s == superfinal_) {
391f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            SetFinal(s, Weight::One());
392f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          } else {
393f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)),
394f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                                          kNoStateId));
395f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            if (final_arc.ilabel == 0 && final_arc.olabel == 0)
396f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson              SetFinal(s, final_arc.weight);
397f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            else
398f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson              SetFinal(s, Weight::Zero());
399f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          }
400f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          break;
401f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
402f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        case MAP_REQUIRE_SUPERFINAL: {
403f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          SetFinal(s, s == superfinal_ ? Weight::One() : Weight::Zero());
404f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          break;
405f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
406f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
407f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
408f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return CacheImpl<B>::Final(s);
409f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
410f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
411f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t NumArcs(StateId s) {
412f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasArcs(s))
413f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Expand(s);
414f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return CacheImpl<B>::NumArcs(s);
415f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
416f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
417f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t NumInputEpsilons(StateId s) {
418f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasArcs(s))
419f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Expand(s);
420f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return CacheImpl<B>::NumInputEpsilons(s);
421f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
422f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
423f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t NumOutputEpsilons(StateId s) {
424f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasArcs(s))
425f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Expand(s);
426f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return CacheImpl<B>::NumOutputEpsilons(s);
427f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
428f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
429f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties() const { return Properties(kFstProperties); }
430f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
431f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Set error if found; return FST impl properties.
432f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 mask) const {
433f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if ((mask & kError) && (fst_->Properties(kError, false) ||
434f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                            (mapper_->Properties(0) & kError)))
435f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetProperties(kError, kError);
436f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return FstImpl<Arc>::Properties(mask);
437f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
438f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
439f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void InitArcIterator(StateId s, ArcIteratorData<B> *data) {
440f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasArcs(s))
441f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      Expand(s);
442f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CacheImpl<B>::InitArcIterator(s, data);
443f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
444f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
445f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Expand(StateId s) {
446f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Add exiting arcs.
447f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (s == superfinal_) { SetArcs(s); return; }
448f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
449f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (ArcIterator< Fst<A> > aiter(*fst_, FindIState(s));
450f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         !aiter.Done(); aiter.Next()) {
451f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      A aarc(aiter.Value());
452f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      aarc.nextstate = FindOState(aarc.nextstate);
453f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      const B& barc = (*mapper_)(aarc);
454f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      PushArc(s, barc);
455f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
456f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
457f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Check for superfinal arcs.
458f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!HasFinal(s) || Final(s) == Weight::Zero())
459f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      switch (final_action_) {
460f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        case MAP_NO_SUPERFINAL:
461f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        default:
462f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          break;
463f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        case MAP_ALLOW_SUPERFINAL: {
464f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)),
465f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                                        kNoStateId));
466f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          if (final_arc.ilabel != 0 || final_arc.olabel != 0) {
467f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            if (superfinal_ == kNoStateId)
468f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson              superfinal_ = nstates_++;
469f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            final_arc.nextstate = superfinal_;
470f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            PushArc(s, final_arc);
471f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          }
472f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          break;
473f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
474f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      case MAP_REQUIRE_SUPERFINAL: {
475f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)),
476f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                                      kNoStateId));
477f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (final_arc.ilabel != 0 || final_arc.olabel != 0 ||
478f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            final_arc.weight != B::Weight::Zero())
479f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          PushArc(s, B(final_arc.ilabel, final_arc.olabel,
480f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                      final_arc.weight, superfinal_));
481f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        break;
482f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
483f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
484f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetArcs(s);
485f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
486f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
487f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
488f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Init() {
489f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetType("map");
490f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
491f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (mapper_->InputSymbolsAction() == MAP_COPY_SYMBOLS)
492f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetInputSymbols(fst_->InputSymbols());
493f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    else if (mapper_->InputSymbolsAction() == MAP_CLEAR_SYMBOLS)
494f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetInputSymbols(0);
495f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
496f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (mapper_->OutputSymbolsAction() == MAP_COPY_SYMBOLS)
497f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetOutputSymbols(fst_->OutputSymbols());
498f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    else if (mapper_->OutputSymbolsAction() == MAP_CLEAR_SYMBOLS)
499f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetOutputSymbols(0);
500f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
501f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (fst_->Start() == kNoStateId) {
502f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      final_action_ = MAP_NO_SUPERFINAL;
503f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetProperties(kNullProperties);
504f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else {
505f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      final_action_ = mapper_->FinalAction();
506f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      uint64 props = fst_->Properties(kCopyProperties, false);
507f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetProperties(mapper_->Properties(props));
508f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (final_action_ == MAP_REQUIRE_SUPERFINAL)
509f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        superfinal_ = 0;
510f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
511f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
512f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
513f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Maps from output state to input state.
514f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId FindIState(StateId s) {
515f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (superfinal_ == kNoStateId || s < superfinal_)
516f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return s;
517f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    else
518f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return s - 1;
519f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
520f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
521f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Maps from input state to output state.
522f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId FindOState(StateId is) {
523f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    StateId os;
524f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (superfinal_ == kNoStateId || is < superfinal_)
525f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      os = is;
526f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    else
527f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      os = is + 1;
528f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
529f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (os >= nstates_)
530f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      nstates_ = os + 1;
531f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
532f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return os;
533f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
534f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
535f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
536f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const Fst<A> *fst_;
537f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  C*   mapper_;
538f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool own_mapper_;
539f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction final_action_;
540f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
541f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId superfinal_;
542f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId nstates_;
543f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
544f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void operator=(const ArcMapFstImpl<A, B, C> &);  // disallow
545f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
546f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
547f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
548f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Maps an arc type A to an arc type B using Mapper function object
549f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// C. This version is a delayed Fst.
550f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, class B, class C>
551f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass ArcMapFst : public ImplToFst< ArcMapFstImpl<A, B, C> > {
552f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
553f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  friend class ArcIterator< ArcMapFst<A, B, C> >;
554f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  friend class StateIterator< ArcMapFst<A, B, C> >;
555f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
556f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef B Arc;
557f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename B::Weight Weight;
558f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename B::StateId StateId;
559f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef CacheState<B> State;
560f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef ArcMapFstImpl<A, B, C> Impl;
561f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
562f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMapFst(const Fst<A> &fst, const C &mapper, const ArcMapFstOptions& opts)
563f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ImplToFst<Impl>(new Impl(fst, mapper, opts)) {}
564f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
565f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMapFst(const Fst<A> &fst, C* mapper, const ArcMapFstOptions& opts)
566f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ImplToFst<Impl>(new Impl(fst, mapper, opts)) {}
567f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
568f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMapFst(const Fst<A> &fst, const C &mapper)
569f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ImplToFst<Impl>(new Impl(fst, mapper, ArcMapFstOptions())) {}
570f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
571f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMapFst(const Fst<A> &fst, C* mapper)
572f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ImplToFst<Impl>(new Impl(fst, mapper, ArcMapFstOptions())) {}
573f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
574f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // See Fst<>::Copy() for doc.
575f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcMapFst(const ArcMapFst<A, B, C> &fst, bool safe = false)
576f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : ImplToFst<Impl>(fst, safe) {}
577f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
578f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Get a copy of this ArcMapFst. See Fst<>::Copy() for further doc.
579f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual ArcMapFst<A, B, C> *Copy(bool safe = false) const {
580f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return new ArcMapFst<A, B, C>(*this, safe);
581f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
582f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
583f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual inline void InitStateIterator(StateIteratorData<B> *data) const;
584f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
585f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual void InitArcIterator(StateId s, ArcIteratorData<B> *data) const {
586f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    GetImpl()->InitArcIterator(s, data);
587f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
588f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
589f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
590f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Makes visible to friends.
591f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Impl *GetImpl() const { return ImplToFst<Impl>::GetImpl(); }
592f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
593f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void operator=(const ArcMapFst<A, B, C> &fst);  // disallow
594f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
595f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
596f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
597f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for ArcMapFst.
598f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class A, class B, class C>
599f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass StateIterator< ArcMapFst<A, B, C> > : public StateIteratorBase<B> {
600f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
601f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename B::StateId StateId;
602f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
603f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit StateIterator(const ArcMapFst<A, B, C> &fst)
604f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : impl_(fst.GetImpl()), siter_(*impl_->fst_), s_(0),
605f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        superfinal_(impl_->final_action_ == MAP_REQUIRE_SUPERFINAL)
606f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  { CheckSuperfinal(); }
607f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
608f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool Done() const { return siter_.Done() && !superfinal_; }
609f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
610f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId Value() const { return s_; }
611f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
612f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Next() {
613f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ++s_;
614f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!siter_.Done()) {
615f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      siter_.Next();
616f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CheckSuperfinal();
617f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
618f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    else if (superfinal_)
619f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      superfinal_ = false;
620f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
621f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
622f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Reset() {
623f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    s_ = 0;
624f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    siter_.Reset();
625f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    superfinal_ = impl_->final_action_ == MAP_REQUIRE_SUPERFINAL;
626f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    CheckSuperfinal();
627f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
628f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
629f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
630f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // This allows base-class virtual access to non-virtual derived-
631f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // class members of the same name. It makes the derived class more
632f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // efficient to use but unsafe to further derive.
633f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool Done_() const { return Done(); }
634f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId Value_() const { return Value(); }
635f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Next_() { Next(); }
636f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Reset_() { Reset(); }
637f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
638f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void CheckSuperfinal() {
639f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (impl_->final_action_ != MAP_ALLOW_SUPERFINAL || superfinal_)
640f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return;
641f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!siter_.Done()) {
642f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      B final_arc = (*impl_->mapper_)(A(0, 0, impl_->fst_->Final(s_),
643f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                                           kNoStateId));
644f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (final_arc.ilabel != 0 || final_arc.olabel != 0)
645f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        superfinal_ = true;
646f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
647f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
648f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
649f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const ArcMapFstImpl<A, B, C> *impl_;
650f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateIterator< Fst<A> > siter_;
651f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId s_;
652f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool superfinal_;    // true if there is a superfinal state and not done
653f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
654f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(StateIterator);
655f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
656f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
657f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
658f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for ArcMapFst.
659f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, class B, class C>
660f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass ArcIterator< ArcMapFst<A, B, C> >
661f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : public CacheArcIterator< ArcMapFst<A, B, C> > {
662f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
663f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
664f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
665f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcIterator(const ArcMapFst<A, B, C> &fst, StateId s)
666f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : CacheArcIterator< ArcMapFst<A, B, C> >(fst.GetImpl(), s) {
667f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!fst.GetImpl()->HasArcs(s))
668f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      fst.GetImpl()->Expand(s);
669f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
670f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
671f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
672f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(ArcIterator);
673f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
674f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
675f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, class B, class C> inline
676f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid ArcMapFst<A, B, C>::InitStateIterator(StateIteratorData<B> *data)
677f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    const {
678f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  data->base = new StateIterator< ArcMapFst<A, B, C> >(*this);
679f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
680f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
681f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
682f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
683f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Utility Mappers
684f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
685f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
686f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper that returns its input.
687f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
688f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct IdentityArcMapper {
689f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A FromArc;
690f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A ToArc;
691f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
692f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  A operator()(const A &arc) const { return arc; }
693f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
694f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
695f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
696f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
697f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
698f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_COPY_SYMBOLS;}
699f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
700f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 props) const { return props; }
701f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
702f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
703f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
704f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper that returns its input with final states redirected to
705f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// a single super-final state.
706f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
707f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct SuperFinalMapper {
708f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A FromArc;
709f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A ToArc;
710f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
711f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  A operator()(const A &arc) const { return arc; }
712f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
713f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_REQUIRE_SUPERFINAL; }
714f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
715f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
716f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
717f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_COPY_SYMBOLS;}
718f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
719f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 props) const {
720f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return props & kAddSuperFinalProperties;
721f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
722f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
723f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
724f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
725f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper that leaves labels and nextstate unchanged and constructs a new weight
726f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// from the underlying value of the arc weight.  Requires that there is a
727f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WeightConvert class specialization that converts the weights.
728f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, class B>
729f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass WeightConvertMapper {
730f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
731f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A FromArc;
732f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef B ToArc;
733f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename FromArc::Weight FromWeight;
734f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename ToArc::Weight ToWeight;
735f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
736f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ToArc operator()(const FromArc &arc) const {
737f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return ToArc(arc.ilabel, arc.olabel,
738f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 convert_weight_(arc.weight), arc.nextstate);
739f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
740f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
741f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
742f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
743f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
744f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
745f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_COPY_SYMBOLS;}
746f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
747f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 props) const { return props; }
748f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
749f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
750f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  WeightConvert<FromWeight, ToWeight> convert_weight_;
751f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
752f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
753f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Non-precision-changing weight conversions.
754f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Consider using more efficient Cast (fst.h) instead.
755f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef WeightConvertMapper<StdArc, LogArc> StdToLogMapper;
756f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef WeightConvertMapper<LogArc, StdArc> LogToStdMapper;
757f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
758f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Precision-changing weight conversions.
759f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef WeightConvertMapper<StdArc, Log64Arc> StdToLog64Mapper;
760f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef WeightConvertMapper<LogArc, Log64Arc> LogToLog64Mapper;
761f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef WeightConvertMapper<Log64Arc, StdArc> Log64ToStdMapper;
762f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef WeightConvertMapper<Log64Arc, LogArc> Log64ToLogMapper;
763f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
764f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper from A to GallicArc<A>.
765f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, StringType S = STRING_LEFT>
766f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct ToGallicMapper {
767f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A FromArc;
768f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef GallicArc<A, S> ToArc;
769f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
770f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef StringWeight<typename A::Label, S> SW;
771f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight AW;
772f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename GallicArc<A, S>::Weight GW;
773f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
774f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ToArc operator()(const A &arc) const {
775f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // 'Super-final' arc.
776f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.nextstate == kNoStateId && arc.weight != AW::Zero())
777f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return ToArc(0, 0, GW(SW::One(), arc.weight), kNoStateId);
778f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // 'Super-non-final' arc.
779f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    else if (arc.nextstate == kNoStateId)
780f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return ToArc(0, 0, GW(SW::Zero(), arc.weight), kNoStateId);
781f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Epsilon label.
782f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    else if (arc.olabel == 0)
783f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return ToArc(arc.ilabel, arc.ilabel,
784f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                   GW(SW::One(), arc.weight), arc.nextstate);
785f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // Regular label.
786f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    else
787f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return ToArc(arc.ilabel, arc.ilabel,
788f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                   GW(SW(arc.olabel), arc.weight), arc.nextstate);
789f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
790f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
791f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
792f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
793f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
794f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
795f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_CLEAR_SYMBOLS;}
796f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
797f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 props) const {
798f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return ProjectProperties(props, true) & kWeightInvariantProperties;
799f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
800f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
801f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
802f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
803f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper from GallicArc<A> to A.
804f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, StringType S = STRING_LEFT>
805f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct FromGallicMapper {
806f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef GallicArc<A, S> FromArc;
807f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A ToArc;
808f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
809f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Label Label;
810f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef StringWeight<Label, S> SW;
811f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight AW;
812f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename GallicArc<A, S>::Weight GW;
813f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
814f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  FromGallicMapper(Label superfinal_label = 0)
815f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : superfinal_label_(superfinal_label), error_(false) {}
816f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
817f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  A operator()(const FromArc &arc) const {
818f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // 'Super-non-final' arc.
819f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.nextstate == kNoStateId && arc.weight == GW::Zero())
820f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return A(arc.ilabel, 0, AW::Zero(), kNoStateId);
821f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
822f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SW w1 = arc.weight.Value1();
823f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    AW w2 = arc.weight.Value2();
824f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    StringWeightIterator<Label, S> iter1(w1);
825f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
826f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Label l = w1.Size() == 1 ? iter1.Value() : 0;
827f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
828f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (l == kStringInfinity || l == kStringBad ||
829f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        arc.ilabel != arc.olabel || w1.Size() > 1) {
830f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      FSTERROR() << "FromGallicMapper: unrepesentable weight";
831f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      error_ = true;
832f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
833f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
834f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.ilabel == 0 && l != 0 && arc.nextstate == kNoStateId)
835f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return A(superfinal_label_, l, w2, arc.nextstate);
836f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    else
837f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return A(arc.ilabel, l, w2, arc.nextstate);
838f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
839f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
840f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_ALLOW_SUPERFINAL; }
841f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
842f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
843f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
844f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_CLEAR_SYMBOLS;}
845f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
846f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 inprops) const {
847f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    uint64 outprops = inprops & kOLabelInvariantProperties &
848f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        kWeightInvariantProperties & kAddSuperFinalProperties;
849f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (error_)
850f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      outprops |= kError;
851f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return outprops;
852f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
853f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
854f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
855f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Label superfinal_label_;
856f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  mutable bool error_;
857f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
858f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
859f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
860f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper from GallicArc<A> to A.
861f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, StringType S = STRING_LEFT>
862f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct GallicToNewSymbolsMapper {
863f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef GallicArc<A, S> FromArc;
864f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A ToArc;
865f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
866f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
867f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Label Label;
868f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef StringWeight<Label, S> SW;
869f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight AW;
870f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename GallicArc<A, S>::Weight GW;
871f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
872f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  GallicToNewSymbolsMapper(MutableFst<ToArc> *fst)
873f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : fst_(fst), lmax_(0), osymbols_(fst->OutputSymbols()),
874f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        isymbols_(0), error_(false) {
875f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    fst_->DeleteStates();
876f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    state_ = fst_->AddState();
877f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    fst_->SetStart(state_);
878f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    fst_->SetFinal(state_, AW::One());
879f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (osymbols_) {
880f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      string name = osymbols_->Name() + "_from_gallic";
881f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      fst_->SetInputSymbols(new SymbolTable(name));
882f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      isymbols_ = fst_->MutableInputSymbols();
883f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      isymbols_->AddSymbol(osymbols_->Find((int64) 0), 0);
884f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else {
885f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      fst_->SetInputSymbols(0);
886f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
887f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
888f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
889f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  A operator()(const FromArc &arc) {
890f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // 'Super-non-final' arc.
891f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.nextstate == kNoStateId && arc.weight == GW::Zero())
892f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return A(arc.ilabel, 0, AW::Zero(), kNoStateId);
893f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
894f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SW w1 = arc.weight.Value1();
895f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    AW w2 = arc.weight.Value2();
896f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Label l;
897f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
898f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (w1.Size() == 0) {
899f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      l = 0;
900f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else {
901f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      typename Map::iterator miter = map_.find(w1);
902f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (miter != map_.end()) {
903f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        l = (*miter).second;
904f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else {
905f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        l = ++lmax_;
906f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        map_.insert(pair<const SW, Label>(w1, l));
907f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        StringWeightIterator<Label, S> iter1(w1);
908f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        StateId n;
909f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        string s;
910f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        for(size_t i = 0, p = state_;
911f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            i < w1.Size();
912f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            ++i, iter1.Next(), p = n) {
913f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          n = i == w1.Size() - 1 ? state_ : fst_->AddState();
914f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          fst_->AddArc(p, ToArc(i ? 0 : l, iter1.Value(), AW::One(), n));
915f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          if (isymbols_) {
916f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            if (i) s = s + "_";
917f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            s = s + osymbols_->Find(iter1.Value());
918f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          }
919f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
920f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (isymbols_)
921f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          isymbols_->AddSymbol(s, l);
922f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
923f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
924f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
925f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (l == kStringInfinity || l == kStringBad || arc.ilabel != arc.olabel) {
926f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      FSTERROR() << "GallicToNewSymbolMapper: unrepesentable weight";
927f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      error_ = true;
928f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
929f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
930f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return A(arc.ilabel, l, w2, arc.nextstate);
931f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
932f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
933f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_ALLOW_SUPERFINAL; }
934f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
935f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
936f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
937f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_CLEAR_SYMBOLS; }
938f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
939f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 inprops) const {
940f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    uint64 outprops = inprops & kOLabelInvariantProperties &
941f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        kWeightInvariantProperties & kAddSuperFinalProperties;
942f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (error_)
943f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      outprops |= kError;
944f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return outprops;
945f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
946f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
947f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
948f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  class StringKey {
949f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson   public:
950f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    size_t operator()(const SW &x) const {
951f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return x.Hash();
952f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
953f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  };
954f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
955f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef unordered_map<SW, Label, StringKey> Map;
956f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
957f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MutableFst<ToArc> *fst_;
958f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Map map_;
959f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Label lmax_;
960f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId state_;
961f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const SymbolTable *osymbols_;
962f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SymbolTable *isymbols_;
963f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  mutable bool error_;
964f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
965f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(GallicToNewSymbolsMapper);
966f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
967f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
968f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
969f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper to add a constant to all weights.
970f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
971f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct PlusMapper {
972f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A FromArc;
973f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A ToArc;
974f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight Weight;
975f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
976f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit PlusMapper(Weight w) : weight_(w) {}
977f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
978f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  A operator()(const A &arc) const {
979f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.weight == Weight::Zero())
980f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return arc;
981f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Weight w = Plus(arc.weight, weight_);
982f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return A(arc.ilabel, arc.olabel, w, arc.nextstate);
983f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
984f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
985f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
986f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
987f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
988f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
989f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_COPY_SYMBOLS;}
990f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
991f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 props) const {
992f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return props & kWeightInvariantProperties;
993f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
994f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
995f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
996f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
997f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
998f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
999f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight weight_;
1000f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
1001f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1002f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1003f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper to (right) multiply a constant to all weights.
1004f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
1005f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct TimesMapper {
1006f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A FromArc;
1007f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A ToArc;
1008f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight Weight;
1009f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1010f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit TimesMapper(Weight w) : weight_(w) {}
1011f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1012f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  A operator()(const A &arc) const {
1013f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.weight == Weight::Zero())
1014f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return arc;
1015f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Weight w = Times(arc.weight, weight_);
1016f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return A(arc.ilabel, arc.olabel, w, arc.nextstate);
1017f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
1018f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1019f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1020f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1021f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
1022f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1023f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_COPY_SYMBOLS;}
1024f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1025f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 props) const {
1026f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return props & kWeightInvariantProperties;
1027f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
1028f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1029f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
1030f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight weight_;
1031f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
1032f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1033f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1034f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper to reciprocate all non-Zero() weights.
1035f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
1036f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct InvertWeightMapper {
1037f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A FromArc;
1038f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A ToArc;
1039f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight Weight;
1040f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1041f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  A operator()(const A &arc) const {
1042f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.weight == Weight::Zero())
1043f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return arc;
1044f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Weight w = Divide(Weight::One(), arc.weight);
1045f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return A(arc.ilabel, arc.olabel, w, arc.nextstate);
1046f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
1047f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1048f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1049f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1050f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
1051f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1052f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_COPY_SYMBOLS;}
1053f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1054f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 props) const {
1055f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return props & kWeightInvariantProperties;
1056f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
1057f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
1058f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1059f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1060f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper to map all non-Zero() weights to One().
1061f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, class B = A>
1062f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct RmWeightMapper {
1063f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A FromArc;
1064f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef B ToArc;
1065f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename FromArc::Weight FromWeight;
1066f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename ToArc::Weight ToWeight;
1067f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1068f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  B operator()(const A &arc) const {
1069f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ToWeight w = arc.weight != FromWeight::Zero() ?
1070f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                   ToWeight::One() : ToWeight::Zero();
1071f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return B(arc.ilabel, arc.olabel, w, arc.nextstate);
1072f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
1073f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1074f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1075f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1076f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
1077f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1078f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_COPY_SYMBOLS;}
1079f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1080f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 props) const {
1081f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return (props & kWeightInvariantProperties) | kUnweighted;
1082f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
1083f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
1084f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1085f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1086f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper to quantize all weights.
1087f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, class B = A>
1088f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct QuantizeMapper {
1089f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A FromArc;
1090f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef B ToArc;
1091f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename FromArc::Weight FromWeight;
1092f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename ToArc::Weight ToWeight;
1093f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1094f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  QuantizeMapper() : delta_(kDelta) {}
1095f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1096f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit QuantizeMapper(float d) : delta_(d) {}
1097f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1098f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  B operator()(const A &arc) const {
1099f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ToWeight w = arc.weight.Quantize(delta_);
1100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return B(arc.ilabel, arc.olabel, w, arc.nextstate);
1101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
1102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
1106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_COPY_SYMBOLS;}
1108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 props) const {
1110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return props & kWeightInvariantProperties;
1111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
1112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
1114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  float delta_;
1115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
1116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Mapper from A to B under the assumption:
1119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//    B::Weight = A::Weight::ReverseWeight
1120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//    B::Label == A::Label
1121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//    B::StateId == A::StateId
1122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The weight is reversed, while the label and nextstate preserved
1123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// in the mapping.
1124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, class B>
1125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct ReverseWeightMapper {
1126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A FromArc;
1127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef B ToArc;
1128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  B operator()(const A &arc) const {
1130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return B(arc.ilabel, arc.olabel, arc.weight.Reverse(), arc.nextstate);
1131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
1132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
1134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS; }
1136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MapSymbolsAction OutputSymbolsAction() const { return MAP_COPY_SYMBOLS;}
1138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties(uint64 props) const { return props; }
1140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
1141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}  // namespace fst
1143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
1144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif  // FST_LIB_ARC_MAP_H__
1145