20 #ifndef FST_EXTENSIONS_MPDT_MPDT_H_ 21 #define FST_EXTENSIONS_MPDT_MPDT_H_ 32 #include <unordered_map> 45 template <
typename StackId,
typename Level, Level nlevels>
49 template <
typename Level>
54 template <
typename Level>
57 KeyPair(Level level,
size_t id) : level_(level), underlying_id_(id) {}
60 return level_ == rhs.level_ && underlying_id_ == rhs.underlying_id_;
66 size_t underlying_id_;
69 template <
typename Level>
72 return std::hash<Level>()(keypair.level_) ^
73 (std::hash<size_t>()(keypair.underlying_id_) << 1);
77 template <
typename StackId,
typename Level, Level nlevels = 2,
85 MPdtStack(
const std::vector<std::pair<Label, Label>> &parens,
86 const std::vector<Level> &assignments);
91 : error_(other.error_),
92 min_paren_(other.min_paren_),
93 max_paren_(other.max_paren_),
94 paren_levels_(other.paren_levels_),
95 parens_(other.parens_),
96 paren_map_(other.paren_map_),
97 paren_id_map_(other.paren_id_map_),
98 config_to_stack_id_map_(other.config_to_stack_id_map_),
99 stack_id_to_config_map_(other.stack_id_to_config_map_),
100 next_stack_id_(other.next_stack_id_),
101 stacks_(other.stacks_) {}
112 StackId Find(StackId stack_id,
Label label);
119 ssize_t
Top(StackId stack_id)
const {
120 if (stack_id == -1)
return -1;
121 const auto config = InternalStackIds(stack_id);
123 StackId underlying_id = -1;
124 for (; level < nlevels; ++level) {
125 if (!Empty(config, level)) {
126 underlying_id = stacks_[level]->Top(config[level]);
130 if (underlying_id == -1)
return -1;
131 const auto it = paren_id_map_.find(
KeyPair<Level>(level, underlying_id));
132 if (it == paren_id_map_.end())
return -1;
137 const auto it = paren_map_.find(label);
138 return it != paren_map_.end() ? it->second : -1;
148 const auto it = config_to_stack_id_map_.find(config);
150 if (it == config_to_stack_id_map_.end()) {
151 result = next_stack_id_++;
152 config_to_stack_id_map_.insert(
153 std::pair<Config, StackId>(config, result));
154 stack_id_to_config_map_[result] = config;
163 auto it = stack_id_to_config_map_.find(stack_id);
164 if (it == stack_id_to_config_map_.end()) {
165 it = stack_id_to_config_map_.find(-1);
171 return config[level] <= 0;
175 for (Level level = 0; level < nlevels; ++level) {
176 if (!Empty(config, level))
return false;
186 std::unordered_map<Label, Label> paren_levels_;
187 std::vector<std::pair<Label, Label>> parens_;
188 std::unordered_map<Label, size_t> paren_map_;
194 std::unordered_map<StackId, Config> stack_id_to_config_map_;
195 StackId next_stack_id_;
197 std::array<std::optional<PdtStack<StackId, Label>>, nlevels> stacks_;
200 template <
typename StackId,
typename Level, Level nlevels, MPdtType restrict>
202 const std::vector<std::pair<Level, Level>> &parens,
203 const std::vector<Level> &assignments)
210 if (parens.size() != assignments.size()) {
211 FSTERROR() <<
"MPdtStack: Parens of different size from assignments";
215 std::array<std::vector<std::pair<Label, Label>>, nlevels> vectors;
216 for (Level i = 0; i < assignments.size(); ++i) {
219 const auto level = assignments[i] - 1;
220 if (level < 0 || level >= nlevels) {
221 FSTERROR() <<
"MPdtStack: Specified level " << level <<
" out of bounds";
225 const auto &pair = parens[i];
226 vectors[level].push_back(pair);
227 paren_levels_[pair.first] = level;
228 paren_levels_[pair.second] = level;
229 paren_map_[pair.first] = i;
230 paren_map_[pair.second] = i;
232 paren_id_map_[key] = i;
233 if (min_paren_ ==
kNoLabel || pair.first < min_paren_) {
234 min_paren_ = pair.first;
236 if (pair.second < min_paren_) min_paren_ = pair.second;
237 if (max_paren_ ==
kNoLabel || pair.first > max_paren_) {
238 max_paren_ = pair.first;
240 if (pair.second > max_paren_) max_paren_ = pair.second;
245 for (Level level = 0; level < nlevels; ++level) {
246 stacks_[level].emplace(vectors[level]);
250 config_to_stack_id_map_[neg_one] = -1;
251 config_to_stack_id_map_[zero] = 0;
252 stack_id_to_config_map_[-1] = neg_one;
253 stack_id_to_config_map_[0] = zero;
256 template <
typename StackId,
typename Level, Level nlevels, MPdtType restrict>
260 if (min_paren_ ==
kNoLabel || label < min_paren_ || label > max_paren_) {
263 const auto it = paren_map_.find(label);
265 if (it == paren_map_.end())
return stack_id;
266 ssize_t paren_id = it->second;
270 const auto level = paren_levels_.find(label)->second;
276 if (label == parens_[paren_id].first) {
278 for (Level upper_level = 0; upper_level < level; ++upper_level) {
279 if (!
Empty(config, upper_level))
return -1;
288 for (Level lower_level = 0; lower_level < level; ++lower_level) {
289 if (!
Empty(config, lower_level))
return -1;
292 const auto nid = stacks_[level]->Find(config[level], label);
300 nconfig[level] = nid;
308 #endif // FST_EXTENSIONS_MPDT_MPDT_H_ MPdtStack & operator=(const MPdtStack &other)
MPdtStack(const MPdtStack &other)
std::array< StackId, nlevels > StackConfig
ssize_t Top(StackId stack_id) const
const Config InternalStackIds(StackId stack_id) const
std::map< Config, StackId > ConfigToStackId
StackId ExternalStackId(const Config &config)
bool Empty(const Config &config, Level level) const
bool operator==(const KeyPair &rhs) const
KeyPair(Level level, size_t id)
ssize_t ParenId(Label label) const
bool AllEmpty(const Config &config)
StackConfig< StackId, Label, 2 > Config
size_t operator()(const KeyPair< Level > &keypair) const
StackId Find(StackId stack_id, Label label)