22 if (bd.
roots_.size() > 1) {
27 next_tree_.push_back(0);
34 InitNextRec(tmp.
roots_[0]);
46 for (
const auto& p : ps) {
48 start_constr[p.name_] = 0;
50 f_.AddRoot(Reduce(tmp.
GetRoot(), f_, start_constr));
63 while (RemoveEqualTrees()) {
64 RemoveUselessConditions();
110 for (
int out_offset = 1;; ++out_offset) {
113 for (
const auto& p : ps) {
114 if (p.GetDx() >= out_offset)
115 end_constr[p.name_] = 0;
117 if (end_constr.empty()) {
123 for (
const auto& t : f_.roots_) {
124 end_forests_.back().AddRoot(Reduce(t, end_forests_.back(), end_constr));
127 assert(f_.roots_.size() == end_forests_.back().roots_.size());
131 main_end_tree_mapping_ = vector<vector<size_t>>(end_forests_.size(), vector<size_t>(f_.roots_.size()));
132 for (
auto& etm : main_end_tree_mapping_) {
133 iota(etm.begin(), etm.end(), 0);
135 end_next_tree_ = main_end_tree_mapping_;
140 for (
auto& f : end_forests_) {
141 for (
auto& n : f.nodes_) {
143 n->data.next = numeric_limits<size_t>::max();
150 while (RemoveEqualEndTrees()) {
151 RemoveEndTreesUselessConditions();
216 for (
auto& r : f_.roots_) {
225 for (
auto& f : end_forests_) {
226 for (
auto& t : f.roots_) {
234 bool changed =
false;
235 for (
size_t i = 0; i < end_forests_.size(); ++i) {
236 changed |= RemoveTrees(
EqualTrees, end_next_tree_[i], end_forests_[i],
true, main_end_tree_mapping_[i]);
249 n->data.next = next_tree_[n->data.next];
253 UpdateNext(n->right);
262 return RemoveTrees(
EqualTrees, next_tree_, f_);
267 vector<size_t>& next_tree,
270 vector<size_t>& mapping) {
273 for (
size_t i = 0; i < next_tree.size() - 1; ++i) {
274 if (next_tree[i] == i) {
275 for (
size_t j = i + 1; j < next_tree.size(); ++j) {
276 if (next_tree[j] == j) {
292 size_t new_index = 0;
293 for (
size_t i = 0; i < next_tree.size(); ++i) {
294 if (next_tree[i] == i) {
295 next_tree[i] = new_index;
299 next_tree[i] = next_tree[next_tree[i]];
305 for (
size_t i = 0; i < next_tree.size(); ++i) {
306 if (next_tree[i] != new_index) {
318 for (
size_t i = 0; i < mapping.size(); ++i) {
319 mapping[i] = next_tree[mapping[i]];
324 for (
auto& r : f.
roots_) {
329 next_tree.resize(f.
roots_.size());
330 iota(begin(next_tree), end(next_tree), 0);
338 n->data.next = next_tree_.size();
340 next_tree_.push_back(next_tree_.size());
343 InitNextRec(n->left);
344 InitNextRec(n->right);
354 auto it = constr.find(n->data.condition);
355 if (it != end(constr)) {
357 return Reduce(n->left, t, constr);
359 return Reduce(n->right, t, constr);
362 return t.
make_node(n->data, Reduce(n->left, t, constr), Reduce(n->right, t, constr));
node * GetRoot() const
Returns the last root of the BinaryDrag.
void AddRoot(node *r)
Adds a new root to the vector of roots.
std::vector< node * > roots_
node * make_node(Args &&... args)
Creates and returns a new node updating the nodes_ vector.
void IntersectTrees(BinaryDrag< conact >::node *n1, BinaryDrag< conact >::node *n2)
bool EqualTrees(const BinaryDrag< conact >::node *n1, const BinaryDrag< conact >::node *n2)
Checks whether two (sub)trees 'n1' and 'n2' are equal or nor.
bool equivalent_trees(const BinaryDrag< conact >::node *n1, const BinaryDrag< conact >::node *n2)
void RemoveUselessConditionsRec(BinaryDrag< conact >::node *n, bool &changed)
std::map< std::string, int > constraints
Creates forest of trees pruning original tree.
void RemoveUselessConditions()
void UpdateNext(BinaryDrag< conact >::node *n)
void RemoveEndTreesUselessConditions()
static BinaryDrag< conact >::node * Reduce(const BinaryDrag< conact >::node *n, BinaryDrag< conact > &t, const constraints &constr)
void InitNextRec(BinaryDrag< conact >::node *n)
bool RemoveEqualEndTrees()
bool RemoveEquivalentTrees()
bool RemoveEquivalentEndTrees()