14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// push.h
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Licensed under the Apache License, Version 2.0 (the "License");
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// you may not use this file except in compliance with the License.
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// You may obtain a copy of the License at
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//      http://www.apache.org/licenses/LICENSE-2.0
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Unless required by applicable law or agreed to in writing, software
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// distributed under the License is distributed on an "AS IS" BASIS,
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// See the License for the specific language governing permissions and
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// limitations under the License.
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Author: allauzen@cs.nyu.edu (Cyril Allauzen)
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \file
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Class to reweight/push an FST.
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef FST_LIB_PUSH_H__
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define FST_LIB_PUSH_H__
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/factor-weight.h"
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/fst.h"
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/map.h"
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/reweight.h"
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/shortest-distance.h"
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectnamespace fst {
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Pushes the weights in FST in the direction defined by TYPE.  If
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// pushing towards the initial state, the sum of the weight of the
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// outgoing transitions and final weight at a non-initial state is
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// equal to One() in the resulting machine.  If pushing towards the
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// final state, the same property holds on the reverse machine.
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Weight needs to be left distributive when pushing towards the
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// initial state and right distributive when pushing towards the final
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// states.
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class Arc>
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid Push(MutableFst<Arc> *fst, ReweightType type) {
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  vector<typename Arc::Weight> distance;
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ShortestDistance(*fst, &distance, type == REWEIGHT_TO_INITIAL);
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Reweight(fst, distance, type);
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectconst uint32 kPushWeights = 0x0001;
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectconst uint32 kPushLabels =  0x0002;
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// OFST obtained from IFST by pushing weights and/or labels according
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// to PTYPE in the direction defined by RTYPE.  Weight needs to be
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// left distributive when pushing weights towards the initial state
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// and right distributive when pushing weights towards the final
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// states.
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class Arc, ReweightType rtype>
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid Push(const Fst<Arc> &ifst, MutableFst<Arc> *ofst, uint32 ptype) {
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (ptype == kPushWeights) {
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *ofst = ifst;
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Push(ofst, rtype);
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  } else if (ptype & kPushLabels) {
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const StringType stype = rtype == REWEIGHT_TO_INITIAL
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                             ? STRING_LEFT
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                             : STRING_RIGHT;
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    vector<typename GallicArc<Arc, stype>::Weight> gdistance;
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    VectorFst< GallicArc<Arc, stype> > gfst;
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Map(ifst, &gfst, ToGallicMapper<Arc, stype>());
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (ptype == (kPushWeights | kPushLabels)) {
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ShortestDistance(gfst, &gdistance, rtype == REWEIGHT_TO_INITIAL);
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    } else {
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      MapFst<Arc, Arc, RmWeightMapper<Arc> >
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        uwfst(ifst, RmWeightMapper<Arc>());
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      MapFst<Arc, GallicArc<Arc, stype>, ToGallicMapper<Arc, stype> >
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        guwfst(uwfst, ToGallicMapper<Arc, stype>());
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      ShortestDistance(guwfst, &gdistance, rtype == REWEIGHT_TO_INITIAL);
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Reweight(&gfst, gdistance, rtype);
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    FactorWeightFst< GallicArc<Arc, stype>, GallicFactor<typename Arc::Label,
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      typename Arc::Weight, stype> > fwfst(gfst);
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    Map(fwfst, ofst, FromGallicMapper<Arc, stype>());
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  } else {
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *ofst = ifst;
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}  // namespace fst
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif /* FST_LIB_PUSH_H_ */
90