// map.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
// Class to map over/transform states e.g., sort transitions
// Consider using when operation does not change the number of states.
#ifndef FST_LIB_STATE_MAP_H__
#define FST_LIB_STATE_MAP_H__
#include <algorithm>
#include <tr1/unordered_map>
using std::tr1::unordered_map;
using std::tr1::unordered_multimap;
#include <string>
#include <utility>
using std::pair; using std::make_pair;
#include <fst/cache.h>
#include <fst/arc-map.h>
#include <fst/mutable-fst.h>
namespace fst {
// StateMapper Interface - class determinies how states are mapped.
// Useful for implementing operations that do not change the number of states.
//
// class StateMapper {
// public:
// typedef A FromArc;
// typedef B ToArc;
//
// // Typical constructor
// StateMapper(const Fst<A> &fst);
// // Required copy constructor that allows updating Fst argument;
// // pass only if relevant and changed.
// StateMapper(const StateMapper &mapper, const Fst<A> *fst = 0);
//
// // Specifies initial state of result
// B::StateId Start() const;
// // Specifies state's final weight in result
// B::Weight Final(B::StateId s) const;
//
// // These methods iterate through a state's arcs in result
// // Specifies state to iterate over
// void SetState(B::StateId s);
// // End of arcs?
// bool Done() const;
// // Current arc
// const B &Value() const;
// // Advance to next arc (when !Done)
// void Next();
//
// // Specifies input symbol table action the mapper requires (see above).
// MapSymbolsAction InputSymbolsAction() const;
// // Specifies output symbol table action the mapper requires (see above).
// MapSymbolsAction OutputSymbolsAction() const;
// // This specifies the known properties of an Fst mapped by this
// // mapper. It takes as argument the input Fst's known properties.
// uint64 Properties(uint64 props) const;
// };
//
// We include a various state map versions below. One dimension of
// variation is whether the mapping mutates its input, writes to a
// new result Fst, or is an on-the-fly Fst. Another dimension is how
// we pass the mapper. We allow passing the mapper by pointer
// for cases that we need to change the state of the user's mapper.
// We also include map versions that pass the mapper
// by value or const reference when this suffices.
// Maps an arc type A using a mapper function object C, passed
// by pointer. This version modifies its Fst input.
template<class A, class C>
void StateMap(MutableFst<A> *fst, C* mapper) {
typedef typename A::StateId StateId;
typedef typename A::Weight Weight;
if (mapper->InputSymbolsAction() == MAP_CLEAR_SYMBOLS)
fst->SetInputSymbols(0);
if (mapper->OutputSymbolsAction() == MAP_CLEAR_SYMBOLS)
fst->SetOutputSymbols(0);
if (fst->Start() == kNoStateId)
return;
uint64 props = fst->Properties(kFstProperties, false);
fst->SetStart(mapper->Start());
for (StateId s = 0; s < fst->NumStates(); ++s) {
mapper->SetState(s);
fst->DeleteArcs(s);
for (; !mapper->Done(); mapper->Next())
fst->AddArc(s, mapper->Value());
fst->SetFinal(s, mapper->Final(s));
}
fst->SetProperties(mapper->Properties(props), kFstProperties);
}
// Maps an arc type A using a mapper function object C, passed
// by value. This version modifies its Fst input.
template<class A, class C>
void StateMap(MutableFst<A> *fst, C mapper) {
StateMap(fst, &mapper);
}
// Maps an arc type A to an arc type B using mapper function
// object C, passed by pointer. This version writes the mapped
// input Fst to an output MutableFst.
template<class A, class B, class C>
void StateMap(const Fst<A> &ifst, MutableFst<B> *ofst, C* mapper) {
typedef typename A::StateId StateId;
typedef typename A::Weight Weight;
ofst->DeleteStates();
if (mapper->InputSymbolsAction() == MAP_COPY_SYMBOLS)
ofst->SetInputSymbols(ifst.InputSymbols());
else if (mapper->InputSymbolsAction() == MAP_CLEAR_SYMBOLS)
ofst->SetInputSymbols(0);
if (mapper->OutputSymbolsAction() == MAP_COPY_SYMBOLS)
ofst->SetOutputSymbols(ifst.OutputSymbols());
else if (mapper->OutputSymbolsAction() == MAP_CLEAR_SYMBOLS)
ofst->SetOutputSymbols(0);
uint64 iprops = ifst.Properties(kCopyProperties, false);
if (ifst.Start() == kNoStateId) {
if (iprops & kError) ofst->SetProperties(kError, kError);
return;
}
// Add all states.
if (ifst.Properties(kExpanded, false))
ofst->ReserveStates(CountStates(ifst));
for (StateIterator< Fst<A> > siter(ifst); !siter.Done(); siter.Next())
ofst->AddState();
ofst->SetStart(mapper->Start());
for (StateIterator< Fst<A> > siter(ifst); !siter.Done(); siter.Next()) {
StateId s = siter.Value();
mapper->SetState(s);
for (; !mapper->Done(); mapper->Next())
ofst->AddArc(s, mapper->Value());
ofst->SetFinal(s, mapper->Final(s));
}
uint64 oprops = ofst->Properties(kFstProperties, false);
ofst->SetProperties(mapper->Properties(iprops) | oprops, kFstProperties);
}
// Maps an arc type A to an arc type B using mapper function
// object C, passed by value. This version writes the mapped input
// Fst to an output MutableFst.
template<class A, class B, class C>
void StateMap(const Fst<A> &ifst, MutableFst<B> *ofst, C mapper) {
StateMap(ifst, ofst, &mapper);
}
typedef CacheOptions StateMapFstOptions;
template <class A, class B, class C> class StateMapFst;
// Implementation of delayed StateMapFst.
template <class A, class B, class C>
class StateMapFstImpl : public CacheImpl<B> {
public:
using FstImpl<B>::SetType;
using FstImpl<B>::SetProperties;
using FstImpl<B>::SetInputSymbols;
using FstImpl<B>::SetOutputSymbols;
using VectorFstBaseImpl<typename CacheImpl<B>::State>::NumStates;
using CacheImpl<B>::PushArc;
using CacheImpl<B>::HasArcs;
using CacheImpl<B>::HasFinal;
using CacheImpl<B>::HasStart;
using CacheImpl<B>::SetArcs;
using CacheImpl<B>::SetFinal;
using CacheImpl<B>::SetStart;
friend class StateIterator< StateMapFst<A, B, C> >;
typedef B Arc;
typedef typename B::Weight Weight;
typedef typename B::StateId StateId;
StateMapFstImpl(const Fst<A> &fst, const C &mapper,
const StateMapFstOptions& opts)
: CacheImpl<B>(opts),
fst_(fst.Copy()),
mapper_(new C(mapper, fst_)),
own_mapper_(true) {
Init();
}
StateMapFstImpl(const Fst<A> &fst, C *mapper,
const StateMapFstOptions& opts)
: CacheImpl<B>(opts),
fst_(fst.Copy()),
mapper_(mapper),
own_mapper_(false) {
Init();
}
StateMapFstImpl(const StateMapFstImpl<A, B, C> &impl)
: CacheImpl<B>(impl),
fst_(impl.fst_->