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; }
cep_state_ptr stateful_sequence::create_state(tuple_ptr context, cep_state* parent) { universal_state* result = new universal_state(this, parent); // initialize a single state of the first expression // (further expression won't match without preceding events // -> this is the functionality of the sequence operator!) cep_state_ptr left_child = get_left_child()->create_state(context, result); result->set_property("left_child", left_child); result->set_property("right_states", boost::shared_ptr< state_type >(new state_type())); cep_state_ptr state = cep_state_ptr(result); states.push_back(cep_state_ptr(state)); return state; }