| // 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. |
| // |
| // |
| // \file |
| // Class to map over/transform arcs e.g., change semirings or |
| // implement project/invert. |
| |
| #ifndef FST_LIB_MAP_H__ |
| #define FST_LIB_MAP_H__ |
| |
| #include "fst/lib/cache.h" |
| #include "fst/lib/mutable-fst.h" |
| |
| namespace fst { |
| |
| // This determines how final weights are mapped. |
| enum MapFinalAction { |
| |
| // A final weight is mapped into a final weight. An error |
| // is raised if this is not possible. |
| MAP_NO_SUPERFINAL, |
| |
| // A final weight is mapped to an arc to the superfinal state |
| // when the result cannot be represented as a final weight. |
| // The superfinal state will be added only if it is needed. |
| MAP_ALLOW_SUPERFINAL, |
| |
| // A final weight is mapped to an arc to the superfinal state |
| // unless the result can be represented as a final weight of weight |
| // Zero(). The superfinal state is always added (if the input is |
| // not the empty Fst). |
| MAP_REQUIRE_SUPERFINAL |
| }; |
| |
| // Mapper Interface - class determinies how arcs and final weights |
| // are mapped. |
| // |
| // class Mapper { |
| // public: |
| // // Maps an arc type A to arc type B. |
| // B operator()(const A &arc); |
| // // Specifies final action the mapper requires (see above). |
| // // The mapper will be passed final weights as arcs of the |
| // // form A(0, 0, weight, kNoStateId). |
| // MapFinalAction FinalAction() 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; |
| // } |
| // |
| // The Map functions and classes below will use the FinalAction() |
| // method of the mapper to determine how to treat final weights, |
| // e.g. whether to add a superfinal state. They will use the Properties() |
| // method to set the result Fst properties. |
| // |
| // We include a various 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. |
| // This is the case with the encode mapper, which is reused during |
| // decoding. 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 Map(MutableFst<A> *fst, C* mapper) { |
| typedef typename A::StateId StateId; |
| typedef typename A::Weight Weight; |
| |
| if (fst->Start() == kNoStateId) |
| return; |
| |
| uint64 props = fst->Properties(kFstProperties, false); |
| |
| MapFinalAction final_action = mapper->FinalAction(); |
| StateId superfinal = kNoStateId; |
| if (final_action == MAP_REQUIRE_SUPERFINAL) { |
| superfinal = fst->AddState(); |
| fst->SetFinal(superfinal, Weight::One()); |
| } |
| |
| for (StateId s = 0; s < fst->NumStates(); ++s) { |
| for (MutableArcIterator< MutableFst<A> > aiter(fst, s); |
| !aiter.Done(); aiter.Next()) { |
| const A &arc = aiter.Value(); |
| aiter.SetValue((*mapper)(arc)); |
| } |
| |
| switch (final_action) { |
| case MAP_NO_SUPERFINAL: |
| default: { |
| A final_arc = (*mapper)(A(0, 0, fst->Final(s), kNoStateId)); |
| CHECK(final_arc.ilabel == 0 && final_arc.olabel == 0); |
| fst->SetFinal(s, final_arc.weight); |
| break; |
| } |
| case MAP_ALLOW_SUPERFINAL: { |
| if (s != superfinal) { |
| A final_arc = (*mapper)(A(0, 0, fst->Final(s), kNoStateId)); |
| if (final_arc.ilabel != 0 || final_arc.olabel != 0) { |
| // Add a superfinal state if not already done. |
| if (superfinal == kNoStateId) { |
| superfinal = fst->AddState(); |
| fst->SetFinal(superfinal, Weight::One()); |
| } |
| final_arc.nextstate = superfinal; |
| fst->AddArc(s, final_arc); |
| fst->SetFinal(s, Weight::Zero()); |
| } else { |
| fst->SetFinal(s, final_arc.weight); |
| } |
| break; |
| } |
| } |
| case MAP_REQUIRE_SUPERFINAL: { |
| if (s != superfinal) { |
| A final_arc = (*mapper)(A(0, 0, fst->Final(s), kNoStateId)); |
| if (final_arc.ilabel != 0 || final_arc.olabel != 0 || |
| final_arc.weight != Weight::Zero()) |
| fst->AddArc(s, A(final_arc.ilabel, final_arc.olabel, |
| final_arc.weight, superfinal)); |
| fst->SetFinal(s, Weight::Zero()); |
| } |
| break; |
| } |
| } |
| } |
| 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 Map(MutableFst<A> *fst, C mapper) { |
| Map(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 Map(const Fst<A> &ifst, MutableFst<B> *ofst, C* mapper) { |
| typedef typename A::StateId StateId; |
| typedef typename A::Weight Weight; |
| |
| ofst->DeleteStates(); |
| ofst->SetInputSymbols(ifst.InputSymbols()); |
| ofst->SetOutputSymbols(ifst.OutputSymbols()); |
| |
| if (ifst.Start() == kNoStateId) |
| return; |
| |
| // Add all states. |
| for (StateIterator< Fst<A> > siter(ifst); !siter.Done(); siter.Next()) |
| ofst->AddState(); |
| |
| MapFinalAction final_action = mapper->FinalAction(); |
| StateId superfinal = kNoStateId; |
| if (final_action == MAP_REQUIRE_SUPERFINAL) { |
| superfinal = ofst->AddState(); |
| ofst->SetFinal(superfinal, B::Weight::One()); |
| } |
| for (StateIterator< Fst<A> > siter(ifst); !siter.Done(); siter.Next()) { |
| StateId s = siter.Value(); |
| if (s == ifst.Start()) |
| ofst->SetStart(s); |
| |
| for (ArcIterator< Fst<A> > aiter(ifst, s); !aiter.Done(); aiter.Next()) |
| ofst->AddArc(s, (*mapper)(aiter.Value())); |
| |
| switch (final_action) { |
| case MAP_NO_SUPERFINAL: |
| default: { |
| B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId)); |
| CHECK(final_arc.ilabel == 0 && final_arc.olabel == 0); |
| ofst->SetFinal(s, final_arc.weight); |
| break; |
| } |
| case MAP_ALLOW_SUPERFINAL: { |
| B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId)); |
| if (final_arc.ilabel != 0 || final_arc.olabel != 0) { |
| // Add a superfinal state if not already done. |
| if (superfinal == kNoStateId) { |
| superfinal = ofst->AddState(); |
| ofst->SetFinal(superfinal, B::Weight::One()); |
| } |
| final_arc.nextstate = superfinal; |
| ofst->AddArc(s, final_arc); |
| ofst->SetFinal(s, B::Weight::Zero()); |
| } else { |
| ofst->SetFinal(s, final_arc.weight); |
| } |
| break; |
| } |
| case MAP_REQUIRE_SUPERFINAL: { |
| B final_arc = (*mapper)(A(0, 0, ifst.Final(s), kNoStateId)); |
| if (final_arc.ilabel != 0 || final_arc.olabel != 0 || |
| final_arc.weight != B::Weight::Zero()) |
| ofst->AddArc(s, B(final_arc.ilabel, final_arc.olabel, |
| final_arc.weight, superfinal)); |
| ofst->SetFinal(s, B::Weight::Zero()); |
| break; |
| } |
| } |
| } |
| uint64 iprops = ifst.Properties(kCopyProperties, false); |
| 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 Map(const Fst<A> &ifst, MutableFst<B> *ofst, C mapper) { |
| Map(ifst, ofst, &mapper); |
| } |
| |
| |
| struct MapFstOptions : public CacheOptions { |
| // MapFst default caching behaviour is to do no caching. Most |
| // mappers are cheap and therefore we save memory by not doing |
| // caching. |
| MapFstOptions() : CacheOptions(true, 0) {} |
| MapFstOptions(const CacheOptions& opts) : CacheOptions(opts) {} |
| }; |
| |
| |
| template <class A, class B, class C> class MapFst; |
| |
| // Implementation of delayed MapFst. |
| template <class A, class B, class C> |
| class MapFstImpl : public CacheImpl<B> { |
| public: |
| using FstImpl<B>::SetType; |
| using FstImpl<B>::SetProperties; |
| using FstImpl<B>::Properties; |
| using FstImpl<B>::SetInputSymbols; |
| using FstImpl<B>::SetOutputSymbols; |
| |
| using VectorFstBaseImpl<typename CacheImpl<B>::State>::NumStates; |
| |
| using CacheImpl<B>::HasArcs; |
| using CacheImpl<B>::HasFinal; |
| using CacheImpl<B>::HasStart; |
| |
| friend class StateIterator< MapFst<A, B, C> >; |
| |
| typedef B Arc; |
| typedef typename B::Weight Weight; |
| typedef typename B::StateId StateId; |
| |
| MapFstImpl(const Fst<A> &fst, const C &mapper, |
| const MapFstOptions& opts) |
| : CacheImpl<B>(opts), fst_(fst.Copy()), |
| mapper_(new C(mapper)), |
| own_mapper_(true), |
| superfinal_(kNoStateId), |
| nstates_(0) { |
| Init(); |
| } |
| |
| MapFstImpl(const Fst<A> &fst, C *mapper, |
| const MapFstOptions& opts) |
| : CacheImpl<B>(opts), fst_(fst.Copy()), |
| mapper_(mapper), |
| own_mapper_(false), |
| superfinal_(kNoStateId), |
| nstates_(0) { |
| Init(); |
| } |
| |
| |
| ~MapFstImpl() { |
| delete fst_; |
| if (own_mapper_) delete mapper_; |
| } |
| |
| StateId Start() { |
| if (!HasStart()) |
| SetStart(FindOState(fst_->Start())); |
| return CacheImpl<B>::Start(); |
| } |
| |
| Weight Final(StateId s) { |
| if (!HasFinal(s)) { |
| switch (final_action_) { |
| case MAP_NO_SUPERFINAL: |
| default: { |
| B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)), |
| kNoStateId)); |
| CHECK(final_arc.ilabel == 0 && final_arc.olabel == 0); |
| SetFinal(s, final_arc.weight); |
| break; |
| } |
| case MAP_ALLOW_SUPERFINAL: { |
| if (s == superfinal_) { |
| SetFinal(s, Weight::One()); |
| } else { |
| B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)), |
| kNoStateId)); |
| if (final_arc.ilabel == 0 && final_arc.olabel == 0) |
| SetFinal(s, final_arc.weight); |
| else |
| SetFinal(s, Weight::Zero()); |
| } |
| break; |
| } |
| case MAP_REQUIRE_SUPERFINAL: { |
| SetFinal(s, s == superfinal_ ? Weight::One() : Weight::Zero()); |
| break; |
| } |
| } |
| } |
| return CacheImpl<B>::Final(s); |
| } |
| |
| size_t NumArcs(StateId s) { |
| if (!HasArcs(s)) |
| Expand(s); |
| return CacheImpl<B>::NumArcs(s); |
| } |
| |
| size_t NumInputEpsilons(StateId s) { |
| if (!HasArcs(s)) |
| Expand(s); |
| return CacheImpl<B>::NumInputEpsilons(s); |
| } |
| |
| size_t NumOutputEpsilons(StateId s) { |
| if (!HasArcs(s)) |
| Expand(s); |
| return CacheImpl<B>::NumOutputEpsilons(s); |
| } |
| |
| void InitArcIterator(StateId s, ArcIteratorData<B> *data) { |
| if (!HasArcs(s)) |
| Expand(s); |
| CacheImpl<B>::InitArcIterator(s, data); |
| } |
| |
| void Expand(StateId s) { |
| // Add exiting arcs. |
| if (s == superfinal_) { SetArcs(s); return; } |
| |
| for (ArcIterator< Fst<A> > aiter(*fst_, FindIState(s)); |
| !aiter.Done(); aiter.Next()) { |
| A aarc(aiter.Value()); |
| aarc.nextstate = FindOState(aarc.nextstate); |
| const B& barc = (*mapper_)(aarc); |
| AddArc(s, barc); |
| } |
| |
| // Check for superfinal arcs. |
| if (!HasFinal(s) || Final(s) == Weight::Zero()) |
| switch (final_action_) { |
| case MAP_NO_SUPERFINAL: |
| default: |
| break; |
| case MAP_ALLOW_SUPERFINAL: { |
| B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)), |
| kNoStateId)); |
| if (final_arc.ilabel != 0 || final_arc.olabel != 0) { |
| if (superfinal_ == kNoStateId) |
| superfinal_ = nstates_++; |
| final_arc.nextstate = superfinal_; |
| AddArc(s, final_arc); |
| } |
| break; |
| } |
| case MAP_REQUIRE_SUPERFINAL: { |
| B final_arc = (*mapper_)(A(0, 0, fst_->Final(FindIState(s)), |
| kNoStateId)); |
| if (final_arc.ilabel != 0 || final_arc.olabel != 0 || |
| final_arc.weight != B::Weight::Zero()) |
| AddArc(s, B(final_arc.ilabel, final_arc.olabel, |
| final_arc.weight, superfinal_)); |
| break; |
| } |
| } |
| SetArcs(s); |
| } |
| |
| private: |
| void Init() { |
| SetType("map"); |
| SetInputSymbols(fst_->InputSymbols()); |
| SetOutputSymbols(fst_->OutputSymbols()); |
| if (fst_->Start() == kNoStateId) { |
| final_action_ = MAP_NO_SUPERFINAL; |
| SetProperties(kNullProperties); |
| } else { |
| final_action_ = mapper_->FinalAction(); |
| uint64 props = fst_->Properties(kCopyProperties, false); |
| SetProperties(mapper_->Properties(props)); |
| if (final_action_ == MAP_REQUIRE_SUPERFINAL) |
| superfinal_ = 0; |
| } |
| } |
| |
| // Maps from output state to input state. |
| StateId FindIState(StateId s) { |
| if (superfinal_ == kNoStateId || s < superfinal_) |
| return s; |
| else |
| return s - 1; |
| } |
| |
| // Maps from input state to output state. |
| StateId FindOState(StateId is) { |
| StateId os; |
| if (superfinal_ == kNoStateId || is < superfinal_) |
| os = is; |
| else |
| os = is + 1; |
| |
| if (os >= nstates_) |
| nstates_ = os + 1; |
| |
| return os; |
| } |
| |
| |
| const Fst<A> *fst_; |
| C* mapper_; |
| bool own_mapper_; |
| MapFinalAction final_action_; |
| |
| StateId superfinal_; |
| StateId nstates_; |
| }; |
| |
| |
| // Maps an arc type A to an arc type B using Mapper function object |
| // C. This version is a delayed Fst. |
| template <class A, class B, class C> |
| class MapFst : public Fst<B> { |
| public: |
| friend class ArcIterator< MapFst<A, B, C> >; |
| friend class StateIterator< MapFst<A, B, C> >; |
| friend class CacheArcIterator< MapFst<A, B, C> >; |
| |
| typedef B Arc; |
| typedef typename B::Weight Weight; |
| typedef typename B::StateId StateId; |
| typedef CacheState<B> State; |
| |
| MapFst(const Fst<A> &fst, const C &mapper, |
| const MapFstOptions& opts) |
| : impl_(new MapFstImpl<A, B, C>(fst, mapper, opts)) {} |
| |
| MapFst(const Fst<A> &fst, C* mapper, |
| const MapFstOptions& opts) |
| : impl_(new MapFstImpl<A, B, C>(fst, mapper, opts)) {} |
| |
| MapFst(const Fst<A> &fst, const C &mapper) |
| : impl_(new MapFstImpl<A, B, C>(fst, mapper, |
| MapFstOptions())) {} |
| |
| MapFst(const Fst<A> &fst, C* mapper) |
| : impl_(new MapFstImpl<A, B, C>(fst, mapper, |
| MapFstOptions())) {} |
| |
| MapFst(const MapFst<A, B, C> &fst) : Fst<B>(fst), impl_(fst.impl_) { |
| impl_->IncrRefCount(); |
| } |
| |
| virtual ~MapFst() { if (!impl_->DecrRefCount()) delete impl_; } |
| |
| virtual StateId Start() const { return impl_->Start(); } |
| |
| virtual Weight Final(StateId s) const { return impl_->Final(s); } |
| |
| StateId NumStates() const { return impl_->NumStates(); } |
| |
| size_t NumArcs(StateId s) const { return impl_->NumArcs(s); } |
| |
| size_t NumInputEpsilons(StateId s) const { |
| return impl_->NumInputEpsilons(s); |
| } |
| |
| size_t NumOutputEpsilons(StateId s) const { |
| return impl_->NumOutputEpsilons(s); |
| } |
| |
| virtual uint64 Properties(uint64 mask, bool test) const { |
| if (test) { |
| uint64 known, test = TestProperties(*this, mask, &known); |
| impl_->SetProperties(test, known); |
| return test & mask; |
| } else { |
| return impl_->Properties(mask); |
| } |
| } |
| |
| virtual const string& Type() const { return impl_->Type(); } |
| |
| virtual MapFst<A, B, C> *Copy() const { |
| return new MapFst<A, B, C>(*this); |
| } |
| |
| virtual const SymbolTable* InputSymbols() const { |
| return impl_->InputSymbols(); |
| } |
| |
| virtual const SymbolTable* OutputSymbols() const { |
| return impl_->OutputSymbols(); |
| } |
| |
| virtual inline void InitStateIterator(StateIteratorData<B> *data) const; |
| |
| virtual void InitArcIterator(StateId s, ArcIteratorData<B> *data) const { |
| impl_->InitArcIterator(s, data); |
| } |
| |
| private: |
| MapFstImpl<A, B, C> *impl_; |
| |
| void operator=(const MapFst<A, B, C> &fst); // disallow |
| }; |
| |
| |
| // Specialization for MapFst. |
| template<class A, class B, class C> |
| class StateIterator< MapFst<A, B, C> > : public StateIteratorBase<B> { |
| public: |
| typedef typename B::StateId StateId; |
| |
| explicit StateIterator(const MapFst<A, B, C> &fst) |
| : impl_(fst.impl_), siter_(*impl_->fst_), s_(0), |
| superfinal_(impl_->final_action_ == MAP_REQUIRE_SUPERFINAL) |
| { CheckSuperfinal(); } |
| |
| bool Done() const { return siter_.Done() && !superfinal_; } |
| |
| StateId Value() const { return s_; } |
| |
| void Next() { |
| ++s_; |
| if (!siter_.Done()) { |
| siter_.Next(); |
| CheckSuperfinal(); |
| } |
| else if (superfinal_) |
| superfinal_ = false; |
| } |
| |
| void Reset() { |
| s_ = 0; |
| siter_.Reset(); |
| superfinal_ = impl_->final_action_ == MAP_REQUIRE_SUPERFINAL; |
| CheckSuperfinal(); |
| } |
| |
| private: |
| void CheckSuperfinal() { |
| if (impl_->final_action_ != MAP_ALLOW_SUPERFINAL || superfinal_) |
| return; |
| if (!siter_.Done()) { |
| B final_arc = (*impl_->mapper_)(A(0, 0, impl_->fst_->Final(s_), |
| kNoStateId)); |
| if (final_arc.ilabel != 0 || final_arc.olabel != 0) |
| superfinal_ = true; |
| } |
| } |
| |
| const MapFstImpl<A, B, C> *impl_; |
| StateIterator< Fst<A> > siter_; |
| StateId s_; |
| bool superfinal_; // true if there is a superfinal state and not done |
| |
| DISALLOW_EVIL_CONSTRUCTORS(StateIterator); |
| }; |
| |
| // Specialization for MapFst. |
| template <class A, class B, class C> |
| class ArcIterator< MapFst<A, B, C> > |
| : public CacheArcIterator< MapFst<A, B, C> > { |
| public: |
| typedef typename A::StateId StateId; |
| |
| ArcIterator(const MapFst<A, B, C> &fst, StateId s) |
| : CacheArcIterator< MapFst<A, B, C> >(fst, s) { |
| if (!fst.impl_->HasArcs(s)) |
| fst.impl_->Expand(s); |
| } |
| |
| private: |
| DISALLOW_EVIL_CONSTRUCTORS(ArcIterator); |
| }; |
| |
| template <class A, class B, class C> inline |
| void MapFst<A, B, C>::InitStateIterator(StateIteratorData<B> *data) |
| const { |
| data->base = new StateIterator< MapFst<A, B, C> >(*this); |
| } |
| |
| |
| // |
| // Utility Mappers |
| // |
| |
| // Mapper that returns its input. |
| template <class A> |
| struct IdentityMapper { |
| typedef A FromArc; |
| typedef A ToArc; |
| |
| A operator()(const A &arc) const { return arc; } |
| |
| MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { return props; } |
| }; |
| |
| |
| // Mapper that returns its input with final states redirected to |
| // a single super-final state. |
| template <class A> |
| struct SuperFinalMapper { |
| typedef A FromArc; |
| typedef A ToArc; |
| |
| A operator()(const A &arc) const { return arc; } |
| |
| MapFinalAction FinalAction() const { return MAP_REQUIRE_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { |
| return props & kAddSuperFinalProperties; |
| } |
| }; |
| |
| |
| // Mapper from StdArc to LogArc. |
| struct StdToLogMapper { |
| typedef StdArc FromArc; |
| typedef LogArc ToArc; |
| |
| LogArc operator()(const StdArc &arc) const { |
| return LogArc(arc.ilabel, arc.olabel, arc.weight.Value(), arc.nextstate); |
| } |
| |
| MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { return props; } |
| }; |
| |
| |
| // Mapper from LogArc to StdArc. |
| struct LogToStdMapper { |
| typedef LogArc FromArc; |
| typedef StdArc ToArc; |
| |
| StdArc operator()(const LogArc &arc) const { |
| return StdArc(arc.ilabel, arc.olabel, arc.weight.Value(), arc.nextstate); |
| } |
| |
| MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { return props; } |
| }; |
| |
| |
| // Mapper from A to GallicArc<A>. |
| template <class A, StringType S = STRING_LEFT> |
| struct ToGallicMapper { |
| typedef A FromArc; |
| typedef GallicArc<A, S> ToArc; |
| |
| typedef StringWeight<typename A::Label, S> SW; |
| typedef typename A::Weight AW; |
| typedef typename GallicArc<A, S>::Weight GW; |
| |
| ToArc operator()(const A &arc) const { |
| // 'Super-final' arc. |
| if (arc.nextstate == kNoStateId && arc.weight != AW::Zero()) |
| return ToArc(0, 0, GW(SW::One(), arc.weight), kNoStateId); |
| // 'Super-non-final' arc. |
| else if (arc.nextstate == kNoStateId) |
| return ToArc(0, 0, GW(SW::Zero(), arc.weight), kNoStateId); |
| // Epsilon label. |
| else if (arc.olabel == 0) |
| return ToArc(arc.ilabel, arc.ilabel, |
| GW(SW::One(), arc.weight), arc.nextstate); |
| // Regular label. |
| else |
| return ToArc(arc.ilabel, arc.ilabel, |
| GW(SW(arc.olabel), arc.weight), arc.nextstate); |
| } |
| |
| MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { |
| return ProjectProperties(props, true) & kWeightInvariantProperties; |
| } |
| }; |
| |
| |
| // Mapper from GallicArc<A> to A. |
| template <class A, StringType S = STRING_LEFT> |
| struct FromGallicMapper { |
| typedef GallicArc<A, S> FromArc; |
| typedef A ToArc; |
| |
| typedef typename A::Label Label; |
| typedef StringWeight<Label, S> SW; |
| typedef typename A::Weight AW; |
| typedef typename GallicArc<A, S>::Weight GW; |
| |
| A operator()(const FromArc &arc) const { |
| // 'Super-non-final' arc. |
| if (arc.nextstate == kNoStateId && arc.weight == GW::Zero()) |
| return A(arc.ilabel, 0, AW::Zero(), kNoStateId); |
| |
| SW w1 = arc.weight.Value1(); |
| AW w2 = arc.weight.Value2(); |
| StringWeightIterator<Label, S> iter1(w1); |
| |
| Label l = w1.Size() == 1 ? iter1.Value() : 0; |
| |
| CHECK(l != kStringInfinity); |
| CHECK(l != kStringBad); |
| CHECK(arc.ilabel == arc.olabel); |
| CHECK(w1.Size() <= 1); |
| |
| return A(arc.ilabel, l, w2, arc.nextstate); |
| } |
| |
| MapFinalAction FinalAction() const { return MAP_ALLOW_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { |
| return props & kOLabelInvariantProperties & |
| kWeightInvariantProperties & kAddSuperFinalProperties; |
| } |
| }; |
| |
| |
| // Mapper from GallicArc<A> to A. |
| template <class A, StringType S = STRING_LEFT> |
| struct GallicToNewSymbolsMapper { |
| typedef GallicArc<A, S> FromArc; |
| typedef A ToArc; |
| |
| typedef typename A::StateId StateId; |
| typedef typename A::Label Label; |
| typedef StringWeight<Label, S> SW; |
| typedef typename A::Weight AW; |
| typedef typename GallicArc<A, S>::Weight GW; |
| |
| GallicToNewSymbolsMapper(MutableFst<ToArc> *fst) |
| : fst_(fst), lmax_(0), osymbols_(fst->OutputSymbols()), isymbols_(0) { |
| fst_->DeleteStates(); |
| state_ = fst_->AddState(); |
| fst_->SetStart(state_); |
| fst_->SetFinal(state_, AW::One()); |
| if (osymbols_) { |
| string name = osymbols_->Name() + "_from_gallic"; |
| isymbols_ = new SymbolTable(name); |
| isymbols_->AddSymbol(osymbols_->Find((int64) 0), 0); |
| } |
| fst_->SetInputSymbols(isymbols_); |
| } |
| |
| A operator()(const FromArc &arc) { |
| // 'Super-non-final' arc. |
| if (arc.nextstate == kNoStateId && arc.weight == GW::Zero()) |
| return A(arc.ilabel, 0, AW::Zero(), kNoStateId); |
| |
| SW w1 = arc.weight.Value1(); |
| AW w2 = arc.weight.Value2(); |
| Label l; |
| |
| if (w1.Size() == 0) { |
| l = 0; |
| } else { |
| typename Map::iterator miter = map_.find(w1); |
| if (miter != map_.end()) { |
| l = (*miter).second; |
| } else { |
| l = ++lmax_; |
| map_.insert(pair<const SW, Label>(w1, l)); |
| StringWeightIterator<Label, S> iter1(w1); |
| StateId n; |
| string s; |
| for(ssize_t i = 0, p = state_; |
| i < w1.Size(); |
| ++i, iter1.Next(), p = n) { |
| n = i == w1.Size() - 1 ? state_ : fst_->AddState(); |
| fst_->AddArc(p, ToArc(i ? 0 : l, iter1.Value(), AW::One(), n)); |
| if (isymbols_) { |
| if (i) s = s + "_"; |
| s = s + osymbols_->Find(iter1.Value()); |
| } |
| } |
| if (isymbols_) |
| isymbols_->AddSymbol(s, l); |
| } |
| } |
| |
| CHECK(l != kStringInfinity); |
| CHECK(l != kStringBad); |
| CHECK(arc.ilabel == arc.olabel); |
| |
| return A(arc.ilabel, l, w2, arc.nextstate); |
| } |
| |
| MapFinalAction FinalAction() const { return MAP_ALLOW_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { |
| return props & kOLabelInvariantProperties & |
| kWeightInvariantProperties & kAddSuperFinalProperties; |
| } |
| |
| private: |
| class StringKey { |
| public: |
| size_t operator()(const SW &x) const { |
| return x.Hash(); |
| } |
| }; |
| |
| typedef hash_map<SW, Label, StringKey> Map; |
| |
| MutableFst<ToArc> *fst_; |
| Map map_; |
| Label lmax_; |
| StateId state_; |
| SymbolTable *osymbols_, *isymbols_; |
| }; |
| |
| |
| // Mapper to add a constant to all weights. |
| template <class A> |
| struct PlusMapper { |
| typedef typename A::Weight Weight; |
| |
| explicit PlusMapper(Weight w) : weight_(w) {} |
| |
| A operator()(const A &arc) const { |
| if (arc.weight == Weight::Zero()) |
| return arc; |
| Weight w = Plus(arc.weight, weight_); |
| return A(arc.ilabel, arc.olabel, w, arc.nextstate); |
| } |
| |
| MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { |
| return props & kWeightInvariantProperties; |
| } |
| |
| Weight weight_; |
| }; |
| |
| |
| // Mapper to (right) multiply a constant to all weights. |
| template <class A> |
| struct TimesMapper { |
| typedef typename A::Weight Weight; |
| |
| explicit TimesMapper(Weight w) : weight_(w) {} |
| |
| A operator()(const A &arc) const { |
| if (arc.weight == Weight::Zero()) |
| return arc; |
| Weight w = Times(arc.weight, weight_); |
| return A(arc.ilabel, arc.olabel, w, arc.nextstate); |
| } |
| |
| MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { |
| return props & kWeightInvariantProperties; |
| } |
| |
| Weight weight_; |
| }; |
| |
| |
| // Mapper to map all non-Zero() weights to One(). |
| template <class A, class B = A> |
| struct RmWeightMapper { |
| typedef A FromArc; |
| typedef B ToArc; |
| typedef typename FromArc::Weight FromWeight; |
| typedef typename ToArc::Weight ToWeight; |
| |
| B operator()(const A &arc) const { |
| ToWeight w = arc.weight != FromWeight::Zero() ? |
| ToWeight::One() : ToWeight::Zero(); |
| return B(arc.ilabel, arc.olabel, w, arc.nextstate); |
| } |
| |
| MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { |
| return props & kWeightInvariantProperties | kUnweighted; |
| } |
| }; |
| |
| |
| // Mapper to quantize all weights. |
| template <class A, class B = A> |
| struct QuantizeMapper { |
| typedef A FromArc; |
| typedef B ToArc; |
| typedef typename FromArc::Weight FromWeight; |
| typedef typename ToArc::Weight ToWeight; |
| |
| QuantizeMapper() : delta_(kDelta) {} |
| |
| explicit QuantizeMapper(float d) : delta_(d) {} |
| |
| B operator()(const A &arc) const { |
| ToWeight w = arc.weight.Quantize(delta_); |
| return B(arc.ilabel, arc.olabel, w, arc.nextstate); |
| } |
| |
| MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { |
| return props & kWeightInvariantProperties; |
| } |
| |
| float delta_; |
| }; |
| |
| |
| // Mapper from A to B under the assumption: |
| // B::Weight = A::Weight::ReverseWeight |
| // B::Label == A::Label |
| // B::StateId == A::StateId |
| // The weight is reversed, while the label and nextstate preserved |
| // in the mapping. |
| template <class A, class B> |
| struct ReverseWeightMapper { |
| typedef A FromArc; |
| typedef B ToArc; |
| |
| B operator()(const A &arc) const { |
| return B(arc.ilabel, arc.olabel, arc.weight.Reverse(), arc.nextstate); |
| } |
| |
| MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; } |
| |
| uint64 Properties(uint64 props) const { return props; } |
| }; |
| |
| } // namespace fst |
| |
| #endif // FST_LIB_MAP_H__ |