Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef FST_LIB_UNION_H__
00022 #define FST_LIB_UNION_H__
00023
00024 #include <vector>
00025 using std::vector;
00026 #include <algorithm>
00027 #include <fst/mutable-fst.h>
00028 #include <fst/rational.h>
00029
00030 namespace fst {
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 template <class Arc>
00042 void Union(MutableFst<Arc> *fst1, const Fst<Arc> &fst2) {
00043 typedef typename Arc::StateId StateId;
00044 typedef typename Arc::Label Label;
00045 typedef typename Arc::Weight Weight;
00046
00047 StateId start2 = fst2.Start();
00048 if (start2 == kNoStateId)
00049 return;
00050
00051 StateId numstates1 = fst1->NumStates();
00052 bool initial_acyclic1 = fst1->Properties(kInitialAcyclic, true);
00053 uint64 props1 = fst1->Properties(kFstProperties, false);
00054 uint64 props2 = fst2.Properties(kFstProperties, false);
00055
00056 for (StateIterator< Fst<Arc> > siter(fst2);
00057 !siter.Done();
00058 siter.Next()) {
00059 StateId s1 = fst1->AddState();
00060 StateId s2 = siter.Value();
00061 fst1->SetFinal(s1, fst2.Final(s2));
00062 for (ArcIterator< Fst<Arc> > aiter(fst2, s2);
00063 !aiter.Done();
00064 aiter.Next()) {
00065 Arc arc = aiter.Value();
00066 arc.nextstate += numstates1;
00067 fst1->AddArc(s1, arc);
00068 }
00069 }
00070 StateId start1 = fst1->Start();
00071 if (start1 == kNoStateId) {
00072 fst1->SetStart(start2);
00073 fst1->SetProperties(props2, kCopyProperties);
00074 return;
00075 }
00076
00077 if (initial_acyclic1) {
00078 fst1->AddArc(start1, Arc(0, 0, Weight::One(), start2 + numstates1));
00079 } else {
00080 StateId nstart1 = fst1->AddState();
00081 fst1->SetStart(nstart1);
00082 fst1->AddArc(nstart1, Arc(0, 0, Weight::One(), start1));
00083 fst1->AddArc(nstart1, Arc(0, 0, Weight::One(), start2 + numstates1));
00084 }
00085 fst1->SetProperties(UnionProperties(props1, props2), kFstProperties);
00086 }
00087
00088
00089
00090
00091 template<class Arc>
00092 void Union(RationalFst<Arc> *fst1, const Fst<Arc> &fst2) {
00093 fst1->GetImpl()->AddUnion(fst2);
00094 }
00095
00096
00097 typedef RationalFstOptions UnionFstOptions;
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 template <class A>
00112 class UnionFst : public RationalFst<A> {
00113 public:
00114 using ImplToFst< RationalFstImpl<A> >::GetImpl;
00115
00116 typedef A Arc;
00117 typedef typename A::Weight Weight;
00118 typedef typename A::StateId StateId;
00119
00120 UnionFst(const Fst<A> &fst1, const Fst<A> &fst2) {
00121 GetImpl()->InitUnion(fst1, fst2);
00122 }
00123
00124 UnionFst(const Fst<A> &fst1, const Fst<A> &fst2, const UnionFstOptions &opts)
00125 : RationalFst<A>(opts) {
00126 GetImpl()->InitUnion(fst1, fst2);
00127 }
00128
00129
00130 UnionFst(const UnionFst<A> &fst, bool safe = false)
00131 : RationalFst<A>(fst, safe) {}
00132
00133
00134 virtual UnionFst<A> *Copy(bool safe = false) const {
00135 return new UnionFst<A>(*this, safe);
00136 }
00137 };
00138
00139
00140
00141 template <class A>
00142 class StateIterator< UnionFst<A> > : public StateIterator< RationalFst<A> > {
00143 public:
00144 explicit StateIterator(const UnionFst<A> &fst)
00145 : StateIterator< RationalFst<A> >(fst) {}
00146 };
00147
00148
00149
00150 template <class A>
00151 class ArcIterator< UnionFst<A> > : public ArcIterator< RationalFst<A> > {
00152 public:
00153 typedef typename A::StateId StateId;
00154
00155 ArcIterator(const UnionFst<A> &fst, StateId s)
00156 : ArcIterator< RationalFst<A> >(fst, s) {}
00157 };
00158
00159
00160
00161 typedef UnionFst<StdArc> StdUnionFst;
00162
00163 }
00164
00165 #endif /// FST_LIB_UNION_H__
00166