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_COMPLEMENT_H__
00022 #define FST_LIB_COMPLEMENT_H__
00023
00024 #include <algorithm>
00025 #include <string>
00026 #include <vector>
00027 using std::vector;
00028 #include <fst/fst.h>
00029 #include <fst/test-properties.h>
00030
00031 namespace fst {
00032
00033 template <class A> class ComplementFst;
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 template <class A>
00046 class ComplementFstImpl : public FstImpl<A> {
00047 public:
00048 using FstImpl<A>::SetType;
00049 using FstImpl<A>::SetProperties;
00050 using FstImpl<A>::Properties;
00051 using FstImpl<A>::SetInputSymbols;
00052 using FstImpl<A>::SetOutputSymbols;
00053
00054 friend class StateIterator< ComplementFst<A> >;
00055 friend class ArcIterator< ComplementFst<A> >;
00056
00057 typedef A Arc;
00058 typedef typename A::Label Label;
00059 typedef typename A::Weight Weight;
00060 typedef typename A::StateId StateId;
00061
00062 explicit ComplementFstImpl(const Fst<A> &fst) : fst_(fst.Copy()) {
00063 SetType("complement");
00064 uint64 props = fst.Properties(kILabelSorted, false);
00065 SetProperties(ComplementProperties(props), kCopyProperties);
00066 SetInputSymbols(fst.InputSymbols());
00067 SetOutputSymbols(fst.OutputSymbols());
00068 }
00069
00070 ComplementFstImpl(const ComplementFstImpl<A> &impl)
00071 : fst_(impl.fst_->Copy()) {
00072 SetType("complement");
00073 SetProperties(impl.Properties(), kCopyProperties);
00074 SetInputSymbols(impl.InputSymbols());
00075 SetOutputSymbols(impl.OutputSymbols());
00076 }
00077
00078 ~ComplementFstImpl() { delete fst_; }
00079
00080 StateId Start() const {
00081 StateId start = fst_->Start();
00082 if (start != kNoStateId)
00083 return start + 1;
00084 else
00085 return 0;
00086 }
00087
00088
00089 Weight Final(StateId s) const {
00090 if (s == 0 || fst_->Final(s - 1) == Weight::Zero())
00091 return Weight::One();
00092 else
00093 return Weight::Zero();
00094 }
00095
00096 size_t NumArcs(StateId s) const {
00097 if (s == 0)
00098 return 1;
00099 else
00100 return fst_->NumArcs(s - 1) + 1;
00101 }
00102
00103 size_t NumInputEpsilons(StateId s) const {
00104 return s == 0 ? 0 : fst_->NumInputEpsilons(s - 1);
00105 }
00106
00107 size_t NumOutputEpsilons(StateId s) const {
00108 return s == 0 ? 0 : fst_->NumOutputEpsilons(s - 1);
00109 }
00110
00111 private:
00112 const Fst<A> *fst_;
00113
00114 void operator=(const ComplementFstImpl<A> &fst);
00115 };
00116
00117
00118
00119
00120
00121
00122
00123
00124 template <class A>
00125 class ComplementFst : public ImplToFst< ComplementFstImpl<A> > {
00126 public:
00127 friend class StateIterator< ComplementFst<A> >;
00128 friend class ArcIterator< ComplementFst<A> >;
00129
00130 typedef A Arc;
00131 typedef typename A::StateId StateId;
00132 typedef typename A::Label Label;
00133 typedef ComplementFstImpl<A> Impl;
00134
00135 explicit ComplementFst(const Fst<A> &fst)
00136 : ImplToFst<Impl>(new Impl(fst)) {
00137 uint64 props = kUnweighted | kNoEpsilons | kIDeterministic | kAcceptor;
00138 if (fst.Properties(props, true) != props)
00139 LOG(FATAL) << "ComplementFst: argument not an unweighted"
00140 << " epsilon-free deterministic acceptor";
00141 }
00142
00143
00144 ComplementFst(const ComplementFst<A> &fst, bool safe = false)
00145 : ImplToFst<Impl>(fst, safe) {}
00146
00147
00148 virtual ComplementFst<A> *Copy(bool safe = false) const {
00149 return new ComplementFst<A>(*this, safe);
00150 }
00151
00152 virtual inline void InitStateIterator(StateIteratorData<A> *data) const;
00153
00154 virtual inline void InitArcIterator(StateId s,
00155 ArcIteratorData<A> *data) const;
00156
00157
00158
00159
00160 static const Label kRhoLabel = -2;
00161 private:
00162
00163 Impl *GetImpl() const { return ImplToFst<Impl>::GetImpl(); }
00164
00165 void operator=(const ComplementFst<A> &fst);
00166 };
00167
00168 template <class A> const typename A::Label ComplementFst<A>::kRhoLabel;
00169
00170
00171
00172 template <class A>
00173 class StateIterator< ComplementFst<A> > : public StateIteratorBase<A> {
00174 public:
00175 typedef typename A::StateId StateId;
00176 typedef typename A::Label Label;
00177
00178 explicit StateIterator(const ComplementFst<A> &fst)
00179 : siter_(*fst.GetImpl()->fst_), s_(0) {
00180 }
00181
00182 bool Done() const { return s_ > 0 && siter_.Done(); }
00183
00184 StateId Value() const { return s_; }
00185
00186 void Next() {
00187 if (s_ != 0)
00188 siter_.Next();
00189 ++s_;
00190 }
00191
00192 void Reset() {
00193 siter_.Reset();
00194 s_ = 0;
00195 }
00196
00197 private:
00198
00199
00200
00201 virtual bool Done_() const { return Done(); }
00202 virtual StateId Value_() const { return Value(); }
00203 virtual void Next_() { Next(); }
00204 virtual void Reset_() { Reset(); }
00205
00206 StateIterator< Fst<A> > siter_;
00207 StateId s_;
00208
00209 DISALLOW_COPY_AND_ASSIGN(StateIterator);
00210 };
00211
00212
00213
00214 template <class A>
00215 class ArcIterator< ComplementFst<A> > : public ArcIteratorBase<A> {
00216 public:
00217 typedef typename A::StateId StateId;
00218 typedef typename A::Label Label;
00219 typedef typename A::Weight Weight;
00220
00221 ArcIterator(const ComplementFst<A> &fst, StateId s)
00222 : aiter_(0), s_(s), pos_(0) {
00223 if (s_ != 0)
00224 aiter_ = new ArcIterator< Fst<A> >(*fst.GetImpl()->fst_, s - 1);
00225 }
00226
00227 virtual ~ArcIterator() { delete aiter_; }
00228
00229 bool Done() const {
00230 if (s_ != 0)
00231 return pos_ > 0 && aiter_->Done();
00232 else
00233 return pos_ > 0;
00234 }
00235
00236
00237 const A& Value() const {
00238 if (pos_ == 0) {
00239 arc_.ilabel = arc_.olabel = ComplementFst<A>::kRhoLabel;
00240 arc_.weight = Weight::One();
00241 arc_.nextstate = 0;
00242 } else {
00243 arc_ = aiter_->Value();
00244 ++arc_.nextstate;
00245 }
00246 return arc_;
00247 }
00248
00249 void Next() {
00250 if (s_ != 0 && pos_ > 0)
00251 aiter_->Next();
00252 ++pos_;
00253 }
00254
00255 size_t Position() const {
00256 return pos_;
00257 }
00258
00259 void Reset() {
00260 if (s_ != 0)
00261 aiter_->Reset();
00262 pos_ = 0;
00263 }
00264
00265 void Seek(size_t a) {
00266 if (s_ != 0) {
00267 if (a == 0) {
00268 aiter_->Reset();
00269 } else {
00270 aiter_->Seek(a - 1);
00271 }
00272 }
00273 pos_ = a;
00274 }
00275
00276 uint32 Flags() const {
00277 return kArcValueFlags;
00278 }
00279
00280 void SetFlags(uint32 f, uint32 m) {}
00281
00282 private:
00283
00284
00285
00286 virtual bool Done_() const { return Done(); }
00287 virtual const A& Value_() const { return Value(); }
00288 virtual void Next_() { Next(); }
00289 virtual size_t Position_() const { return Position(); }
00290 virtual void Reset_() { Reset(); }
00291 virtual void Seek_(size_t a) { Seek(a); }
00292 uint32 Flags_() const { return Flags(); }
00293 void SetFlags_(uint32 f, uint32 m) { SetFlags(f, m); }
00294
00295 ArcIterator< Fst<A> > *aiter_;
00296 StateId s_;
00297 size_t pos_;
00298 mutable A arc_;
00299 DISALLOW_COPY_AND_ASSIGN(ArcIterator);
00300 };
00301
00302
00303 template <class A> inline void
00304 ComplementFst<A>::InitStateIterator(StateIteratorData<A> *data) const {
00305 data->base = new StateIterator< ComplementFst<A> >(*this);
00306 }
00307
00308 template <class A> inline void
00309 ComplementFst<A>::InitArcIterator(StateId s, ArcIteratorData<A> *data) const {
00310 data->base = new ArcIterator< ComplementFst<A> >(*this, s);
00311 }
00312
00313
00314
00315 typedef ComplementFst<StdArc> StdComplementFst;
00316
00317 }
00318
00319 #endif /// FST_LIB_COMPLEMENT_H__
00320