Home | History | Annotate | Download | only in lib
      1 // rational.h
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 //
     15 //
     16 // \file
     17 // An Fst implementation and base interface for delayed unions,
     18 // concatenations and closures.
     19 
     20 #ifndef FST_LIB_RATIONAL_H__
     21 #define FST_LIB_RATIONAL_H__
     22 
     23 #include "fst/lib/map.h"
     24 #include "fst/lib/mutable-fst.h"
     25 #include "fst/lib/replace.h"
     26 #include "fst/lib/test-properties.h"
     27 
     28 namespace fst {
     29 
     30 typedef CacheOptions RationalFstOptions;
     31 
     32 // This specifies whether to add the empty string.
     33 enum ClosureType { CLOSURE_STAR = 0,    // T* -> add the empty string
     34                    CLOSURE_PLUS = 1 };  // T+ -> don't add the empty string
     35 
     36 template <class A> class RationalFst;
     37 template <class A> void Union(RationalFst<A> *fst1, const Fst<A> &fst2);
     38 template <class A> void Concat(RationalFst<A> *fst1, const Fst<A> &fst2);
     39 template <class A> void Closure(RationalFst<A> *fst, ClosureType closure_type);
     40 
     41 
     42 // Implementation class for delayed unions, concatenations and closures.
     43 template<class A>
     44 class RationalFstImpl : public ReplaceFstImpl<A> {
     45  public:
     46   using FstImpl<A>::SetType;
     47   using FstImpl<A>::SetProperties;
     48   using FstImpl<A>::Properties;
     49   using FstImpl<A>::SetInputSymbols;
     50   using FstImpl<A>::SetOutputSymbols;
     51   using ReplaceFstImpl<A>::SetRoot;
     52 
     53   typedef typename A::Weight Weight;
     54   typedef typename A::Label Label;
     55 
     56   explicit RationalFstImpl(const RationalFstOptions &opts)
     57       : ReplaceFstImpl<A>(ReplaceFstOptions(opts, kNoLabel)),
     58         nonterminals_(0) {
     59     SetType("rational");
     60   }
     61 
     62   // Implementation of UnionFst(fst1,fst2)
     63   void InitUnion(const Fst<A> &fst1, const Fst<A> &fst2) {
     64     uint64 props1 = fst1.Properties(kFstProperties, false);
     65     uint64 props2 = fst2.Properties(kFstProperties, false);
     66     SetInputSymbols(fst1.InputSymbols());
     67     SetOutputSymbols(fst1.OutputSymbols());
     68     rfst_.AddState();
     69     rfst_.AddState();
     70     rfst_.SetStart(0);
     71     rfst_.SetFinal(1, Weight::One());
     72     rfst_.SetInputSymbols(fst1.InputSymbols());
     73     rfst_.SetOutputSymbols(fst1.OutputSymbols());
     74     nonterminals_ = 2;
     75     rfst_.AddArc(0, A(0, -1, Weight::One(), 1));
     76     rfst_.AddArc(0, A(0, -2, Weight::One(), 1));
     77     AddFst(0, &rfst_);
     78     AddFst(-1, &fst1);
     79     AddFst(-2, &fst2);
     80     SetRoot(0);
     81     SetProperties(UnionProperties(props1, props2, true), kCopyProperties);
     82   }
     83 
     84   // Implementation of ConcatFst(fst1,fst2)
     85   void InitConcat(const Fst<A> &fst1, const Fst<A> &fst2) {
     86     uint64 props1 = fst1.Properties(kFstProperties, false);
     87     uint64 props2 = fst2.Properties(kFstProperties, false);
     88     SetInputSymbols(fst1.InputSymbols());
     89     SetOutputSymbols(fst1.OutputSymbols());
     90     rfst_.AddState();
     91     rfst_.AddState();
     92     rfst_.AddState();
     93     rfst_.SetStart(0);
     94     rfst_.SetFinal(2, Weight::One());
     95     rfst_.SetInputSymbols(fst1.InputSymbols());
     96     rfst_.SetOutputSymbols(fst1.OutputSymbols());
     97     nonterminals_ = 2;
     98     rfst_.AddArc(0, A(0, -1, Weight::One(), 1));
     99     rfst_.AddArc(1, A(0, -2, Weight::One(), 2));
    100     AddFst(0, &rfst_);
    101     AddFst(-1, &fst1);
    102     AddFst(-2, &fst2);
    103     SetRoot(0);
    104     SetProperties(ConcatProperties(props1, props2, true), kCopyProperties);
    105   }
    106 
    107   // Implementation of ClosureFst(fst, closure_type)
    108   void InitClosure(const Fst<A> &fst, ClosureType closure_type) {
    109     uint64 props = fst.Properties(kFstProperties, false);
    110     SetInputSymbols(fst.InputSymbols());
    111     SetOutputSymbols(fst.OutputSymbols());
    112     if (closure_type == CLOSURE_STAR) {
    113       rfst_.AddState();
    114       rfst_.SetStart(0);
    115       rfst_.SetFinal(0, Weight::One());
    116       rfst_.AddArc(0, A(0, -1, Weight::One(), 0));
    117     } else {
    118       rfst_.AddState();
    119       rfst_.AddState();
    120       rfst_.SetStart(0);
    121       rfst_.SetFinal(1, Weight::One());
    122       rfst_.AddArc(0, A(0, -1, Weight::One(), 1));
    123       rfst_.AddArc(1, A(0, 0, Weight::One(), 0));
    124     }
    125     rfst_.SetInputSymbols(fst.InputSymbols());
    126     rfst_.SetOutputSymbols(fst.OutputSymbols());
    127     AddFst(0, &rfst_);
    128     AddFst(-1, &fst);
    129     SetRoot(0);
    130     nonterminals_ = 1;
    131     SetProperties(ClosureProperties(props, closure_type == CLOSURE_STAR, true),
    132                   kCopyProperties);
    133   }
    134 
    135   // Implementation of Union(Fst &, RationalFst *)
    136   void AddUnion(const Fst<A> &fst) {
    137     uint64 props1 = Properties();
    138     uint64 props2 = fst.Properties(kFstProperties, false);
    139     VectorFst<A> afst;
    140     afst.AddState();
    141     afst.AddState();
    142     afst.SetStart(0);
    143     afst.SetFinal(1, Weight::One());
    144     afst.AddArc(0, A(0, -nonterminals_, Weight::One(), 1));
    145     Union(&rfst_, afst);
    146     SetFst(0, &rfst_);
    147     ++nonterminals_;
    148     SetProperties(UnionProperties(props1, props2, true), kCopyProperties);
    149   }
    150 
    151   // Implementation of Concat(Fst &, RationalFst *)
    152   void AddConcat(const Fst<A> &fst) {
    153     uint64 props1 = Properties();
    154     uint64 props2 = fst.Properties(kFstProperties, false);
    155     VectorFst<A> afst;
    156     afst.AddState();
    157     afst.AddState();
    158     afst.SetStart(0);
    159     afst.SetFinal(1, Weight::One());
    160     afst.AddArc(0, A(0, -nonterminals_, Weight::One(), 1));
    161     Concat(&rfst_, afst);
    162     SetFst(0, &rfst_);
    163     ++nonterminals_;
    164     SetProperties(ConcatProperties(props1, props2, true), kCopyProperties);
    165   }
    166 
    167   // Implementation of Closure(RationalFst *, closure_type)
    168   void AddClosure(ClosureType closure_type) {
    169     uint64 props = Properties();
    170     Closure(&rfst_, closure_type);
    171     SetFst(0, &rfst_);
    172     SetProperties(ClosureProperties(props, closure_type == CLOSURE_STAR, true),
    173                   kCopyProperties);
    174   }
    175 
    176  private:
    177   VectorFst<A> rfst_;   // rational topology machine; uses neg. nonterminals
    178   Label nonterminals_;  // # of nonterminals used
    179 
    180   DISALLOW_EVIL_CONSTRUCTORS(RationalFstImpl);
    181 };
    182 
    183 // Parent class for the delayed rational operations - delayed union,
    184 // concatenation, and closure.  This class attaches interface to
    185 // implementation and handles reference counting.
    186 template <class A>
    187 class RationalFst : public Fst<A> {
    188  public:
    189   friend class CacheStateIterator< RationalFst<A> >;
    190   friend class ArcIterator< RationalFst<A> >;
    191   friend class CacheArcIterator< RationalFst<A> >;
    192   friend void Union<>(RationalFst<A> *fst1, const Fst<A> &fst2);
    193   friend void Concat<>(RationalFst<A> *fst1, const Fst<A> &fst2);
    194   friend void Closure<>(RationalFst<A> *fst, ClosureType closure_type);
    195 
    196   typedef A Arc;
    197   typedef typename A::Weight Weight;
    198   typedef typename A::StateId StateId;
    199   typedef CacheState<A> State;
    200 
    201   virtual StateId Start() const { return impl_->Start(); }
    202   virtual Weight Final(StateId s) const { return impl_->Final(s); }
    203   virtual size_t NumArcs(StateId s) const { return impl_->NumArcs(s); }
    204   virtual size_t NumInputEpsilons(StateId s) const {
    205     return impl_->NumInputEpsilons(s);
    206   }
    207   virtual size_t NumOutputEpsilons(StateId s) const {
    208     return impl_->NumOutputEpsilons(s);
    209   }
    210   virtual uint64 Properties(uint64 mask, bool test) const {
    211     if (test) {
    212       uint64 known, test = TestProperties(*this, mask, &known);
    213       impl_->SetProperties(test, known);
    214       return test & mask;
    215     } else {
    216       return impl_->Properties(mask);
    217     }
    218   }
    219   virtual const string& Type() const { return impl_->Type(); }
    220   virtual const SymbolTable* InputSymbols() const {
    221     return impl_->InputSymbols();
    222   }
    223   virtual const SymbolTable* OutputSymbols() const {
    224     return impl_->OutputSymbols();
    225   }
    226 
    227   virtual inline void InitStateIterator(StateIteratorData<A> *data) const;
    228 
    229   virtual void InitArcIterator(StateId s, ArcIteratorData<A> *data) const {
    230     impl_->InitArcIterator(s, data);
    231   }
    232 
    233  protected:
    234   RationalFst() : impl_(new RationalFstImpl<A>(RationalFstOptions())) {}
    235   explicit RationalFst(const RationalFstOptions &opts)
    236       : impl_(new RationalFstImpl<A>(opts)) {}
    237 
    238 
    239   RationalFst(const RationalFst<A> &fst) : impl_(fst.impl_) {
    240     impl_->IncrRefCount();
    241   }
    242 
    243   virtual ~RationalFst() { if (!impl_->DecrRefCount()) delete impl_; }
    244 
    245   RationalFstImpl<A> *Impl() { return impl_; }
    246 
    247  private:
    248   RationalFstImpl<A> *impl_;
    249 
    250   void operator=(const RationalFst<A> &fst);  // disallow
    251 };
    252 
    253 // Specialization for RationalFst.
    254 template <class A>
    255 class StateIterator< RationalFst<A> >
    256     : public CacheStateIterator< RationalFst<A> > {
    257  public:
    258   explicit StateIterator(const RationalFst<A> &fst)
    259       : CacheStateIterator< RationalFst<A> >(fst) {}
    260 };
    261 
    262 // Specialization for RationalFst.
    263 template <class A>
    264 class ArcIterator< RationalFst<A> >
    265     : public CacheArcIterator< RationalFst<A> > {
    266  public:
    267   typedef typename A::StateId StateId;
    268 
    269   ArcIterator(const RationalFst<A> &fst, StateId s)
    270       : CacheArcIterator< RationalFst<A> >(fst, s) {
    271     if (!fst.impl_->HasArcs(s))
    272       fst.impl_->Expand(s);
    273   }
    274 
    275  private:
    276   DISALLOW_EVIL_CONSTRUCTORS(ArcIterator);
    277 };
    278 
    279 template <class A> inline
    280 void RationalFst<A>::InitStateIterator(StateIteratorData<A> *data) const {
    281   data->base = new StateIterator< RationalFst<A> >(*this);
    282 }
    283 
    284 }  // namespace fst
    285 
    286 #endif  // FST_LIB_RATIONAL_H__
    287