aboutsummaryrefslogtreecommitdiff
path: root/src/include/fst/matcher.h
diff options
context:
space:
mode:
authorAlexander Gutkin <agutkin@google.com>2012-09-12 18:11:43 +0100
committerAlexander Gutkin <agutkin@google.com>2012-09-12 18:11:43 +0100
commitdfd8b8327b93660601d016cdc6f29f433b45a8d8 (patch)
tree968ec84b8e32ad73ec18d74334930f36b7471906 /src/include/fst/matcher.h
parentf4c12fce1ee58e670f9c3fce46c40296ba9ee8a2 (diff)
downloadopenfst-dfd8b8327b93660601d016cdc6f29f433b45a8d8.tar.gz
Updated OpenFST version to openfst-1.3.2-CL32004048 from Greco3.
Change-Id: I19b0db718256b35c0e3e5a7315f1ed6335e6dcac
Diffstat (limited to 'src/include/fst/matcher.h')
-rw-r--r--src/include/fst/matcher.h72
1 files changed, 62 insertions, 10 deletions
diff --git a/src/include/fst/matcher.h b/src/include/fst/matcher.h
index a89325b..5ab3d26 100644
--- a/src/include/fst/matcher.h
+++ b/src/include/fst/matcher.h
@@ -83,8 +83,17 @@ namespace fst {
// uint64 Properties(uint64 props) const;
// };
+//
+// MATCHER FLAGS (see also kLookAheadFlags in lookahead-matcher.h)
+//
+// Matcher prefers being used as the matching side in composition.
+const uint32 kPreferMatch = 0x00000001;
+
+// Matcher needs to be used as the matching side in composition.
+const uint32 kRequireMatch = 0x00000002;
+
// Flags used for basic matchers (see also lookahead.h).
-const uint32 kMatcherFlags = 0x00000000;
+const uint32 kMatcherFlags = kPreferMatch | kRequireMatch;
// Matcher interface, templated on the Arc definition; used
// for matcher specializations that are returned by the
@@ -452,6 +461,12 @@ class RhoMatcher : public MatcherBase<typename M::Arc> {
virtual uint64 Properties(uint64 props) const;
+ virtual uint32 Flags() const {
+ if (rho_label_ == kNoLabel || match_type_ == MATCH_NONE)
+ return matcher_->Flags();
+ return matcher_->Flags() | kRequireMatch;
+ }
+
private:
virtual void SetState_(StateId s) { SetState(s); }
virtual bool Find_(Label label) { return Find(label); }
@@ -631,6 +646,15 @@ class SigmaMatcher : public MatcherBase<typename M::Arc> {
virtual uint64 Properties(uint64 props) const;
+ virtual uint32 Flags() const {
+ if (sigma_label_ == kNoLabel || match_type_ == MATCH_NONE)
+ return matcher_->Flags();
+ // kRequireMatch temporarily disabled until issues
+ // in //speech/gaudi/annotation/util/denorm are resolved.
+ // return matcher_->Flags() | kRequireMatch;
+ return matcher_->Flags();
+ }
+
private:
virtual void SetState_(StateId s) { SetState(s); }
virtual bool Find_(Label label) { return Find(label); }
@@ -722,11 +746,6 @@ class PhiMatcher : public MatcherBase<typename M::Arc> {
match_type_ = MATCH_NONE;
error_ = true;
}
- if (phi_label == 0) {
- FSTERROR() << "PhiMatcher: 0 cannot be used as phi_label";
- phi_label_ = kNoLabel;
- error_ = true;
- }
if (rewrite_mode == MATCHER_REWRITE_AUTO)
rewrite_both_ = fst.Properties(kAcceptor, true);
@@ -768,10 +787,15 @@ class PhiMatcher : public MatcherBase<typename M::Arc> {
const Arc& Value() const {
if ((phi_match_ == kNoLabel) && (phi_weight_ == Weight::One())) {
return matcher_->Value();
+ } else if (phi_match_ == 0) { // Virtual epsilon loop
+ phi_arc_ = Arc(kNoLabel, 0, Weight::One(), state_);
+ if (match_type_ == MATCH_OUTPUT)
+ swap(phi_arc_.ilabel, phi_arc_.olabel);
+ return phi_arc_;
} else {
phi_arc_ = matcher_->Value();
phi_arc_.weight = Times(phi_weight_, phi_arc_.weight);
- if (phi_match_ != kNoLabel) {
+ if (phi_match_ != kNoLabel) { // Phi loop match
if (rewrite_both_) {
if (phi_arc_.ilabel == phi_label_)
phi_arc_.ilabel = phi_match_;
@@ -793,6 +817,12 @@ class PhiMatcher : public MatcherBase<typename M::Arc> {
virtual uint64 Properties(uint64 props) const;
+ virtual uint32 Flags() const {
+ if (phi_label_ == kNoLabel || match_type_ == MATCH_NONE)
+ return matcher_->Flags();
+ return matcher_->Flags() | kRequireMatch;
+ }
+
private:
virtual void SetState_(StateId s) { SetState(s); }
virtual bool Find_(Label label) { return Find(label); }
@@ -818,19 +848,33 @@ private:
template <class M> inline
bool PhiMatcher<M>::Find(Label match_label) {
- if (match_label == phi_label_ && phi_label_ != kNoLabel) {
- FSTERROR() << "PhiMatcher::Find: bad label (phi)";
+ if (match_label == phi_label_ && phi_label_ != kNoLabel && phi_label_ != 0) {
+ FSTERROR() << "PhiMatcher::Find: bad label (phi): " << phi_label_;
error_ = true;
return false;
}
matcher_->SetState(state_);
phi_match_ = kNoLabel;
phi_weight_ = Weight::One();
+ if (phi_label_ == 0) { // When 'phi_label_ == 0',
+ if (match_label == kNoLabel) // there are no more true epsilon arcs,
+ return false;
+ if (match_label == 0) { // but virtual eps loop need to be returned
+ if (!matcher_->Find(kNoLabel)) {
+ return matcher_->Find(0);
+ } else {
+ phi_match_ = 0;
+ return true;
+ }
+ }
+ }
if (!has_phi_ || match_label == 0 || match_label == kNoLabel)
return matcher_->Find(match_label);
StateId state = state_;
while (!matcher_->Find(match_label)) {
- if (!matcher_->Find(phi_label_))
+ // Look for phi transition (if phi_label_ == 0, we need to look
+ // for -1 to avoid getting the virtual self-loop)
+ if (!matcher_->Find(phi_label_ == 0 ? -1 : phi_label_))
return false;
if (phi_loop_ && matcher_->Value().nextstate == state) {
phi_match_ = match_label;
@@ -856,6 +900,10 @@ uint64 PhiMatcher<M>::Properties(uint64 inprops) const {
if (match_type_ == MATCH_NONE) {
return outprops;
} else if (match_type_ == MATCH_INPUT) {
+ if (phi_label_ == 0) {
+ outprops &= ~kEpsilons | ~kIEpsilons | ~kOEpsilons;
+ outprops |= kNoEpsilons | kNoIEpsilons;
+ }
if (rewrite_both_) {
return outprops & ~(kODeterministic | kNonODeterministic | kString |
kILabelSorted | kNotILabelSorted |
@@ -866,6 +914,10 @@ uint64 PhiMatcher<M>::Properties(uint64 inprops) const {
kOLabelSorted | kNotOLabelSorted);
}
} else if (match_type_ == MATCH_OUTPUT) {
+ if (phi_label_ == 0) {
+ outprops &= ~kEpsilons | ~kIEpsilons | ~kOEpsilons;
+ outprops |= kNoEpsilons | kNoOEpsilons;
+ }
if (rewrite_both_) {
return outprops & ~(kIDeterministic | kNonIDeterministic | kString |
kILabelSorted | kNotILabelSorted |