Home | History | Annotate | Download | only in script
      1 
      2 // Licensed under the Apache License, Version 2.0 (the "License");
      3 // you may not use this file except in compliance with the License.
      4 // You may obtain a copy of the License at
      5 //
      6 //     http://www.apache.org/licenses/LICENSE-2.0
      7 //
      8 // Unless required by applicable law or agreed to in writing, software
      9 // distributed under the License is distributed on an "AS IS" BASIS,
     10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     11 // See the License for the specific language governing permissions and
     12 // limitations under the License.
     13 //
     14 // Copyright 2005-2010 Google, Inc.
     15 // Author: jpr (at) google.com (Jake Ratkiewicz)
     16 
     17 #ifndef FST_SCRIPT_RMEPSILON_H_
     18 #define FST_SCRIPT_RMEPSILON_H_
     19 
     20 #include <vector>
     21 using std::vector;
     22 
     23 #include <fst/script/arg-packs.h>
     24 #include <fst/script/fst-class.h>
     25 #include <fst/script/weight-class.h>
     26 #include <fst/script/shortest-distance.h>  // for ShortestDistanceOptions
     27 #include <fst/rmepsilon.h>
     28 #include <fst/queue.h>
     29 
     30 // the following is necessary, or SWIG complains mightily about
     31 // shortestdistanceoptions not being defined before being used as a base.
     32 #ifdef SWIG
     33 %include "nlp/fst/script/shortest-distance.h"
     34 #endif
     35 
     36 
     37 namespace fst {
     38 namespace script {
     39 
     40 //
     41 // OPTIONS
     42 //
     43 
     44 struct RmEpsilonOptions : public fst::script::ShortestDistanceOptions {
     45   bool connect;
     46   WeightClass weight_threshold;
     47   int64 state_threshold;
     48 
     49   RmEpsilonOptions(QueueType qt = AUTO_QUEUE, float d = kDelta, bool c = true,
     50                    WeightClass w = fst::script::WeightClass::Zero(),
     51                    int64 n = kNoStateId)
     52       : ShortestDistanceOptions(qt, EPSILON_ARC_FILTER,
     53                                 kNoStateId, d),
     54         connect(c), weight_threshold(w), state_threshold(n) { }
     55 };
     56 
     57 
     58 //
     59 // TEMPLATES
     60 //
     61 
     62 // this function takes care of transforming a script-land RmEpsilonOptions
     63 // into a lib-land RmEpsilonOptions
     64 template<class Arc>
     65 void RmEpsilonHelper(MutableFst<Arc> *fst,
     66                      vector<typename Arc::Weight> *distance,
     67                      const RmEpsilonOptions &opts) {
     68   typedef typename Arc::StateId StateId;
     69   typedef typename Arc::Weight Weight;
     70 
     71   typename Arc::Weight weight_thresh =
     72       *(opts.weight_threshold.GetWeight<Weight>());
     73 
     74   switch (opts.queue_type) {
     75     case AUTO_QUEUE: {
     76       AutoQueue<StateId> queue(*fst, distance, EpsilonArcFilter<Arc>());
     77       fst::RmEpsilonOptions<Arc, AutoQueue<StateId> > ropts(
     78           &queue, opts.delta, opts.connect, weight_thresh,
     79           opts.state_threshold);
     80       RmEpsilon(fst, distance, ropts);
     81       break;
     82     }
     83     case FIFO_QUEUE: {
     84       FifoQueue<StateId> queue;
     85       fst::RmEpsilonOptions<Arc, FifoQueue<StateId> > ropts(
     86           &queue, opts.delta, opts.connect, weight_thresh,
     87           opts.state_threshold);
     88       RmEpsilon(fst, distance, ropts);
     89       break;
     90     }
     91     case LIFO_QUEUE: {
     92       LifoQueue<StateId> queue;
     93       fst::RmEpsilonOptions<Arc, LifoQueue<StateId> > ropts(
     94           &queue, opts.delta, opts.connect, weight_thresh,
     95           opts.state_threshold);
     96       RmEpsilon(fst, distance, ropts);
     97       break;
     98     }
     99     case SHORTEST_FIRST_QUEUE: {
    100       NaturalShortestFirstQueue<StateId, Weight>  queue(*distance);
    101       fst::RmEpsilonOptions<Arc, NaturalShortestFirstQueue<StateId,
    102                                                                Weight> > ropts(
    103           &queue, opts.delta, opts.connect, weight_thresh,
    104           opts.state_threshold);
    105       RmEpsilon(fst, distance, ropts);
    106       break;
    107     }
    108     case STATE_ORDER_QUEUE: {
    109       StateOrderQueue<StateId> queue;
    110       fst::RmEpsilonOptions<Arc, StateOrderQueue<StateId> > ropts(
    111           &queue, opts.delta, opts.connect, weight_thresh,
    112           opts.state_threshold);
    113       RmEpsilon(fst, distance, ropts);
    114       break;
    115     }
    116     case TOP_ORDER_QUEUE: {
    117       TopOrderQueue<StateId> queue(*fst, EpsilonArcFilter<Arc>());
    118       fst::RmEpsilonOptions<Arc, TopOrderQueue<StateId> > ropts(
    119           &queue, opts.delta, opts.connect, weight_thresh,
    120           opts.state_threshold);
    121       RmEpsilon(fst, distance, ropts);
    122       break;
    123     }
    124     default:
    125       FSTERROR() << "Unknown or unsupported queue type: " << opts.queue_type;
    126       fst->SetProperties(kError, kError);
    127   }
    128 }
    129 
    130 // 1
    131 typedef args::Package<const FstClass &, MutableFstClass *,
    132                       bool, const RmEpsilonOptions &> RmEpsilonArgs1;
    133 
    134 template<class Arc>
    135 void RmEpsilon(RmEpsilonArgs1 *args) {
    136   const Fst<Arc> &ifst = *(args->arg1.GetFst<Arc>());
    137   MutableFst<Arc> *ofst = args->arg2->GetMutableFst<Arc>();
    138   vector<typename Arc::Weight> distance;
    139   bool reverse = args->arg3;
    140 
    141   if (reverse) {
    142     VectorFst<Arc> rfst;
    143     Reverse(ifst, &rfst);
    144     RmEpsilonHelper(&rfst, &distance, args->arg4);
    145     Reverse(rfst, ofst);
    146   } else {
    147     *ofst = ifst;
    148   }
    149   RmEpsilonHelper(ofst, &distance, args->arg4);
    150 }
    151 
    152 // 2
    153 typedef args::Package<MutableFstClass *, bool,
    154                       const WeightClass, int64,
    155                       float> RmEpsilonArgs2;
    156 
    157 template<class Arc>
    158 void RmEpsilon(RmEpsilonArgs2 *args) {
    159   MutableFst<Arc> *fst = args->arg1->GetMutableFst<Arc>();
    160   typename Arc::Weight w = *(args->arg3.GetWeight<typename Arc::Weight>());
    161 
    162   RmEpsilon(fst, args->arg2, w, args->arg4, args->arg5);
    163 }
    164 
    165 // 3
    166 typedef args::Package<MutableFstClass *, vector<WeightClass> *,
    167                       const RmEpsilonOptions &> RmEpsilonArgs3;
    168 
    169 template<class Arc>
    170 void RmEpsilon(RmEpsilonArgs3 *args) {
    171   MutableFst<Arc> *fst = args->arg1->GetMutableFst<Arc>();
    172   const RmEpsilonOptions &opts = args->arg3;
    173 
    174   vector<typename Arc::Weight> weights;
    175 
    176   RmEpsilonHelper(fst, &weights, opts);
    177 
    178   // Copy the weights back
    179   args->arg2->resize(weights.size());
    180   for (unsigned i = 0; i < weights.size(); ++i) {
    181     (*args->arg2)[i] = WeightClass(weights[i]);
    182   }
    183 }
    184 
    185 //
    186 // PROTOTYPES
    187 //
    188 
    189 // 1
    190 void RmEpsilon(const FstClass &ifst, MutableFstClass *ofst,
    191                bool reverse = false,
    192                const RmEpsilonOptions& opts =
    193                  fst::script::RmEpsilonOptions());
    194 
    195 // 2
    196 void RmEpsilon(MutableFstClass *arc, bool connect = true,
    197                const WeightClass &weight_threshold =
    198                  fst::script::WeightClass::Zero(),
    199                int64 state_threshold = fst::kNoStateId,
    200                float delta = fst::kDelta);
    201 
    202 // 3
    203 void RmEpsilon(MutableFstClass *fst, vector<WeightClass> *distance,
    204                const RmEpsilonOptions &opts);
    205 
    206 
    207 }  // namespace script
    208 }  // namespace fst
    209 
    210 
    211 #endif  // FST_SCRIPT_RMEPSILON_H_
    212