aboutsummaryrefslogtreecommitdiff
path: root/src/include/fst/rational.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/fst/rational.h')
-rw-r--r--src/include/fst/rational.h330
1 files changed, 330 insertions, 0 deletions
diff --git a/src/include/fst/rational.h b/src/include/fst/rational.h
new file mode 100644
index 0000000..96aa00d
--- /dev/null
+++ b/src/include/fst/rational.h
@@ -0,0 +1,330 @@
+// rational.h
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Copyright 2005-2010 Google, Inc.
+// Author: riley@google.com (Michael Riley)
+//
+// \file
+// An Fst implementation and base interface for delayed unions,
+// concatenations and closures.
+
+#ifndef FST_LIB_RATIONAL_H__
+#define FST_LIB_RATIONAL_H__
+
+#include <algorithm>
+#include <string>
+#include <vector>
+using std::vector;
+
+#include <fst/mutable-fst.h>
+#include <fst/replace.h>
+#include <fst/test-properties.h>
+
+
+namespace fst {
+
+typedef CacheOptions RationalFstOptions;
+
+// This specifies whether to add the empty string.
+enum ClosureType { CLOSURE_STAR = 0, // T* -> add the empty string
+ CLOSURE_PLUS = 1 }; // T+ -> don't add the empty string
+
+template <class A> class RationalFst;
+template <class A> void Union(RationalFst<A> *fst1, const Fst<A> &fst2);
+template <class A> void Concat(RationalFst<A> *fst1, const Fst<A> &fst2);
+template <class A> void Concat(const Fst<A> &fst1, RationalFst<A> *fst2);
+template <class A> void Closure(RationalFst<A> *fst, ClosureType closure_type);
+
+
+// Implementation class for delayed unions, concatenations and closures.
+template<class A>
+class RationalFstImpl : public FstImpl<A> {
+ public:
+ using FstImpl<A>::SetType;
+ using FstImpl<A>::SetProperties;
+ using FstImpl<A>::WriteHeader;
+ using FstImpl<A>::SetInputSymbols;
+ using FstImpl<A>::SetOutputSymbols;
+
+ typedef A Arc;
+ typedef typename A::Weight Weight;
+ typedef typename A::StateId StateId;
+ typedef typename A::Label Label;
+
+ explicit RationalFstImpl(const RationalFstOptions &opts)
+ : nonterminals_(0),
+ replace_(0),
+ replace_options_(opts, 0) {
+ SetType("rational");
+ fst_tuples_.push_back(pair<Label, const Fst<A>*>(0, 0));
+ }
+
+ RationalFstImpl(const RationalFstImpl<A> &impl)
+ : rfst_(impl.rfst_),
+ nonterminals_(impl.nonterminals_),
+
+ replace_(impl.replace_ ? impl.replace_->Copy(true) : 0),
+ replace_options_(impl.replace_options_) {
+ SetType("rational");
+ fst_tuples_.reserve(impl.fst_tuples_.size());
+ for (size_t i = 0; i < impl.fst_tuples_.size(); ++i)
+ fst_tuples_.push_back(make_pair(impl.fst_tuples_[i].first,
+ impl.fst_tuples_[i].second
+ ? impl.fst_tuples_[i].second->Copy(true)
+ : 0));
+ }
+
+ virtual ~RationalFstImpl() {
+ for (size_t i = 0; i < fst_tuples_.size(); ++i)
+ if (fst_tuples_[i].second)
+ delete fst_tuples_[i].second;
+ if (replace_)
+ delete replace_;
+ }
+
+ StateId Start() { return Replace()->Start(); }
+
+ Weight Final(StateId s) { return Replace()->Final(s); }
+
+ size_t NumArcs(StateId s) { return Replace()->NumArcs(s); }
+
+ size_t NumInputEpsilons(StateId s) {
+ return Replace()->NumInputEpsilons(s);
+ }
+
+ size_t NumOutputEpsilons(StateId s) {
+ return Replace()->NumOutputEpsilons(s);
+ }
+
+ uint64 Properties() const { return Properties(kFstProperties); }
+
+ // Set error if found; return FST impl properties.
+ uint64 Properties(uint64 mask) const {
+ if ((mask & kError) && Replace()->Properties(kError, false))
+ SetProperties(kError, kError);
+ return FstImpl<Arc>::Properties(mask);
+ }
+
+ // Implementation of UnionFst(fst1,fst2)
+ void InitUnion(const Fst<A> &fst1, const Fst<A> &fst2) {
+ if (replace_)
+ delete replace_;
+ uint64 props1 = fst1.Properties(kFstProperties, false);
+ uint64 props2 = fst2.Properties(kFstProperties, false);
+ SetInputSymbols(fst1.InputSymbols());
+ SetOutputSymbols(fst1.OutputSymbols());
+ rfst_.AddState();
+ rfst_.AddState();
+ rfst_.SetStart(0);
+ rfst_.SetFinal(1, Weight::One());
+ rfst_.SetInputSymbols(fst1.InputSymbols());
+ rfst_.SetOutputSymbols(fst1.OutputSymbols());
+ nonterminals_ = 2;
+ rfst_.AddArc(0, A(0, -1, Weight::One(), 1));
+ rfst_.AddArc(0, A(0, -2, Weight::One(), 1));
+ fst_tuples_.push_back(make_pair(-1, fst1.Copy()));
+ fst_tuples_.push_back(make_pair(-2, fst2.Copy()));
+ SetProperties(UnionProperties(props1, props2, true), kCopyProperties);
+ }
+
+ // Implementation of ConcatFst(fst1,fst2)
+ void InitConcat(const Fst<A> &fst1, const Fst<A> &fst2) {
+ if (replace_)
+ delete replace_;
+ uint64 props1 = fst1.Properties(kFstProperties, false);
+ uint64 props2 = fst2.Properties(kFstProperties, false);
+ SetInputSymbols(fst1.InputSymbols());
+ SetOutputSymbols(fst1.OutputSymbols());
+ rfst_.AddState();
+ rfst_.AddState();
+ rfst_.AddState();
+ rfst_.SetStart(0);
+ rfst_.SetFinal(2, Weight::One());
+ rfst_.SetInputSymbols(fst1.InputSymbols());
+ rfst_.SetOutputSymbols(fst1.OutputSymbols());
+ nonterminals_ = 2;
+ rfst_.AddArc(0, A(0, -1, Weight::One(), 1));
+ rfst_.AddArc(1, A(0, -2, Weight::One(), 2));
+ fst_tuples_.push_back(make_pair(-1, fst1.Copy()));
+ fst_tuples_.push_back(make_pair(-2, fst2.Copy()));
+ SetProperties(ConcatProperties(props1, props2, true), kCopyProperties);
+ }
+
+ // Implementation of ClosureFst(fst, closure_type)
+ void InitClosure(const Fst<A> &fst, ClosureType closure_type) {
+ if (replace_)
+ delete replace_;
+ uint64 props = fst.Properties(kFstProperties, false);
+ SetInputSymbols(fst.InputSymbols());
+ SetOutputSymbols(fst.OutputSymbols());
+ if (closure_type == CLOSURE_STAR) {
+ rfst_.AddState();
+ rfst_.SetStart(0);
+ rfst_.SetFinal(0, Weight::One());
+ rfst_.AddArc(0, A(0, -1, Weight::One(), 0));
+ } else {
+ rfst_.AddState();
+ rfst_.AddState();
+ rfst_.SetStart(0);
+ rfst_.SetFinal(1, Weight::One());
+ rfst_.AddArc(0, A(0, -1, Weight::One(), 1));
+ rfst_.AddArc(1, A(0, 0, Weight::One(), 0));
+ }
+ rfst_.SetInputSymbols(fst.InputSymbols());
+ rfst_.SetOutputSymbols(fst.OutputSymbols());
+ fst_tuples_.push_back(make_pair(-1, fst.Copy()));
+ nonterminals_ = 1;
+ SetProperties(ClosureProperties(props, closure_type == CLOSURE_STAR, true),
+ kCopyProperties);
+ }
+
+ // Implementation of Union(Fst &, RationalFst *)
+ void AddUnion(const Fst<A> &fst) {
+ if (replace_)
+ delete replace_;
+ uint64 props1 = FstImpl<A>::Properties();
+ uint64 props2 = fst.Properties(kFstProperties, false);
+ VectorFst<A> afst;
+ afst.AddState();
+ afst.AddState();
+ afst.SetStart(0);
+ afst.SetFinal(1, Weight::One());
+ ++nonterminals_;
+ afst.AddArc(0, A(0, -nonterminals_, Weight::One(), 1));
+ Union(&rfst_, afst);
+ fst_tuples_.push_back(make_pair(-nonterminals_, fst.Copy()));
+ SetProperties(UnionProperties(props1, props2, true), kCopyProperties);
+ }
+
+ // Implementation of Concat(Fst &, RationalFst *)
+ void AddConcat(const Fst<A> &fst, bool append) {
+ if (replace_)
+ delete replace_;
+ uint64 props1 = FstImpl<A>::Properties();
+ uint64 props2 = fst.Properties(kFstProperties, false);
+ VectorFst<A> afst;
+ afst.AddState();
+ afst.AddState();
+ afst.SetStart(0);
+ afst.SetFinal(1, Weight::One());
+ ++nonterminals_;
+ afst.AddArc(0, A(0, -nonterminals_, Weight::One(), 1));
+ if (append)
+ Concat(&rfst_, afst);
+ else
+ Concat(afst, &rfst_);
+ fst_tuples_.push_back(make_pair(-nonterminals_, fst.Copy()));
+ SetProperties(ConcatProperties(props1, props2, true), kCopyProperties);
+ }
+
+ // Implementation of Closure(RationalFst *, closure_type)
+ void AddClosure(ClosureType closure_type) {
+ if (replace_)
+ delete replace_;
+ uint64 props = FstImpl<A>::Properties();
+ Closure(&rfst_, closure_type);
+ SetProperties(ClosureProperties(props, closure_type == CLOSURE_STAR, true),
+ kCopyProperties);
+ }
+
+ // Returns the underlying ReplaceFst.
+ ReplaceFst<A> *Replace() const {
+ if (!replace_) {
+ fst_tuples_[0].second = rfst_.Copy();
+ replace_ = new ReplaceFst<A>(fst_tuples_, replace_options_);
+ }
+ return replace_;
+ }
+
+ private:
+ VectorFst<A> rfst_; // rational topology machine; uses neg. nonterminals
+ Label nonterminals_; // # of nonterminals used
+ // Contains the nonterminals and their corresponding FSTs.
+ mutable vector<pair<Label, const Fst<A>*> > fst_tuples_;
+ mutable ReplaceFst<A> *replace_; // Underlying ReplaceFst
+ ReplaceFstOptions<A> replace_options_; // Options for creating 'replace_'
+
+ void operator=(const RationalFstImpl<A> &impl); // disallow
+};
+
+// Parent class for the delayed rational operations - delayed union,
+// concatenation, and closure.
+//
+// This class attaches interface to implementation and handles
+// reference counting, delegating most methods to ImplToFst.
+template <class A>
+class RationalFst : public ImplToFst< RationalFstImpl<A> > {
+ public:
+ friend class StateIterator< RationalFst<A> >;
+ friend class ArcIterator< RationalFst<A> >;
+ friend void Union<>(RationalFst<A> *fst1, const Fst<A> &fst2);
+ friend void Concat<>(RationalFst<A> *fst1, const Fst<A> &fst2);
+ friend void Concat<>(const Fst<A> &fst1, RationalFst<A> *fst2);
+ friend void Closure<>(RationalFst<A> *fst, ClosureType closure_type);
+
+ typedef A Arc;
+ typedef typename A::StateId StateId;
+ typedef RationalFstImpl<A> Impl;
+
+ virtual void InitStateIterator(StateIteratorData<A> *data) const {
+ GetImpl()->Replace()->InitStateIterator(data);
+ }
+
+ virtual void InitArcIterator(StateId s, ArcIteratorData<A> *data) const {
+ GetImpl()->Replace()->InitArcIterator(s, data);
+ }
+
+ protected:
+ RationalFst()
+ : ImplToFst<Impl>(new Impl(RationalFstOptions())) {}
+
+ explicit RationalFst(const RationalFstOptions &opts)
+ : ImplToFst<Impl>(new Impl(opts)) {}
+
+ // See Fst<>::Copy() for doc.
+ RationalFst(const RationalFst<A> &fst , bool safe = false)
+ : ImplToFst<Impl>(fst, safe) {}
+
+ private:
+ // Makes visible to friends.
+ Impl *GetImpl() const { return ImplToFst<Impl>::GetImpl(); }
+
+ void operator=(const RationalFst<A> &fst); // disallow
+};
+
+
+// Specialization for RationalFst.
+template <class A>
+class StateIterator< RationalFst<A> >
+ : public StateIterator< ReplaceFst<A> > {
+ public:
+ explicit StateIterator(const RationalFst<A> &fst)
+ : StateIterator< ReplaceFst<A> >(*(fst.GetImpl()->Replace())) {}
+};
+
+
+// Specialization for RationalFst.
+template <class A>
+class ArcIterator< RationalFst<A> >
+ : public CacheArcIterator< ReplaceFst<A> > {
+ public:
+ typedef typename A::StateId StateId;
+
+ ArcIterator(const RationalFst<A> &fst, StateId s)
+ : ArcIterator< ReplaceFst<A> >(*(fst.GetImpl()->Replace()), s) {}
+};
+
+} // namespace fst
+
+#endif // FST_LIB_RATIONAL_H__