14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// vector-fst.h
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Licensed under the Apache License, Version 2.0 (the "License");
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// you may not use this file except in compliance with the License.
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// You may obtain a copy of the License at
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//      http://www.apache.org/licenses/LICENSE-2.0
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Unless required by applicable law or agreed to in writing, software
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// distributed under the License is distributed on an "AS IS" BASIS,
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// See the License for the specific language governing permissions and
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// limitations under the License.
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \file
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Simple concrete, mutable FST whose states and arcs are stored in STL
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// vectors.
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef FST_LIB_VECTOR_FST_H__
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define FST_LIB_VECTOR_FST_H__
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <string>
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <string.h>
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/mutable-fst.h"
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/test-properties.h"
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectnamespace fst {
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A> class VectorFst;
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// States and arcs implemented by STL vectors, templated on the
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// State definition. This does not manage the Fst properties.
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class State>
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass VectorFstBaseImpl : public FstImpl<typename State::Arc> {
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename State::Arc Arc;
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename Arc::Weight Weight;
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename Arc::StateId StateId;
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  VectorFstBaseImpl() : start_(kNoStateId) {}
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ~VectorFstBaseImpl() {
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (StateId s = 0; s < (StateId)states_.size(); ++s)
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      delete states_[s];
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId Start() const { return start_; }
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Weight Final(StateId s) const { return states_[s]->final; }
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId NumStates() const { return states_.size(); }
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t NumArcs(StateId s) const { return states_[s]->arcs.size(); }
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void SetStart(StateId s) { start_ = s; }
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void SetFinal(StateId s, Weight w) { states_[s]->final = w; }
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId AddState() {
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    states_.push_back(new State);
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return states_.size() - 1;
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId AddState(State *state) {
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    states_.push_back(state);
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return states_.size() - 1;
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void AddArc(StateId s, const Arc &arc) {
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    states_[s]->arcs.push_back(arc);
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void DeleteStates(const vector<StateId>& dstates) {
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    vector<StateId> newid(states_.size(), 0);
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (size_t i = 0; i < dstates.size(); ++i)
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      newid[dstates[i]] = kNoStateId;
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    StateId nstates = 0;
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (StateId s = 0; s < (StateId)states_.size(); ++s) {
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (newid[s] != kNoStateId) {
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        newid[s] = nstates;
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (s != nstates)
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          states_[nstates] = states_[s];
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        ++nstates;
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      } else {
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        delete states_[s];
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    states_.resize(nstates);
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (StateId s = 0; s < (StateId)states_.size(); ++s) {
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      vector<Arc> &arcs = states_[s]->arcs;
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      size_t narcs = 0;
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      for (size_t i = 0; i < arcs.size(); ++i) {
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        StateId t = newid[arcs[i].nextstate];
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (t != kNoStateId) {
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          arcs[i].nextstate = t;
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          if (i != narcs)
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            arcs[narcs] = arcs[i];
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          ++narcs;
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        } else {
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          if (arcs[i].ilabel == 0)
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            --states_[s]->niepsilons;
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          if (arcs[i].olabel == 0)
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            --states_[s]->noepsilons;
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      arcs.resize(narcs);
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (Start() != kNoStateId)
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetStart(newid[Start()]);
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void DeleteStates() {
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (StateId s = 0; s < (StateId)states_.size(); ++s)
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      delete states_[s];
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    states_.clear();
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetStart(kNoStateId);
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void DeleteArcs(StateId s, size_t n) {
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    states_[s]->arcs.resize(states_[s]->arcs.size() - n);
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void DeleteArcs(StateId s) { states_[s]->arcs.clear(); }
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  State *GetState(StateId s) { return states_[s]; }
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const State *GetState(StateId s) const { return states_[s]; }
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void SetState(StateId s, State *state) { states_[s] = state; }
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void ReserveStates(StateId n) { states_.reserve(n); }
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void ReserveArcs(StateId s, size_t n) { states_[s]->arcs.reserve(n); }
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Provide information needed for generic state iterator
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void InitStateIterator(StateIteratorData<Arc> *data) const {
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->base = 0;
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->nstates = states_.size();
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Provide information needed for generic arc iterator
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const {
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->base = 0;
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->narcs = states_[s]->arcs.size();
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->arcs = data->narcs > 0 ? &states_[s]->arcs[0] : 0;
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    data->ref_count = 0;
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  vector<State *> states_;      // States represenation.
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId start_;               // initial state
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(VectorFstBaseImpl);
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Arcs implemented by an STL vector per state.
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstruct VectorState {
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef A Arc;
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Weight Weight;
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  VectorState() : final(Weight::Zero()), niepsilons(0), noepsilons(0) {}
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Weight final;              // Final weight
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  vector<A> arcs;            // Arcs represenation
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t niepsilons;         // # of input epsilons
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t noepsilons;         // # of output epsilons
1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// This is a VectorFstBaseImpl container that holds VectorState's.  It
1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// manages Fst properties and the # of input and output epsilons.
1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass VectorFstImpl : public VectorFstBaseImpl< VectorState<A> > {
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::SetType;
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::SetProperties;
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::Properties;
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using FstImpl<A>::WriteHeaderAndSymbols;
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using VectorFstBaseImpl<VectorState<A> >::Start;
1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  using VectorFstBaseImpl<VectorState<A> >::NumStates;
1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  friend class MutableArcIterator< VectorFst<A> >;
1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef VectorFstBaseImpl< VectorState<A> > BaseImpl;
1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Weight Weight;
1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  VectorFstImpl() {
1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetType("vector");
1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(kNullProperties | kStaticProperties);
1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit VectorFstImpl(const Fst<A> &fst);
1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static VectorFstImpl<A> *Read(istream &strm, const FstReadOptions &opts);
1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
200ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton  size_t NumInputEpsilons(StateId s) const { return this->GetState(s)->niepsilons; }
2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
202ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton  size_t NumOutputEpsilons(StateId s) const { return this->GetState(s)->noepsilons; }
2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool Write(ostream &strm, const FstWriteOptions &opts) const;
2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void SetStart(StateId s) {
2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    BaseImpl::SetStart(s);
2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(Properties() & kSetStartProperties);
2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (Properties() & kAcyclic)
2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() | kInitialAcyclic);
2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void SetFinal(StateId s, Weight w) {
214ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton    Weight ow = this->Final(s);
2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (ow != Weight::Zero() && ow != Weight::One())
2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() & ~kWeighted);
2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    BaseImpl::SetFinal(s, w);
2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (w != Weight::Zero() && w != Weight::One()) {
2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() | kWeighted);
2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() & ~kUnweighted);
2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(Properties() &
2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                  (kSetFinalProperties | kWeighted | kUnweighted));
2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId AddState() {
2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    StateId s = BaseImpl::AddState();
2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(Properties() & kAddStateProperties);
2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return s;
2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void AddArc(StateId s, const A &arc) {
233ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton    VectorState<A> *state = this->GetState(s);
2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (arc.ilabel != arc.olabel) {
2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() | kNotAcceptor);
2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() & ~kAcceptor);
2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (arc.ilabel == 0) {
2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ++state->niepsilons;
2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() | kIEpsilons);
2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() & ~kNoIEpsilons);
2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arc.olabel == 0) {
2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        SetProperties(Properties() | kEpsilons);
2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        SetProperties(Properties() & ~kNoEpsilons);
2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (arc.olabel == 0) {
2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ++state->noepsilons;
2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() | kOEpsilons);
2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() & ~kNoOEpsilons);
2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!state->arcs.empty()) {
2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      A &parc = state->arcs.back();
2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (parc.ilabel > arc.ilabel) {
2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        SetProperties(Properties() | kNotILabelSorted);
2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        SetProperties(Properties() & ~kILabelSorted);
2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (parc.olabel > arc.olabel) {
2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        SetProperties(Properties() | kNotOLabelSorted);
2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        SetProperties(Properties() & ~kOLabelSorted);
2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (arc.weight != Weight::Zero() && arc.weight != Weight::One()) {
2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() | kWeighted);
2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() & ~kUnweighted);
2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (arc.nextstate <= s) {
2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() | kNotTopSorted);
2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() & ~kTopSorted);
2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(Properties() &
2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                  (kAddArcProperties | kAcceptor |
2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                   kNoEpsilons | kNoIEpsilons | kNoOEpsilons |
2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                   kILabelSorted | kOLabelSorted | kUnweighted | kTopSorted));
2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (Properties() & kTopSorted)
2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SetProperties(Properties() | kAcyclic | kInitialAcyclic);
2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    BaseImpl::AddArc(s, arc);
2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void DeleteStates(const vector<StateId> &dstates) {
2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    BaseImpl::DeleteStates(dstates);
2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(Properties() & kDeleteStatesProperties);
2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void DeleteStates() {
2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    BaseImpl::DeleteStates();
2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(kNullProperties | kStaticProperties);
2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void DeleteArcs(StateId s, size_t n) {
291ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton    const vector<A> &arcs = this->GetState(s)->arcs;
2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (size_t i = 0; i < n; ++i) {
2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      size_t j = arcs.size() - i - 1;
2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arcs[j].ilabel == 0)
295ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton        --this->GetState(s)->niepsilons;
2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arcs[j].olabel == 0)
297ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton        --this->GetState(s)->noepsilons;
2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    BaseImpl::DeleteArcs(s, n);
3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(Properties() & kDeleteArcsProperties);
3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void DeleteArcs(StateId s) {
304ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton    this->GetState(s)->niepsilons = 0;
305ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton    this->GetState(s)->noepsilons = 0;
3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    BaseImpl::DeleteArcs(s);
3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    SetProperties(Properties() & kDeleteArcsProperties);
3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Properties always true of this Fst class
3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static const uint64 kStaticProperties = kExpanded | kMutable;
3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Current file format version
3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static const int kFileVersion = 2;
3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Minimum file format version supported
3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static const int kMinFileVersion = 2;
3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(VectorFstImpl);
3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectVectorFstImpl<A>::VectorFstImpl(const Fst<A> &fst) {
3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  SetType("vector");
3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  SetProperties(fst.Properties(kCopyProperties, false) | kStaticProperties);
325ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton  this->SetInputSymbols(fst.InputSymbols());
326ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton  this->SetOutputSymbols(fst.OutputSymbols());
3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  BaseImpl::SetStart(fst.Start());
3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (StateIterator< Fst<A> > siter(fst);
3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       !siter.Done();
3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       siter.Next()) {
3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    StateId s = siter.Value();
3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    BaseImpl::AddState();
3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    BaseImpl::SetFinal(s, fst.Final(s));
335ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton    this->ReserveArcs(s, fst.NumArcs(s));
3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ArcIterator< Fst<A> > aiter(fst, s);
3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         !aiter.Done();
3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         aiter.Next()) {
3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      const A &arc = aiter.Value();
3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      BaseImpl::AddArc(s, arc);
3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arc.ilabel == 0)
342ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton        ++this->GetState(s)->niepsilons;
3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arc.olabel == 0)
344ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton        ++this->GetState(s)->noepsilons;
3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectVectorFstImpl<A> *VectorFstImpl<A>::Read(istream &strm,
3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                         const FstReadOptions &opts) {
3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  VectorFstImpl<A> *impl = new VectorFstImpl;
3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FstHeader hdr;
3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (!impl->ReadHeaderAndSymbols(strm, opts, kMinFileVersion, &hdr))
3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  impl->BaseImpl::SetStart(hdr.Start());
3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  impl->ReserveStates(hdr.NumStates());
3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (StateId s = 0; s < hdr.NumStates(); ++s) {
3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl->BaseImpl::AddState();
3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    VectorState<A> *state = impl->GetState(s);
3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    state->final.Read(strm);
3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int64 narcs;
3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ReadType(strm, &narcs);
3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!strm) {
3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      LOG(ERROR) << "VectorFst::Read: read failed: " << opts.source;
3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return 0;
3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl->ReserveArcs(s, narcs);
3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (size_t j = 0; j < narcs; ++j) {
3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      A arc;
3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ReadType(strm, &arc.ilabel);
3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ReadType(strm, &arc.olabel);
3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      arc.weight.Read(strm);
3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ReadType(strm, &arc.nextstate);
3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (!strm) {
3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        LOG(ERROR) << "VectorFst::Read: read failed: " << opts.source;
3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return 0;
3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      impl->BaseImpl::AddArc(s, arc);
3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arc.ilabel == 0)
3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        ++state->niepsilons;
3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arc.olabel == 0)
3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        ++state->noepsilons;
3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return impl;
3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Converts a string into a weight.
3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class W> class WeightFromString {
3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  W operator()(const string &s);
3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Generic case fails.
3974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class W> inline
3984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectW WeightFromString<W>::operator()(const string &s) {
3994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LOG(FATAL) << "VectorFst::Read: Obsolete file format";
4004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return W();
4014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// TropicalWeight version.
4044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <> inline
4054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectTropicalWeight WeightFromString<TropicalWeight>::operator()(const string &s) {
4064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  float f;
4074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  memcpy(&f, s.data(), sizeof(f));
4084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return TropicalWeight(f);
4094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// LogWeight version.
4124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <> inline
4134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectLogWeight WeightFromString<LogWeight>::operator()(const string &s) {
4144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  float f;
4154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  memcpy(&f, s.data(), sizeof(f));
4164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return LogWeight(f);
4174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
4204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectbool VectorFstImpl<A>::Write(ostream &strm,
4214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                             const FstWriteOptions &opts) const {
4224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FstHeader hdr;
4234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  hdr.SetStart(Start());
4244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  hdr.SetNumStates(NumStates());
4254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  WriteHeaderAndSymbols(strm, opts, kFileVersion, &hdr);
4264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (!strm)
4274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return false;
4284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (StateId s = 0; s < NumStates(); ++s) {
430ea4ad6085a8661b5513c394316108c0ef26f3e7bAl Sutton    const VectorState<A> *state = this->GetState(s);
4314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    state->final.Write(strm);
4324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int64 narcs = state->arcs.size();
4334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    WriteType(strm, narcs);
4344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (size_t a = 0; a < narcs; ++a) {
4354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      const A &arc = state->arcs[a];
4364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      WriteType(strm, arc.ilabel);
4374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      WriteType(strm, arc.olabel);
4384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      arc.weight.Write(strm);
4394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      WriteType(strm, arc.nextstate);
4404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
4414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  strm.flush();
4434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (!strm)
4444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    LOG(ERROR) << "VectorFst::Write: write failed: " << opts.source;
4454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return strm;
4464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Simple concrete, mutable FST. Supports additional operations:
4494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// ReserveStates and ReserveArcs (cf. STL vectors). This class
4504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// attaches interface to implementation and handles reference
4514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// counting.
4524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
4534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass VectorFst : public MutableFst<A> {
4544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
4554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  friend class StateIterator< VectorFst<A> >;
4564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  friend class ArcIterator< VectorFst<A> >;
4574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  friend class MutableArcIterator< VectorFst<A> >;
4584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef A Arc;
4604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Weight Weight;
4614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
4624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  VectorFst() : impl_(new VectorFstImpl<A>) {}
4644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  VectorFst(const VectorFst<A> &fst) : MutableFst<A>(fst), impl_(fst.impl_) {
4664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->IncrRefCount();
4674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit VectorFst(const Fst<A> &fst) : impl_(new VectorFstImpl<A>(fst)) {}
4694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual ~VectorFst() { if (!impl_->DecrRefCount()) delete impl_; }
4714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  VectorFst<A> &operator=(const VectorFst<A> &fst) {
4734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (this != &fst) {
4744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (!impl_->DecrRefCount()) delete impl_;
4754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      fst.impl_->IncrRefCount();
4764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      impl_ = fst.impl_;
4774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
4784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return *this;
4794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual VectorFst<A> &operator=(const Fst<A> &fst) {
4824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (this != &fst) {
4834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (!impl_->DecrRefCount()) delete impl_;
4844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      impl_ = new VectorFstImpl<A>(fst);
4854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
4864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return *this;
4874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual StateId Start() const { return impl_->Start(); }
4904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual Weight Final(StateId s) const { return impl_->Final(s); }
4924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual StateId NumStates() const { return impl_->NumStates(); }
4944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual size_t NumArcs(StateId s) const { return impl_->NumArcs(s); }
4964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual size_t NumInputEpsilons(StateId s) const {
4984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->NumInputEpsilons(s);
4994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual size_t NumOutputEpsilons(StateId s) const {
5024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->NumOutputEpsilons(s);
5034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual uint64 Properties(uint64 mask, bool test) const {
5064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (test) {
5074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      uint64 known, test = TestProperties(*this, mask, &known);
5084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      impl_->SetProperties(test, known);
5094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return test & mask;
5104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    } else {
5114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return impl_->Properties(mask);
5124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
5134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual const string& Type() const { return impl_->Type(); }
5164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Get a copy of this VectorFst
5184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual VectorFst<A> *Copy() const {
5194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->IncrRefCount();
5204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return new VectorFst<A>(impl_);
5214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Read a VectorFst from an input stream; return NULL on error
5244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static VectorFst<A> *Read(istream &strm, const FstReadOptions &opts) {
5254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    VectorFstImpl<A>* impl = VectorFstImpl<A>::Read(strm, opts);
5264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl ? new VectorFst<A>(impl) : 0;
5274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Read a VectorFst from a file; return NULL on error
5304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static VectorFst<A> *Read(const string &filename) {
5314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    ifstream strm(filename.c_str());
5324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!strm) {
5334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      LOG(ERROR) << "VectorFst::Read: Can't open file: " << filename;
5344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return 0;
5354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
5364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return Read(strm, FstReadOptions(filename));
5374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Write a VectorFst to an output stream; return false on error
5404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual bool Write(ostream &strm, const FstWriteOptions &opts) const {
5414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->Write(strm, opts);
5424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Write a VectorFst to a file; return false on error
5454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual bool Write(const string &filename) const {
5464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!filename.empty()) {
5474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ofstream strm(filename.c_str());
5484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (!strm) {
5494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        LOG(ERROR) << "VectorFst::Write: Can't open file: " << filename;
5504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return false;
5514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
5524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return Write(strm, FstWriteOptions(filename));
5534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    } else {
5544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return Write(std::cout, FstWriteOptions("standard output"));
5554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
5564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual SymbolTable* InputSymbols() {
5594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->InputSymbols();
5604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual SymbolTable* OutputSymbols() {
5634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->OutputSymbols();
5644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual const SymbolTable* InputSymbols() const {
5674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->InputSymbols();
5684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual const SymbolTable* OutputSymbols() const {
5714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->OutputSymbols();
5724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void SetStart(StateId s) {
5754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
5764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->SetStart(s);
5774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void SetFinal(StateId s, Weight w) {
5804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
5814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->SetFinal(s, w);
5824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void SetProperties(uint64 props, uint64 mask) {
5854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->SetProperties(props, mask);
5864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual StateId AddState() {
5894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
5904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return impl_->AddState();
5914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void AddArc(StateId s, const A &arc) {
5944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
5954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->AddArc(s, arc);
5964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
5974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
5984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void DeleteStates(const vector<StateId> &dstates) {
5994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
6004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->DeleteStates(dstates);
6014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void DeleteStates() {
6044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
6054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->DeleteStates();
6064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void DeleteArcs(StateId s, size_t n) {
6094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
6104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->DeleteArcs(s, n);
6114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void DeleteArcs(StateId s) {
6144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
6154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->DeleteArcs(s);
6164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void SetInputSymbols(const SymbolTable* isyms) {
6194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
6204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->SetInputSymbols(isyms);
6214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void SetOutputSymbols(const SymbolTable* osyms) {
6244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
6254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->SetOutputSymbols(osyms);
6264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void ReserveStates(StateId n) {
6294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
6304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->ReserveStates(n);
6314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void ReserveArcs(StateId s, size_t n) {
6344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MutateCheck();
6354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->ReserveArcs(s, n);
6364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void InitStateIterator(StateIteratorData<A> *data) const {
6394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->InitStateIterator(data);
6404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void InitArcIterator(StateId s, ArcIteratorData<A> *data) const {
6434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    impl_->InitArcIterator(s, data);
6444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual inline
6474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void InitMutableArcIterator(StateId s, MutableArcIteratorData<A> *);
6484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
6504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit VectorFst(VectorFstImpl<A> *impl) : impl_(impl) {}
6514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void MutateCheck() {
6534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    // Copy on write
6544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (impl_->RefCount() > 1) {
6554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      impl_->DecrRefCount();
6564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      impl_ = new VectorFstImpl<A>(*this);
6574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
6584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
6594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  VectorFstImpl<A> *impl_;  // FST's impl
6614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
6624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Specialization for VectorFst; see generic version in fst.h
6644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// for sample usage (but use the VectorFst type!). This version
6654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// should inline.
6664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
6674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass StateIterator< VectorFst<A> > {
6684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
6694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
6704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  explicit StateIterator(const VectorFst<A> &fst)
6724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : nstates_(fst.impl_->NumStates()), s_(0) {}
6734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool Done() const { return s_ >= nstates_; }
6754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId Value() const { return s_; }
6774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Next() { ++s_; }
6794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Reset() { s_ = 0; }
6814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
6834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId nstates_;
6844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StateId s_;
6854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(StateIterator);
6874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
6884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Specialization for VectorFst; see generic version in fst.h
6904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// for sample usage (but use the VectorFst type!). This version
6914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// should inline.
6924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
6934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass ArcIterator< VectorFst<A> > {
6944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
6954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
6964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
6974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ArcIterator(const VectorFst<A> &fst, StateId s)
6984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : arcs_(fst.impl_->GetState(s)->arcs), i_(0) {}
6994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool Done() const { return i_ >= arcs_.size(); }
7014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const A& Value() const { return arcs_[i_]; }
7034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Next() { ++i_; }
7054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Reset() { i_ = 0; }
7074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  void Seek(size_t a) { i_ = a; }
7094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
7114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  const vector<A>& arcs_;
7124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t i_;
7134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(ArcIterator);
7154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
7164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Specialization for VectorFst; see generic version in fst.h
7184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// for sample usage (but use the VectorFst type!). This version
7194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// should inline.
7204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A>
7214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass MutableArcIterator< VectorFst<A> >
7224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  : public MutableArcIteratorBase<A> {
7234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
7244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::StateId StateId;
7254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename A::Weight Weight;
7264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  MutableArcIterator(VectorFst<A> *fst, StateId s) : i_(0) {
7284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    fst->MutateCheck();
7294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    state_ = fst->impl_->GetState(s);
7304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    properties_ = &fst->impl_->properties_;
7314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
7324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual bool Done() const { return i_ >= state_->arcs.size(); }
7344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual const A& Value() const { return state_->arcs[i_]; }
7364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void Next() { ++i_; }
7384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void Reset() { i_ = 0; }
7404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void Seek(size_t a) { i_ = a; }
7424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  virtual void SetValue(const A &arc) {
7444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    A& oarc = state_->arcs[i_];
7454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (oarc.ilabel != oarc.olabel)
7464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      *properties_ &= ~kNotAcceptor;
7474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (oarc.ilabel == 0) {
7484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      --state_->niepsilons;
7494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      *properties_ &= ~kIEpsilons;
7504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (oarc.olabel == 0)
7514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        *properties_ &= ~kEpsilons;
7524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
7534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (oarc.olabel == 0) {
7544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      --state_->noepsilons;
7554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      *properties_ &= ~kOEpsilons;
7564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
7574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (oarc.weight != Weight::Zero() && oarc.weight != Weight::One())
7584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      *properties_ &= ~kWeighted;
7594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    oarc = arc;
7604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (arc.ilabel != arc.olabel)
7614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      *properties_ |= kNotAcceptor;
7624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (arc.ilabel == 0) {
7634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ++state_->niepsilons;
7644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      *properties_ |= kIEpsilons;
7654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (arc.olabel == 0)
7664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        *properties_ |= kEpsilons;
7674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
7684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (arc.olabel == 0) {
7694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ++state_->noepsilons;
7704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      *properties_ |= kOEpsilons;
7714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
7724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (arc.weight != Weight::Zero() && arc.weight != Weight::One())
7734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      *properties_ |= kWeighted;
7744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *properties_ &= kSetArcProperties | kNotAcceptor |
7754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    kEpsilons | kIEpsilons | kOEpsilons | kWeighted;
7764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
7774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
7794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  struct VectorState<A> *state_;
7804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  uint64 *properties_;
7814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t i_;
7824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  DISALLOW_EVIL_CONSTRUCTORS(MutableArcIterator);
7844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
7854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Provide information needed for the generic mutable arc iterator
7874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class A> inline
7884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid VectorFst<A>::InitMutableArcIterator(
7894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    StateId s, MutableArcIteratorData<A> *data) {
7904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  data->base = new MutableArcIterator< VectorFst<A> >(this, s);
7914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
7924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// A useful alias when using StdArc.
7944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef VectorFst<StdArc> StdVectorFst;
7954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}  // namespace fst
7974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
7984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif  // FST_LIB_VECTOR_FST_H__
799