00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef FST_LIB_MATCHER_H__
00022 #define FST_LIB_MATCHER_H__
00023
00024 #include <algorithm>
00025 #include <set>
00026
00027 #include <fst/fst.h>
00028
00029 namespace fst {
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 const uint32 kMatcherFlags = 0x00000000;
00087
00088
00089
00090
00091 template <class A>
00092 class MatcherBase {
00093 public:
00094 typedef A Arc;
00095 typedef typename A::StateId StateId;
00096 typedef typename A::Label Label;
00097 typedef typename A::Weight Weight;
00098
00099 virtual ~MatcherBase() {}
00100
00101 virtual MatcherBase<A> *Copy(bool safe = false) const = 0;
00102 virtual MatchType Type(bool test) const = 0;
00103 void SetState(StateId s) { SetState_(s); }
00104 bool Find(Label label) { return Find_(label); }
00105 bool Done() const { return Done_(); }
00106 const A& Value() const { return Value_(); }
00107 void Next() { Next_(); }
00108 virtual const Fst<A> &GetFst() const = 0;
00109 virtual uint64 Properties(uint64 props) const = 0;
00110 virtual uint32 Flags() const { return 0; }
00111 private:
00112 virtual void SetState_(StateId s) = 0;
00113 virtual bool Find_(Label label) = 0;
00114 virtual bool Done_() const = 0;
00115 virtual const A& Value_() const = 0;
00116 virtual void Next_() = 0;
00117 };
00118
00119
00120
00121
00122
00123
00124
00125 template <class F>
00126 class SortedMatcher : public MatcherBase<typename F::Arc> {
00127 public:
00128 typedef F FST;
00129 typedef typename F::Arc Arc;
00130 typedef typename Arc::StateId StateId;
00131 typedef typename Arc::Label Label;
00132 typedef typename Arc::Weight Weight;
00133
00134
00135
00136 SortedMatcher(const F &fst, MatchType match_type,
00137 Label binary_label = 1)
00138 : fst_(fst.Copy()),
00139 s_(kNoStateId),
00140 aiter_(0),
00141 match_type_(match_type),
00142 binary_label_(binary_label),
00143 match_label_(kNoLabel),
00144 narcs_(0),
00145 loop_(kNoLabel, 0, Weight::One(), kNoStateId) {
00146 switch(match_type_) {
00147 case MATCH_INPUT:
00148 case MATCH_NONE:
00149 break;
00150 case MATCH_OUTPUT:
00151 swap(loop_.ilabel, loop_.olabel);
00152 break;
00153 default:
00154 LOG(FATAL) << "SortedMatcher: bad match type";
00155 }
00156 }
00157
00158 SortedMatcher(const SortedMatcher<F> &matcher, bool safe = false)
00159 : fst_(matcher.fst_->Copy(safe)),
00160 s_(kNoStateId),
00161 aiter_(0),
00162 match_type_(matcher.match_type_),
00163 binary_label_(matcher.binary_label_),
00164 match_label_(kNoLabel),
00165 narcs_(0),
00166 loop_(matcher.loop_) {}
00167
00168 virtual ~SortedMatcher() {
00169 if (aiter_)
00170 delete aiter_;
00171 delete fst_;
00172 }
00173
00174 virtual SortedMatcher<F> *Copy(bool safe = false) const {
00175 return new SortedMatcher<F>(*this, safe);
00176 }
00177
00178 virtual MatchType Type(bool test) const {
00179 if (match_type_ == MATCH_NONE)
00180 return match_type_;
00181
00182 uint64 true_prop = match_type_ == MATCH_INPUT ?
00183 kILabelSorted : kOLabelSorted;
00184 uint64 false_prop = match_type_ == MATCH_INPUT ?
00185 kNotILabelSorted : kNotOLabelSorted;
00186 uint64 props = fst_->Properties(true_prop | false_prop, test);
00187
00188 if (props & true_prop)
00189 return match_type_;
00190 else if (props & false_prop)
00191 return MATCH_NONE;
00192 else
00193 return MATCH_UNKNOWN;
00194 }
00195
00196 void SetState(StateId s) {
00197 if (s_ == s)
00198 return;
00199 s_ = s;
00200 if (match_type_ == MATCH_NONE)
00201 LOG(FATAL) << "SortedMatcher: bad match type";
00202 if (aiter_)
00203 delete aiter_;
00204 aiter_ = new ArcIterator<F>(*fst_, s);
00205 aiter_->SetFlags(kArcNoCache, kArcNoCache);
00206 narcs_ = internal::NumArcs(*fst_, s);
00207 loop_.nextstate = s;
00208 }
00209
00210 bool Find(Label match_label);
00211
00212 bool Done() const {
00213 if (current_loop_)
00214 return false;
00215 if (aiter_->Done())
00216 return true;
00217 Label label = match_type_ == MATCH_INPUT ?
00218 aiter_->Value().ilabel : aiter_->Value().olabel;
00219 return label != match_label_;
00220 }
00221
00222 const Arc& Value() const {
00223 return current_loop_ ? loop_ : aiter_->Value();
00224 }
00225
00226 void Next() {
00227 if (current_loop_)
00228 current_loop_ = false;
00229 else
00230 aiter_->Next();
00231 }
00232
00233 virtual const F &GetFst() const { return *fst_; }
00234
00235 virtual uint64 Properties(uint64 props) const { return props; }
00236
00237 private:
00238 virtual void SetState_(StateId s) { SetState(s); }
00239 virtual bool Find_(Label label) { return Find(label); }
00240 virtual bool Done_() const { return Done(); }
00241 virtual const Arc& Value_() const { return Value(); }
00242 virtual void Next_() { Next(); }
00243
00244 const F *fst_;
00245 StateId s_;
00246 ArcIterator<F> *aiter_;
00247 MatchType match_type_;
00248 Label binary_label_;
00249 Label match_label_;
00250 size_t narcs_;
00251 Arc loop_;
00252 bool current_loop_;
00253
00254 void operator=(const SortedMatcher<F> &);
00255 };
00256
00257 template <class F> inline
00258 bool SortedMatcher<F>::Find(Label match_label) {
00259 current_loop_ = match_label == 0;
00260 match_label_ = match_label == kNoLabel ? 0 : match_label;
00261 aiter_->SetFlags(
00262 match_type_ == MATCH_INPUT ? kArcILabelValue : kArcOLabelValue,
00263 kArcValueFlags);
00264 if (match_label_ >= binary_label_) {
00265
00266 size_t low = 0;
00267 size_t high = narcs_;
00268 while (low < high) {
00269 size_t mid = (low + high) / 2;
00270 aiter_->Seek(mid);
00271 Label label = match_type_ == MATCH_INPUT ?
00272 aiter_->Value().ilabel : aiter_->Value().olabel;
00273 if (label > match_label_) {
00274 high = mid;
00275 } else if (label < match_label_) {
00276 low = mid + 1;
00277 } else {
00278
00279 for (size_t i = mid; i > low; --i) {
00280 aiter_->Seek(i - 1);
00281 label = match_type_ == MATCH_INPUT ? aiter_->Value().ilabel :
00282 aiter_->Value().olabel;
00283 if (label != match_label_) {
00284 aiter_->Seek(i);
00285 aiter_->SetFlags(kArcValueFlags, kArcValueFlags);
00286 return true;
00287 }
00288 }
00289 aiter_->SetFlags(kArcValueFlags, kArcValueFlags);
00290 return true;
00291 }
00292 }
00293 return current_loop_;
00294 } else {
00295
00296 for (aiter_->Reset(); !aiter_->Done(); aiter_->Next()) {
00297 Label label = match_type_ == MATCH_INPUT ?
00298 aiter_->Value().ilabel : aiter_->Value().olabel;
00299 if (label == match_label_) {
00300 aiter_->SetFlags(kArcValueFlags, kArcValueFlags);
00301 return true;
00302 }
00303 if (label > match_label_)
00304 break;
00305 }
00306 aiter_->SetFlags(kArcValueFlags, kArcValueFlags);
00307 return current_loop_;
00308 }
00309 }
00310
00311
00312
00313 enum MatcherRewriteMode {
00314 MATCHER_REWRITE_AUTO = 0,
00315 MATCHER_REWRITE_ALWAYS,
00316 MATCHER_REWRITE_NEVER
00317 };
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 template <class M>
00332 class RhoMatcher : public MatcherBase<typename M::Arc> {
00333 public:
00334 typedef typename M::FST FST;
00335 typedef typename M::Arc Arc;
00336 typedef typename Arc::StateId StateId;
00337 typedef typename Arc::Label Label;
00338 typedef typename Arc::Weight Weight;
00339
00340 RhoMatcher(const FST &fst,
00341 MatchType match_type,
00342 Label rho_label = kNoLabel,
00343 MatcherRewriteMode rewrite_mode = MATCHER_REWRITE_AUTO,
00344 M *matcher = 0)
00345 : matcher_(matcher ? matcher : new M(fst, match_type)),
00346 match_type_(match_type),
00347 rho_label_(rho_label) {
00348 if (match_type == MATCH_BOTH)
00349 LOG(FATAL) << "RhoMatcher: bad match type";
00350 if (rho_label == 0)
00351 LOG(FATAL) << "RhoMatcher: 0 cannot be used as rho_label";
00352
00353 if (rewrite_mode == MATCHER_REWRITE_AUTO)
00354 rewrite_both_ = fst.Properties(kAcceptor, true);
00355 else if (rewrite_mode == MATCHER_REWRITE_ALWAYS)
00356 rewrite_both_ = true;
00357 else
00358 rewrite_both_ = false;
00359 }
00360
00361 RhoMatcher(const RhoMatcher<M> &matcher, bool safe = false)
00362 : matcher_(new M(*matcher.matcher_, safe)),
00363 match_type_(matcher.match_type_),
00364 rho_label_(matcher.rho_label_),
00365 rewrite_both_(matcher.rewrite_both_) {}
00366
00367 virtual ~RhoMatcher() {
00368 delete matcher_;
00369 }
00370
00371 virtual RhoMatcher<M> *Copy(bool safe = false) const {
00372 return new RhoMatcher<M>(*this, safe);
00373 }
00374
00375 virtual MatchType Type(bool test) const { return matcher_->Type(test); }
00376
00377 void SetState(StateId s) {
00378 matcher_->SetState(s);
00379 has_rho_ = rho_label_ != kNoLabel;
00380 }
00381
00382 bool Find(Label match_label) {
00383 if (match_label == rho_label_ && rho_label_ != kNoLabel) {
00384 LOG(FATAL) << "RhoMatcher::Find: bad label (rho)";
00385 }
00386 if (matcher_->Find(match_label)) {
00387 rho_match_ = kNoLabel;
00388 return true;
00389 } else if (has_rho_ && match_label != 0 && match_label != kNoLabel &&
00390 (has_rho_ = matcher_->Find(rho_label_))) {
00391 rho_match_ = match_label;
00392 return true;
00393 } else {
00394 return false;
00395 }
00396 }
00397
00398 bool Done() const { return matcher_->Done(); }
00399
00400 const Arc& Value() const {
00401 if (rho_match_ == kNoLabel) {
00402 return matcher_->Value();
00403 } else {
00404 rho_arc_ = matcher_->Value();
00405 if (rewrite_both_) {
00406 if (rho_arc_.ilabel == rho_label_)
00407 rho_arc_.ilabel = rho_match_;
00408 if (rho_arc_.olabel == rho_label_)
00409 rho_arc_.olabel = rho_match_;
00410 } else if (match_type_ == MATCH_INPUT) {
00411 rho_arc_.ilabel = rho_match_;
00412 } else {
00413 rho_arc_.olabel = rho_match_;
00414 }
00415 return rho_arc_;
00416 }
00417 }
00418
00419 void Next() { matcher_->Next(); }
00420
00421 virtual const FST &GetFst() const { return matcher_->GetFst(); }
00422
00423 virtual uint64 Properties(uint64 props) const;
00424
00425 private:
00426 virtual void SetState_(StateId s) { SetState(s); }
00427 virtual bool Find_(Label label) { return Find(label); }
00428 virtual bool Done_() const { return Done(); }
00429 virtual const Arc& Value_() const { return Value(); }
00430 virtual void Next_() { Next(); }
00431
00432 M *matcher_;
00433 MatchType match_type_;
00434 Label rho_label_;
00435 bool rewrite_both_;
00436 bool has_rho_;
00437 Label rho_match_;
00438 mutable Arc rho_arc_;
00439
00440 void operator=(const RhoMatcher<M> &);
00441 };
00442
00443 template <class M> inline
00444 uint64 RhoMatcher<M>::Properties(uint64 props) const {
00445 if (match_type_ == MATCH_NONE) {
00446 return props;
00447 } else if (match_type_ == MATCH_INPUT) {
00448 if (rewrite_both_) {
00449 return props & ~(kODeterministic | kNonODeterministic | kString |
00450 kILabelSorted | kNotILabelSorted |
00451 kOLabelSorted | kNotOLabelSorted);
00452 } else {
00453 return props & ~(kODeterministic | kAcceptor | kString |
00454 kILabelSorted | kNotILabelSorted);
00455 }
00456 } else if (match_type_ == MATCH_OUTPUT) {
00457 if (rewrite_both_) {
00458 return props & ~(kIDeterministic | kNonIDeterministic | kString |
00459 kILabelSorted | kNotILabelSorted |
00460 kOLabelSorted | kNotOLabelSorted);
00461 } else {
00462 return props & ~(kIDeterministic | kAcceptor | kString |
00463 kOLabelSorted | kNotOLabelSorted);
00464 }
00465 } else {
00466 LOG(FATAL) << "RhoMatcher::Properties: Invalid match type: "
00467 << match_type_;
00468 return 0;
00469 }
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 template <class M>
00486 class SigmaMatcher : public MatcherBase<typename M::Arc> {
00487 public:
00488 typedef typename M::FST FST;
00489 typedef typename M::Arc Arc;
00490 typedef typename Arc::StateId StateId;
00491 typedef typename Arc::Label Label;
00492 typedef typename Arc::Weight Weight;
00493
00494 SigmaMatcher(const FST &fst,
00495 MatchType match_type,
00496 Label sigma_label = kNoLabel,
00497 MatcherRewriteMode rewrite_mode = MATCHER_REWRITE_AUTO,
00498 M *matcher = 0)
00499 : matcher_(matcher ? matcher : new M(fst, match_type)),
00500 match_type_(match_type),
00501 sigma_label_(sigma_label) {
00502 if (match_type == MATCH_BOTH)
00503 LOG(FATAL) << "SigmaMatcher: bad match type";
00504 if (sigma_label == 0)
00505 LOG(FATAL) << "SigmaMatcher: 0 cannot be used as sigma_label";
00506
00507 if (rewrite_mode == MATCHER_REWRITE_AUTO)
00508 rewrite_both_ = fst.Properties(kAcceptor, true);
00509 else if (rewrite_mode == MATCHER_REWRITE_ALWAYS)
00510 rewrite_both_ = true;
00511 else
00512 rewrite_both_ = false;
00513 }
00514
00515 SigmaMatcher(const SigmaMatcher<M> &matcher, bool safe = false)
00516 : matcher_(new M(*matcher.matcher_, safe)),
00517 match_type_(matcher.match_type_),
00518 sigma_label_(matcher.sigma_label_),
00519 rewrite_both_(matcher.rewrite_both_) {}
00520
00521 virtual ~SigmaMatcher() {
00522 delete matcher_;
00523 }
00524
00525 virtual SigmaMatcher<M> *Copy(bool safe = false) const {
00526 return new SigmaMatcher<M>(*this, safe);
00527 }
00528
00529 virtual MatchType Type(bool test) const { return matcher_->Type(test); }
00530
00531 void SetState(StateId s) {
00532 matcher_->SetState(s);
00533 has_sigma_ =
00534 sigma_label_ != kNoLabel ? matcher_->Find(sigma_label_) : false;
00535 }
00536
00537 bool Find(Label match_label) {
00538 match_label_ = match_label;
00539 if (match_label == sigma_label_ && sigma_label_ != kNoLabel) {
00540 LOG(FATAL) << "SigmaMatcher::Find: bad label (sigma)";
00541 }
00542 if (matcher_->Find(match_label)) {
00543 sigma_match_ = kNoLabel;
00544 return true;
00545 } else if (has_sigma_ && match_label != 0 && match_label != kNoLabel &&
00546 matcher_->Find(sigma_label_)) {
00547 sigma_match_ = match_label;
00548 return true;
00549 } else {
00550 return false;
00551 }
00552 }
00553
00554 bool Done() const {
00555 return matcher_->Done();
00556 }
00557
00558 const Arc& Value() const {
00559 if (sigma_match_ == kNoLabel) {
00560 return matcher_->Value();
00561 } else {
00562 sigma_arc_ = matcher_->Value();
00563 if (rewrite_both_) {
00564 if (sigma_arc_.ilabel == sigma_label_)
00565 sigma_arc_.ilabel = sigma_match_;
00566 if (sigma_arc_.olabel == sigma_label_)
00567 sigma_arc_.olabel = sigma_match_;
00568 } else if (match_type_ == MATCH_INPUT) {
00569 sigma_arc_.ilabel = sigma_match_;
00570 } else {
00571 sigma_arc_.olabel = sigma_match_;
00572 }
00573 return sigma_arc_;
00574 }
00575 }
00576
00577 void Next() {
00578 matcher_->Next();
00579 if (matcher_->Done() && has_sigma_ && (sigma_match_ == kNoLabel) &&
00580 (match_label_ > 0)) {
00581 matcher_->Find(sigma_label_);
00582 sigma_match_ = match_label_;
00583 }
00584 }
00585
00586 virtual const FST &GetFst() const { return matcher_->GetFst(); }
00587
00588 virtual uint64 Properties(uint64 props) const;
00589
00590 private:
00591 virtual void SetState_(StateId s) { SetState(s); }
00592 virtual bool Find_(Label label) { return Find(label); }
00593 virtual bool Done_() const { return Done(); }
00594 virtual const Arc& Value_() const { return Value(); }
00595 virtual void Next_() { Next(); }
00596
00597 M *matcher_;
00598 MatchType match_type_;
00599 Label sigma_label_;
00600 bool rewrite_both_;
00601 bool has_sigma_;
00602 Label sigma_match_;
00603 mutable Arc sigma_arc_;
00604 Label match_label_;
00605
00606 void operator=(const SigmaMatcher<M> &);
00607 };
00608
00609 template <class M> inline
00610 uint64 SigmaMatcher<M>::Properties(uint64 props) const {
00611 if (match_type_ == MATCH_NONE) {
00612 return props;
00613 } else if (rewrite_both_) {
00614 return props & ~(kIDeterministic | kNonIDeterministic |
00615 kODeterministic | kNonODeterministic |
00616 kILabelSorted | kNotILabelSorted |
00617 kOLabelSorted | kNotOLabelSorted |
00618 kString);
00619 } else if (match_type_ == MATCH_INPUT) {
00620 return props & ~(kIDeterministic | kNonIDeterministic |
00621 kODeterministic | kNonODeterministic |
00622 kILabelSorted | kNotILabelSorted |
00623 kString | kAcceptor);
00624 } else if (match_type_ == MATCH_OUTPUT) {
00625 return props & ~(kIDeterministic | kNonIDeterministic |
00626 kODeterministic | kNonODeterministic |
00627 kOLabelSorted | kNotOLabelSorted |
00628 kString | kAcceptor);
00629 } else {
00630 LOG(FATAL) << "SigmaMatcher::Properties: Invalid match type: "
00631 << match_type_;
00632 return 0;
00633 }
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 template <class M>
00652 class PhiMatcher : public MatcherBase<typename M::Arc> {
00653 public:
00654 typedef typename M::FST FST;
00655 typedef typename M::Arc Arc;
00656 typedef typename Arc::StateId StateId;
00657 typedef typename Arc::Label Label;
00658 typedef typename Arc::Weight Weight;
00659
00660 PhiMatcher(const FST &fst,
00661 MatchType match_type,
00662 Label phi_label = kNoLabel,
00663 bool phi_loop = true,
00664 MatcherRewriteMode rewrite_mode = MATCHER_REWRITE_AUTO,
00665 M *matcher = 0)
00666 : matcher_(matcher ? matcher : new M(fst, match_type)),
00667 match_type_(match_type),
00668 phi_label_(phi_label),
00669 state_(kNoStateId),
00670 phi_loop_(phi_loop) {
00671 if (match_type == MATCH_BOTH)
00672 LOG(FATAL) << "PhiMatcher: bad match type";
00673 if (phi_label == 0)
00674 LOG(FATAL) << "PhiMatcher: 0 cannot be used as phi_label";
00675
00676 if (rewrite_mode == MATCHER_REWRITE_AUTO)
00677 rewrite_both_ = fst.Properties(kAcceptor, true);
00678 else if (rewrite_mode == MATCHER_REWRITE_ALWAYS)
00679 rewrite_both_ = true;
00680 else
00681 rewrite_both_ = false;
00682 }
00683
00684 PhiMatcher(const PhiMatcher<M> &matcher, bool safe = false)
00685 : matcher_(new M(*matcher.matcher_, safe)),
00686 match_type_(matcher.match_type_),
00687 phi_label_(matcher.phi_label_),
00688 rewrite_both_(matcher.rewrite_both_),
00689 state_(kNoStateId),
00690 phi_loop_(matcher.phi_loop_) {}
00691
00692 virtual ~PhiMatcher() {
00693 delete matcher_;
00694 }
00695
00696 virtual PhiMatcher<M> *Copy(bool safe = false) const {
00697 return new PhiMatcher<M>(*this, safe);
00698 }
00699
00700 virtual MatchType Type(bool test) const { return matcher_->Type(test); }
00701
00702 void SetState(StateId s) {
00703 matcher_->SetState(s);
00704 state_ = s;
00705 has_phi_ = phi_label_ != kNoLabel;
00706 }
00707
00708 bool Find(Label match_label);
00709
00710 bool Done() const { return matcher_->Done(); }
00711
00712 const Arc& Value() const {
00713 if ((phi_match_ == kNoLabel) && (phi_weight_ == Weight::One())) {
00714 return matcher_->Value();
00715 } else {
00716 phi_arc_ = matcher_->Value();
00717 phi_arc_.weight = Times(phi_weight_, phi_arc_.weight);
00718 if (phi_match_ != kNoLabel) {
00719 if (rewrite_both_) {
00720 if (phi_arc_.ilabel == phi_label_)
00721 phi_arc_.ilabel = phi_match_;
00722 if (phi_arc_.olabel == phi_label_)
00723 phi_arc_.olabel = phi_match_;
00724 } else if (match_type_ == MATCH_INPUT) {
00725 phi_arc_.ilabel = phi_match_;
00726 } else {
00727 phi_arc_.olabel = phi_match_;
00728 }
00729 }
00730 return phi_arc_;
00731 }
00732 }
00733
00734 void Next() { matcher_->Next(); }
00735
00736 virtual const FST &GetFst() const { return matcher_->GetFst(); }
00737
00738 virtual uint64 Properties(uint64 props) const;
00739
00740 private:
00741 virtual void SetState_(StateId s) { SetState(s); }
00742 virtual bool Find_(Label label) { return Find(label); }
00743 virtual bool Done_() const { return Done(); }
00744 virtual const Arc& Value_() const { return Value(); }
00745 virtual void Next_() { Next(); }
00746
00747 M *matcher_;
00748 MatchType match_type_;
00749 Label phi_label_;
00750 bool rewrite_both_;
00751 bool has_phi_;
00752 Label phi_match_;
00753 mutable Arc phi_arc_;
00754 StateId state_;
00755 Weight phi_weight_;
00756 bool phi_loop_;
00757
00758
00759 void operator=(const PhiMatcher<M> &);
00760 };
00761
00762 template <class M> inline
00763 bool PhiMatcher<M>::Find(Label match_label) {
00764 if (match_label == phi_label_ && phi_label_ != kNoLabel) {
00765 LOG(FATAL) << "PhiMatcher::Find: bad label (phi)";
00766 }
00767 matcher_->SetState(state_);
00768 phi_match_ = kNoLabel;
00769 phi_weight_ = Weight::One();
00770 if (!has_phi_ || match_label == 0 || match_label == kNoLabel)
00771 return matcher_->Find(match_label);
00772 StateId state = state_;
00773 while (!matcher_->Find(match_label)) {
00774 if (!matcher_->Find(phi_label_))
00775 return false;
00776 if (phi_loop_ && matcher_->Value().nextstate == state) {
00777 phi_match_ = match_label;
00778 return true;
00779 }
00780 phi_weight_ = Times(phi_weight_, matcher_->Value().weight);
00781 state = matcher_->Value().nextstate;
00782 matcher_->Next();
00783 if (!matcher_->Done())
00784 LOG(FATAL) << "PhiMatcher: phi non-determinism not supported";
00785 matcher_->SetState(state);
00786 }
00787 return true;
00788 }
00789
00790 template <class M> inline
00791 uint64 PhiMatcher<M>::Properties(uint64 props) const {
00792 if (match_type_ == MATCH_NONE) {
00793 return props;
00794 } else if (match_type_ == MATCH_INPUT) {
00795 if (rewrite_both_) {
00796 return props & ~(kODeterministic | kNonODeterministic | kString |
00797 kILabelSorted | kNotILabelSorted |
00798 kOLabelSorted | kNotOLabelSorted);
00799 } else {
00800 return props & ~(kODeterministic | kAcceptor | kString |
00801 kILabelSorted | kNotILabelSorted |
00802 kOLabelSorted | kNotOLabelSorted);
00803 }
00804 } else if (match_type_ == MATCH_OUTPUT) {
00805 if (rewrite_both_) {
00806 return props & ~(kIDeterministic | kNonIDeterministic | kString |
00807 kILabelSorted | kNotILabelSorted |
00808 kOLabelSorted | kNotOLabelSorted);
00809 } else {
00810 return props & ~(kIDeterministic | kAcceptor | kString |
00811 kILabelSorted | kNotILabelSorted |
00812 kOLabelSorted | kNotOLabelSorted);
00813 }
00814 } else {
00815 LOG(FATAL) << "PhiMatcher::Properties: Invalid match type: "
00816 << match_type_;
00817 return 0;
00818 }
00819 }
00820
00821
00822
00823
00824
00825
00826
00827 const uint32 kMultiEpsList = 0x00000001;
00828
00829
00830 const uint32 kMultiEpsLoop = 0x00000002;
00831
00832
00833
00834
00835
00836
00837
00838
00839 template <class M>
00840 class MultiEpsMatcher {
00841 public:
00842 typedef typename M::FST FST;
00843 typedef typename M::Arc Arc;
00844 typedef typename Arc::StateId StateId;
00845 typedef typename Arc::Label Label;
00846 typedef typename Arc::Weight Weight;
00847
00848 MultiEpsMatcher(const FST &fst, MatchType match_type,
00849 uint32 flags = (kMultiEpsLoop | kMultiEpsList),
00850 M *matcher = 0, bool own_matcher = true)
00851 : matcher_(matcher ? matcher : new M(fst, match_type)),
00852 flags_(flags),
00853 own_matcher_(matcher ? own_matcher : true) {
00854 if (match_type == MATCH_INPUT) {
00855 loop_.ilabel = kNoLabel;
00856 loop_.olabel = 0;
00857 } else {
00858 loop_.ilabel = 0;
00859 loop_.olabel = kNoLabel;
00860 }
00861 loop_.weight = Weight::One();
00862 loop_.nextstate = kNoStateId;
00863 }
00864
00865 MultiEpsMatcher(const MultiEpsMatcher<M> &matcher, bool safe = false)
00866 : matcher_(new M(*matcher.matcher_, safe)),
00867 flags_(matcher.flags_),
00868 own_matcher_(true),
00869 multi_eps_labels_(matcher.multi_eps_labels_),
00870 loop_(matcher.loop_) {
00871 loop_.nextstate = kNoStateId;
00872 }
00873
00874 ~MultiEpsMatcher() {
00875 if (own_matcher_)
00876 delete matcher_;
00877 }
00878
00879 MultiEpsMatcher<M> *Copy(bool safe = false) const {
00880 return new MultiEpsMatcher<M>(*this, safe);
00881 }
00882
00883 MatchType Type(bool test) const { return matcher_->Type(test); }
00884
00885 void SetState(StateId s) {
00886 matcher_->SetState(s);
00887 loop_.nextstate = s;
00888 }
00889
00890 bool Find(Label match_label);
00891
00892 bool Done() const {
00893 return done_;
00894 }
00895
00896 const Arc& Value() const {
00897 return current_loop_ ? loop_ : matcher_->Value();
00898 }
00899
00900 void Next() {
00901 if (!current_loop_) {
00902 matcher_->Next();
00903 done_ = matcher_->Done();
00904 if (done_ && multi_eps_iter_ != multi_eps_labels_.End()) {
00905 ++multi_eps_iter_;
00906 while ((multi_eps_iter_ != multi_eps_labels_.End()) &&
00907 !matcher_->Find(*multi_eps_iter_))
00908 ++multi_eps_iter_;
00909 if (multi_eps_iter_ != multi_eps_labels_.End())
00910 done_ = false;
00911 else
00912 done_ = !matcher_->Find(kNoLabel);
00913
00914 }
00915 } else {
00916 done_ = true;
00917 }
00918 }
00919
00920 const FST &GetFst() const { return matcher_->GetFst(); }
00921
00922 uint64 Properties(uint64 props) const { return props; }
00923
00924 uint32 Flags() const { return matcher_->Flags(); }
00925
00926 void AddMultiEpsLabel(Label label) {
00927 if (label == 0)
00928 LOG(FATAL) << "MultiEpsMatcher: Bad multi-eps label: 0";
00929 multi_eps_labels_.Insert(label);
00930 }
00931
00932 void ClearMultiEpsLabels() {
00933 multi_eps_labels_.Clear();
00934 }
00935
00936 private:
00937
00938 bool IsMultiEps(const set<Label> &multi_eps_labels, Label label) const {
00939 return multi_eps_labels.Find(label) != multi_eps_labels.end();
00940 }
00941
00942 M *matcher_;
00943 uint32 flags_;
00944 bool own_matcher_;
00945
00946
00947 CompactSet<Label, kNoLabel> multi_eps_labels_;
00948 typename CompactSet<Label, kNoLabel>::const_iterator multi_eps_iter_;
00949
00950 bool current_loop_;
00951 mutable Arc loop_;
00952 bool done_;
00953
00954 void operator=(const MultiEpsMatcher<M> &);
00955 };
00956
00957 template <class M> inline
00958 bool MultiEpsMatcher<M>::Find(Label match_label) {
00959 multi_eps_iter_ = multi_eps_labels_.End();
00960 current_loop_ = false;
00961 bool ret;
00962 if (match_label == 0) {
00963 ret = matcher_->Find(0);
00964 } else if (match_label == kNoLabel) {
00965 if (flags_ & kMultiEpsList) {
00966
00967 multi_eps_iter_ = multi_eps_labels_.Begin();
00968 while ((multi_eps_iter_ != multi_eps_labels_.End()) &&
00969 !matcher_->Find(*multi_eps_iter_))
00970 ++multi_eps_iter_;
00971 if (multi_eps_iter_ != multi_eps_labels_.End())
00972 ret = true;
00973 else
00974 ret = matcher_->Find(kNoLabel);
00975 } else {
00976
00977 ret = matcher_->Find(kNoLabel);
00978 }
00979 } else if ((flags_ & kMultiEpsLoop) &&
00980 multi_eps_labels_.Find(match_label) != multi_eps_labels_.End()) {
00981
00982 current_loop_ = true;
00983 ret = true;
00984 } else {
00985 ret = matcher_->Find(match_label);
00986 }
00987 done_ = !ret;
00988 return ret;
00989 }
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 template <class F>
01003 class Matcher {
01004 public:
01005 typedef F FST;
01006 typedef typename F::Arc Arc;
01007 typedef typename Arc::StateId StateId;
01008 typedef typename Arc::Label Label;
01009 typedef typename Arc::Weight Weight;
01010
01011 Matcher(const F &fst, MatchType match_type) {
01012 base_ = fst.InitMatcher(match_type);
01013 if (!base_)
01014 base_ = new SortedMatcher<F>(fst, match_type);
01015 }
01016
01017 Matcher(const Matcher<F> &matcher, bool safe = false) {
01018 base_ = matcher.base_->Copy(safe);
01019 }
01020
01021
01022 Matcher(MatcherBase<Arc>* base_matcher) { base_ = base_matcher; }
01023
01024 ~Matcher() { delete base_; }
01025
01026 Matcher<F> *Copy(bool safe = false) const {
01027 return new Matcher<F>(*this, safe);
01028 }
01029
01030 MatchType Type(bool test) const { return base_->Type(test); }
01031 void SetState(StateId s) { base_->SetState(s); }
01032 bool Find(Label label) { return base_->Find(label); }
01033 bool Done() const { return base_->Done(); }
01034 const Arc& Value() const { return base_->Value(); }
01035 void Next() { base_->Next(); }
01036 const F &GetFst() const { return static_cast<const F &>(base_->GetFst()); }
01037 uint64 Properties(uint64 props) const { return base_->Properties(props); }
01038 uint32 Flags() const { return base_->Flags() & kMatcherFlags; }
01039
01040 private:
01041 MatcherBase<Arc> *base_;
01042
01043 void operator=(const Matcher<Arc> &);
01044 };
01045
01046 }
01047
01048
01049
01050 #endif /// FST_LIB_MATCHER_H__
01051