00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef FST_LIB_STATE_TABLE_H__
00022 #define FST_LIB_STATE_TABLE_H__
00023
00024 #include <deque>
00025 #include <vector>
00026 using std::vector;
00027
00028 #include <fst/expanded-fst.h>
00029
00030 namespace fst {
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 template <class T, class H>
00068 class HashStateTable {
00069 public:
00070 typedef T StateTuple;
00071 typedef typename StateTuple::StateId StateId;
00072
00073 HashStateTable() {
00074 StateTuple empty_tuple;
00075 }
00076
00077 StateId FindState(const StateTuple &tuple) {
00078 StateId &id_ref = tuple2id_[tuple];
00079 if (id_ref == 0) {
00080 id2tuple_.push_back(tuple);
00081 id_ref = id2tuple_.size();
00082 }
00083 return id_ref - 1;
00084 }
00085
00086 const StateTuple &Tuple(StateId s) const {
00087 return id2tuple_[s];
00088 }
00089
00090 StateId Size() const { return id2tuple_.size(); }
00091
00092 private:
00093 unordered_map<StateTuple, StateId, H> tuple2id_;
00094 vector<StateTuple> id2tuple_;
00095
00096 DISALLOW_COPY_AND_ASSIGN(HashStateTable);
00097 };
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 template <class T, class H>
00109 class CompactHashStateTable {
00110 public:
00111 friend class HashFunc;
00112 friend class HashEqual;
00113 typedef T StateTuple;
00114 typedef typename StateTuple::StateId StateId;
00115 typedef StateId Key;
00116
00117 CompactHashStateTable()
00118 : hash_func_(*this),
00119 hash_equal_(*this),
00120 keys_(0, hash_func_, hash_equal_) {
00121 }
00122
00123
00124 explicit CompactHashStateTable(size_t table_size)
00125 : hash_func_(*this),
00126 hash_equal_(*this),
00127 keys_(table_size, hash_func_, hash_equal_) {
00128 id2tuple_.reserve(table_size);
00129 }
00130
00131 StateId FindState(const StateTuple &tuple) {
00132 current_tuple_ = &tuple;
00133 typename KeyHashSet::const_iterator it = keys_.find(kCurrentKey);
00134 if (it == keys_.end()) {
00135 Key key = id2tuple_.size();
00136 id2tuple_.push_back(tuple);
00137 keys_.insert(key);
00138 return key;
00139 } else {
00140 return *it;
00141 }
00142 }
00143
00144 const StateTuple &Tuple(StateId s) const {
00145 return id2tuple_[s];
00146 }
00147
00148 StateId Size() const { return id2tuple_.size(); }
00149
00150 private:
00151 static const StateId kEmptyKey;
00152 static const StateId kCurrentKey;
00153
00154 class HashFunc {
00155 public:
00156 HashFunc(const CompactHashStateTable &ht) : ht_(&ht) {}
00157
00158 size_t operator()(Key k) const { return hf(ht_->Key2Tuple(k)); }
00159 private:
00160 const CompactHashStateTable *ht_;
00161 H hf;
00162 };
00163
00164 class HashEqual {
00165 public:
00166 HashEqual(const CompactHashStateTable &ht) : ht_(&ht) {}
00167
00168 bool operator()(Key k1, Key k2) const {
00169 return ht_->Key2Tuple(k1) == ht_->Key2Tuple(k2);
00170 }
00171 private:
00172 const CompactHashStateTable *ht_;
00173 };
00174
00175 typedef unordered_set<Key, HashFunc, HashEqual> KeyHashSet;
00176
00177 const StateTuple &Key2Tuple(Key k) const {
00178 if (k == kEmptyKey)
00179 return empty_tuple_;
00180 else if (k == kCurrentKey)
00181 return *current_tuple_;
00182 else
00183 return id2tuple_[k];
00184 }
00185
00186 HashFunc hash_func_;
00187 HashEqual hash_equal_;
00188 KeyHashSet keys_;
00189 vector<StateTuple> id2tuple_;
00190 const StateTuple empty_tuple_;
00191 const StateTuple *current_tuple_;
00192
00193 DISALLOW_COPY_AND_ASSIGN(CompactHashStateTable);
00194 };
00195
00196 template <class T, class H>
00197 const typename CompactHashStateTable<T, H>::StateId
00198 CompactHashStateTable<T, H>::kEmptyKey = -1;
00199
00200 template <class T, class H>
00201 const typename CompactHashStateTable<T, H>::StateId
00202 CompactHashStateTable<T, H>::kCurrentKey = -2;
00203
00204
00205
00206
00207
00208
00209
00210
00211 template <class T, class FP>
00212 class VectorStateTable {
00213 public:
00214 typedef T StateTuple;
00215 typedef typename StateTuple::StateId StateId;
00216 typedef typename StateTuple::FilterState FilterState;
00217
00218 explicit VectorStateTable(FP *fp = 0)
00219 : fp_(fp ? fp : new FP()) {}
00220
00221 ~VectorStateTable() { delete fp_; }
00222
00223 StateId FindState(const StateTuple &tuple) {
00224 ssize_t fp = (*fp_)(tuple);
00225 if (fp >= fp2id_.size())
00226 fp2id_.resize(fp + 1);
00227 StateId &id_ref = fp2id_[fp];
00228 if (id_ref == 0) {
00229 id2tuple_.push_back(tuple);
00230 id_ref = id2tuple_.size();
00231 }
00232 return id_ref - 1;
00233 }
00234
00235 const StateTuple &Tuple(StateId s) const {
00236 return id2tuple_[s];
00237 }
00238
00239 StateId Size() const { return id2tuple_.size(); }
00240
00241 const FP &Fingerprint() const { return *fp_; }
00242
00243 private:
00244 FP *fp_;
00245 vector<StateId> fp2id_;
00246 vector<StateTuple> id2tuple_;
00247
00248 DISALLOW_COPY_AND_ASSIGN(VectorStateTable);
00249 };
00250
00251
00252
00253
00254
00255 template <class T, class F>
00256 class ErasableStateTable {
00257 public:
00258 typedef T StateTuple;
00259 typedef typename StateTuple::StateId StateId;
00260
00261 ErasableStateTable() : first_(0) {}
00262
00263 StateId FindState(const StateTuple &tuple) {
00264 StateId &id_ref = tuple2id_[tuple];
00265 if (id_ref == 0) {
00266 id2tuple_.push_back(tuple);
00267 id_ref = id2tuple_.size() + first_;
00268 }
00269 return id_ref - 1;
00270 }
00271
00272 const StateTuple &Tuple(StateId s) const {
00273 return id2tuple_[s - first_];
00274 }
00275
00276 StateId Size() const { return id2tuple_.size(); }
00277
00278 void Erase(StateId s) {
00279 StateTuple &tuple = id2tuple_[s - first_];
00280 typename unordered_map<StateTuple, StateId, F>::iterator it =
00281 tuple2id_.find(tuple);
00282 tuple2id_.erase(it);
00283 id2tuple_[s - first_] = empty_tuple_;
00284 while (!id2tuple_.empty() && id2tuple_.front() == empty_tuple_) {
00285 id2tuple_.pop_front();
00286 ++first_;
00287 }
00288 }
00289
00290 private:
00291 unordered_map<StateTuple, StateId, F> tuple2id_;
00292 deque<StateTuple> id2tuple_;
00293 const StateTuple empty_tuple_;
00294 StateId first_;
00295
00296 DISALLOW_COPY_AND_ASSIGN(ErasableStateTable);
00297 };
00298
00299
00300
00301
00302
00303
00304
00305
00306 template <class T, class S, class FP, class H>
00307 class VectorHashStateTable {
00308 public:
00309 friend class HashFunc;
00310 friend class HashEqual;
00311 typedef T StateTuple;
00312 typedef typename StateTuple::StateId StateId;
00313 typedef StateId Key;
00314
00315 VectorHashStateTable(S *s, FP *fp, H *h,
00316 size_t vector_size = 0,
00317 size_t tuple_size = 0)
00318 : selector_(s),
00319 fp_(fp),
00320 h_(h),
00321 hash_func_(*this),
00322 hash_equal_(*this),
00323 keys_(0, hash_func_, hash_equal_) {
00324 if (vector_size)
00325 fp2id_.reserve(vector_size);
00326 if (tuple_size)
00327 id2tuple_.reserve(tuple_size);
00328 }
00329
00330 ~VectorHashStateTable() {
00331 delete selector_;
00332 delete fp_;
00333 delete h_;
00334 }
00335
00336 StateId FindState(const StateTuple &tuple) {
00337 if ((*selector_)(tuple)) {
00338 uint64 fp = (*fp_)(tuple);
00339 if (fp2id_.size() <= fp)
00340 fp2id_.resize(fp + 1, 0);
00341 if (fp2id_[fp] == 0) {
00342 id2tuple_.push_back(tuple);
00343 fp2id_[fp] = id2tuple_.size();
00344 }
00345 return fp2id_[fp] - 1;
00346 } else {
00347 current_tuple_ = &tuple;
00348 typename KeyHashSet::const_iterator it = keys_.find(kCurrentKey);
00349 if (it == keys_.end()) {
00350 Key key = id2tuple_.size();
00351 id2tuple_.push_back(tuple);
00352 keys_.insert(key);
00353 return key;
00354 } else {
00355 return *it;
00356 }
00357 }
00358 }
00359
00360 const StateTuple &Tuple(StateId s) const {
00361 return id2tuple_[s];
00362 }
00363
00364 StateId Size() const { return id2tuple_.size(); }
00365
00366 const S &Selector() const { return *selector_; }
00367
00368 const FP &Fingerprint() const { return *fp_; }
00369
00370 const H &Hash() const { return *h_; }
00371
00372 private:
00373 static const StateId kEmptyKey;
00374 static const StateId kCurrentKey;
00375
00376 class HashFunc {
00377 public:
00378 HashFunc(const VectorHashStateTable &ht) : ht_(&ht) {}
00379
00380 size_t operator()(Key k) const { return (*(ht_->h_))(ht_->Key2Tuple(k)); }
00381 private:
00382 const VectorHashStateTable *ht_;
00383 };
00384
00385 class HashEqual {
00386 public:
00387 HashEqual(const VectorHashStateTable &ht) : ht_(&ht) {}
00388
00389 bool operator()(Key k1, Key k2) const {
00390 return ht_->Key2Tuple(k1) == ht_->Key2Tuple(k2);
00391 }
00392 private:
00393 const VectorHashStateTable *ht_;
00394 };
00395
00396 typedef unordered_set<Key, HashFunc, HashEqual> KeyHashSet;
00397
00398 const StateTuple &Key2Tuple(Key k) const {
00399 if (k == kEmptyKey)
00400 return empty_tuple_;
00401 else if (k == kCurrentKey)
00402 return *current_tuple_;
00403 else
00404 return id2tuple_[k];
00405 }
00406
00407
00408 S *selector_;
00409 FP *fp_;
00410 H *h_;
00411
00412 vector<StateTuple> id2tuple_;
00413 vector<StateId> fp2id_;
00414
00415
00416
00417 HashFunc hash_func_;
00418 HashEqual hash_equal_;
00419 KeyHashSet keys_;
00420 const StateTuple empty_tuple_;
00421 const StateTuple *current_tuple_;
00422
00423 DISALLOW_COPY_AND_ASSIGN(VectorHashStateTable);
00424 };
00425
00426 template <class T, class S, class FP, class H>
00427 const typename VectorHashStateTable<T, S, FP, H>::StateId
00428 VectorHashStateTable<T, S, FP, H>::kEmptyKey = -1;
00429
00430 template <class T, class S, class FP, class H>
00431 const typename VectorHashStateTable<T, S, FP, H>::StateId
00432 VectorHashStateTable<T, S, FP, H>::kCurrentKey = -2;
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 template <typename S, typename F>
00461 struct ComposeStateTuple {
00462 typedef S StateId;
00463 typedef F FilterState;
00464
00465 ComposeStateTuple()
00466 : state_id1(kNoStateId), state_id2(kNoStateId),
00467 filter_state(FilterState::NoState()) {}
00468
00469 ComposeStateTuple(StateId s1, StateId s2, const FilterState &f)
00470 : state_id1(s1), state_id2(s2), filter_state(f) {}
00471
00472 StateId state_id1;
00473 StateId state_id2;
00474 FilterState filter_state;
00475 };
00476
00477
00478 template <typename S, typename F>
00479 inline bool operator==(const ComposeStateTuple<S, F>& x,
00480 const ComposeStateTuple<S, F>& y) {
00481 if (&x == &y)
00482 return true;
00483 return x.state_id1 == y.state_id1 &&
00484 x.state_id2 == y.state_id2 &&
00485 x.filter_state == y.filter_state;
00486 }
00487
00488
00489
00490 template <typename S, typename F>
00491 class ComposeHash {
00492 public:
00493 size_t operator()(const ComposeStateTuple<S, F>& t) const {
00494 return t.state_id1 + t.state_id2 * kPrime0 +
00495 t.filter_state.Hash() * kPrime1;
00496 }
00497 private:
00498 static const size_t kPrime0;
00499 static const size_t kPrime1;
00500 };
00501
00502 template <typename S, typename F>
00503 const size_t ComposeHash<S, F>::kPrime0 = 7853;
00504
00505 template <typename S, typename F>
00506 const size_t ComposeHash<S, F>::kPrime1 = 7867;
00507
00508
00509
00510 template <typename A,
00511 typename F,
00512 typename H =
00513 CompactHashStateTable<ComposeStateTuple<typename A::StateId, F>,
00514 ComposeHash<typename A::StateId, F> > >
00515 class GenericComposeStateTable : public H {
00516 public:
00517 typedef A Arc;
00518 typedef typename A::StateId StateId;
00519 typedef F FilterState;
00520 typedef ComposeStateTuple<StateId, F> StateTuple;
00521
00522 GenericComposeStateTable(const Fst<A> &fst1, const Fst<A> &fst2) {}
00523
00524 GenericComposeStateTable(const GenericComposeStateTable<A, F> &table) {}
00525
00526 private:
00527 void operator=(const GenericComposeStateTable<A, F> &table);
00528 };
00529
00530
00531
00532 template <typename S, typename F>
00533 class ComposeFingerprint {
00534 public:
00535 typedef S StateId;
00536 typedef F FilterState;
00537 typedef ComposeStateTuple<S, F> StateTuple;
00538
00539
00540 ComposeFingerprint() {
00541 LOG(FATAL) << "TupleFingerprint: # of FST state must be provided.";
00542 }
00543
00544
00545 ComposeFingerprint(StateId nstates1, StateId nstates2)
00546 : mult1_(nstates1), mult2_(nstates1 * nstates2) { }
00547
00548 size_t operator()(const StateTuple &tuple) {
00549 return tuple.state_id1 + tuple.state_id2 * mult1_ +
00550 tuple.filter_state.Hash() * mult2_;
00551 }
00552
00553 private:
00554 ssize_t mult1_;
00555 ssize_t mult2_;
00556 };
00557
00558
00559
00560 template <typename S, typename F>
00561 class ComposeState1Fingerprint {
00562 public:
00563 typedef S StateId;
00564 typedef F FilterState;
00565 typedef ComposeStateTuple<S, F> StateTuple;
00566
00567 size_t operator()(const StateTuple &tuple) { return tuple.state_id1; }
00568 };
00569
00570
00571
00572 template <typename S, typename F>
00573 class ComposeState2Fingerprint {
00574 public:
00575 typedef S StateId;
00576 typedef F FilterState;
00577 typedef ComposeStateTuple<S, F> StateTuple;
00578
00579 size_t operator()(const StateTuple &tuple) { return tuple.state_id2; }
00580 };
00581
00582
00583
00584
00585
00586
00587 template <typename A, typename F>
00588 class ProductComposeStateTable : public
00589 VectorStateTable<ComposeStateTuple<typename A::StateId, F>,
00590 ComposeFingerprint<typename A::StateId, F> > {
00591 public:
00592 typedef A Arc;
00593 typedef typename A::StateId StateId;
00594 typedef F FilterState;
00595 typedef ComposeStateTuple<StateId, F> StateTuple;
00596
00597 ProductComposeStateTable(const Fst<A> &fst1, const Fst<A> &fst2)
00598 : VectorStateTable<ComposeStateTuple<StateId, F>,
00599 ComposeFingerprint<StateId, F> >
00600 (new ComposeFingerprint<StateId, F>(CountStates(fst1),
00601 CountStates(fst2))) { }
00602
00603 ProductComposeStateTable(const ProductComposeStateTable<A, F> &table)
00604 : VectorStateTable<ComposeStateTuple<StateId, F>,
00605 ComposeFingerprint<StateId, F> >
00606 (new ComposeFingerprint<StateId, F>(table.Fingerprint())) {}
00607
00608 private:
00609 void operator=(const ProductComposeStateTable<A, F> &table);
00610 };
00611
00612
00613
00614
00615
00616
00617
00618 template <typename A, typename F>
00619 class StringDetComposeStateTable : public
00620 VectorStateTable<ComposeStateTuple<typename A::StateId, F>,
00621 ComposeState1Fingerprint<typename A::StateId, F> > {
00622 public:
00623 typedef A Arc;
00624 typedef typename A::StateId StateId;
00625 typedef F FilterState;
00626 typedef ComposeStateTuple<StateId, F> StateTuple;
00627
00628 StringDetComposeStateTable(const Fst<A> &fst1, const Fst<A> &fst2) {
00629 uint64 props1 = kString;
00630 uint64 props2 = kIDeterministic | kNoIEpsilons;
00631 if (fst1.Properties(props1, true) != props1 ||
00632 fst2.Properties(props2, true) != props2)
00633 LOG(FATAL) << "StringDetComposeStateTable: fst1 not a string or"
00634 << " fst2 not input deterministic and epsilon-free";
00635 }
00636
00637 StringDetComposeStateTable(const StringDetComposeStateTable<A, F> &table) {}
00638
00639 private:
00640 void operator=(const StringDetComposeStateTable<A, F> &table);
00641 };
00642
00643
00644
00645
00646
00647
00648
00649
00650 template <typename A, typename F>
00651 class DetStringComposeStateTable : public
00652 VectorStateTable<ComposeStateTuple<typename A::StateId, F>,
00653 ComposeState1Fingerprint<typename A::StateId, F> > {
00654 public:
00655 typedef A Arc;
00656 typedef typename A::StateId StateId;
00657 typedef F FilterState;
00658 typedef ComposeStateTuple<StateId, F> StateTuple;
00659
00660 DetStringComposeStateTable(const Fst<A> &fst1, const Fst<A> &fst2) {
00661 uint64 props1 = kODeterministic | kNoOEpsilons;
00662 uint64 props2 = kString;
00663 if (fst1.Properties(props1, true) != props1 ||
00664 fst2.Properties(props2, true) != props2)
00665 LOG(FATAL) << "StringDetComposeStateTable: fst2 not a string or"
00666 << " fst1 not output deterministic and epsilon-free";
00667 }
00668
00669 DetStringComposeStateTable(const DetStringComposeStateTable<A, F> &table) {}
00670
00671 private:
00672 void operator=(const DetStringComposeStateTable<A, F> &table);
00673 };
00674
00675
00676
00677
00678
00679
00680 template <typename A, typename F>
00681 class ErasableComposeStateTable : public
00682 ErasableStateTable<ComposeStateTuple<typename A::StateId, F>,
00683 ComposeHash<typename A::StateId, F> > {
00684 public:
00685 typedef A Arc;
00686 typedef typename A::StateId StateId;
00687 typedef F FilterState;
00688 typedef ComposeStateTuple<StateId, F> StateTuple;
00689
00690 ErasableComposeStateTable(const Fst<A> &fst1, const Fst<A> &fst2) {}
00691
00692 ErasableComposeStateTable(const ErasableComposeStateTable<A, F> &table) {}
00693
00694 private:
00695 void operator=(const ErasableComposeStateTable<A, F> &table);
00696 };
00697
00698 }
00699
00700 #endif /// FST_LIB_STATE_TABLE_H__
00701