// const-fst.h
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2005-2010 Google, Inc.
// Author: riley@google.com (Michael Riley)
//
// \file
// Simple concrete immutable FST whose states and arcs are each stored
// in single arrays.
#ifndef FST_LIB_CONST_FST_H__
#define FST_LIB_CONST_FST_H__
#include <string>
#include <vector>
using std::vector;
#include <fst/expanded-fst.h>
#include <fst/fst-decl.h> // For optional argument declarations
#include <fst/mapped-file.h>
#include <fst/test-properties.h>
#include <fst/util.h>
namespace fst {
template <class A, class U> class ConstFst;
template <class F, class G> void Cast(const F &, G *);
// States and arcs each implemented by single arrays, templated on the
// Arc definition. The unsigned type U is used to represent indices into
// the arc array.
template <class A, class U>
class ConstFstImpl : public FstImpl<A> {
public:
using FstImpl<A>::SetInputSymbols;
using FstImpl<A>::SetOutputSymbols;
using FstImpl<A>::SetType;
using FstImpl<A>::SetProperties;
using FstImpl<A>::Properties;
typedef A Arc;
typedef typename A::Weight Weight;
typedef typename A::StateId StateId;
typedef U Unsigned;
ConstFstImpl()
: states_region_(0), arcs_region_(0), states_(0), arcs_(0), nstates_(0),
narcs_(0), start_(kNoStateId) {
string type = "const";
if (sizeof(U) != sizeof(uint32)) {
string size;
Int64ToStr(8 * sizeof(U), &size);
type += size;
}
SetType(type);
SetProperties(kNullProperties | kStaticProperties);
}
explicit ConstFstImpl(const Fst<A> &fst);
~ConstFstImpl() {
delete arcs_region_;
delete states_region_;
}
StateId Start() const { return start_; }
Weight Final(StateId s) const { return states_[s].final; }
StateId NumStates() const { return nstates_; }
size_t NumArcs(StateId s) const { return states_[s].narcs; }
size_t NumInputEpsilons(StateId s) const { return states_[s].niepsilons; }
size_t NumOutputEpsilons(StateId s) const { return states_[s].noepsilons; }
static ConstFstImpl<A, U> *Read(istream &strm, const FstReadOptions &opts);
A *Arcs(StateId s) { return arcs_ + states_[s].pos; }
// Provide information needed for generic state iterator
void InitStateIterator(StateIteratorData<A> *data) const {
data->base = 0;
data->nstates = nstates_;
}
// Provide information needed for the generic arc iterator
void InitArcIterator(StateId s, ArcIteratorData<A> *data) const {
data->base = 0;
data->arcs = arcs_ + states_[s].pos;
data->narcs = states_[s].narcs;
data->ref_count = 0;
}
private:
friend class ConstFst<A, U>; // Allow finding narcs_, nstates_ during Write
// States implemented by array *states_ below, arcs by (single) *arcs_.
struct State {
Weight final; // Final weight
Unsigned pos; // Start of state's arcs in *arcs_
Unsigned narcs; // Number of arcs (per state)
Unsigned niepsilons; // # of input epsilons
Unsigned noepsilons; // # of output epsilons
State() : final(Weight::Zero()), niepsilons(0), noepsilons(0) {}
};
// Properties always true of this Fst class
static const uint64 kStaticProperties = kExpanded;
// Current unaligned file format version. The unaligned version was added and
// made the default since the aligned version does not work on pipes.
static const int kFileVersion = 2;
// Current aligned file format version
static const int kAlignedFileVersion = 1;
// Minimum file format version supported
static const int kMinFileVersion = 1;
MappedFile *states_region_; // Mapped file for states
MappedFile *arcs_region_; // Mapped file for arcs
State *states_; // States represenation
A *arcs_; // Arcs representation
StateId nstates_; // Number of states
size_t narcs_; // Number of arcs (per FST)
StateId start_; // Initial state
DISALLOW_COPY_AND_ASSIGN(ConstFstImpl);
};
template <class A, class U>
const uint64 ConstFstImpl<A, U>::kStaticProperties;
template <class A, class U>
const int ConstFstImpl<A, U>::kFileVersion;
template <class A, class U>
const int ConstFstImpl<A, U>::kAlignedFileVersion;
template <class A, class U>
const int ConstFstImpl<A, U>::kMinFileVersion;
template<class A, class U>
ConstFstImpl<A, U>::ConstFstImpl(const Fst<A> &fst) : nstates_(0), narcs_(0) {
string type = "const";
if (sizeof(U) != sizeof(uint32)) {
string size;
Int64ToStr(sizeof(U) * 8, &size);
type += size;
}
SetType(type);
SetInputSymbols(fst.InputSymbols());
SetOutputSymbols(fst.OutputSymbols());
start_ = fst.Start();
// Count # of states and arcs.
for (StateIterator< Fst<A> > siter(fst);
!siter.Done();
siter.Next()) {
++nstates_;
StateId s = siter.Value();
for (ArcIterator< Fst<A> > aiter(fst, s);
!aiter.Done();
aiter.Next())
++narcs_;
}
states_region_ = MappedFile::Allocate(nstates_ * sizeof(*states_));
arcs_region_ = MappedFile::Allocate(narcs_ * sizeof(*arcs_));
states_ = reinterpret_cast<State*>(states_region_->mutable_data());
arcs_ = reinterpret_cast<A*>(arcs_region_->mutable_data());
size_t pos = 0;
for (StateId s = 0; s < nstates_; ++s) {
states_[s].final = fst.Final(s);
states_[s].pos = pos;
states_[s].narcs = 0;
states_[s].niepsilons = 0;
states_[s].noepsilons = 0;
for (ArcIterator< Fst<A> > aiter(fst, s);
!aiter.Done();
aiter.Next()) {
const A &arc = aiter.Value();
++states_[s].narcs;
if (arc.ilabel == 0)
++states_[s].niepsilons;
if (arc.olabel == 0)
++states_[s].noepsilons;
arcs_[pos++] = arc;
}
}
SetProperties(fst.Properties(kCopyProperties, true) | kStaticProperties);
}
template<class A, class U>
ConstFstImpl