• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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)
ShortestDistanceOptionsRmEpsilonOptions52       : 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>
RmEpsilonHelper(MutableFst<Arc> * fst,vector<typename Arc::Weight> * distance,const RmEpsilonOptions & opts)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>
RmEpsilon(RmEpsilonArgs1 * args)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>
RmEpsilon(RmEpsilonArgs2 * args)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>
RmEpsilon(RmEpsilonArgs3 * args)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