// Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Copyright 2005-2010 Google, Inc. // Author: jpr@google.com (Jake Ratkiewicz) #ifndef FST_SCRIPT_RMEPSILON_H_ #define FST_SCRIPT_RMEPSILON_H_ #include using std::vector; #include #include #include #include // for ShortestDistanceOptions #include #include // the following is necessary, or SWIG complains mightily about // shortestdistanceoptions not being defined before being used as a base. #ifdef SWIG %include "nlp/fst/script/shortest-distance.h" #endif namespace fst { namespace script { // // OPTIONS // struct RmEpsilonOptions : public fst::script::ShortestDistanceOptions { bool connect; WeightClass weight_threshold; int64 state_threshold; RmEpsilonOptions(QueueType qt = AUTO_QUEUE, float d = kDelta, bool c = true, WeightClass w = fst::script::WeightClass::Zero(), int64 n = kNoStateId) : ShortestDistanceOptions(qt, EPSILON_ARC_FILTER, kNoStateId, d), connect(c), weight_threshold(w), state_threshold(n) { } }; // // TEMPLATES // // this function takes care of transforming a script-land RmEpsilonOptions // into a lib-land RmEpsilonOptions template void RmEpsilonHelper(MutableFst *fst, vector *distance, const RmEpsilonOptions &opts) { typedef typename Arc::StateId StateId; typedef typename Arc::Weight Weight; typename Arc::Weight weight_thresh = *(opts.weight_threshold.GetWeight()); switch (opts.queue_type) { case AUTO_QUEUE: { AutoQueue queue(*fst, distance, EpsilonArcFilter()); fst::RmEpsilonOptions > ropts( &queue, opts.delta, opts.connect, weight_thresh, opts.state_threshold); RmEpsilon(fst, distance, ropts); break; } case FIFO_QUEUE: { FifoQueue queue; fst::RmEpsilonOptions > ropts( &queue, opts.delta, opts.connect, weight_thresh, opts.state_threshold); RmEpsilon(fst, distance, ropts); break; } case LIFO_QUEUE: { LifoQueue queue; fst::RmEpsilonOptions > ropts( &queue, opts.delta, opts.connect, weight_thresh, opts.state_threshold); RmEpsilon(fst, distance, ropts); break; } case SHORTEST_FIRST_QUEUE: { NaturalShortestFirstQueue queue(*distance); fst::RmEpsilonOptions > ropts( &queue, opts.delta, opts.connect, weight_thresh, opts.state_threshold); RmEpsilon(fst, distance, ropts); break; } case STATE_ORDER_QUEUE: { StateOrderQueue queue; fst::RmEpsilonOptions > ropts( &queue, opts.delta, opts.connect, weight_thresh, opts.state_threshold); RmEpsilon(fst, distance, ropts); break; } case TOP_ORDER_QUEUE: { TopOrderQueue queue(*fst, EpsilonArcFilter()); fst::RmEpsilonOptions > ropts( &queue, opts.delta, opts.connect, weight_thresh, opts.state_threshold); RmEpsilon(fst, distance, ropts); break; } default: FSTERROR() << "Unknown or unsupported queue type: " << opts.queue_type; fst->SetProperties(kError, kError); } } // 1 typedef args::Package RmEpsilonArgs1; template void RmEpsilon(RmEpsilonArgs1 *args) { const Fst &ifst = *(args->arg1.GetFst()); MutableFst *ofst = args->arg2->GetMutableFst(); vector distance; bool reverse = args->arg3; if (reverse) { VectorFst rfst; Reverse(ifst, &rfst); RmEpsilonHelper(&rfst, &distance, args->arg4); Reverse(rfst, ofst); } else { *ofst = ifst; } RmEpsilonHelper(ofst, &distance, args->arg4); } // 2 typedef args::Package RmEpsilonArgs2; template void RmEpsilon(RmEpsilonArgs2 *args) { MutableFst *fst = args->arg1->GetMutableFst(); typename Arc::Weight w = *(args->arg3.GetWeight()); RmEpsilon(fst, args->arg2, w, args->arg4, args->arg5); } // 3 typedef args::Package *, const RmEpsilonOptions &> RmEpsilonArgs3; template void RmEpsilon(RmEpsilonArgs3 *args) { MutableFst *fst = args->arg1->GetMutableFst(); const RmEpsilonOptions &opts = args->arg3; vector weights; RmEpsilonHelper(fst, &weights, opts); // Copy the weights back args->arg2->resize(weights.size()); for (unsigned i = 0; i < weights.size(); ++i) { (*args->arg2)[i] = WeightClass(weights[i]); } } // // PROTOTYPES // // 1 void RmEpsilon(const FstClass &ifst, MutableFstClass *ofst, bool reverse = false, const RmEpsilonOptions& opts = fst::script::RmEpsilonOptions()); // 2 void RmEpsilon(MutableFstClass *arc, bool connect = true, const WeightClass &weight_threshold = fst::script::WeightClass::Zero(), int64 state_threshold = fst::kNoStateId, float delta = fst::kDelta); // 3 void RmEpsilon(MutableFstClass *fst, vector *distance, const RmEpsilonOptions &opts); } // namespace script } // namespace fst #endif // FST_SCRIPT_RMEPSILON_H_