00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef FST_LIB_DIFFERENCE_H__
00022 #define FST_LIB_DIFFERENCE_H__
00023
00024 #include <vector>
00025 using std::vector;
00026 #include <algorithm>
00027 #include <fst/cache.h>
00028 #include <fst/compose.h>
00029 #include <fst/complement.h>
00030
00031 namespace fst {
00032
00033 template <class A,
00034 class M = Matcher<Fst<A> >,
00035 class F = SequenceComposeFilter<M>,
00036 class T = GenericComposeStateTable<A, typename F::FilterState> >
00037 struct DifferenceFstOptions : public ComposeFstOptions<A, M, F, T> {
00038 explicit DifferenceFstOptions(const CacheOptions &opts,
00039 M *mat1 = 0, M *mat2 = 0,
00040 F *filt = 0, T *sttable= 0)
00041 : ComposeFstOptions<A, M, F, T>(mat1, mat2, filt, sttable) { }
00042
00043 DifferenceFstOptions() {}
00044 };
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 template <class A>
00058 class DifferenceFst : public ComposeFst<A> {
00059 public:
00060 using ImplToFst< ComposeFstImplBase<A> >::SetImpl;
00061
00062 using ComposeFst<A>::CreateBase1;
00063
00064 typedef A Arc;
00065 typedef typename A::Weight Weight;
00066 typedef typename A::StateId StateId;
00067
00068
00069 DifferenceFst(const Fst<A> &fst1, const Fst<A> &fst2,
00070 const CacheOptions &opts = CacheOptions()) {
00071 if (!fst1.Properties(kAcceptor, true))
00072 LOG(FATAL) << "DifferenceFst: 1st argument not an acceptor";
00073
00074 typedef RhoMatcher< Matcher<Fst<A> > > R;
00075
00076 ComplementFst<A> cfst(fst2);
00077 ComposeFstOptions<A, R> copts(CacheOptions(),
00078 new R(fst1, MATCH_NONE),
00079 new R(cfst, MATCH_INPUT,
00080 ComplementFst<A>::kRhoLabel));
00081 SetImpl(CreateBase1(fst1, cfst, copts));
00082 }
00083
00084 template <class M, class F, class T>
00085 DifferenceFst(const Fst<A> &fst1, const Fst<A> &fst2,
00086 const DifferenceFstOptions<A, M, F, T> &opts) {
00087 if (!fst1.Properties(kAcceptor, true))
00088 LOG(FATAL) << "DifferenceFst: 1st argument not an acceptor";
00089
00090 typedef RhoMatcher<M> R;
00091
00092 ComplementFst<A> cfst(fst2);
00093 ComposeFstOptions<A, R> copts(opts);
00094 copts.matcher1 = new R(fst1, MATCH_NONE, kNoLabel, MATCHER_REWRITE_ALWAYS,
00095 opts.matcher1);
00096 copts.matcher2 = new R(cfst, MATCH_INPUT, ComplementFst<A>::kRhoLabel,
00097 MATCHER_REWRITE_ALWAYS, opts.matcher2);
00098
00099 SetImpl(CreateBase1(fst1, cfst, copts));
00100 }
00101
00102
00103 DifferenceFst(const DifferenceFst<A> &fst, bool safe = false)
00104 : ComposeFst<A>(fst, safe) {}
00105
00106
00107 virtual DifferenceFst<A> *Copy(bool safe = false) const {
00108 return new DifferenceFst<A>(*this, safe);
00109 }
00110 };
00111
00112
00113
00114 template <class A>
00115 class StateIterator< DifferenceFst<A> >
00116 : public StateIterator< ComposeFst<A> > {
00117 public:
00118 explicit StateIterator(const DifferenceFst<A> &fst)
00119 : StateIterator< ComposeFst<A> >(fst) {}
00120 };
00121
00122
00123
00124 template <class A>
00125 class ArcIterator< DifferenceFst<A> >
00126 : public ArcIterator< ComposeFst<A> > {
00127 public:
00128 typedef typename A::StateId StateId;
00129
00130 ArcIterator(const DifferenceFst<A> &fst, StateId s)
00131 : ArcIterator< ComposeFst<A> >(fst, s) {}
00132 };
00133
00134
00135 typedef DifferenceFst<StdArc> StdDifferenceFst;
00136
00137
00138 typedef ComposeOptions DifferenceOptions;
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 template<class Arc>
00153 void Difference(const Fst<Arc> &ifst1, const Fst<Arc> &ifst2,
00154 MutableFst<Arc> *ofst,
00155 const DifferenceOptions &opts = DifferenceOptions()) {
00156 typedef Matcher< Fst<Arc> > M;
00157
00158 if (opts.filter_type == AUTO_FILTER) {
00159 CacheOptions nopts;
00160 nopts.gc_limit = 0;
00161 *ofst = DifferenceFst<Arc>(ifst1, ifst2, nopts);
00162 } else if (opts.filter_type == SEQUENCE_FILTER) {
00163 DifferenceFstOptions<Arc> dopts;
00164 dopts.gc_limit = 0;
00165 *ofst = DifferenceFst<Arc>(ifst1, ifst2, dopts);
00166 } else if (opts.filter_type == ALT_SEQUENCE_FILTER) {
00167 DifferenceFstOptions<Arc, M, AltSequenceComposeFilter<M> > dopts;
00168 dopts.gc_limit = 0;
00169 *ofst = DifferenceFst<Arc>(ifst1, ifst2, dopts);
00170 } else if (opts.filter_type == MATCH_FILTER) {
00171 DifferenceFstOptions<Arc, M, MatchComposeFilter<M> > dopts;
00172 dopts.gc_limit = 0;
00173 *ofst = DifferenceFst<Arc>(ifst1, ifst2, dopts);
00174 }
00175
00176 if (opts.connect)
00177 Connect(ofst);
00178 }
00179
00180 }
00181
00182 #endif /// FST_LIB_DIFFERENCE_H__
00183