1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#ifndef FF_FSA_DYNAMIC_H
#define FF_FSA_DYNAMIC_H
struct SentenceMetadata;
#include "ff_fsa_data.h"
#include "hg.h" // can't forward declare nested Hypergraph::Edge class
#include <sstream>
// the type-erased interface
//FIXME: diamond inheritance problem. make a copy of the fixed data? or else make the dynamic version not wrap but rather be templated CRTP base (yuck)
struct FsaFeatureFunction : public FsaFeatureFunctionData {
static const bool simple_phrase_score=false;
virtual int markov_order() const = 0;
// see ff_fsa.h - FsaFeatureFunctionBase<Impl> gives you reasonable impls of these if you override just ScanAccum
virtual void ScanAccum(SentenceMetadata const& smeta,Hypergraph::Edge const& edge,
WordID w,void const* state,void *next_state,Accum *a) const = 0;
virtual void ScanPhraseAccum(SentenceMetadata const& smeta,Hypergraph::Edge const & edge,
WordID const* i, WordID const* end,
void const* state,void *next_state,Accum *accum) const = 0;
virtual void ScanPhraseAccumOnly(SentenceMetadata const& smeta,Hypergraph::Edge const& edge,
WordID const* i, WordID const* end,
void const* state,Accum *accum) const = 0;
virtual void *ScanPhraseAccumBounce(SentenceMetadata const& smeta,Hypergraph::Edge const& edge,WordID const* i, WordID const* end,void *cs,void *ns,Accum *accum) const = 0;
virtual int early_score_words(SentenceMetadata const& smeta,Hypergraph::Edge const& edge,WordID const* i, WordID const* end,Accum *accum) const { return 0; }
// called after constructor, before use
virtual void Init() = 0;
virtual std::string usage_v(bool param,bool verbose) const {
return FeatureFunction::usage_helper("unnamed_dynamic_fsa_feature","","",param,verbose);
}
virtual void init_name_debug(std::string const& n,bool debug) {
FsaFeatureFunctionData::init_name_debug(n,debug);
}
virtual void print_state(std::ostream &o,void const*state) const {
FsaFeatureFunctionData::print_state(o,state);
}
//end_phrase()
virtual ~FsaFeatureFunction() {}
// no need to override:
std::string describe_state(void const* state) const {
std::ostringstream o;
print_state(o,state);
return o.str();
}
};
// conforming to above interface, type erases FsaImpl
// you might be wondering: why do this? answer: it's cool, and it means that the bottom-up ff over ff_fsa wrapper doesn't go through multiple layers of dynamic dispatch
// usage: typedef FsaFeatureFunctionDynamic<MyFsa> MyFsaDyn;
template <class Impl>
struct FsaFeatureFunctionDynamic : public FsaFeatureFunction {
static const bool simple_phrase_score=Impl::simple_phrase_score;
Impl& d() { return impl;//static_cast<Impl&>(*this);
}
Impl const& d() const { return impl;
//static_cast<Impl const&>(*this);
}
int markov_order() const { return d().markov_order(); }
virtual void ScanAccum(SentenceMetadata const& smeta,Hypergraph::Edge const& edge,
WordID w,void const* state,void *next_state,Accum *a) const {
return d().ScanAccum(smeta,edge,w,state,next_state,a);
}
virtual void ScanPhraseAccum(SentenceMetadata const& smeta,Hypergraph::Edge const & edge,
WordID const* i, WordID const* end,
void const* state,void *next_state,Accum *a) const {
return d().ScanPhraseAccum(smeta,edge,i,end,state,next_state,a);
}
virtual void ScanPhraseAccumOnly(SentenceMetadata const& smeta,Hypergraph::Edge const& edge,
WordID const* i, WordID const* end,
void const* state,Accum *a) const {
return d().ScanPhraseAccumOnly(smeta,edge,i,end,state,a);
}
virtual void *ScanPhraseAccumBounce(SentenceMetadata const& smeta,Hypergraph::Edge const& edge,WordID const* i, WordID const* end,void *cs,void *ns,Accum *a) const {
return d().ScanPhraseAccumBounce(smeta,edge,i,end,cs,ns,a);
}
virtual int early_score_words(SentenceMetadata const& smeta,Hypergraph::Edge const& edge,WordID const* i, WordID const* end,Accum *accum) const {
return d().early_score_words(smeta,edge,i,end,accum);
}
static std::string usage(bool param,bool verbose) {
return Impl::usage(param,verbose);
}
std::string usage_v(bool param,bool verbose) const {
return Impl::usage(param,verbose);
}
virtual void print_state(std::ostream &o,void const*state) const {
return d().print_state(o,state);
}
void init_name_debug(std::string const& n,bool debug) {
FsaFeatureFunction::init_name_debug(n,debug);
d().init_name_debug(n,debug);
}
virtual void Init() {
d().sync_to_=(FsaFeatureFunction*)this;
d().Init();
d().sync();
}
FsaFeatureFunctionDynamic(std::string const& param) : impl(param) {
Init();
}
private:
Impl impl;
};
//TODO: combine 2 (or N) FsaFeatureFunction (type erased)
#endif
|