// Conjonction of all formulas returned by all calls (one per node) to // get_color_limitation_formula_for_node. SPEF get_color_limitation_formula(int nb_nodes, int nb_colors, int nb_bits) { int i; SPEF formula = SPEF(new EF(EF::TRUE)); SPEF new_formula; for (i=0; i<nb_nodes; i++) { formula = SPEF(new EF(EF::AND, formula, get_color_limitation_formula_for_node(i, nb_colors, nb_bits))); } return formula; }
// Get a disjonction of XORs saying “I don't want these two nodes to be the // same color”. SPEF get_color_disjonction_of_edge(int first_node_id, int second_node_id, int nb_bits) { int i; SPEF literal1, literal2, formula2; SPEF formula = SPEF(new EF(EF::FALSE)); for (i=0; i<nb_bits; i++) { literal1 = SPEF(new EF(EF::LITERAL, get_variable_of_node_bit(first_node_id, i))); literal2 = SPEF(new EF(EF::LITERAL, get_variable_of_node_bit(second_node_id, i))); formula2 = SPEF(new EF(EF::XOR, literal1, literal2)); formula = SPEF(new EF(EF::OR, formula, formula2)); } return formula; }
// Get a disjonction saying “I don't want the color identifier of the node // to be greater or equal to X”. SPEF get_color_limitation_formula_for_node(int node_id, int nb_colors, int nb_bits) { int i; SPEF formula, this_bit, not_this_bit; nb_colors--; if (nb_colors % 2) formula = SPEF(new EF(EF::TRUE)); else formula = SPEF(new EF(EF::NOT, SPEF(new EF(EF::LITERAL, get_variable_of_node_bit(node_id, 0))))); for (i=1; i<nb_bits; i++) { nb_colors >>= 1; this_bit = SPEF(new EF(EF::LITERAL, get_variable_of_node_bit(node_id, i))); not_this_bit = SPEF(new EF(EF::NOT, this_bit)); if (nb_colors % 2) { // (¬“node_id i”)+((“node_id i”∧formula)) formula = SPEF(new EF(EF::OR, not_this_bit, SPEF(new EF(EF::AND, this_bit, formula )) )); } else { formula = SPEF(new EF(EF::AND, not_this_bit, formula)); } } return formula; }
// Returns an extended formula from a graph coloration problem. int reduce_graph_coloration_to_extended_formula(graphsolver::Graph *graph, int nb_colors, SPEF *formula) { int nb_bits = static_cast<int>(ceil(log2(nb_colors))); int nodes_count = graph->get_nodes_count(); int i; std::set<int> *adjacent_nodes; *formula = get_color_limitation_formula(graph->get_nodes_count(), nb_colors, nb_bits); for (i=0; i<nodes_count; i++) { adjacent_nodes = graph->get_lower_adjacent_nodes(i); for (auto adjacent_node : *adjacent_nodes) { *formula = SPEF(new EF(EF::AND, get_color_disjonction_of_edge(i, adjacent_node, nb_bits), *formula)); } } return nb_bits; }
void read_spef (graph* graphin) { string SPEFFile = "1.spef"; ifstream SPEF (SPEFFile.c_str()); if (SPEF.is_open()) { string SPEFLine; bool found_dnet = false; bool found_conn = false; bool found_cap = false; bool found_res = false; while ( getline (SPEF,SPEFLine) ) { // Trim SPEFLine.erase(remove(SPEFLine.begin(), SPEFLine.end(), '\n'), SPEFLine.end()); SPEFLine.erase(remove(SPEFLine.begin(), SPEFLine.end(), '\r'), SPEFLine.end()); SPEFLine.erase(remove(SPEFLine.begin(), SPEFLine.end(), '\t'), SPEFLine.end()); SPEFLine = trim(SPEFLine); // Ignore null lines if ( SPEFLine.empty() ) { continue; } vector<string> SPEFTokens = split(SPEFLine, ' '); if (SPEFTokens[0] == "*D_NET") { found_dnet = true; continue; } if (SPEFTokens[0] == "*CONN" && found_dnet == true) { found_conn = true; continue; } if (SPEFTokens[0] == "*CAP" && found_dnet == true) { found_cap = true; found_conn = false; continue; } if (SPEFTokens[0] == "*RES" && found_dnet == true) { found_res = true; found_cap = false; continue; } if (SPEFTokens[0] == "*END") { continue; } if (found_conn == true) { int victim_found=SPEFLine.find("V1"); if (victim_found!=std::string::npos) { graphin->inputs++; node *new_node = new node("V1"); new_node->level = 0; new_node->tree_id = 0; vector<node*> temp; temp.push_back(new_node); graphin->level_order.push_back(temp); graphin->node_map["V1"] = new_node; } int agg_found=SPEFLine.find("A"); if (agg_found!=std::string::npos) { graphin->inputs++; node *new_node = new node("A1"); new_node->level = 0; new_node->tree_id = 1; vector<node*> temp; temp.push_back(new_node); graphin->level_order.push_back(temp); graphin->node_map["A1"] = new_node; } int out_found=SPEFLine.find("O1"); if (out_found!=std::string::npos) { node *new_node = new node("O1"); graphin->node_map["O1"] = new_node; } } if (found_cap == true) { if (SPEFTokens.size() == 4) { if (graphin->node_map.find(SPEFTokens[1]) == graphin->node_map.end()) { node *new_node = new node(SPEFTokens[1]); graphin->node_map[SPEFTokens[1]] = new_node; } if (graphin->node_map.find(SPEFTokens[2]) == graphin->node_map.end()) { node *new_node = new node(SPEFTokens[2]); graphin->node_map[SPEFTokens[2]] = new_node; } graphin->add_ccap(SPEFTokens[0],strtod(SPEFTokens[3].c_str(),NULL),graphin->node_map[SPEFTokens[1]],graphin->node_map[SPEFTokens[2]]); } else if (SPEFTokens.size() == 3) { if (graphin->node_map.find(SPEFTokens[1]) == graphin->node_map.end()) { node *new_node = new node(SPEFTokens[1]); graphin->node_map[SPEFTokens[1]] = new_node; } graphin->add_gcap(SPEFTokens[0],strtod(SPEFTokens[2].c_str(),NULL),graphin->node_map[SPEFTokens[1]]); } else { cout << "Invalid line in SPEF found"; } } if (found_res == true) { if (SPEFTokens.size() == 4) { if (graphin->node_map.find(SPEFTokens[1]) == graphin->node_map.end()) { node *new_node = new node(SPEFTokens[1]); graphin->node_map[SPEFTokens[1]] = new_node; } if (graphin->node_map.find(SPEFTokens[2]) == graphin->node_map.end()) { node *new_node = new node(SPEFTokens[2]); graphin->node_map[SPEFTokens[2]] = new_node; } graphin->add_res(SPEFTokens[0],strtod(SPEFTokens[3].c_str(),NULL),graphin->node_map[SPEFTokens[1]],graphin->node_map[SPEFTokens[2]]); } else { cout << "Invalid line in SPEF found "<< SPEFLine<<"\n"; } } } } }