1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// vector-fst.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// Simple concrete, mutable FST whose states and arcs are stored in STL
20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// vectors.
21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_VECTOR_FST_H__
23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_VECTOR_FST_H__
24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <string>
26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <vector>
27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::vector;
28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/mutable-fst.h>
30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/test-properties.h>
31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst {
34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> class VectorFst;
36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class F, class G> void Cast(const F &, G *);
37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// States and arcs implemented by STL vectors, templated on the
40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// State definition. This does not manage the Fst properties.
41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class State>
42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass VectorFstBaseImpl : public FstImpl<typename State::Arc> {
43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename State::Arc Arc;
45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename Arc::Weight Weight;
46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename Arc::StateId StateId;
47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  VectorFstBaseImpl() : start_(kNoStateId) {}
49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ~VectorFstBaseImpl() {
51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (StateId s = 0; s < states_.size(); ++s)
52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      delete states_[s];
53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId Start() const { return start_; }
56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight Final(StateId s) const { return states_[s]->final; }
58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId NumStates() const { return states_.size(); }
60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t NumArcs(StateId s) const { return states_[s]->arcs.size(); }
62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetStart(StateId s) { start_ = s; }
64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetFinal(StateId s, Weight w) { states_[s]->final = w; }
66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId AddState() {
68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    states_.push_back(new State);
69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return states_.size() - 1;
70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId AddState(State *state) {
73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    states_.push_back(state);
74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return states_.size() - 1;
75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void AddArc(StateId s, const Arc &arc) {
78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    states_[s]->arcs.push_back(arc);
79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void DeleteStates(const vector<StateId>& dstates) {
82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    vector<StateId> newid(states_.size(), 0);
83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (size_t i = 0; i < dstates.size(); ++i)
84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      newid[dstates[i]] = kNoStateId;
85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    StateId nstates = 0;
86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (StateId s = 0; s < states_.size(); ++s) {
87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (newid[s] != kNoStateId) {
88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        newid[s] = nstates;
89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (s != nstates)
90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          states_[nstates] = states_[s];
91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        ++nstates;
92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else {
93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        delete states_[s];
94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    states_.resize(nstates);
97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (StateId s = 0; s < states_.size(); ++s) {
98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      vector<Arc> &arcs = states_[s]->arcs;
99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      size_t narcs = 0;
100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      for (size_t i = 0; i < arcs.size(); ++i) {
101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        StateId t = newid[arcs[i].nextstate];
102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (t != kNoStateId) {
103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          arcs[i].nextstate = t;
104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          if (i != narcs)
105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            arcs[narcs] = arcs[i];
106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ++narcs;
107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        } else {
108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          if (arcs[i].ilabel == 0)
109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            --states_[s]->niepsilons;
110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          if (arcs[i].olabel == 0)
111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson            --states_[s]->noepsilons;
112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      arcs.resize(narcs);
115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (Start() != kNoStateId)
117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SetStart(newid[Start()]);
118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void DeleteStates() {
121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (StateId s = 0; s < states_.size(); ++s)
122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      delete states_[s];
123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    states_.clear();
124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetStart(kNoStateId);
125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void DeleteArcs(StateId s, size_t n) {
128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    states_[s]->arcs.resize(states_[s]->arcs.size() - n);
129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void DeleteArcs(StateId s) { states_[s]->arcs.clear(); }
132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  State *GetState(StateId s) { return states_[s]; }
134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const State *GetState(StateId s) const { return states_[s]; }
136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetState(StateId s, State *state) { states_[s] = state; }
138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void ReserveStates(StateId n) { states_.reserve(n); }
140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void ReserveArcs(StateId s, size_t n) { states_[s]->arcs.reserve(n); }
142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Provide information needed for generic state iterator
144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void InitStateIterator(StateIteratorData<Arc> *data) const {
145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    data->base = 0;
146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    data->nstates = states_.size();
147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Provide information needed for generic arc iterator
150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const {
151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    data->base = 0;
152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    data->narcs = states_[s]->arcs.size();
153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    data->arcs = data->narcs > 0 ? &states_[s]->arcs[0] : 0;
154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    data->ref_count = 0;
155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  vector<State *> states_;      // States represenation.
159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId start_;               // initial state
160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(VectorFstBaseImpl);
162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Arcs implemented by an STL vector per state.
165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct VectorState {
167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A Arc;
168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight Weight;
169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  VectorState() : final(Weight::Zero()), niepsilons(0), noepsilons(0) {}
172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight final;              // Final weight
174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  vector<A> arcs;            // Arcs represenation
175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t niepsilons;         // # of input epsilons
176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t noepsilons;         // # of output epsilons
177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This is a VectorFstBaseImpl container that holds VectorState's.  It
180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// manages Fst properties and the # of input and output epsilons.
181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass VectorFstImpl : public VectorFstBaseImpl< VectorState<A> > {
183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<A>::SetInputSymbols;
185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<A>::SetOutputSymbols;
186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<A>::SetType;
187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<A>::SetProperties;
188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using FstImpl<A>::Properties;
189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using VectorFstBaseImpl<VectorState<A> >::Start;
191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using VectorFstBaseImpl<VectorState<A> >::NumStates;
192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using VectorFstBaseImpl<VectorState<A> >::GetState;
193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  using VectorFstBaseImpl<VectorState<A> >::ReserveArcs;
194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  friend class MutableArcIterator< VectorFst<A> >;
196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef VectorFstBaseImpl< VectorState<A> > BaseImpl;
198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight Weight;
199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  VectorFstImpl() {
202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetType("vector");
203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(kNullProperties | kStaticProperties);
204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit VectorFstImpl(const Fst<A> &fst);
206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static VectorFstImpl<A> *Read(istream &strm, const FstReadOptions &opts);
208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t NumInputEpsilons(StateId s) const { return GetState(s)->niepsilons; }
210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t NumOutputEpsilons(StateId s) const { return GetState(s)->noepsilons; }
212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetStart(StateId s) {
214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    BaseImpl::SetStart(s);
215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(SetStartProperties(Properties()));
216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetFinal(StateId s, Weight w) {
219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Weight ow = BaseImpl::Final(s);
220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    BaseImpl::SetFinal(s, w);
221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(SetFinalProperties(Properties(), ow, w));
222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId AddState() {
225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    StateId s = BaseImpl::AddState();
226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(AddStateProperties(Properties()));
227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return s;
228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void AddArc(StateId s, const A &arc) {
231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    VectorState<A> *state = GetState(s);
232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.ilabel == 0) {
233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ++state->niepsilons;
234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.olabel == 0) {
236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ++state->noepsilons;
237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    const A *parc = state->arcs.empty() ? 0 : &(state->arcs.back());
240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(AddArcProperties(Properties(), s, arc, parc));
241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    BaseImpl::AddArc(s, arc);
243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void DeleteStates(const vector<StateId> &dstates) {
246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    BaseImpl::DeleteStates(dstates);
247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(DeleteStatesProperties(Properties()));
248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void DeleteStates() {
251f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    BaseImpl::DeleteStates();
252f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(DeleteAllStatesProperties(Properties(),
253f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                                            kStaticProperties));
254f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
255f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void DeleteArcs(StateId s, size_t n) {
257f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    const vector<A> &arcs = GetState(s)->arcs;
258f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (size_t i = 0; i < n; ++i) {
259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      size_t j = arcs.size() - i - 1;
260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (arcs[j].ilabel == 0)
261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        --GetState(s)->niepsilons;
262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (arcs[j].olabel == 0)
263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        --GetState(s)->noepsilons;
264f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
265f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    BaseImpl::DeleteArcs(s, n);
266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(DeleteArcsProperties(Properties()));
267f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
268f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void DeleteArcs(StateId s) {
270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    GetState(s)->niepsilons = 0;
271f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    GetState(s)->noepsilons = 0;
272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    BaseImpl::DeleteArcs(s);
273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetProperties(DeleteArcsProperties(Properties()));
274f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
275f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
276f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Properties always true of this Fst class
277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const uint64 kStaticProperties = kExpanded | kMutable;
278dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin
279dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin private:
280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Current file format version
281f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const int kFileVersion = 2;
282f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Minimum file format version supported
283f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const int kMinFileVersion = 1;
284f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
285f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(VectorFstImpl);
286f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
287f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
288f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> const uint64 VectorFstImpl<A>::kStaticProperties;
289f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> const int VectorFstImpl<A>::kFileVersion;
290f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> const int VectorFstImpl<A>::kMinFileVersion;
291f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
292f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
293f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
294f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonVectorFstImpl<A>::VectorFstImpl(const Fst<A> &fst) {
295f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SetType("vector");
296f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SetInputSymbols(fst.InputSymbols());
297f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SetOutputSymbols(fst.OutputSymbols());
298f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  BaseImpl::SetStart(fst.Start());
299f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (fst.Properties(kExpanded, false))
300f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    BaseImpl::ReserveStates(CountStates(fst));
301f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
302f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (StateIterator< Fst<A> > siter(fst);
303f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson       !siter.Done();
304f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson       siter.Next()) {
305f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    StateId s = siter.Value();
306f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    BaseImpl::AddState();
307f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    BaseImpl::SetFinal(s, fst.Final(s));
308f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ReserveArcs(s, fst.NumArcs(s));
309f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (ArcIterator< Fst<A> > aiter(fst, s);
310f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         !aiter.Done();
311f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         aiter.Next()) {
312f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      const A &arc = aiter.Value();
313f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      BaseImpl::AddArc(s, arc);
314f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (arc.ilabel == 0)
315f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        ++GetState(s)->niepsilons;
316f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (arc.olabel == 0)
317f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        ++GetState(s)->noepsilons;
318f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
319f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
320f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SetProperties(fst.Properties(kCopyProperties, false) | kStaticProperties);
321f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
322f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
323f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
324f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonVectorFstImpl<A> *VectorFstImpl<A>::Read(istream &strm,
325f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                                         const FstReadOptions &opts) {
326f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  VectorFstImpl<A> *impl = new VectorFstImpl;
327f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  FstHeader hdr;
328f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) {
329f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    delete impl;
330f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return 0;
331f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
332f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  impl->BaseImpl::SetStart(hdr.Start());
333f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (hdr.NumStates() != kNoStateId) {
334f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    impl->ReserveStates(hdr.NumStates());
335f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
336f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
337f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId s = 0;
338f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (;hdr.NumStates() == kNoStateId || s < hdr.NumStates(); ++s) {
339f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    typename A::Weight final;
340f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!final.Read(strm)) break;
341f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    impl->BaseImpl::AddState();
342f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    VectorState<A> *state = impl->GetState(s);
343f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    state->final = final;
344f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    int64 narcs;
345f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ReadType(strm, &narcs);
346f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!strm) {
347f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      LOG(ERROR) << "VectorFst::Read: read failed: " << opts.source;
348f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      delete impl;
349f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return 0;
350f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
351f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    impl->ReserveArcs(s, narcs);
352f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (size_t j = 0; j < narcs; ++j) {
353f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      A arc;
354f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ReadType(strm, &arc.ilabel);
355f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ReadType(strm, &arc.olabel);
356f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      arc.weight.Read(strm);
357f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson       ReadType(strm, &arc.nextstate);
358f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson       if (!strm) {
359f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        LOG(ERROR) << "VectorFst::Read: read failed: " << opts.source;
360f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        delete impl;
361f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        return 0;
362f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
363f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      impl->BaseImpl::AddArc(s, arc);
364f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (arc.ilabel == 0)
365f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        ++state->niepsilons;
366f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (arc.olabel == 0)
367f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        ++state->noepsilons;
368f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
369f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
370f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (hdr.NumStates() != kNoStateId && s != hdr.NumStates()) {
371f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    LOG(ERROR) << "VectorFst::Read: unexpected end of file: " << opts.source;
372f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    delete impl;
373f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return 0;
374f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
375f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return impl;
376f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
377f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
378f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Converts a string into a weight.
379f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W> class WeightFromString {
380f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
381f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  W operator()(const string &s);
382f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
383f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
384f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Generic case fails.
385f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W> inline
386f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonW WeightFromString<W>::operator()(const string &s) {
387f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  FSTERROR() << "VectorFst::Read: Obsolete file format";
388f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return W::NoWeight();
389f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
390f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
391f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// TropicalWeight version.
392f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> inline
393f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonTropicalWeight WeightFromString<TropicalWeight>::operator()(const string &s) {
394f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  float f;
395f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  memcpy(&f, s.data(), sizeof(f));
396f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return TropicalWeight(f);
397f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
398f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
399f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// LogWeight version.
400f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> inline
401f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonLogWeight WeightFromString<LogWeight>::operator()(const string &s) {
402f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  float f;
403f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  memcpy(&f, s.data(), sizeof(f));
404f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return LogWeight(f);
405f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
406f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
407f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Simple concrete, mutable FST. This class attaches interface to
408f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// implementation and handles reference counting, delegating most
409f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// methods to ImplToMutableFst. Supports additional operations:
410f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// ReserveStates and ReserveArcs (cf. STL vectors).
411f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
412f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass VectorFst : public ImplToMutableFst< VectorFstImpl<A> > {
413f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
414f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  friend class StateIterator< VectorFst<A> >;
415f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  friend class ArcIterator< VectorFst<A> >;
416f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  friend class MutableArcIterator< VectorFst<A> >;
417f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  template <class F, class G> friend void Cast(const F &, G *);
418f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
419f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A Arc;
420f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
421f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef VectorFstImpl<A> Impl;
422f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
423f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  VectorFst() : ImplToMutableFst<Impl>(new Impl) {}
424f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
425f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit VectorFst(const Fst<A> &fst)
426f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : ImplToMutableFst<Impl>(new Impl(fst)) {}
427f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
428f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  VectorFst(const VectorFst<A> &fst) : ImplToMutableFst<Impl>(fst) {}
429f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
430f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Get a copy of this VectorFst. See Fst<>::Copy() for further doc.
431f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual VectorFst<A> *Copy(bool safe = false) const {
432f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return new VectorFst<A>(*this);
433f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
434f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
435f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  VectorFst<A> &operator=(const VectorFst<A> &fst) {
436f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SetImpl(fst.GetImpl(), false);
437f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return *this;
438f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
439f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
440f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual VectorFst<A> &operator=(const Fst<A> &fst) {
441f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (this != &fst) SetImpl(new Impl(fst));
442f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return *this;
443f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
444f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
445f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Read a VectorFst from an input stream; return NULL on error
446f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static VectorFst<A> *Read(istream &strm, const FstReadOptions &opts) {
447f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Impl* impl = Impl::Read(strm, opts);
448f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return impl ? new VectorFst<A>(impl) : 0;
449f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
450f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
451f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Read a VectorFst from a file; return NULL on error
452f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Empty filename reads from standard input
453f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static VectorFst<A> *Read(const string &filename) {
454f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Impl* impl = ImplToExpandedFst<Impl, MutableFst<A> >::Read(filename);
455f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return impl ? new VectorFst<A>(impl) : 0;
456f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
457f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
458f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual bool Write(ostream &strm, const FstWriteOptions &opts) const {
459f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return WriteFst(*this, strm, opts);
460f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
461f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
462f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual bool Write(const string &filename) const {
463f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return Fst<A>::WriteFile(filename);
464f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
465f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
466f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  template <class F>
467f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static bool WriteFst(const F &fst, ostream &strm,
468f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                       const FstWriteOptions &opts);
469f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
470f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void ReserveStates(StateId n) {
471f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    MutateCheck();
472f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    GetImpl()->ReserveStates(n);
473f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
474f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
475f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void ReserveArcs(StateId s, size_t n) {
476f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    MutateCheck();
477f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    GetImpl()->ReserveArcs(s, n);
478f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
479f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
480f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual void InitStateIterator(StateIteratorData<Arc> *data) const {
481f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    GetImpl()->InitStateIterator(data);
482f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
483f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
484f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const {
485f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    GetImpl()->InitArcIterator(s, data);
486f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
487f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
488f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual inline
489f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void InitMutableArcIterator(StateId s, MutableArcIteratorData<A> *);
490f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
491f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
492f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit VectorFst(Impl *impl) : ImplToMutableFst<Impl>(impl) {}
493f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
494f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Makes visible to friends.
495f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Impl *GetImpl() const { return ImplToFst< Impl, MutableFst<A> >::GetImpl(); }
496f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
497f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetImpl(Impl *impl, bool own_impl = true) {
498f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ImplToFst< Impl, MutableFst<A> >::SetImpl(impl, own_impl);
499f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
500f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
501f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void MutateCheck() { return ImplToMutableFst<Impl>::MutateCheck(); }
502f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
503f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
504f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for VectorFst; see generic version in fst.h
505f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// for sample usage (but use the VectorFst type!). This version
506f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// should inline.
507f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
508f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass StateIterator< VectorFst<A> > {
509f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
510f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
511f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
512f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  explicit StateIterator(const VectorFst<A> &fst)
513f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : nstates_(fst.GetImpl()->NumStates()), s_(0) {}
514f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
515f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool Done() const { return s_ >= nstates_; }
516f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
517f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId Value() const { return s_; }
518f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
519f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Next() { ++s_; }
520f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
521f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Reset() { s_ = 0; }
522f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
523f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
524f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId nstates_;
525f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId s_;
526f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
527f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(StateIterator);
528f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
529f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
530f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Writes Fst to file, will call CountStates so may involve two passes if
531f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// called from an Fst that is not derived from Expanded.
532f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
533f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class F>
534f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonbool VectorFst<A>::WriteFst(const F &fst, ostream &strm,
535f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                            const FstWriteOptions &opts) {
536f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const int kFileVersion = 2;
537f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool update_header = true;
538f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  FstHeader hdr;
539f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  hdr.SetStart(fst.Start());
540f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  hdr.SetNumStates(kNoStateId);
541f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t start_offset = 0;
542f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (fst.Properties(kExpanded, false) || (start_offset = strm.tellp()) != -1) {
543f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    hdr.SetNumStates(CountStates(fst));
544f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    update_header = false;
545f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
546dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin  uint64 properties = fst.Properties(kCopyProperties, false) |
547dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin      VectorFstImpl<A>::kStaticProperties;
548dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin  FstImpl<A>::WriteFstHeader(fst, strm, opts, kFileVersion, "vector",
549dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin                             properties, &hdr);
550f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StateId num_states = 0;
551f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (StateIterator<F> siter(fst); !siter.Done(); siter.Next()) {
552f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    typename A::StateId s = siter.Value();
553f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    fst.Final(s).Write(strm);
554f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    int64 narcs = fst.NumArcs(s);
555f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    WriteType(strm, narcs);
556f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (ArcIterator<F> aiter(fst, s); !aiter.Done(); aiter.Next()) {
557f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      const A &arc = aiter.Value();
558f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      WriteType(strm, arc.ilabel);
559f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      WriteType(strm, arc.olabel);
560f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      arc.weight.Write(strm);
561f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      WriteType(strm, arc.nextstate);
562f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
563f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    num_states++;
564f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
565f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  strm.flush();
566f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (!strm) {
567f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    LOG(ERROR) << "VectorFst::Write: write failed: " << opts.source;
568f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return false;
569f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
570f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (update_header) {
571f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    hdr.SetNumStates(num_states);
572f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return FstImpl<A>::UpdateFstHeader(fst, strm, opts, kFileVersion, "vector",
573dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin                                       properties, &hdr, start_offset);
574f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  } else {
575f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (num_states != hdr.NumStates()) {
576f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      LOG(ERROR) << "Inconsistent number of states observed during write";
577f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return false;
578f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
579f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
580f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return true;
581f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
582f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
583f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for VectorFst; see generic version in fst.h
584f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// for sample usage (but use the VectorFst type!). This version
585f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// should inline.
586f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
587f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass ArcIterator< VectorFst<A> > {
588f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
589f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
590f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
591f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ArcIterator(const VectorFst<A> &fst, StateId s)
592f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : arcs_(fst.GetImpl()->GetState(s)->arcs), i_(0) {}
593f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
594f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool Done() const { return i_ >= arcs_.size(); }
595f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
596f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const A& Value() const { return arcs_[i_]; }
597f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
598f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Next() { ++i_; }
599f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
600f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Reset() { i_ = 0; }
601f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
602f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Seek(size_t a) { i_ = a; }
603f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
604f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t Position() const { return i_; }
605f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
606f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint32 Flags() const {
607f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return kArcValueFlags;
608f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
609f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
610f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetFlags(uint32 f, uint32 m) {}
611f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
612f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
613f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const vector<A>& arcs_;
614f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t i_;
615f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
616f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(ArcIterator);
617f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
618f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
619f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for VectorFst; see generic version in fst.h
620f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// for sample usage (but use the VectorFst type!). This version
621f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// should inline.
622f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
623f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass MutableArcIterator< VectorFst<A> >
624f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  : public MutableArcIteratorBase<A> {
625f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
626f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
627f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight Weight;
628f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
629f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MutableArcIterator(VectorFst<A> *fst, StateId s) : i_(0) {
630f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    fst->MutateCheck();
631f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    state_ = fst->GetImpl()->GetState(s);
632f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    properties_ = &fst->GetImpl()->properties_;
633f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
634f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
635f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool Done() const { return i_ >= state_->arcs.size(); }
636f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
637f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const A& Value() const { return state_->arcs[i_]; }
638f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
639f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Next() { ++i_; }
640f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
641f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t Position() const { return i_; }
642f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
643f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Reset() { i_ = 0; }
644f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
645f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Seek(size_t a) { i_ = a; }
646f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
647f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetValue(const A &arc) {
648f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    A& oarc = state_->arcs[i_];
649f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (oarc.ilabel != oarc.olabel)
650f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ &= ~kNotAcceptor;
651f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (oarc.ilabel == 0) {
652f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      --state_->niepsilons;
653f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ &= ~kIEpsilons;
654f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (oarc.olabel == 0)
655f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        *properties_ &= ~kEpsilons;
656f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
657f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (oarc.olabel == 0) {
658f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      --state_->noepsilons;
659f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ &= ~kOEpsilons;
660f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
661f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (oarc.weight != Weight::Zero() && oarc.weight != Weight::One())
662f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ &= ~kWeighted;
663f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    oarc = arc;
664f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.ilabel != arc.olabel) {
665f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ |= kNotAcceptor;
666f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ &= ~kAcceptor;
667f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
668f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.ilabel == 0) {
669f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ++state_->niepsilons;
670f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ |= kIEpsilons;
671f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ &= ~kNoIEpsilons;
672f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (arc.olabel == 0) {
673f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        *properties_ |= kEpsilons;
674f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        *properties_ &= ~kNoEpsilons;
675f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
676f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
677f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.olabel == 0) {
678f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ++state_->noepsilons;
679f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ |= kOEpsilons;
680f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ &= ~kNoOEpsilons;
681f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
682f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (arc.weight != Weight::Zero() && arc.weight != Weight::One()) {
683f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ |= kWeighted;
684f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      *properties_ &= ~kUnweighted;
685f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
686f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    *properties_ &= kSetArcProperties | kAcceptor | kNotAcceptor |
687f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        kEpsilons | kNoEpsilons | kIEpsilons | kNoIEpsilons |
688f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        kOEpsilons | kNoOEpsilons | kWeighted | kUnweighted;
689f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
690f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
691f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint32 Flags() const {
692f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return kArcValueFlags;
693f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
694f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
695f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetFlags(uint32 f, uint32 m) {}
696f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
697f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
698f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
699f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // This allows base-class virtual access to non-virtual derived-
700f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // class members of the same name. It makes the derived class more
701f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // efficient to use but unsafe to further derive.
702f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual bool Done_() const { return Done(); }
703f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual const A& Value_() const { return Value(); }
704f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual void Next_() { Next(); }
705f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual size_t Position_() const { return Position(); }
706f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual void Reset_() { Reset(); }
707f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual void Seek_(size_t a) { Seek(a); }
708f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  virtual void SetValue_(const A &a) { SetValue(a); }
709f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint32 Flags_() const { return Flags(); }
710f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetFlags_(uint32 f, uint32 m) { SetFlags(f, m); }
711f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
712f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  struct VectorState<A> *state_;
713f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 *properties_;
714f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t i_;
715f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
716f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(MutableArcIterator);
717f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
718f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
719f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Provide information needed for the generic mutable arc iterator
720f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> inline
721f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid VectorFst<A>::InitMutableArcIterator(
722f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    StateId s, MutableArcIteratorData<A> *data) {
723f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  data->base = new MutableArcIterator< VectorFst<A> >(this, s);
724f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
725f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
726f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// A useful alias when using StdArc.
727f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef VectorFst<StdArc> StdVectorFst;
728f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
729f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}  // namespace fst
730f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
731f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif  // FST_LIB_VECTOR_FST_H__
732