Home | History | Annotate | Download | only in lib
      1 // push.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 // Author: allauzen (at) cs.nyu.edu (Cyril Allauzen)
     16 //
     17 // \file
     18 // Class to reweight/push an FST.
     19 
     20 #ifndef FST_LIB_PUSH_H__
     21 #define FST_LIB_PUSH_H__
     22 
     23 #include "fst/lib/factor-weight.h"
     24 #include "fst/lib/fst.h"
     25 #include "fst/lib/map.h"
     26 #include "fst/lib/reweight.h"
     27 #include "fst/lib/shortest-distance.h"
     28 
     29 namespace fst {
     30 
     31 // Pushes the weights in FST in the direction defined by TYPE.  If
     32 // pushing towards the initial state, the sum of the weight of the
     33 // outgoing transitions and final weight at a non-initial state is
     34 // equal to One() in the resulting machine.  If pushing towards the
     35 // final state, the same property holds on the reverse machine.
     36 //
     37 // Weight needs to be left distributive when pushing towards the
     38 // initial state and right distributive when pushing towards the final
     39 // states.
     40 template <class Arc>
     41 void Push(MutableFst<Arc> *fst, ReweightType type) {
     42   vector<typename Arc::Weight> distance;
     43   ShortestDistance(*fst, &distance, type == REWEIGHT_TO_INITIAL);
     44   Reweight(fst, distance, type);
     45 }
     46 
     47 
     48 const uint32 kPushWeights = 0x0001;
     49 const uint32 kPushLabels =  0x0002;
     50 
     51 // OFST obtained from IFST by pushing weights and/or labels according
     52 // to PTYPE in the direction defined by RTYPE.  Weight needs to be
     53 // left distributive when pushing weights towards the initial state
     54 // and right distributive when pushing weights towards the final
     55 // states.
     56 template <class Arc, ReweightType rtype>
     57 void Push(const Fst<Arc> &ifst, MutableFst<Arc> *ofst, uint32 ptype) {
     58 
     59   if (ptype == kPushWeights) {
     60     *ofst = ifst;
     61     Push(ofst, rtype);
     62   } else if (ptype & kPushLabels) {
     63     const StringType stype = rtype == REWEIGHT_TO_INITIAL
     64                              ? STRING_LEFT
     65                              : STRING_RIGHT;
     66     vector<typename GallicArc<Arc, stype>::Weight> gdistance;
     67     VectorFst< GallicArc<Arc, stype> > gfst;
     68     Map(ifst, &gfst, ToGallicMapper<Arc, stype>());
     69     if (ptype == (kPushWeights | kPushLabels)) {
     70       ShortestDistance(gfst, &gdistance, rtype == REWEIGHT_TO_INITIAL);
     71     } else {
     72       MapFst<Arc, Arc, RmWeightMapper<Arc> >
     73         uwfst(ifst, RmWeightMapper<Arc>());
     74       MapFst<Arc, GallicArc<Arc, stype>, ToGallicMapper<Arc, stype> >
     75         guwfst(uwfst, ToGallicMapper<Arc, stype>());
     76       ShortestDistance(guwfst, &gdistance, rtype == REWEIGHT_TO_INITIAL);
     77     }
     78     Reweight(&gfst, gdistance, rtype);
     79     FactorWeightFst< GallicArc<Arc, stype>, GallicFactor<typename Arc::Label,
     80       typename Arc::Weight, stype> > fwfst(gfst);
     81     Map(fwfst, ofst, FromGallicMapper<Arc, stype>());
     82   } else {
     83     *ofst = ifst;
     84   }
     85 }
     86 
     87 }  // namespace fst
     88 
     89 #endif /* FST_LIB_PUSH_H_ */
     90