Version: 1.0
forest_optimizer.h
Go to the documentation of this file.
1 // Copyright (c) 2020, the GRAPHGEN contributors, as
2 // shown by the AUTHORS file. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6 
7 #ifndef GRAPHGEN_FOREST_OPTIMIZER_H_
8 #define GRAPHGEN_FOREST_OPTIMIZER_H_
9 
10 #include <algorithm>
11 #include <bitset>
12 #include <string>
13 #include <vector>
14 
15 #include "forest.h"
16 
17 using namespace std;
18 
19 //struct STree {
20 // struct STreeProp {
21 // string conditions;
22 // vector<std::bitset</*11881*/128>> actions;
23 // vector<uint> nexts;
24 // BinaryDrag<conact>::node* n_;
25 //
26 // STreeProp& operator+=(const STreeProp& rhs) {
27 // conditions += rhs.conditions;
28 // copy(begin(rhs.actions), end(rhs.actions), back_inserter(actions));
29 // copy(begin(rhs.nexts), end(rhs.nexts), back_inserter(nexts));
30 // return *this;
31 // }
32 //
33 // bool operator<(const STreeProp& rhs) {
34 // if (conditions.size() > rhs.conditions.size())
35 // return true;
36 // else if (conditions.size() < rhs.conditions.size())
37 // return false;
38 // else if (conditions < rhs.conditions)
39 // return true;
40 // else if (conditions > rhs.conditions)
41 // return false;
42 //
43 // else if (nexts.size() > rhs.nexts.size())
44 // return true;
45 // else if (nexts.size() < rhs.nexts.size())
46 // return false;
47 // else {
48 // for (size_t i = 0; i < nexts.size(); ++i)
49 // if (nexts[i] < rhs.nexts[i])
50 // return true;
51 // else if (nexts[i] > rhs.nexts[i])
52 // return false;
53 // }
54 //
55 // if (actions.size() > rhs.actions.size())
56 // return true;
57 // else if (actions.size() < rhs.actions.size())
58 // return false;
59 // else {
60 // int diff = 0;
61 // for (size_t i = 0; i < actions.size(); ++i) {
62 // diff += actions[i].count();
63 // diff -= rhs.actions[i].count();
64 // }
65 //
66 // return diff > 0;
67 // }
68 // }
69 //
70 // bool equivalent(const STreeProp& rhs) {
71 // if (conditions != rhs.conditions)
72 // return false;
73 // for (size_t i = 0; i < nexts.size(); ++i)
74 // if (nexts[i] != rhs.nexts[i])
75 // return false;
76 // for (size_t i = 0; i < actions.size(); ++i)
77 // if ((actions[i] & rhs.actions[i]) == 0)
78 // return false;
79 // return true;
80 // }
81 // };
82 // map<BinaryDrag<conact>::node*, STreeProp> np_;
83 // LineForestHandler& f_;
84 //
85 // STreeProp CollectStatsRec(BinaryDrag<conact>::node * n) {
86 // auto it = np_.find(n);
87 // if (it != end(np_))
88 // return it->second;
89 //
90 // STreeProp sp;
91 // sp.n_ = n;
92 // if (n->isleaf()) {
93 // sp.conditions = ".";
94 // sp.actions.push_back(n->data.action);
95 // sp.nexts.push_back(n->data.next);
96 // }
97 // else {
98 // sp.conditions = n->data.condition;
99 // sp += CollectStatsRec(n->left);
100 // sp += CollectStatsRec(n->right);
101 // }
102 //
103 // np_[n] = sp;
104 // return sp;
105 // }
106 //
107 // // Works only with equivalent trees
108 // static void Intersect(BinaryDrag<conact>::node* n1, BinaryDrag<conact>::node* n2) {
109 // if (n1->isleaf()) {
110 // n1->data.action &= n2->data.action;
111 // n2->data.action = n1->data.action;
112 // }
113 // else {
114 // Intersect(n1->left, n2->left);
115 // Intersect(n1->right, n2->right);
116 // }
117 // }
118 // // tbr to be replaced
119 // // rw replace with
120 // static void FindAndReplace(BinaryDrag<conact>::node* n, BinaryDrag<conact>::node* tbr, BinaryDrag<conact>::node* rw) {
121 // if (!n->isleaf()) {
122 // if (n->left == tbr) {
123 // n->left = rw;
124 // }
125 // else if (n->right == tbr) {
126 // n->right = rw;
127 // }
128 // else {
129 // FindAndReplace(n->left, tbr, rw);
130 // FindAndReplace(n->right, tbr, rw);
131 // }
132 // }
133 // }
134 //
135 // bool LetsDoIt() {
136 // np_.clear();
137 //
138 // for (size_t i = 0; i < f_.trees_.size(); ++i) {
139 // const auto& t = f_.trees_[i];
140 // // To avoid finding of equal trees that optimizer cannot compress
141 // CollectStatsRec(t.GetRoot()->right);
142 // CollectStatsRec(t.GetRoot()->left);
143 // }
144 //
145 // vector<STreeProp> vec;
146 // for (const auto& x : np_)
147 // vec.emplace_back(x.second);
148 // sort(begin(vec), end(vec));
149 //
150 // for (size_t i = 0; i < vec.size(); /*empty*/) {
151 // size_t j = i + 1;
152 // for (; j < vec.size(); ++j) {
153 // if (vec[i].conditions != vec[j].conditions)
154 // break;
155 // }
156 // if (j == i + 1) {
157 // vec.erase(begin(vec) + i);
158 // }
159 // else {
160 // // from i to j-1 the subtrees have the same conditions.
161 // // Let's check if they have any equivalent subtree
162 // map<int, bool> keep;
163 // for (size_t k = i; k < j; ++k)
164 // keep[k] = false;
165 // for (size_t k = i; k < j; ++k) {
166 // for (size_t h = k + 1; h < j; ++h) {
167 // if (vec[k].equivalent(vec[h])) {
168 // keep[k] = true;
169 // keep[h] = true;
170 // }
171 // }
172 // if (!keep[k])
173 // vec[k].conditions = "Mark for erase";
174 // }
175 // for (size_t k = i; k < j;) {
176 // if (vec[k].conditions == "Mark for erase") {
177 // vec.erase(begin(vec) + k);
178 // --j;
179 // }
180 // else
181 // ++k;
182 // }
183 //
184 // i = j;
185 // }
186 // }
187 //
188 // if (vec.empty())
189 // return false;
190 //
191 // size_t j = 1;
192 // for (; j < vec.size(); ++j) {
193 // if (vec[0].equivalent(vec[j]))
194 // break;
195 // }
196 // if (j >= vec.size()) {
197 // throw;
198 // }
199 //
200 // Intersect(vec[0].n_, vec[j].n_);
201 // for (size_t k = 0; k < f_.trees_.size(); ++k) {
202 // auto& t = f_.trees_[k];
203 // //// Whole trees can be equivalent too
204 // //if (t.GetRoot() == vec[0].n_) {
205 // // t.GetRoot() = vec[j].n_;
206 // //}
207 // /////////////////////////////////////
208 // FindAndReplace(t.GetRoot(), vec[0].n_, vec[j].n_);
209 // }
210 // return true;
211 // }
212 //
213 // bool LetsDoEndTrees(const vector<vector<BinaryDrag<conact>*>> trees) {
214 // np_.clear();
215 //
216 // for (size_t tg = 0; tg < trees.size(); ++tg) {
217 // const auto& cur_trees = trees[tg];
218 // for (size_t i = 0; i < cur_trees.size(); ++i) {
219 // const auto t = cur_trees[i];
220 // // To avoid finding of equal trees that optimizer cannot compress
221 // CollectStatsRec(t->GetRoot()->right);
222 // CollectStatsRec(t->GetRoot()->left);
223 // }
224 // }
225 //
226 // vector<STreeProp> vec;
227 // for (const auto& x : np_)
228 // vec.emplace_back(x.second);
229 // sort(begin(vec), end(vec));
230 //
231 // for (size_t i = 0; i < vec.size(); /*empty*/) {
232 // size_t j = i + 1;
233 // for (; j < vec.size(); ++j) {
234 // if (vec[i].conditions != vec[j].conditions)
235 // break;
236 // }
237 // if (j == i + 1) {
238 // vec.erase(begin(vec) + i);
239 // }
240 // else {
241 // // from i to j-1 the subtrees have the same conditions.
242 // // Let's check if they have any equivalent subtree
243 // map<int, bool> keep;
244 // for (size_t k = i; k < j; ++k)
245 // keep[k] = false;
246 // for (size_t k = i; k < j; ++k) {
247 // for (size_t h = k + 1; h < j; ++h) {
248 // if (vec[k].equivalent(vec[h])) {
249 // keep[k] = true;
250 // keep[h] = true;
251 // }
252 // }
253 // if (!keep[k])
254 // vec[k].conditions = "Mark for erase";
255 // }
256 // for (size_t k = i; k < j;) {
257 // if (vec[k].conditions == "Mark for erase") {
258 // vec.erase(begin(vec) + k);
259 // --j;
260 // }
261 // else
262 // ++k;
263 // }
264 //
265 // i = j;
266 // }
267 // }
268 //
269 // if (vec.empty())
270 // return false;
271 //
272 // size_t j = 1;
273 // for (; j < vec.size(); ++j) {
274 // if (vec[0].equivalent(vec[j]))
275 // break;
276 // }
277 // if (j >= vec.size()) {
278 // throw;
279 // }
280 //
281 // Intersect(vec[0].n_, vec[j].n_);
282 // for (size_t tg = 0; tg < trees.size(); ++tg) {
283 // const auto& cur_trees = trees[tg];
284 // for (size_t k = 0; k < cur_trees.size(); ++k) {
285 // const auto& t = cur_trees[k];
286 // // Whole trees can be equivalent too
287 // /*if (t->root == vec[0].n_) {
288 // t->root = vec[j].n_;
289 // }*/
290 // ///////////////////////////////////
291 // FindAndReplace(t->GetRoot(), vec[0].n_, vec[j].n_);
292 // }
293 // }
294 //
295 // return true;
296 // }
297 //
298 // STree(LineForestHandler& f) : f_(f) {
299 // while (LetsDoIt()) {
300 // f_.RemoveUselessConditions();
301 // //f_.RemoveEqualTrees();
302 // }
303 //
304 // if (f_.separately) {
305 // for (auto& tg : f.end_trees_) {
306 // vector<vector<BinaryDrag<conact>*>> cur_tree_ptrs = { vector<BinaryDrag<conact>*>() };
307 // for (BinaryDrag<conact> &t : tg) {
308 // cur_tree_ptrs.front().push_back(&t);
309 // }
310 // while (LetsDoEndTrees(cur_tree_ptrs)) {
311 // f_.RemoveEndTreesUselessConditions();
312 // //f_.RemoveEqualEndTrees();
313 // }
314 // }
315 // }
316 // else {
317 // vector<vector<BinaryDrag<conact>*>> tree_ptrs;
318 // for (vector<BinaryDrag<conact>> &tg : f_.end_trees_) {
319 // tree_ptrs.emplace_back();
320 // for (BinaryDrag<conact> &t : tg) {
321 // tree_ptrs.back().push_back(&t);
322 // }
323 // }
324 // while (LetsDoEndTrees(tree_ptrs)) {
325 // f_.RemoveEndTreesUselessConditions();
326 // //f_.RemoveEqualEndTrees();
327 // }
328 // }
329 // }
330 //};
331 
332 #endif // !GRAPHGEN_FOREST_OPTIMIZER_H_