virtual tree_ptr finalize_tree(tree_ptr tree) const { std::queue<node_ptr> node_queue; node_queue.push(tree->get_root()); while (!node_queue.empty()) { auto current_node = node_queue.front(); node_queue.pop(); if (current_node->is_leaf()) { // Check nodes such as {E, F}, which can be broken without any more info if (current_node->get_size() == 2) { auto broken_color = current_node->get_data().break_into_parts(); auto left = broken_color[0]; auto right = broken_color[1]; current_node->set_left_child(std::make_shared<node_t>(left)); current_node->get_left_child()->set_parent(current_node.get()); current_node->get_left_child()->set_name( cfg::get().mcolor_to_name(current_node->get_left_child()->get_data())); current_node->set_right_child(std::make_shared<node_t>(right)); current_node->get_right_child()->set_parent(current_node.get()); current_node->get_right_child()->set_name( cfg::get().mcolor_to_name(current_node->get_right_child()->get_data())); } } else { node_queue.push(current_node->get_left_child()); node_queue.push(current_node->get_right_child()); } } return tree; }
static node_ptr fold_into_root_node(branch_vector& branches) { // No branches - no tree assert(!branches.empty()); if (cfg::get().is_debug) { std::cout << "Start folding" << std::endl; } // Sort is done, so singleton nodes won't break nodes, for example // Imagine we have a = ABC|D, b = AB|CD, c = B|ACD: if we apply a -> c -> b we won't get node AB std::sort(std::begin(branches), std::end(branches), [](branch_t const& left, branch_t const& right) { auto left_diff = std::abs(static_cast<long>(left.first.size()) - static_cast<long>(left.second.size())); auto right_diff = std::abs(static_cast<long>(right.first.size()) - static_cast<long>(right.second.size())); return left_diff < right_diff; }); if (cfg::get().is_debug) { for (auto branch: branches) { std::cout << branch_to_string(branch) << std::endl; } } auto branch_iter = std::begin(branches); auto root_node = node_from_branch(*branch_iter++); for (; branch_iter != std::end(branches); ++branch_iter) { merge_branch_into_node(root_node, *branch_iter); } root_node->set_name( cfg::get().mcolor_to_name( mcolor_t(root_node->get_left_child()->get_data(), root_node->get_right_child()->get_data(), mcolor_t::Union))); return root_node; }
static branch_vector break_trees_into_branches( tree_vector const& trees, mcolor_t complete_color = cfg::get().complete_color()) { branch_vector result; for (auto& tree: trees) { node_queue nodes_to_process; nodes_to_process.push(tree.get_root()); while (!nodes_to_process.empty()) { auto node = nodes_to_process.front(); auto node_color = node->get_data(); nodes_to_process.pop(); if (node_color != complete_color) { // Otherwise packed compliment is empty result.push_back(node_color.packed_compliment(complete_color)); } if (!node->is_leaf()) { nodes_to_process.push(node->get_left_child()); nodes_to_process.push(node->get_right_child()); } } } std::sort(result.begin(), result.end()); result.erase(std::unique(result.begin(), result.end()), result.end()); return result; }
bool stateful_sequence::evaluate_true(cep_state* source, cep_state* target, tuple_ptr match) { universal_state* target2 = (universal_state*)target; if(is_left_child(source)) { // start a right-hand expression with match as context cep_state_ptr next = get_right_child()->create_state(match, target2); boost::any_cast<state_type_ptr>(target2->get_property("right_states"))->insert(next); return false; } else { if(selection == selection::FIRST) { if(boost::any_cast<bool>(target2->get_property("block"))) { // return first result and no more (block=false) target2->set_property("block", bool(false)); send_true(target, match); // selection = FIRST and consumption = ALL is faster // when we stop all child nodes immediately if(consumption == consumption::ALL) { boost::any_cast<state_type_ptr>(target2->get_property("right_states"))->clear(); } } } else { /* selection == selection::ALL */ send_true(target, match); } if(consumption == consumption::MATCHING) { boost::any_cast<state_type_ptr>(target2->get_property("right_states"))->erase(cep_state_ptr(target)); } } }