From cc604d090617fa6c88709c3f731753b6181b22b8 Mon Sep 17 00:00:00 2001 From: panhongyang0 Date: Mon, 4 Mar 2024 18:12:13 +0800 Subject: [PATCH] update for exact synthesis --- src/commands/exact/exact_lut.hpp | 76 +- src/commands/exact/exact_multi.hpp | 121 + src/commands/functional_reduction.hpp | 2 +- src/commands/lut_mapping.hpp | 23 +- src/commands/techmap.hpp | 179 +- src/core/exact/exact_lut.cpp | 2898 -------------------- src/core/exact/exact_lut.hpp | 3633 ++++++++++++++++++++++++- src/phyLS.cpp | 2 +- 8 files changed, 3936 insertions(+), 2998 deletions(-) create mode 100644 src/commands/exact/exact_multi.hpp delete mode 100644 src/core/exact/exact_lut.cpp diff --git a/src/commands/exact/exact_lut.hpp b/src/commands/exact/exact_lut.hpp index 4d2b999..b86dc61 100644 --- a/src/commands/exact/exact_lut.hpp +++ b/src/commands/exact/exact_lut.hpp @@ -21,6 +21,7 @@ #include "../../core/exact/exact_dag.hpp" #include "../../core/exact/exact_lut.hpp" +#include "../core/exact/lut_rewriting.hpp" using namespace std; using namespace percy; @@ -38,6 +39,8 @@ class exact_command : public command { "stp based cegar encoding and partial DAG structure"); add_flag("--dag_depth, -t", "cegar encoding and partial DAG structure for Delay"); + add_flag("--decomposition, -p", + "using decomposition before exact synthesis"); add_option("--output, -o", filename, "the verilog filename"); add_flag("--enumeration, -e", "enumerate all solutions"); add_flag("--new_entry, -w", "adds k-LUT store entry"); @@ -46,6 +49,7 @@ class exact_command : public command { add_flag("--xag, -g", "enable exact synthesis for XAG, default = false"); add_flag("--npn, -n", "print result for NPN storing, default = false"); add_flag("--depth, -d", "print the depth of each result, default = false"); + add_flag("--parallel, -l", "parallel exact synthesis"); add_flag("--verbose, -v", "verbose results, default = true"); } @@ -200,6 +204,29 @@ class exact_command : public command { } } + void es_parallel(int nr_in, chain& result) { + spec spec; + chain c; + + spec.add_alonce_clauses = false; + spec.add_nontriv_clauses = false; + spec.add_lex_func_clauses = false; + spec.add_colex_clauses = false; + spec.add_noreapply_clauses = false; + spec.add_symvar_clauses = false; + spec.verbosity = 0; + + kitty::dynamic_truth_table f(nr_in); + kitty::create_from_hex_string(f, tt); + spec[0] = f; + + spec.preprocess(); + auto res = pd_ser_synthesize_parallel(spec, c, 4, "../src/pd/"); + // auto res = pf_fence_synthesize(spec, c, 8); + + if (res == success) result.copy(c); + } + void es_delay(int nr_in, list& chains) { int node = nr_in - 1, max_level = 0, count = 0; bool target = false; @@ -338,6 +365,12 @@ class exact_command : public command { return target; } + void es_after_decomposition() { + dec_network = store().current(); + phyLS::lut_rewriting_params ps; + dec_network = phyLS::lut_rewriting_c(dec_network, ps); + } + void execute() { t.clear(); t.push_back(binary_to_hex()); @@ -522,7 +555,7 @@ class exact_command : public command { } cout << "[Total realization]: " << count << endl; } else if (is_set("stp_cegar_dag")) { - if (is_set("map")){ + if (is_set("map")) { ps.gates = store>().current(); begin = clock(); exact_lut_dag_enu_map(tt, nr_in, ps); @@ -544,10 +577,45 @@ class exact_command : public command { totalTime = (double)(end - begin) / CLOCKS_PER_SEC; cout << "[Total realization]: " << nr_in << endl; } + } else if (is_set("decomposition")) { + begin = clock(); + es_after_decomposition(); + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + } else if (is_set("parallel")) { + int64_t total_elapsed = 0; + auto start = std::chrono::steady_clock::now(); + chain chain; + es_parallel(nr_in, chain); + const auto elapsed1 = + std::chrono::duration_cast( + std::chrono::steady_clock::now() - start) + .count(); + total_elapsed += elapsed1; + if (ps.verbose) { + chain.print_bench(); + if (ps.depth) { + klut_network klut = create_network(chain); + mockturtle::depth_view depth_lut{klut}; + std::cout << "level = " << depth_lut.depth() - 1 << std::endl; + } + } + if (ps.npn) { + chain.print_npn(); + if (ps.depth) { + klut_network klut = create_network(chain); + mockturtle::depth_view depth_lut{klut}; + std::cout << "l{" << depth_lut.depth() - 1 << "}" << std::endl; + } else { + std::cout << std::endl; + } + } + printf("[Total CPU time] : %ldus\n", total_elapsed); } else { if (is_set("enumeration")) { begin = clock(); - phyLS::exact_lut_enu(tt_h, nr_in); + int cut_size = 0; + phyLS::exact_lut_enu(tt_h, nr_in, cut_size); end = clock(); totalTime = (double)(end - begin) / CLOCKS_PER_SEC; int count = 0; @@ -558,7 +626,8 @@ class exact_command : public command { cout << "[Total realization]: " << count << endl; } else { begin = clock(); - phyLS::exact_lut(tt_h, nr_in); + int cut_size = 0; + phyLS::exact_lut(tt_h, nr_in, cut_size); end = clock(); totalTime = (double)(end - begin) / CLOCKS_PER_SEC; int count = 0; @@ -582,6 +651,7 @@ class exact_command : public command { double min_delay = 0.00; int mapping_gate = 0; std::string filename = "techmap.v"; + klut_network dec_network; }; ALICE_ADD_COMMAND(exact, "Synthesis") diff --git a/src/commands/exact/exact_multi.hpp b/src/commands/exact/exact_multi.hpp new file mode 100644 index 0000000..826e44b --- /dev/null +++ b/src/commands/exact/exact_multi.hpp @@ -0,0 +1,121 @@ +#ifndef EXACT_MULTI_HPP +#define EXACT_MULTI_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include "../store.hpp" + +using namespace std; +using namespace percy; +using namespace mockturtle; +using kitty::dynamic_truth_table; + +using namespace std; + +namespace alice { + +class exact_window_command : public command { + public: + explicit exact_window_command(const environment::ptr& env) + : command(env, "using exact synthesis to find optimal window") { + add_flag("--cegar, -c", "cegar encoding"); + add_option("--num_functions, -n", num_functions, + "set the number of functions to be synthesized, default = 1"); + add_option("--file, -f", filename, "input filename"); + add_flag("--verbose, -v", "print the information"); + } + + private: + int num_functions = 1; + std::string filename; + vector iTT; + + aig_network create_network(chain& c) { + klut_network klut; + c.store_bench(0); + std::string filename = "r_0.bench"; + if (lorina::read_bench(filename, mockturtle::bench_reader(klut)) != + lorina::return_code::success) { + std::cout << "[w] parse error\n"; + } + aig_network aig = convert_klut_to_graph(klut); + return aig; + } + + protected: + void execute() { + spec spec; + aig_network aig; + if (is_set("file")) { + ifstream fin_bench(filename); + string tmp; + if (fin_bench.is_open()) { + while (getline(fin_bench, tmp)) { + iTT.push_back(tmp); + } + fin_bench.close(); + int nr_in = 0, value = 0; + while (value < iTT[0].size()) { + value = pow(2, nr_in); + if (value == iTT[0].size()) break; + nr_in++; + } + for (int i = 0; i < iTT.size(); i++) { + kitty::dynamic_truth_table f(nr_in); + kitty::create_from_binary_string(f, iTT[i]); + spec[i] = f; + } + } + } else { + auto store_size = store().size(); + assert(store_size >= num_functions); + if (!is_set("num_functions")) num_functions = 1; + for (int i = 0; i < num_functions; i++) { + auto& opt = store()[store_size - i - 1]; + auto copy = opt.function; + spec[i] = copy; + } + } + + stopwatch<>::duration time{0}; + if (is_set("cegar")) { + bsat_wrapper solver; + msv_encoder encoder(solver); + chain c; + call_with_stopwatch(time, [&]() { + if (synthesize(spec, c, solver, encoder) == success) { + c.print_bench(); + aig = create_network(c); + store().extend(); + store().current() = aig; + } + }); + } else { + bsat_wrapper solver; + ssv_encoder encoder(solver); + chain c; + call_with_stopwatch(time, [&]() { + if (synthesize(spec, c, solver, encoder) == success) { + c.print_bench(); + aig = create_network(c); + store().extend(); + store().current() = aig; + } + }); + } + + std::cout << fmt::format("[Total CPU time] : {:5.3f} seconds\n", + to_seconds(time)); + } +}; + +ALICE_ADD_COMMAND(exact_window, "Synthesis") +} // namespace alice + +#endif diff --git a/src/commands/functional_reduction.hpp b/src/commands/functional_reduction.hpp index ea7708e..77df9d1 100644 --- a/src/commands/functional_reduction.hpp +++ b/src/commands/functional_reduction.hpp @@ -95,7 +95,7 @@ class fr_command : public command { } private: - int max_tfi_node = 10000; + int max_tfi_node = 1000; string filename = "pattern.log"; }; diff --git a/src/commands/lut_mapping.hpp b/src/commands/lut_mapping.hpp index 52f87a2..7e736e6 100644 --- a/src/commands/lut_mapping.hpp +++ b/src/commands/lut_mapping.hpp @@ -34,10 +34,12 @@ class lut_mapping_command : public command { : command(env, "LUT mapping [default = AIG]") { add_option("cut_size, -k", cut_size, "set the cut size from 2 to 8, default = 4"); - add_flag("--verbose, -v", "print the information"); add_flag("--satlut, -s", "satlut mapping"); add_flag("--xag, -g", "LUT mapping for XAG"); add_flag("--mig, -m", "LUT mapping for MIG"); + add_flag("--klut, -l", "LUT mapping for k-LUT"); + add_flag("--area, -a", "area-oriented mapping, default = no"); + add_flag("--verbose, -v", "print the information"); } protected: @@ -45,6 +47,9 @@ class lut_mapping_command : public command { clock_t begin, end; double totalTime; lut_mapping_params ps; + if (is_set("area")){ + ps.rounds_ela = 4u; + } if (is_set("mig")) { /* derive some MIG */ @@ -78,6 +83,22 @@ class lut_mapping_command : public command { totalTime = (double)(end - begin) / CLOCKS_PER_SEC; store().extend(); store().current() = klut; + } else if (is_set("klut")) { + /* derive some kLUT */ + assert(store().size() > 0); + begin = clock(); + klut_network klut = store().current(); + + mapping_view mapped_klut{klut}; + ps.cut_enumeration_ps.cut_size = cut_size; + lut_mapping, true>(mapped_klut, ps); + + /* collapse into k-LUT network */ + const auto klut_new = *collapse_mapped_network(mapped_klut); + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + store().extend(); + store().current() = klut_new; } else { if (store().size() == 0) { assert(false && "Error: Empty AIG network\n"); diff --git a/src/commands/techmap.hpp b/src/commands/techmap.hpp index cb90083..1e2f5a7 100644 --- a/src/commands/techmap.hpp +++ b/src/commands/techmap.hpp @@ -1,14 +1,14 @@ /* phyLS: powerful heightened yielded Logic Synthesis * Copyright (C) 2022 */ - /** - * @file techmap.hpp - * - * @brief Standard cell mapping - * - * @author Homyoung - * @since 2022/12/14 - */ +/** + * @file techmap.hpp + * + * @brief Standard cell mapping + * + * @author Homyoung + * @since 2022/12/14 + */ #ifndef TECHMAP_HPP #define TECHMAP_HPP @@ -26,118 +26,115 @@ namespace alice { - class techmap_command: public command { - public: - explicit techmap_command(const environment::ptr& env) +class techmap_command : public command { + public: + explicit techmap_command(const environment::ptr& env) : command(env, "Standard cell mapping [default = AIG]") { - add_flag("--xmg, -x", "Standard cell mapping for XMG"); - add_flag("--mig, -m", "Standard cell mapping for MIG"); - add_flag("--lut, -l", "Standard cell mapping for k-LUT"); - add_option("--output, -o", filename, "the verilog filename"); - add_flag("--verbose, -v", "print the information"); - } + add_flag("--xmg, -x", "Standard cell mapping for XMG"); + add_flag("--mig, -m", "Standard cell mapping for MIG"); + add_flag("--lut, -l", "Standard cell mapping for k-LUT"); + add_option("--output, -o", filename, "the verilog filename"); + add_flag("--verbose, -v", "print the information"); + } - rules validity_rules() const { - return { has_store_element>(env) }; - } + rules validity_rules() const { + return {has_store_element>(env)}; + } - private: - std::string filename = "techmap.v"; + private: + std::string filename = "techmap.v"; - protected: - void execute() { - /* derive genlib */ - std::vector gates = + protected: + void execute() { + /* derive genlib */ + std::vector gates = store>().current(); + mockturtle::tech_library<5> lib(gates); - mockturtle::tech_library<5> lib(gates); - mockturtle::map_params ps; - mockturtle::map_stats st; + mockturtle::map_params ps; + mockturtle::map_stats st; - if (is_set("xmg")) { - if (store().size() == 0u) - std::cerr << "[e] no XMG in the store\n"; - else { - auto xmg = store().current(); - xmg_gate_stats stats; - xmg_profile_gates(xmg, stats); - std::cout << "[i] "; - stats.report(); + if (is_set("xmg")) { + if (store().size() == 0u) + std::cerr << "[e] no XMG in the store\n"; + else { + auto xmg = store().current(); + xmg_gate_stats stats; + xmg_profile_gates(xmg, stats); + std::cout << "[i] "; + stats.report(); - phyLS::xmg_critical_path_stats critical_stats; - phyLS::xmg_critical_path_profile_gates(xmg, critical_stats); - std::cout << "[i] "; - critical_stats.report(); + phyLS::xmg_critical_path_stats critical_stats; + phyLS::xmg_critical_path_profile_gates(xmg, critical_stats); + std::cout << "[i] "; + critical_stats.report(); - auto res = mockturtle::map(xmg, lib, ps, &st); + auto res = mockturtle::map(xmg, lib, ps, &st); - if (is_set("output")) { - write_verilog_with_binding(res, filename); - } + if (is_set("output")) { + write_verilog_with_binding(res, filename); + } - std::cout << fmt::format( + std::cout << fmt::format( "[i] Mapped XMG into #gates = {} area = {:.2f} delay = {:.2f}\n", res.num_gates(), st.area, st.delay); - } } - else if (is_set("mig")) { - if (store().size() == 0u) { - std::cerr << "[e] no MIG in the store\n"; + } else if (is_set("mig")) { + if (store().size() == 0u) { + std::cerr << "[e] no MIG in the store\n"; + } else { + auto mig = store().current(); + + auto res = mockturtle::map(mig, lib, ps, &st); + + if (is_set("output")) { + write_verilog_with_binding(res, filename); } - else { - auto mig = store().current(); - auto res = mockturtle::map(mig, lib, ps, &st); - - if (is_set("output")) { - write_verilog_with_binding(res, filename); - } - - std::cout << fmt::format( + std::cout << fmt::format( "Mapped MIG into #gates = {} area = {:.2f} delay = {:.2f}\n", res.num_gates(), st.area, st.delay); - } } - else if (is_set("lut")) { - if (store().size() == 0u) { - std::cerr << "[e] no k-LUT in the store\n"; + } else if (is_set("lut")) { + if (store().size() == 0u) { + std::cerr << "[e] no k-LUT in the store\n"; + } else { + auto lut = store().current(); + + auto res = mockturtle::map(lut, lib, ps, &st); + + if (is_set("output")) { + write_verilog_with_binding(res, filename); } - else { - auto lut = store().current(); - auto res = mockturtle::map(lut, lib, ps, &st); - - if (is_set("output")) { - write_verilog_with_binding(res, filename); - } - - std::cout << fmt::format( + std::cout << fmt::format( "Mapped k-LUT into #gates = {} area = {:.2f} delay = {:.2f}\n", res.num_gates(), st.area, st.delay); - } } - else { - if (store().size() == 0u) { - std::cerr << "[e] no AIG in the store\n"; - } - else { - auto aig = store().current(); + } else { + if (store().size() == 0u) { + std::cerr << "[e] no AIG in the store\n"; + } else { + auto aig = store().current(); + auto res = mockturtle::map(aig, lib, ps, &st); - auto res = mockturtle::map(aig, lib, ps, &st); + if (is_set("output")) write_verilog_with_binding(res, filename); - if (is_set("output")) { - write_verilog_with_binding(res, filename); - } - - std::cout << fmt::format( - "Mapped AIG into #gates = {} area = {:.2f} delay = {:.2f}\n", - res.num_gates(), st.area, st.delay); - } + // std::cout << fmt::format( + // "Mapped AIG into #gates = {}, area = {:.2f}, delay = {:.2f}, " + // "power = {:.2f}\n", + // res.num_gates(), st.area, st.delay, st.power); } } - }; + if (is_set("verbose")) { + st.report(); + cout << "Cut enumeration stats: " << endl; + st.cut_enumeration_st.report(); + } + } +}; - ALICE_ADD_COMMAND(techmap, "Mapping") +ALICE_ADD_COMMAND(techmap, "Mapping") } // namespace alice diff --git a/src/core/exact/exact_lut.cpp b/src/core/exact/exact_lut.cpp deleted file mode 100644 index f46f616..0000000 --- a/src/core/exact/exact_lut.cpp +++ /dev/null @@ -1,2898 +0,0 @@ -#include "exact_lut.hpp" - -using namespace std; - -namespace phyLS { -struct node_inf { - int num; - int level; - bool fan_out = 0; - bool fan_in = 0; -}; - -struct bench { - int node; - int right = 0; - int left = 0; - string tt = "2222"; -}; - -struct dag { - int node; - int level; - vector count; - vector> lut; -}; - -struct matrix { - int eye = 0; - int node = 0; - string name; - bool input = 0; -}; - -struct result_lut { - string computed_input; - vector possible_result; -}; - -struct coordinate { - int Abscissa; - int Ordinate; - int parameter_Intermediate; - int parameter_Gate; -}; - -struct cdccl_impl { - vector Intermediate; - string Result; - vector Gate; - vector Level; // Define the network as a coordinate system -}; - -class exact_lut_impl { - public: - exact_lut_impl(vector& tt, int& input) : tt(tt), input(input) {} - - void run() { exact_lut_network(); } - - void run_enu() { exact_lut_network_enu(); } - - private: - void exact_lut_network() { - // the DAG topology family of r nodes and k levels - // initialization - int num_node = input - 1; // first, number of node is number of input - 1 - int num_level = 2; - while (1) { - vector> lut; - create_dags(lut, num_node, num_level); - - if (lut.empty()) { - if (num_level <= num_node) { - num_level += 1; - } - if (num_level > num_node) { - num_level = 2; - num_node += 1; - } - continue; - } - // AllSAT solving to judge the DAGs - stp_simulate(lut); - if (lut.size()) { - vector result_final; - for (int i = 0; i < lut.size(); i++) { - string result; - for (int j = 0; j < lut[i].size(); j++) { - result += to_string(lut[i][j].node); - result += " = 4'b"; - result += lut[i][j].tt; - result += " ("; - if (lut[i][j].left <= input) { - char temp; - temp = 'a' + lut[i][j].left - 1; - result.push_back(temp); - } else { - result += to_string(lut[i][j].left); - } - result += ", "; - if (lut[i][j].right <= input) { - char temp; - temp = 'a' + lut[i][j].right - 1; - result.push_back(temp); - } else { - result += to_string(lut[i][j].right); - } - result += ") "; - } - result_final.push_back(result); - } - tt.assign(result_final.begin(), result_final.end()); - break; - } else { - if (num_level <= num_node) { - num_level += 1; - } - if (num_level > num_node) { - num_level = 2; - num_node += 1; - } - } - } - } - - void exact_lut_network_enu() { - // the DAG topology family of r nodes and k levels - // initialization - int num_node = input - 1; // first, number of node is number of input - 1 - int num_level = 2; - while (1) { - vector> lut; - create_dags(lut, num_node, num_level); - - if (lut.empty()) { - if (num_level <= num_node) { - num_level += 1; - } - if (num_level > num_node) { - num_level = 2; - num_node += 1; - } - continue; - } - // AllSAT solving to judge the DAGs - stp_simulate_enu(lut); - if (lut.size()) { - vector result_final; - for (int i = 0; i < lut.size(); i++) { - string result; - for (int j = 0; j < lut[i].size(); j++) { - result += to_string(lut[i][j].node); - result += " = 4'b"; - result += lut[i][j].tt; - result += " ("; - if (lut[i][j].left <= input) { - char temp; - temp = 'a' + lut[i][j].left - 1; - result.push_back(temp); - } else { - result += to_string(lut[i][j].left); - } - result += ", "; - if (lut[i][j].right <= input) { - char temp; - temp = 'a' + lut[i][j].right - 1; - result.push_back(temp); - } else { - result += to_string(lut[i][j].right); - } - result += ") "; - } - result_final.push_back(result); - } - tt.assign(result_final.begin(), result_final.end()); - break; - } else { - if (num_level <= num_node) { - num_level += 1; - } - if (num_level > num_node) { - num_level = 2; - num_node += 1; - } - } - } - } - - void create_dags(vector>& lut_dags, int node, int level) { - dag lut_dag_init; - lut_dag_init.node = node; - lut_dag_init.level = level; - lut_dag_init.count.resize(level + 1, 1); - lut_dag_init.count[0] = input; - int numnodes = node - level; - int numlevels = level - 1; - vector> q; - if (numlevels > 0) { - if (numnodes == 0) { - vector> lut_dags_temp; - bench_dag(lut_dag_init, lut_dags_temp); - lut_dags.insert(lut_dags.end(), lut_dags_temp.begin(), - lut_dags_temp.end()); - } else { - dag_classify(q, numnodes, numlevels); - for (int i = 0; i < q.size(); i++) { - dag lut_dag_temp = lut_dag_init; - for (int j = 1, k = 0; j < level; j++, k++) { - lut_dag_temp.count[j] += q[i][k]; - } - judge_dag(lut_dag_temp); - if (lut_dag_temp.count.size() != 0) { - vector> lut_dags_temp; - bench_dag(lut_dag_temp, lut_dags_temp); - lut_dags.insert(lut_dags.end(), lut_dags_temp.begin(), - lut_dags_temp.end()); - } - } - } - } - } - - void dag_classify(vector>& result, int numnodes, int numlevels) { - int q[numlevels]; - int x = numnodes; - int j; - for (int i = 0; i < numlevels; i++) { - q[i] = 0; - } - while (1) { - j = 0; - q[0] = x; - while (1) { - vector result_temp; - for (int i = numlevels - 1; i >= 0; i--) { - result_temp.push_back(q[i]); - } - result.push_back(result_temp); - if (j == 0) { - x = q[0] - 1; - j = 1; - } else if (q[0] == 0) { - x = q[j] - 1; - q[j] = 0; - j++; - } - if (j >= numlevels) { - return; - } else if (q[j] == numnodes) { - x = x + numlevels; - q[j] = 0; - j++; - if (j >= numlevels) { - return; - } - } - q[j]++; - if (x == 0) { - q[0] = 0; - continue; - } else { - break; - } - } - } - } - - void judge_dag(dag& lut_dag) { - for (int i = 0; i < lut_dag.count.size(); i++) { - int sum = - accumulate(lut_dag.count.begin() + i + 1, lut_dag.count.end(), 0); - if (lut_dag.count[i] - 1 > sum) { - lut_dag.count.clear(); - break; - } - } - } - - void bench_dag(dag lut_dag, vector>& lut_dags) { - int sum = 0, level_temp = 0, self_temp = 1; - // 第一个for循环 - // 通过lut_dag的count,初始化lut_dag的lut - // 编号每一个节点,并且将其放置在对应的层中 - // 每一层就是lut的层 - for (int i = 0; i < lut_dag.count.size(); i++, level_temp++) { - vector node_vec; - sum += lut_dag.count[i]; - for (; self_temp < sum + 1; self_temp++) { - node_inf node; - node.num = self_temp; - node.level = level_temp; - if (self_temp <= lut_dag.count[0]) { - node.fan_in = 1; - } else if (i == lut_dag.count.size() - 1) { - node.fan_out = 1; - } - node_vec.push_back(node); - } - lut_dag.lut.push_back(node_vec); - } - - /* - cout << "node information : " << endl; - for (auto x : lut_dag.lut) - { - for (auto y : x) - { - cout << y.num << " " << y.level << " " << y.fan_in << " " << - y.fan_out << endl; - } - } - */ - - // 第二个for循环 - // 生成所有满足的DAG结构 - for (int i = lut_dag.lut.size() - 1; i >= 0; i--) { - vector lut_dags_mid; - vector permutation; - // 第2.1个for循环 - // 从lut的最上层开始向下进行遍历 - // 若为输出节点,则直接构造节点,不排列组合并放入结果中 - // 若为输入节点,不构造,直接进行排列组合(permutation) - // 否则,先构造,再排列组合 - for (int j = lut_dag.lut[i].size() - 1; j >= 0; j--) { - if (lut_dag.lut[i][j].fan_out) { - bench LUT_fanout; - LUT_fanout.node = lut_dag.lut[i][j].num; - vector lut_dags_fanout; - lut_dags_fanout.push_back(LUT_fanout); - lut_dags.push_back(lut_dags_fanout); - } else if (lut_dag.lut[i][j].fan_in) { - permutation.push_back(lut_dag.lut[i][j].num); - } else { - bench LUT_mid; - LUT_mid.node = lut_dag.lut[i][j].num; - lut_dags_mid.push_back(LUT_mid); - permutation.push_back(lut_dag.lut[i][j].num); - } - } - // 排列组合算法 - // 仅针对中间节点进行排列组合 - if (permutation.size()) { - vector> lut_dags_result; - // 第2.2个for循环 - // 遍历已存在的所有结果(lut_dags) - for (int k = 0; k < lut_dags.size(); k++) { - vector lut_dags_rst_temp; // 尚未满足的节点 - vector lut_dags_rst; // 已满足的节点 - vector count; - // 第2.2.1个for循环 - // 为排列组合做准备 - // 判断还有哪些节点未填满,并确定剩余空间 - for (int l = 0; l < lut_dags[k].size(); l++) { - if (lut_dags[k][l].left == 0 || lut_dags[k][l].right == 0) { - int space_temp = 0; - if (lut_dags[k][l].right == 0) { - space_temp += 1; - } - if (lut_dags[k][l].left == 0) { - space_temp += 1; - } - count.push_back(space_temp); - lut_dags_rst_temp.push_back(lut_dags[k][l]); - } else { - lut_dags_rst.push_back(lut_dags[k][l]); - } - } - vector> result; - int numnodes = permutation.size(); - int space = accumulate(count.begin(), count.end(), 0); - if (space == numnodes) { - vector> result_temp; - dag_generate_complete(result, result_temp, permutation, count, 0); - } else if (space < numnodes) { - result.clear(); - } else { - vector> result_temp; - dag_generate_uncomplete(result, result_temp, permutation, - permutation, count, 0); - } - // result有结果 - if (result.size()) { - if (i == 0) { - for (int m = 0; m < result.size(); m++) { - bool target = 1; - vector result_temp1; - int n2 = 0; - for (int n1 = 0; n1 < lut_dags_rst_temp.size(); n1++) { - bench result_temp_temp = lut_dags_rst_temp[n1]; - if (result_temp_temp.left == 0 && - result_temp_temp.right == 0) { - if (result[m][n2] != 0) { - result_temp_temp.left = result[m][n2]; - } else { - target = 0; - } - if (result[m][n2 + 1] != 0) { - result_temp_temp.right = result[m][n2 + 1]; - } else { - target = 0; - } - n2 += 2; - } else if (result_temp_temp.left == 0 && - result_temp_temp.right != 0) { - if (result[m][n2] != 0) { - result_temp_temp.left = result[m][n2]; - } else { - target = 0; - } - n2 += 1; - } - if (!target) { - break; - } - result_temp1.push_back(result_temp_temp); - } - if (target) { - if (lut_dags_mid.size()) { - result_temp1.insert(result_temp1.end(), - lut_dags_mid.begin(), - lut_dags_mid.end()); - } - if (lut_dags_rst.size()) { - result_temp1.insert(result_temp1.begin(), - lut_dags_rst.begin(), - lut_dags_rst.end()); - } - lut_dags_result.push_back(result_temp1); - } - } - } else { - for (int m = 0; m < result.size(); m++) { - vector result_temp1; - int n2 = 0; - for (int n1 = 0; n1 < lut_dags_rst_temp.size(); n1++) { - bench result_temp_temp = lut_dags_rst_temp[n1]; - if (result_temp_temp.left == 0 && - result_temp_temp.right == 0) { - result_temp_temp.left = result[m][n2]; - result_temp_temp.right = result[m][n2 + 1]; - n2 += 2; - } else if (result_temp_temp.left == 0 && - result_temp_temp.right != 0) { - result_temp_temp.left = result[m][n2]; - n2 += 1; - } - result_temp1.push_back(result_temp_temp); - } - if (lut_dags_mid.size()) { - result_temp1.insert(result_temp1.end(), lut_dags_mid.begin(), - lut_dags_mid.end()); - } - if (lut_dags_rst.size()) { - result_temp1.insert(result_temp1.begin(), - lut_dags_rst.begin(), lut_dags_rst.end()); - } - lut_dags_result.push_back(result_temp1); - } - } - } - } - lut_dags.assign(lut_dags_result.begin(), lut_dags_result.end()); - } - } - } - - void LUT_classify(vector>& result, int numnodes, int numlevels) { - int q[numlevels]; - int x = numnodes; - int j; - for (int i = 0; i < numlevels; i++) { - q[i] = 0; - } - - while (1) { - j = 0; - q[0] = x; - while (1) { - vector result_temp; - bool target = 0; - for (int i = numlevels - 1; i >= 0; i--) { - result_temp.push_back(q[i]); - if (q[i] > 2) { - target = 1; - } - } - if (!target) { - result.push_back(result_temp); - } - if (j == 0) { - x = q[0] - 1; - j = 1; - } else if (q[0] == 0) { - x = q[j] - 1; - q[j] = 0; - j++; - } - if (j >= numlevels) { - return; - } else if (q[j] == numnodes) { - x = x + numlevels; - q[j] = 0; - j++; - if (j >= numlevels) { - return; - } - } - q[j]++; - if (x == 0) { - q[0] = 0; - continue; - } else { - break; - } - } - } - } - - void dag_generate_complete(vector>& result, - vector>& rst, vector permutation, - vector count, int level) { - vector> result_temp; - vector q(count[level]); - combinate(0, 0, permutation.size(), count[level], permutation, q, - result_temp); - for (int j = 0; j < result_temp.size(); j++) { - vector elected(permutation); - vector result_1; - for (int k = 0; k < result_temp[j].size(); k++) { - result_1.push_back(result_temp[j][k]); - if (level + 1 < count.size()) { - // 从vector中删除指定的某一个元素 - for (vector::iterator iter = elected.begin(); - iter != elected.end(); iter++) { - if (*iter == result_temp[j][k]) { - elected.erase(iter); - break; - } - } - } - } - sort(result_1.begin(), result_1.end()); - if (level + 1 < count.size()) { - vector> rst_temp; - dag_generate_complete(result, rst_temp, elected, count, level + 1); - for (int l = 0; l < rst_temp.size(); l++) { - vector result_2(result_1); - result_2.insert(result_2.end(), rst_temp[l].begin(), - rst_temp[l].end()); - rst.push_back(result_2); - } - } else { - rst.push_back(result_1); - } - - if (level == 0) { - result.insert(result.end(), rst.begin(), rst.end()); - rst.clear(); - } - } - } - - void dag_generate_uncomplete(vector>& result, - vector>& rst, - vector permutation_f, - vector permutation_b, vector count, - int level) { - vector> result_temp2; - for (int i = 0; i <= count[level]; i++) { - vector> result_temp; - vector q(count[level]); - combinate(0, 0, permutation_f.size(), i, permutation_f, q, result_temp); - result_temp2.insert(result_temp2.end(), result_temp.begin(), - result_temp.end()); - } - for (int j = 0; j < result_temp2.size(); j++) { - vector permutation_b_b(permutation_b); - vector result_1; - for (int k = 0; k < result_temp2[j].size(); k++) { - result_1.push_back(result_temp2[j][k]); - // 从vector中删除指定的某一个元素 - for (vector::iterator iter = permutation_b_b.begin(); - iter != permutation_b_b.end(); iter++) { - if (*iter == result_temp2[j][k]) { - permutation_b_b.erase(iter); - break; - } - } - } - sort(result_1.begin(), result_1.end()); - if (level + 1 < count.size()) { - vector> rst_temp; - dag_generate_uncomplete(result, rst_temp, permutation_f, - permutation_b_b, count, level + 1); - for (int l = 0; l < rst_temp.size(); l++) { - vector result_2(result_1); - result_2.insert(result_2.end(), rst_temp[l].begin(), - rst_temp[l].end()); - rst.push_back(result_2); - } - } else { - if (!permutation_b_b.size()) { - rst.push_back(result_1); - } - } - if (level == 0) { - result.insert(result.end(), rst.begin(), rst.end()); - rst.clear(); - } - } - } - - void combinate(int iPos, int iProc, int numnodes, int numlevels, - vector data, vector des, - vector>& result) { - if (iProc > numnodes) { - return; - } - if (iPos == numlevels) { - result.push_back(des); - return; - } else { - combinate(iPos, iProc + 1, numnodes, numlevels, data, des, result); - des[iPos] = data[iProc]; - combinate(iPos + 1, iProc + 1, numnodes, numlevels, data, des, result); - } - } - - void stp_simulate(vector>& lut_dags) { - string tt_binary = tt[0]; - int flag_node = lut_dags[0][lut_dags[0].size() - 1].node; - vector> lut_dags_new; - for (int i = lut_dags.size() - 1; i >= 0; i--) { - string input_tt(tt_binary); - - vector matrix_form = chain_to_matrix(lut_dags[i], flag_node); - matrix_computution(matrix_form); - - vector bench_result; - result_lut first_result; - first_result.computed_input = input_tt; - first_result.possible_result = lut_dags[i]; - bench_result.push_back(first_result); - for (int l = matrix_form.size() - 1; l >= 1; l--) { - int length_string = input_tt.size(); - if (matrix_form[l].input == 0) { - if (matrix_form[l].name == "W") { - if (matrix_form[l].eye == 0) { - string temp1, temp2; - temp1 = input_tt.substr(length_string / 4, length_string / 4); - temp2 = input_tt.substr(length_string / 2, length_string / 4); - input_tt.replace(length_string / 4, length_string / 4, temp2); - input_tt.replace(length_string / 2, length_string / 4, temp1); - } else { - int length2 = length_string / pow(2.0, matrix_form[l].eye + 2); - for (int l1 = pow(2.0, matrix_form[l].eye), add = 1; l1 > 0; - l1--) { - string temp1, temp2; - temp1 = input_tt.substr( - (length_string / pow(2.0, matrix_form[l].eye + 1)) * add - - length2, - length2); - temp2 = input_tt.substr( - (length_string / pow(2.0, matrix_form[l].eye + 1)) * add, - length2); - input_tt.replace( - (length_string / pow(2.0, matrix_form[l].eye + 1)) * add - - length2, - length2, temp2); - input_tt.replace( - (length_string / pow(2.0, matrix_form[l].eye + 1)) * add, - length2, temp1); - add += 2; - } - } - bench_result[0].computed_input = input_tt; - } else if (matrix_form[l].name == "R") { - if (matrix_form[l].eye == 0) { - string temp(length_string, '2'); - input_tt.insert(input_tt.begin() + (length_string / 2), - temp.begin(), temp.end()); - } else { - string temp(length_string / pow(2.0, matrix_form[l].eye), '2'); - for (int l2 = pow(2.0, matrix_form[l].eye), - add1 = pow(2.0, matrix_form[l].eye + 1) - 1; - l2 > 0; l2--) { - input_tt.insert( - input_tt.begin() + - ((length_string / pow(2.0, matrix_form[l].eye + 1)) * - add1), - temp.begin(), temp.end()); - add1 -= 2; - } - } - bench_result[0].computed_input = input_tt; - } else if (matrix_form[l].name == "M") { - vector bench_result_temp; - for (int q = bench_result.size() - 1; q >= 0; q--) { - int length_string2 = bench_result[q].computed_input.size(); - int length1 = length_string2 / - pow(2.0, matrix_form[l].eye + 2); // abcd的长度 - string standard(length1, '2'); - vector standard_int(4, 0); - vector> result; - - for (int l3 = 0; l3 < pow(2.0, matrix_form[l].eye); l3++) { - vector> result_t; - - int ind = (length_string2 / pow(2.0, matrix_form[l].eye)) * l3; - string a = bench_result[q].computed_input.substr(ind, length1); - string b = bench_result[q].computed_input.substr(ind + length1, - length1); - string c = bench_result[q].computed_input.substr( - ind + (2 * length1), length1); - string d = bench_result[q].computed_input.substr( - ind + (3 * length1), length1); - - if (a != standard) { - vector result_temp(4); // size为4的可能结果 - result_temp[0] = 0; // a=0 - if (compare_string(a, b)) // b=a - { - if (b == standard) - result_temp[1] = 2; - else - result_temp[1] = 0; // b=0 - if (compare_string(a, c) && - compare_string(b, c)) // c=(b=a) - { - if (c == standard) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - if (compare_string(a, d) && compare_string(b, d) && - compare_string(c, d)) // d=(c=b=a) - { - result_temp[0] = 2; - result_temp[1] = 2; - result_temp[2] = 2; - result_temp[3] = 2; - } else // d!=(c=b=a) - { - result_temp[3] = 1; // d=1 - if (compare_string(b, d)) result_temp[1] = 2; - if (compare_string(c, d)) result_temp[2] = 2; - } - } else // c!=(b=a) - { - result_temp[2] = 1; // c=1 - if (compare_string(b, c)) result_temp[1] = 2; - if (compare_string(a, d) && - compare_string(b, d)) // d=(b=a) - { - if (d == standard || compare_string(c, d)) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(c, d)) // d=c - { - result_temp[3] = 1; // d=1 - if (compare_string(b, d)) result_temp[1] = 2; - } else // 其他 - break; - } - } else // b!=a - { - result_temp[1] = 1; // b=1 - if (compare_string(a, c)) // c=a - { - if (c == standard || compare_string(b, c)) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - if (compare_string(a, d) && - compare_string(c, d)) // d=(c=a) - { - if (d == standard || compare_string(b, d)) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(b, d)) // d=b - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else if (compare_string(b, c)) // c=b - { - result_temp[2] = 1; // c=1 - if (compare_string(a, d)) // d=a - { - if (d == standard || - (compare_string(b, d) && compare_string(c, d))) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(b, d) && - compare_string(c, d)) // d=(c=b) - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else // 其他 - break; - } - if (result_t.empty()) - vector_generate(result_temp, result_t); - else { - vector> result_t_temp; - vector_generate(result_temp, result_t_temp); - for (int j = result_t.size() - 1; j >= 0; j--) { - for (int k = result_t_temp.size() - 1; k >= 0; k--) { - if (compare_vector(result_t[j], result_t_temp[k])) - result_t_temp.erase(result_t_temp.begin() + k); - } - } - if (!result_t_temp.empty()) { - result_t.insert(result_t.end(), result_t_temp.begin(), - result_t_temp.end()); - } - } - } - if (b != standard) { - vector result_temp(4); // size为4的可能结果 - result_temp[1] = 0; // b=0 - if (compare_string(a, b)) // a=b - { - if (a == standard) - result_temp[0] = 2; - else - result_temp[0] = 0; // a=0 - if (compare_string(a, c) && - compare_string(b, c)) // c=(a=b) - { - if (c == standard) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - if (compare_string(a, d) && compare_string(b, d) && - compare_string(c, d)) // d=(c=a=b) - { - result_temp[0] = 2; - result_temp[1] = 2; - result_temp[2] = 2; - result_temp[3] = 2; - } else // d!=(c=a=b) - { - result_temp[3] = 1; // d=1 - if (compare_string(a, d)) result_temp[0] = 2; - if (compare_string(c, d)) result_temp[2] = 2; - } - } else // c!=(a=b) - { - result_temp[2] = 1; // c=1 - if (compare_string(a, c)) result_temp[0] = 2; - if (compare_string(a, d) && - compare_string(b, d)) // d=(a=b) - { - if (d == standard || compare_string(c, d)) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(c, d)) // d=c - { - result_temp[3] = 1; // d=1 - if (compare_string(a, d)) result_temp[0] = 2; - } else // 其他 - break; - } - } else // a!=b - { - result_temp[0] = 1; // a=1 - if (compare_string(c, b)) // c=b - { - if (c == standard || compare_string(a, c)) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - if (compare_string(b, d) && - compare_string(c, d)) // d=(c=b) - { - if (d == standard || compare_string(a, d)) - result_temp[3] = 2; // d=0 - else - result_temp[3] = 0; // d=0 - } else if (compare_string(a, d)) // d=a - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else if (compare_string(a, c)) // c=a - { - result_temp[2] = 1; // c=1 - if (compare_string(b, d)) // d=b - { - if (d == standard || - (compare_string(a, d) && compare_string(c, d))) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(a, d) && - compare_string(c, d)) // d=(c=a) - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else // 其他 - break; - } - if (result_t.empty()) - vector_generate(result_temp, result_t); - else { - vector> result_t_temp; - vector_generate(result_temp, result_t_temp); - for (int j = result_t.size() - 1; j >= 0; j--) { - for (int k = result_t_temp.size() - 1; k >= 0; k--) { - if (compare_vector(result_t[j], result_t_temp[k])) - result_t_temp.erase(result_t_temp.begin() + k); - } - } - if (!result_t_temp.empty()) { - result_t.insert(result_t.end(), result_t_temp.begin(), - result_t_temp.end()); - } - } - } - if (c != standard) { - vector result_temp(4); // size为4的可能结果 - result_temp[2] = 0; // c=0 - if (compare_string(a, c)) // a=c - { - if (a == standard) - result_temp[0] = 2; - else - result_temp[0] = 0; // a=0 - if (compare_string(b, c) && - compare_string(b, a)) // b=(a=c) - { - if (b == standard) - result_temp[1] = 2; - else - result_temp[1] = 0; // b=0 - if (compare_string(a, d) && compare_string(b, d) && - compare_string(c, d)) // d=(b=a=c) - { - result_temp[0] = 2; - result_temp[1] = 2; - result_temp[2] = 2; - result_temp[3] = 2; - } else // d!=(b=a=c) - { - result_temp[3] = 1; // d=1 - if (compare_string(a, d)) result_temp[0] = 2; - if (compare_string(b, d)) result_temp[1] = 2; - } - } else // b!=(a=c) - { - result_temp[1] = 1; // b=1 - if (compare_string(a, b)) result_temp[0] = 2; - if (compare_string(a, d) && - compare_string(c, d)) // d=(a=c) - { - if (d == standard || compare_string(b, d)) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(b, d)) // d=b - { - result_temp[3] = 1; // d=1 - if (compare_string(a, d)) result_temp[0] = 2; - } else // 其他 - break; - } - } else // a!=c - { - result_temp[0] = 1; // a=1 - if (compare_string(b, c)) // b=c - { - if (b == standard || compare_string(b, a)) - result_temp[1] = 2; - else - result_temp[1] = 0; // b=0 - if (compare_string(b, d) && - compare_string(c, d)) // d=(b=c) - { - if (d == standard || compare_string(a, d)) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(a, d)) // d=a - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else if (compare_string(a, b)) // b=a - { - result_temp[1] = 1; // b=1 - if (compare_string(c, d)) // d=c - { - if (d == standard || - (compare_string(a, d) && compare_string(b, d))) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(a, d) && - compare_string(b, d)) // d=(b=a) - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else // 其他 - break; - } - if (result_t.empty()) - vector_generate(result_temp, result_t); - else { - vector> result_t_temp; - vector_generate(result_temp, result_t_temp); - for (int j = result_t.size() - 1; j >= 0; j--) { - for (int k = result_t_temp.size() - 1; k >= 0; k--) { - if (compare_vector(result_t[j], result_t_temp[k])) - result_t_temp.erase(result_t_temp.begin() + k); - } - } - if (!result_t_temp.empty()) { - result_t.insert(result_t.end(), result_t_temp.begin(), - result_t_temp.end()); - } - } - } - if (d != standard) { - vector result_temp(4); // size为4的可能结果 - result_temp[3] = 0; // d=0 - if (compare_string(a, d)) // a=d - { - if (a == standard) - result_temp[0] = 2; - else - result_temp[0] = 0; // a=0 - if (compare_string(b, a) && - compare_string(b, d)) // b=(a=d) - { - if (b == standard) - result_temp[1] = 2; - else - result_temp[1] = 0; // b=0 - if (compare_string(a, c) && compare_string(b, c) && - compare_string(d, c)) // c=(b=a=d) - { - result_temp[0] = 2; - result_temp[1] = 2; - result_temp[2] = 2; - result_temp[3] = 2; - } else // c!=(b=a=d) - { - result_temp[2] = 1; // c=1 - if (compare_string(a, c)) result_temp[0] = 2; - if (compare_string(b, c)) result_temp[1] = 2; - } - } else // b!=(a=d) - { - result_temp[1] = 1; // b=1 - if (compare_string(a, b)) result_temp[0] = 2; - if (compare_string(c, a) && - compare_string(c, d)) // c=(a=d) - { - if (c == standard || compare_string(c, b)) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - } else if (compare_string(c, b)) // c=b - { - result_temp[2] = 1; // c=1 - if (compare_string(a, c)) result_temp[0] = 2; - } else // 其他 - break; - } - } else // a!=d - { - result_temp[0] = 1; // a=1 - if (compare_string(b, d)) // b=d - { - if (b == standard || compare_string(b, a)) - result_temp[1] = 2; - else - result_temp[1] = 0; // b=0 - if (compare_string(c, d) && - compare_string(c, b)) // c=(b=d) - { - if (c == standard || compare_string(c, a)) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - } else if (compare_string(c, a)) // c=a - result_temp[2] = 1; // c=1 - else // 其他 - break; - } else if (compare_string(b, a)) // b=a - { - result_temp[1] = 1; // b=1 - if (compare_string(c, d)) // c=d - { - if (c == standard || - (compare_string(a, c) && compare_string(b, c))) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - } else if (compare_string(c, a) && - compare_string(c, b)) // c=(b=a) - result_temp[2] = 1; // c=1 - else // 其他 - break; - } else // 其他 - break; - } - if (result_t.empty()) - vector_generate(result_temp, result_t); - else { - vector> result_t_temp; - vector_generate(result_temp, result_t_temp); - for (int j = result_t.size() - 1; j >= 0; j--) { - for (int k = result_t_temp.size() - 1; k >= 0; k--) { - if (compare_vector(result_t[j], result_t_temp[k])) - result_t_temp.erase(result_t_temp.begin() + k); - } - } - if (!result_t_temp.empty()) { - result_t.insert(result_t.end(), result_t_temp.begin(), - result_t_temp.end()); - } - } - } - if (result.empty()) - result.assign(result_t.begin(), result_t.end()); - else { - for (int j = result.size() - 1; j >= 0; j--) { - if (result[j] == standard_int) { - result.assign(result_t.begin(), result_t.end()); - break; - } else { - bool target1 = 0, target2 = 0; - for (int k = result_t.size() - 1; k >= 0; k--) { - if (result_t[k] == standard_int) { - target1 = 1; - break; - } else { - if (compare_vector(result_t[k], result[j])) { - target2 = 1; - break; - } - } - } - if (target1) break; - if (!target2) result.erase(result.begin() + j); - } - } - if (result.empty()) break; - } - } - if (result.empty()) { - bench_result.erase(bench_result.begin() + q); - continue; - } else { - for (int m = 0; m < result.size(); m++) { - string count1, count2; - string res1, res2; - for (int n = 0; n < result[m].size(); n++) { - if (result[m][n] == 0) { - count1 += "1"; - count2 += "0"; - } else { - count1 += "0"; - count2 += "1"; - } - } - if (count1 == "0000" || count1 == "1111" || - count2 == "0000" || count2 == "1111") - continue; - for (int n = 0; n < pow(2.0, matrix_form[l].eye); n++) { - string s1(2 * length1, '2'); - string s2(2 * length1, '2'); - int ind = - (length_string2 / pow(2.0, matrix_form[l].eye)) * n; - string a, b, c, d; - a = bench_result[q].computed_input.substr(ind, length1); - b = bench_result[q].computed_input.substr(ind + length1, - length1); - c = bench_result[q].computed_input.substr( - ind + (length1 * 2), length1); - d = bench_result[q].computed_input.substr( - ind + (length1 * 3), length1); - - if (count1[0] == '0') { - if (s1.substr(length1, length1) == standard) - s1.replace(length1, length1, a); - } else { - if (s1.substr(0, length1) == standard) - s1.replace(0, length1, a); - } - if (count1[1] == '0') { - if (s1.substr(length1, length1) == standard) - s1.replace(length1, length1, b); - } else { - if (s1.substr(0, length1) == standard) - s1.replace(0, length1, b); - } - if (count1[2] == '0') { - if (s1.substr(length1, length1) == standard) - s1.replace(length1, length1, c); - } else { - if (s1.substr(0, length1) == standard) - s1.replace(0, length1, c); - } - if (count1[3] == '0') { - if (s1.substr(length1, length1) == standard) - s1.replace(length1, length1, d); - } else { - if (s1.substr(0, length1) == standard) - s1.replace(0, length1, d); - } - - if (count2[0] == '0') { - if (s2.substr(length1, length1) == standard) - s2.replace(length1, length1, a); - } else { - if (s2.substr(0, length1) == standard) - s2.replace(0, length1, a); - } - if (count2[1] == '0') { - if (s2.substr(length1, length1) == standard) - s2.replace(length1, length1, b); - } else { - if (s2.substr(0, length1) == standard) - s2.replace(0, length1, b); - } - if (count2[2] == '0') { - if (s2.substr(length1, length1) == standard) - s2.replace(length1, length1, c); - } else { - if (s2.substr(0, length1) == standard) - s2.replace(0, length1, c); - } - if (count2[3] == '0') { - if (s2.substr(length1, length1) == standard) - s2.replace(length1, length1, d); - } else { - if (s2.substr(0, length1) == standard) - s2.replace(0, length1, d); - } - res1 += s1; - res2 += s2; - } - result_lut result_temp_1, result_temp_2; - result_temp_1.possible_result = - bench_result[q].possible_result; - result_temp_2.possible_result = - bench_result[q].possible_result; - for (int p = 0; p < result_temp_1.possible_result.size(); - p++) { - if (result_temp_1.possible_result[p].node == - matrix_form[l].node) - result_temp_1.possible_result[p].tt = count1; - if (result_temp_2.possible_result[p].node == - matrix_form[l].node) - result_temp_2.possible_result[p].tt = count2; - } - if (res1.size() == 4) { - for (int p = 0; p < result_temp_1.possible_result.size(); - p++) { - if (result_temp_1.possible_result[p].node == - matrix_form[0].node) - result_temp_1.possible_result[p].tt = res1; - if (result_temp_2.possible_result[p].node == - matrix_form[0].node) - result_temp_2.possible_result[p].tt = res2; - } - } else { - result_temp_1.computed_input = res1; - result_temp_2.computed_input = res2; - } - - bench_result_temp.push_back(result_temp_1); - bench_result_temp.push_back(result_temp_2); - } - } - } - if (bench_result_temp.empty()) - break; - else - bench_result.assign(bench_result_temp.begin(), - bench_result_temp.end()); - } - } - } - - for (int j = bench_result.size() - 1; j >= 0; j--) { - vector> mtxvec; - vector mtx1, mtx2; - vector in; - for (int k = bench_result[j].possible_result.size() - 1; k >= 0; k--) { - vector mtxvec_temp; - in.push_back(bench_result[j].possible_result[k].tt); - mtxvec_temp.push_back(bench_result[j].possible_result[k].left); - mtxvec_temp.push_back(bench_result[j].possible_result[k].right); - mtxvec_temp.push_back(bench_result[j].possible_result[k].node); - mtxvec.push_back(mtxvec_temp); - } - in.push_back("10"); - mtx1.push_back(bench_result[j].possible_result[0].node); - mtx2.push_back(input); - mtx2.push_back(1); - mtxvec.push_back(mtx1); - mtxvec.push_back(mtx2); - vector> in_expansion = bench_expansion(in); - vector bench_temp; - for (int k = in_expansion.size() - 1; k >= 0; k--) { - string tt_temp = in_expansion[k][in_expansion[k].size() - 2]; - bench_solve(in_expansion[k], mtxvec); - if (!compare_result(in_expansion[k], tt_binary)) { - in_expansion.erase(in_expansion.begin() + k); - } else { - result_lut bench_temp_temp = bench_result[j]; - bench_temp_temp.possible_result[0].tt = tt_temp; - bench_temp.push_back(bench_temp_temp); - } - } - if (in_expansion.empty()) - bench_result.erase(bench_result.begin() + j); - else { - bench_result.erase(bench_result.begin() + j); - bench_result.insert(bench_result.end(), bench_temp.begin(), - bench_temp.end()); - } - } - - if (bench_result.size()) { - for (int j = 0; j < bench_result.size(); j++) - lut_dags_new.push_back(bench_result[j].possible_result); - break; - } - } - lut_dags.assign(lut_dags_new.begin(), lut_dags_new.end()); - } - - void stp_simulate_enu(vector>& lut_dags) { - string tt_binary = tt[0]; - int flag_node = lut_dags[0][lut_dags[0].size() - 1].node; - vector> lut_dags_new; - for (int i = lut_dags.size() - 1; i >= 0; i--) { - string input_tt(tt_binary); - - vector matrix_form = chain_to_matrix(lut_dags[i], flag_node); - matrix_computution(matrix_form); - - vector bench_result; - result_lut first_result; - first_result.computed_input = input_tt; - first_result.possible_result = lut_dags[i]; - bench_result.push_back(first_result); - for (int l = matrix_form.size() - 1; l >= 1; l--) { - int length_string = input_tt.size(); - if (matrix_form[l].input == 0) { - if (matrix_form[l].name == "W") { - if (matrix_form[l].eye == 0) { - string temp1, temp2; - temp1 = input_tt.substr(length_string / 4, length_string / 4); - temp2 = input_tt.substr(length_string / 2, length_string / 4); - input_tt.replace(length_string / 4, length_string / 4, temp2); - input_tt.replace(length_string / 2, length_string / 4, temp1); - } else { - int length2 = length_string / pow(2.0, matrix_form[l].eye + 2); - for (int l1 = pow(2.0, matrix_form[l].eye), add = 1; l1 > 0; - l1--) { - string temp1, temp2; - temp1 = input_tt.substr( - (length_string / pow(2.0, matrix_form[l].eye + 1)) * add - - length2, - length2); - temp2 = input_tt.substr( - (length_string / pow(2.0, matrix_form[l].eye + 1)) * add, - length2); - input_tt.replace( - (length_string / pow(2.0, matrix_form[l].eye + 1)) * add - - length2, - length2, temp2); - input_tt.replace( - (length_string / pow(2.0, matrix_form[l].eye + 1)) * add, - length2, temp1); - add += 2; - } - } - bench_result[0].computed_input = input_tt; - } else if (matrix_form[l].name == "R") { - if (matrix_form[l].eye == 0) { - string temp(length_string, '2'); - input_tt.insert(input_tt.begin() + (length_string / 2), - temp.begin(), temp.end()); - } else { - string temp(length_string / pow(2.0, matrix_form[l].eye), '2'); - for (int l2 = pow(2.0, matrix_form[l].eye), - add1 = pow(2.0, matrix_form[l].eye + 1) - 1; - l2 > 0; l2--) { - input_tt.insert( - input_tt.begin() + - ((length_string / pow(2.0, matrix_form[l].eye + 1)) * - add1), - temp.begin(), temp.end()); - add1 -= 2; - } - } - bench_result[0].computed_input = input_tt; - } else if (matrix_form[l].name == "M") { - vector bench_result_temp; - for (int q = bench_result.size() - 1; q >= 0; q--) { - int length_string2 = bench_result[q].computed_input.size(); - int length1 = length_string2 / - pow(2.0, matrix_form[l].eye + 2); // abcd的长度 - string standard(length1, '2'); - vector standard_int(4, 0); - vector> result; - - for (int l3 = 0; l3 < pow(2.0, matrix_form[l].eye); l3++) { - vector> result_t; - - int ind = (length_string2 / pow(2.0, matrix_form[l].eye)) * l3; - string a = bench_result[q].computed_input.substr(ind, length1); - string b = bench_result[q].computed_input.substr(ind + length1, - length1); - string c = bench_result[q].computed_input.substr( - ind + (2 * length1), length1); - string d = bench_result[q].computed_input.substr( - ind + (3 * length1), length1); - - if (a != standard) { - vector result_temp(4); // size为4的可能结果 - result_temp[0] = 0; // a=0 - if (compare_string(a, b)) // b=a - { - if (b == standard) - result_temp[1] = 2; - else - result_temp[1] = 0; // b=0 - if (compare_string(a, c) && - compare_string(b, c)) // c=(b=a) - { - if (c == standard) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - if (compare_string(a, d) && compare_string(b, d) && - compare_string(c, d)) // d=(c=b=a) - { - result_temp[0] = 2; - result_temp[1] = 2; - result_temp[2] = 2; - result_temp[3] = 2; - } else // d!=(c=b=a) - { - result_temp[3] = 1; // d=1 - if (compare_string(b, d)) result_temp[1] = 2; - if (compare_string(c, d)) result_temp[2] = 2; - } - } else // c!=(b=a) - { - result_temp[2] = 1; // c=1 - if (compare_string(b, c)) result_temp[1] = 2; - if (compare_string(a, d) && - compare_string(b, d)) // d=(b=a) - { - if (d == standard || compare_string(c, d)) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(c, d)) // d=c - { - result_temp[3] = 1; // d=1 - if (compare_string(b, d)) result_temp[1] = 2; - } else // 其他 - break; - } - } else // b!=a - { - result_temp[1] = 1; // b=1 - if (compare_string(a, c)) // c=a - { - if (c == standard || compare_string(b, c)) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - if (compare_string(a, d) && - compare_string(c, d)) // d=(c=a) - { - if (d == standard || compare_string(b, d)) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(b, d)) // d=b - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else if (compare_string(b, c)) // c=b - { - result_temp[2] = 1; // c=1 - if (compare_string(a, d)) // d=a - { - if (d == standard || - (compare_string(b, d) && compare_string(c, d))) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(b, d) && - compare_string(c, d)) // d=(c=b) - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else // 其他 - break; - } - if (result_t.empty()) - vector_generate(result_temp, result_t); - else { - vector> result_t_temp; - vector_generate(result_temp, result_t_temp); - for (int j = result_t.size() - 1; j >= 0; j--) { - for (int k = result_t_temp.size() - 1; k >= 0; k--) { - if (compare_vector(result_t[j], result_t_temp[k])) - result_t_temp.erase(result_t_temp.begin() + k); - } - } - if (!result_t_temp.empty()) { - result_t.insert(result_t.end(), result_t_temp.begin(), - result_t_temp.end()); - } - } - } - if (b != standard) { - vector result_temp(4); // size为4的可能结果 - result_temp[1] = 0; // b=0 - if (compare_string(a, b)) // a=b - { - if (a == standard) - result_temp[0] = 2; - else - result_temp[0] = 0; // a=0 - if (compare_string(a, c) && - compare_string(b, c)) // c=(a=b) - { - if (c == standard) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - if (compare_string(a, d) && compare_string(b, d) && - compare_string(c, d)) // d=(c=a=b) - { - result_temp[0] = 2; - result_temp[1] = 2; - result_temp[2] = 2; - result_temp[3] = 2; - } else // d!=(c=a=b) - { - result_temp[3] = 1; // d=1 - if (compare_string(a, d)) result_temp[0] = 2; - if (compare_string(c, d)) result_temp[2] = 2; - } - } else // c!=(a=b) - { - result_temp[2] = 1; // c=1 - if (compare_string(a, c)) result_temp[0] = 2; - if (compare_string(a, d) && - compare_string(b, d)) // d=(a=b) - { - if (d == standard || compare_string(c, d)) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(c, d)) // d=c - { - result_temp[3] = 1; // d=1 - if (compare_string(a, d)) result_temp[0] = 2; - } else // 其他 - break; - } - } else // a!=b - { - result_temp[0] = 1; // a=1 - if (compare_string(c, b)) // c=b - { - if (c == standard || compare_string(a, c)) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - if (compare_string(b, d) && - compare_string(c, d)) // d=(c=b) - { - if (d == standard || compare_string(a, d)) - result_temp[3] = 2; // d=0 - else - result_temp[3] = 0; // d=0 - } else if (compare_string(a, d)) // d=a - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else if (compare_string(a, c)) // c=a - { - result_temp[2] = 1; // c=1 - if (compare_string(b, d)) // d=b - { - if (d == standard || - (compare_string(a, d) && compare_string(c, d))) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(a, d) && - compare_string(c, d)) // d=(c=a) - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else // 其他 - break; - } - if (result_t.empty()) - vector_generate(result_temp, result_t); - else { - vector> result_t_temp; - vector_generate(result_temp, result_t_temp); - for (int j = result_t.size() - 1; j >= 0; j--) { - for (int k = result_t_temp.size() - 1; k >= 0; k--) { - if (compare_vector(result_t[j], result_t_temp[k])) - result_t_temp.erase(result_t_temp.begin() + k); - } - } - if (!result_t_temp.empty()) { - result_t.insert(result_t.end(), result_t_temp.begin(), - result_t_temp.end()); - } - } - } - if (c != standard) { - vector result_temp(4); // size为4的可能结果 - result_temp[2] = 0; // c=0 - if (compare_string(a, c)) // a=c - { - if (a == standard) - result_temp[0] = 2; - else - result_temp[0] = 0; // a=0 - if (compare_string(b, c) && - compare_string(b, a)) // b=(a=c) - { - if (b == standard) - result_temp[1] = 2; - else - result_temp[1] = 0; // b=0 - if (compare_string(a, d) && compare_string(b, d) && - compare_string(c, d)) // d=(b=a=c) - { - result_temp[0] = 2; - result_temp[1] = 2; - result_temp[2] = 2; - result_temp[3] = 2; - } else // d!=(b=a=c) - { - result_temp[3] = 1; // d=1 - if (compare_string(a, d)) result_temp[0] = 2; - if (compare_string(b, d)) result_temp[1] = 2; - } - } else // b!=(a=c) - { - result_temp[1] = 1; // b=1 - if (compare_string(a, b)) result_temp[0] = 2; - if (compare_string(a, d) && - compare_string(c, d)) // d=(a=c) - { - if (d == standard || compare_string(b, d)) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(b, d)) // d=b - { - result_temp[3] = 1; // d=1 - if (compare_string(a, d)) result_temp[0] = 2; - } else // 其他 - break; - } - } else // a!=c - { - result_temp[0] = 1; // a=1 - if (compare_string(b, c)) // b=c - { - if (b == standard || compare_string(b, a)) - result_temp[1] = 2; - else - result_temp[1] = 0; // b=0 - if (compare_string(b, d) && - compare_string(c, d)) // d=(b=c) - { - if (d == standard || compare_string(a, d)) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(a, d)) // d=a - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else if (compare_string(a, b)) // b=a - { - result_temp[1] = 1; // b=1 - if (compare_string(c, d)) // d=c - { - if (d == standard || - (compare_string(a, d) && compare_string(b, d))) - result_temp[3] = 2; - else - result_temp[3] = 0; // d=0 - } else if (compare_string(a, d) && - compare_string(b, d)) // d=(b=a) - result_temp[3] = 1; // d=1 - else // 其他 - break; - } else // 其他 - break; - } - if (result_t.empty()) - vector_generate(result_temp, result_t); - else { - vector> result_t_temp; - vector_generate(result_temp, result_t_temp); - for (int j = result_t.size() - 1; j >= 0; j--) { - for (int k = result_t_temp.size() - 1; k >= 0; k--) { - if (compare_vector(result_t[j], result_t_temp[k])) - result_t_temp.erase(result_t_temp.begin() + k); - } - } - if (!result_t_temp.empty()) { - result_t.insert(result_t.end(), result_t_temp.begin(), - result_t_temp.end()); - } - } - } - if (d != standard) { - vector result_temp(4); // size为4的可能结果 - result_temp[3] = 0; // d=0 - if (compare_string(a, d)) // a=d - { - if (a == standard) - result_temp[0] = 2; - else - result_temp[0] = 0; // a=0 - if (compare_string(b, a) && - compare_string(b, d)) // b=(a=d) - { - if (b == standard) - result_temp[1] = 2; - else - result_temp[1] = 0; // b=0 - if (compare_string(a, c) && compare_string(b, c) && - compare_string(d, c)) // c=(b=a=d) - { - result_temp[0] = 2; - result_temp[1] = 2; - result_temp[2] = 2; - result_temp[3] = 2; - } else // c!=(b=a=d) - { - result_temp[2] = 1; // c=1 - if (compare_string(a, c)) result_temp[0] = 2; - if (compare_string(b, c)) result_temp[1] = 2; - } - } else // b!=(a=d) - { - result_temp[1] = 1; // b=1 - if (compare_string(a, b)) result_temp[0] = 2; - if (compare_string(c, a) && - compare_string(c, d)) // c=(a=d) - { - if (c == standard || compare_string(c, b)) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - } else if (compare_string(c, b)) // c=b - { - result_temp[2] = 1; // c=1 - if (compare_string(a, c)) result_temp[0] = 2; - } else // 其他 - break; - } - } else // a!=d - { - result_temp[0] = 1; // a=1 - if (compare_string(b, d)) // b=d - { - if (b == standard || compare_string(b, a)) - result_temp[1] = 2; - else - result_temp[1] = 0; // b=0 - if (compare_string(c, d) && - compare_string(c, b)) // c=(b=d) - { - if (c == standard || compare_string(c, a)) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - } else if (compare_string(c, a)) // c=a - result_temp[2] = 1; // c=1 - else // 其他 - break; - } else if (compare_string(b, a)) // b=a - { - result_temp[1] = 1; // b=1 - if (compare_string(c, d)) // c=d - { - if (c == standard || - (compare_string(a, c) && compare_string(b, c))) - result_temp[2] = 2; - else - result_temp[2] = 0; // c=0 - } else if (compare_string(c, a) && - compare_string(c, b)) // c=(b=a) - result_temp[2] = 1; // c=1 - else // 其他 - break; - } else // 其他 - break; - } - if (result_t.empty()) - vector_generate(result_temp, result_t); - else { - vector> result_t_temp; - vector_generate(result_temp, result_t_temp); - for (int j = result_t.size() - 1; j >= 0; j--) { - for (int k = result_t_temp.size() - 1; k >= 0; k--) { - if (compare_vector(result_t[j], result_t_temp[k])) - result_t_temp.erase(result_t_temp.begin() + k); - } - } - if (!result_t_temp.empty()) { - result_t.insert(result_t.end(), result_t_temp.begin(), - result_t_temp.end()); - } - } - } - if (result.empty()) - result.assign(result_t.begin(), result_t.end()); - else { - for (int j = result.size() - 1; j >= 0; j--) { - if (result[j] == standard_int) { - result.assign(result_t.begin(), result_t.end()); - break; - } else { - bool target1 = 0, target2 = 0; - for (int k = result_t.size() - 1; k >= 0; k--) { - if (result_t[k] == standard_int) { - target1 = 1; - break; - } else { - if (compare_vector(result_t[k], result[j])) { - target2 = 1; - break; - } - } - } - if (target1) break; - if (!target2) result.erase(result.begin() + j); - } - } - if (result.empty()) break; - } - } - if (result.empty()) { - bench_result.erase(bench_result.begin() + q); - continue; - } else { - for (int m = 0; m < result.size(); m++) { - string count1, count2; - string res1, res2; - for (int n = 0; n < result[m].size(); n++) { - if (result[m][n] == 0) { - count1 += "1"; - count2 += "0"; - } else { - count1 += "0"; - count2 += "1"; - } - } - if (count1 == "0000" || count1 == "1111" || - count2 == "0000" || count2 == "1111") - continue; - for (int n = 0; n < pow(2.0, matrix_form[l].eye); n++) { - string s1(2 * length1, '2'); - string s2(2 * length1, '2'); - int ind = - (length_string2 / pow(2.0, matrix_form[l].eye)) * n; - string a, b, c, d; - a = bench_result[q].computed_input.substr(ind, length1); - b = bench_result[q].computed_input.substr(ind + length1, - length1); - c = bench_result[q].computed_input.substr( - ind + (length1 * 2), length1); - d = bench_result[q].computed_input.substr( - ind + (length1 * 3), length1); - - if (count1[0] == '0') { - if (s1.substr(length1, length1) == standard) - s1.replace(length1, length1, a); - } else { - if (s1.substr(0, length1) == standard) - s1.replace(0, length1, a); - } - if (count1[1] == '0') { - if (s1.substr(length1, length1) == standard) - s1.replace(length1, length1, b); - } else { - if (s1.substr(0, length1) == standard) - s1.replace(0, length1, b); - } - if (count1[2] == '0') { - if (s1.substr(length1, length1) == standard) - s1.replace(length1, length1, c); - } else { - if (s1.substr(0, length1) == standard) - s1.replace(0, length1, c); - } - if (count1[3] == '0') { - if (s1.substr(length1, length1) == standard) - s1.replace(length1, length1, d); - } else { - if (s1.substr(0, length1) == standard) - s1.replace(0, length1, d); - } - - if (count2[0] == '0') { - if (s2.substr(length1, length1) == standard) - s2.replace(length1, length1, a); - } else { - if (s2.substr(0, length1) == standard) - s2.replace(0, length1, a); - } - if (count2[1] == '0') { - if (s2.substr(length1, length1) == standard) - s2.replace(length1, length1, b); - } else { - if (s2.substr(0, length1) == standard) - s2.replace(0, length1, b); - } - if (count2[2] == '0') { - if (s2.substr(length1, length1) == standard) - s2.replace(length1, length1, c); - } else { - if (s2.substr(0, length1) == standard) - s2.replace(0, length1, c); - } - if (count2[3] == '0') { - if (s2.substr(length1, length1) == standard) - s2.replace(length1, length1, d); - } else { - if (s2.substr(0, length1) == standard) - s2.replace(0, length1, d); - } - res1 += s1; - res2 += s2; - } - result_lut result_temp_1, result_temp_2; - result_temp_1.possible_result = - bench_result[q].possible_result; - result_temp_2.possible_result = - bench_result[q].possible_result; - for (int p = 0; p < result_temp_1.possible_result.size(); - p++) { - if (result_temp_1.possible_result[p].node == - matrix_form[l].node) - result_temp_1.possible_result[p].tt = count1; - if (result_temp_2.possible_result[p].node == - matrix_form[l].node) - result_temp_2.possible_result[p].tt = count2; - } - if (res1.size() == 4) { - for (int p = 0; p < result_temp_1.possible_result.size(); - p++) { - if (result_temp_1.possible_result[p].node == - matrix_form[0].node) - result_temp_1.possible_result[p].tt = res1; - if (result_temp_2.possible_result[p].node == - matrix_form[0].node) - result_temp_2.possible_result[p].tt = res2; - } - } else { - result_temp_1.computed_input = res1; - result_temp_2.computed_input = res2; - } - - bench_result_temp.push_back(result_temp_1); - bench_result_temp.push_back(result_temp_2); - } - } - } - if (bench_result_temp.empty()) - break; - else - bench_result.assign(bench_result_temp.begin(), - bench_result_temp.end()); - } - } - } - - for (int j = bench_result.size() - 1; j >= 0; j--) { - vector> mtxvec; - vector mtx1, mtx2; - vector in; - for (int k = bench_result[j].possible_result.size() - 1; k >= 0; k--) { - vector mtxvec_temp; - in.push_back(bench_result[j].possible_result[k].tt); - mtxvec_temp.push_back(bench_result[j].possible_result[k].left); - mtxvec_temp.push_back(bench_result[j].possible_result[k].right); - mtxvec_temp.push_back(bench_result[j].possible_result[k].node); - mtxvec.push_back(mtxvec_temp); - } - in.push_back("10"); - mtx1.push_back(bench_result[j].possible_result[0].node); - mtx2.push_back(input); - mtx2.push_back(1); - mtxvec.push_back(mtx1); - mtxvec.push_back(mtx2); - vector> in_expansion = bench_expansion(in); - vector bench_temp; - for (int k = in_expansion.size() - 1; k >= 0; k--) { - string tt_temp = in_expansion[k][in_expansion[k].size() - 2]; - bench_solve(in_expansion[k], mtxvec); - if (!compare_result(in_expansion[k], tt_binary)) { - in_expansion.erase(in_expansion.begin() + k); - } else { - result_lut bench_temp_temp = bench_result[j]; - bench_temp_temp.possible_result[0].tt = tt_temp; - bench_temp.push_back(bench_temp_temp); - } - } - if (in_expansion.empty()) - bench_result.erase(bench_result.begin() + j); - else { - bench_result.erase(bench_result.begin() + j); - bench_result.insert(bench_result.end(), bench_temp.begin(), - bench_temp.end()); - } - } - - if (bench_result.size()) { - for (int j = 0; j < bench_result.size(); j++) - lut_dags_new.push_back(bench_result[j].possible_result); - } - } - lut_dags.assign(lut_dags_new.begin(), lut_dags_new.end()); - } - - vector chain_to_matrix(vector lut_dags, int flag_node) { - vector matrix_form; - matrix temp_node, temp_left, temp_right; - temp_node.node = lut_dags[0].node; - temp_node.name = "M"; - temp_left.node = lut_dags[0].left; - temp_right.node = lut_dags[0].right; - matrix_form.push_back(temp_node); - - if (lut_dags[0].right >= flag_node) { - vector matrix_form_temp2; - matrix_generate(lut_dags, matrix_form_temp2, lut_dags[0].right); - matrix_form.insert(matrix_form.end(), matrix_form_temp2.begin(), - matrix_form_temp2.end()); - } else { - temp_right.input = 1; - string str = to_string(lut_dags[0].right); - temp_right.name = str; - matrix_form.push_back(temp_right); - } - - if (lut_dags[0].left >= flag_node) { - vector matrix_form_temp1; - matrix_generate(lut_dags, matrix_form_temp1, lut_dags[0].left); - matrix_form.insert(matrix_form.end(), matrix_form_temp1.begin(), - matrix_form_temp1.end()); - } else { - temp_left.input = 1; - string str = to_string(lut_dags[0].left); - temp_left.name = str; - matrix_form.push_back(temp_left); - } - - return matrix_form; - } - - void matrix_computution(vector& matrix_form) { - bool status = true; - while (status) { - status = false; - for (int i = matrix_form.size() - 1; i > 1; i--) { - // 两个变量交换 - if (((matrix_form[i].name != "M") && (matrix_form[i].name != "R") && - (matrix_form[i].name != "W")) && - ((matrix_form[i - 1].name != "M") && - (matrix_form[i - 1].name != "R") && - (matrix_form[i - 1].name != "W"))) { - int left, right; - left = atoi(matrix_form[i - 1].name.c_str()); - right = atoi(matrix_form[i].name.c_str()); - // 相等变量降幂 - if (left == right) { - status = true; - matrix reduce_matrix; - reduce_matrix.name = "R"; - matrix_form.insert(matrix_form.begin() + (i - 1), reduce_matrix); - matrix_form.erase(matrix_form.begin() + i); - } else if (left < right) { - status = true; - matrix swap_matrix; - swap_matrix.name = "W"; - swap(matrix_form[i - 1], matrix_form[i]); - matrix_form.insert(matrix_form.begin() + (i - 1), swap_matrix); - } - } - // 变量与矩阵交换 - if (((matrix_form[i].name == "M") || (matrix_form[i].name == "R") || - (matrix_form[i].name == "W")) && - ((matrix_form[i - 1].name != "M") && - (matrix_form[i - 1].name != "R") && - (matrix_form[i - 1].name != "W"))) { - status = true; - matrix_form[i].eye += 1; - swap(matrix_form[i - 1], matrix_form[i]); - } - } - } - } - - void matrix_generate(vector lut, vector& matrix_form, - int node) { - int flag = lut[lut.size() - 1].node; - for (int i = 0; i < lut.size(); i++) { - if (lut[i].node == node) { - matrix temp_node, temp_left, temp_right; - temp_node.node = node; - temp_node.name = "M"; - matrix_form.push_back(temp_node); - if (lut[i].right >= flag) { - vector matrix_form_temp2; - matrix_generate(lut, matrix_form_temp2, lut[i].right); - matrix_form.insert(matrix_form.end(), matrix_form_temp2.begin(), - matrix_form_temp2.end()); - } else { - temp_right.input = 1; - temp_right.node = lut[i].right; - string str = to_string(lut[i].right); - temp_right.name = str; - matrix_form.push_back(temp_right); - } - if (lut[i].left >= flag) { - vector matrix_form_temp1; - matrix_generate(lut, matrix_form_temp1, lut[i].left); - matrix_form.insert(matrix_form.begin() + 1, matrix_form_temp1.begin(), - matrix_form_temp1.end()); - } else { - temp_left.input = 1; - temp_left.node = lut[i].left; - string str = to_string(lut[i].left); - temp_left.name = str; - matrix_form.push_back(temp_left); - } - } - } - } - - bool compare_string(string a, string b) { - bool target = 1; - for (int i = 0; i < a.size(); i++) { - if ((a[i] != b[i]) && a[i] != '2' && b[i] != '2') { - target = 0; - } - } - return target; - } - - bool compare_vector(vector a, vector b) { - bool target = 0; - if (a == b) { - target = 1; - } else { - for (int i = 0; i < a.size(); i++) { - if (a[i] == 1) { - a[i] = 0; - } else if (a[i] == 0) { - a[i] = 1; - } - } - if (a == b) { - target = 1; - } - } - return target; - } - - bool compare_result(vector t1, string t2) { - bool target = false; - string t3(t2.size(), '0'); - for (int i = 0; i < t1.size(); i++) { - char temp; - for (int j = 0; j < t1[i].size() / 2; j++) { - temp = t1[i][j]; - t1[i][j] = t1[i][t1[i].size() - 1 - j]; - t1[i][t1[i].size() - 1 - j] = temp; - } - int value = stoi(t1[i], 0, 2); - int ind = t3.size() - value - 1; - t3[ind] = '1'; - } - if (t2 == t3) { - target = true; - } - return target; - } - - void vector_generate(vector result_b, vector>& result_a) { - for (int i = 0; i < result_b.size(); i++) { - if (result_b[i] != 2) { - if (result_a.empty()) { - vector temp; - temp.push_back(result_b[i]); - result_a.push_back(temp); - } else { - vector> result_a_temp; - for (int j = 0; j < result_a.size(); j++) { - vector temp(result_a[j]); - temp.push_back(result_b[i]); - result_a_temp.push_back(temp); - } - result_a.assign(result_a_temp.begin(), result_a_temp.end()); - } - } else { - if (result_a.empty()) { - vector temp1(1, 1); - vector temp2(1, 0); - result_a.push_back(temp1); - result_a.push_back(temp2); - } else { - vector> result_a_temp; - for (int j = 0; j < result_a.size(); j++) { - vector temp1(result_a[j]); - vector temp2(result_a[j]); - temp1.push_back(1); - temp2.push_back(0); - result_a_temp.push_back(temp1); - result_a_temp.push_back(temp2); - } - result_a.assign(result_a_temp.begin(), result_a_temp.end()); - } - } - } - } - - void bench_solve(vector& in, vector> mtxvec) { - int length1 = mtxvec[mtxvec.size() - 1][0]; // number of primary input - int length2 = mtxvec[mtxvec.size() - 1][1]; // number of primary output - int length3 = mtxvec[0][2]; // the minimum minuend - int length4 = - mtxvec[mtxvec.size() - 2 - length2][2]; // the maximum variable - vector> - list; // the solution space is two dimension vector - vector list_temp; - cdccl_impl list_temp_temp; - - string Result_temp(length1, '2'); // temporary result - coordinate Level_temp; - Level_temp.Abscissa = -1; - Level_temp.Ordinate = -1; - Level_temp.parameter_Intermediate = -1; - Level_temp.parameter_Gate = -1; - list_temp_temp.Level.resize( - length4, Level_temp); // Initialize level as a space with the size of - // variables(length4) - /* - * initialization - */ - coordinate Gate_level; - Gate_level.Abscissa = 0; - Gate_level.Ordinate = 0; - Gate_level.parameter_Intermediate = -1; - Gate_level.parameter_Gate = -1; - string Intermediate_temp; - for (int i = mtxvec.size() - 1 - length2; i < mtxvec.size() - 1; - i++) // the original intermediate - { - if (mtxvec[i][0] < length3) { - if (in[i][0] == '1') - Result_temp[mtxvec[i][0] - 1] = '1'; - else - Result_temp[mtxvec[i][0] - 1] = '0'; - } else { - list_temp_temp.Gate.push_back(mtxvec[i][0]); - if (in[i][0] == '1') - Intermediate_temp += "1"; - else - Intermediate_temp += "0"; - } - list_temp_temp.Level[mtxvec[i][0] - 1] = Gate_level; - } - list_temp_temp.Result = Result_temp; - list_temp_temp.Intermediate.push_back(Intermediate_temp); - list_temp.push_back(list_temp_temp); // level 0 - list.push_back(list_temp); - /* - * The first level information - */ - int count1 = 0; - for (int level = 0;; level++) // the computation process - { - int flag = 0, ordinate = 0; // the flag of the end of the loop & the - // ordinate of each level's gate - vector list_temp1; - for (int k = 0; k < list[level].size(); k++) { - cdccl_impl temp1; // temporary gate - temp1.Result = list[level][k].Result; // first, next level's Result is - // same as the front level - for (int j = 0; j < list[level][k].Intermediate.size(); j++) { - temp1.Level = list[level][k].Level; // next level's Level information - for (int j1 = 0; j1 < list[level][k].Gate.size(); j1++) { - temp1.Level[list[level][k].Gate[j1] - 1].parameter_Intermediate = j; - temp1.Level[list[level][k].Gate[j1] - 1].parameter_Gate = j1; - } - - coordinate level_current; // new level - level_current.Abscissa = level + 1; - level_current.parameter_Intermediate = -1; - level_current.parameter_Gate = -1; - level_current.Ordinate = ordinate; - - temp1.Gate.assign(list[level][k].Gate.begin(), - list[level][k].Gate.end()); // need more!!!!! - temp1.Intermediate.push_back(list[level][k].Intermediate[j]); - - vector Intermediate_temp; - vector Gate_temp; - vector Gate_judge(length4, -1); - int count_cdccl = 0; - for (int i = 0; i < temp1.Gate.size(); i++) { - int length = temp1.Gate[i] - length3; - int Gate_f = mtxvec[length][0]; // the front Gate variable - int Gate_b = mtxvec[length][1]; // the behind Gate variable - string tt = in[length]; // the correndsponding Truth Table - char target = temp1.Intermediate[0][i]; // the SAT target - vector Intermediate_temp_temp; - - int flag_cdccl = 0; - string Intermediate_temp_temp_F, Intermediate_temp_temp_B; - if (temp1.Level[Gate_f - 1].Abscissa >= 0) { - if (Gate_f < length3) { - char contrast_R1 = list[temp1.Level[Gate_f - 1].Abscissa] - [temp1.Level[Gate_f - 1].Ordinate] - .Result[Gate_f - 1]; - Intermediate_temp_temp_F.push_back(contrast_R1); - } else { - char contrast_I1 = - list[temp1.Level[Gate_f - 1].Abscissa] - [temp1.Level[Gate_f - 1].Ordinate] - .Intermediate - [temp1.Level[Gate_f - 1].parameter_Intermediate] - [temp1.Level[Gate_f - 1].parameter_Gate]; - Intermediate_temp_temp_F.push_back(contrast_I1); - } - flag_cdccl += 1; - } - if (temp1.Level[Gate_b - 1].Abscissa >= 0) { - if (Gate_b < length3) { - char contrast_R2 = list[temp1.Level[Gate_b - 1].Abscissa] - [temp1.Level[Gate_b - 1].Ordinate] - .Result[Gate_b - 1]; - Intermediate_temp_temp_B.push_back(contrast_R2); - } else { - char contrast_I2 = - list[temp1.Level[Gate_b - 1].Abscissa] - [temp1.Level[Gate_b - 1].Ordinate] - .Intermediate - [temp1.Level[Gate_b - 1].parameter_Intermediate] - [temp1.Level[Gate_b - 1].parameter_Gate]; - Intermediate_temp_temp_B.push_back(contrast_I2); - } - flag_cdccl += 2; - } - if (Intermediate_temp.size() == 0) { - if (flag_cdccl == 0) { - Gate_judge[Gate_f - 1] = count_cdccl; - count_cdccl += 1; - Gate_judge[Gate_b - 1] = count_cdccl; - count_cdccl += 1; - Gate_temp.push_back(Gate_f); - Gate_temp.push_back(Gate_b); - if (tt[0] == target) Intermediate_temp_temp.push_back("11"); - if (tt[1] == target) Intermediate_temp_temp.push_back("01"); - if (tt[2] == target) Intermediate_temp_temp.push_back("10"); - if (tt[3] == target) Intermediate_temp_temp.push_back("00"); - } else if (flag_cdccl == 1) { - Gate_judge[Gate_b - 1] = count_cdccl; - count_cdccl += 1; - Gate_temp.push_back(Gate_b); - if (tt[0] == target) { - if (Intermediate_temp_temp_F == "1") - Intermediate_temp_temp.push_back("1"); - } - if (tt[1] == target) { - if (Intermediate_temp_temp_F == "0") - Intermediate_temp_temp.push_back("1"); - } - if (tt[2] == target) { - if (Intermediate_temp_temp_F == "1") - Intermediate_temp_temp.push_back("0"); - } - if (tt[3] == target) { - if (Intermediate_temp_temp_F == "0") - Intermediate_temp_temp.push_back("0"); - } - } else if (flag_cdccl == 2) { - Gate_judge[Gate_f - 1] = count_cdccl; - count_cdccl += 1; - Gate_temp.push_back(Gate_f); - if (tt[0] == target) { - if (Intermediate_temp_temp_B == "1") - Intermediate_temp_temp.push_back("1"); - } - if (tt[1] == target) { - if (Intermediate_temp_temp_B == "1") - Intermediate_temp_temp.push_back("0"); - } - if (tt[2] == target) { - if (Intermediate_temp_temp_B == "0") - Intermediate_temp_temp.push_back("1"); - } - if (tt[3] == target) { - if (Intermediate_temp_temp_B == "0") - Intermediate_temp_temp.push_back("0"); - } - } else { - int t0 = 0, t1 = 0, t2 = 0, t3 = 0; - if (tt[0] == target) { - if ((Intermediate_temp_temp_F == "1") && - (Intermediate_temp_temp_B == "1")) - t0 = 1; - } - if (tt[1] == target) { - if ((Intermediate_temp_temp_F == "0") && - (Intermediate_temp_temp_B == "1")) - t1 = 1; - } - if (tt[2] == target) { - if ((Intermediate_temp_temp_F == "1") && - (Intermediate_temp_temp_B == "0")) - t2 = 1; - } - if (tt[3] == target) { - if ((Intermediate_temp_temp_F == "0") && - (Intermediate_temp_temp_B == "0")) - t3 = 1; - } - if ((t0 == 1) || (t1 == 1) || (t2 == 1) || (t3 == 1)) { - Gate_judge[Gate_f - 1] = count_cdccl; - count_cdccl += 1; - Gate_judge[Gate_b - 1] = count_cdccl; - count_cdccl += 1; - Gate_temp.push_back(Gate_f); - Gate_temp.push_back(Gate_b); - if (t0 == 1) Intermediate_temp_temp.push_back("11"); - if (t1 == 1) Intermediate_temp_temp.push_back("01"); - if (t2 == 1) Intermediate_temp_temp.push_back("10"); - if (t3 == 1) Intermediate_temp_temp.push_back("00"); - } - } - } else { - if (flag_cdccl == 0) { - int count_Gate_f = 0, count_Gate_b = 0; - for (int j = 0; j < Intermediate_temp.size(); j++) { - int flag; - string t1, t2, t3, t4; - if (Gate_judge[Gate_f - 1] < 0) { - count_Gate_f = 1; - if (tt[0] == target) t1 = "1"; - if (tt[1] == target) t2 = "0"; - if (tt[2] == target) t3 = "1"; - if (tt[3] == target) t4 = "0"; - flag = 1; - } else { - int count_sat = 0; - if (tt[0] == target) { - if (Intermediate_temp[j][Gate_judge[Gate_f - 1]] == '1') { - t1 = "11"; - count_sat += 1; - } - } - if (tt[1] == target) { - if (Intermediate_temp[j][Gate_judge[Gate_f - 1]] == '0') { - t2 = "01"; - count_sat += 1; - } - } - if (tt[2] == target) { - if (Intermediate_temp[j][Gate_judge[Gate_f - 1]] == '1') { - t3 = "10"; - count_sat += 1; - } - } - if (tt[3] == target) { - if (Intermediate_temp[j][Gate_judge[Gate_f - 1]] == '0') { - t4 = "00"; - count_sat += 1; - } - } - if (count_sat == 0) continue; - flag = 2; - } - if (Gate_judge[Gate_b - 1] < 0) { - count_Gate_b = 1; - if (flag == 1) { - if (t1 == "1") { - t1 += "1"; - string result_temporary(Intermediate_temp[j]); - result_temporary += t1; - Intermediate_temp_temp.push_back(result_temporary); - } - if (t2 == "0") { - t2 += "1"; - string result_temporary(Intermediate_temp[j]); - result_temporary += t2; - Intermediate_temp_temp.push_back(result_temporary); - } - if (t3 == "1") { - t3 += "0"; - string result_temporary(Intermediate_temp[j]); - result_temporary += t3; - Intermediate_temp_temp.push_back(result_temporary); - } - if (t4 == "0") { - t4 += "0"; - string result_temporary(Intermediate_temp[j]); - result_temporary += t4; - Intermediate_temp_temp.push_back(result_temporary); - } - } - if (flag == 2) { - if (t1 == "11") { - t1 = "1"; - string result_temporary(Intermediate_temp[j]); - result_temporary += t1; - Intermediate_temp_temp.push_back(result_temporary); - } - if (t2 == "01") { - t2 = "1"; - string result_temporary(Intermediate_temp[j]); - result_temporary += t2; - Intermediate_temp_temp.push_back(result_temporary); - } - if (t3 == "10") { - t3 = "0"; - string result_temporary(Intermediate_temp[j]); - result_temporary += t3; - Intermediate_temp_temp.push_back(result_temporary); - } - if (t4 == "00") { - t4 = "0"; - string result_temporary(Intermediate_temp[j]); - result_temporary += t4; - Intermediate_temp_temp.push_back(result_temporary); - } - } - } else { - if (flag == 1) { - if (tt[0] == target) { - if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == - '1') { - string result_temporary(Intermediate_temp[j]); - result_temporary += t1; - Intermediate_temp_temp.push_back(result_temporary); - } - } - if (tt[1] == target) { - if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == - '1') { - string result_temporary(Intermediate_temp[j]); - result_temporary += t2; - Intermediate_temp_temp.push_back(result_temporary); - } - } - if (tt[2] == target) { - if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == - '0') { - string result_temporary(Intermediate_temp[j]); - result_temporary += t3; - Intermediate_temp_temp.push_back(result_temporary); - } - } - if (tt[3] == target) { - if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == - '0') { - string result_temporary(Intermediate_temp[j]); - result_temporary += t4; - Intermediate_temp_temp.push_back(result_temporary); - } - } - } - if (flag == 2) { - int count_sat1 = 0; - if (t1 == "11") { - if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == '1') - count_sat1 += 1; - } - if (t2 == "01") { - if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == '1') - count_sat1 += 1; - } - if (t3 == "10") { - if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == '0') - count_sat1 += 1; - } - if (t4 == "00") { - if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == '0') - count_sat1 += 1; - } - if (count_sat1 > 0) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - } - } - if (count_Gate_f == 1) { - Gate_judge[Gate_f - 1] = count_cdccl; - count_cdccl += 1; - Gate_temp.push_back(Gate_f); - } - if (count_Gate_b == 1) { - Gate_judge[Gate_b - 1] = count_cdccl; - count_cdccl += 1; - Gate_temp.push_back(Gate_b); - } - } else if (flag_cdccl == 1) { - int flag_1 = 0; - for (int j = 0; j < Intermediate_temp.size(); j++) { - if (Gate_judge[Gate_b - 1] < 0) { - flag_1 = 1; - if (tt[0] == target) { - if (Intermediate_temp_temp_F == "1") { - string Intermediate_temp_temp1(Intermediate_temp[j]); - Intermediate_temp_temp1 += "1"; - Intermediate_temp_temp.push_back( - Intermediate_temp_temp1); - } - } - if (tt[1] == target) { - if (Intermediate_temp_temp_F == "0") { - string Intermediate_temp_temp1(Intermediate_temp[j]); - Intermediate_temp_temp1 += "1"; - Intermediate_temp_temp.push_back( - Intermediate_temp_temp1); - } - } - if (tt[2] == target) { - if (Intermediate_temp_temp_F == "1") { - string Intermediate_temp_temp1(Intermediate_temp[j]); - Intermediate_temp_temp1 += "0"; - Intermediate_temp_temp.push_back( - Intermediate_temp_temp1); - } - } - if (tt[3] == target) { - if (Intermediate_temp_temp_F == "0") { - string Intermediate_temp_temp1(Intermediate_temp[j]); - Intermediate_temp_temp1 += "0"; - Intermediate_temp_temp.push_back( - Intermediate_temp_temp1); - } - } - } else { - if (tt[0] == target) { - if ((Intermediate_temp[j][Gate_judge[Gate_b - 1]] == - '1') && - (Intermediate_temp_temp_F == "1")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - if (tt[1] == target) { - if ((Intermediate_temp[j][Gate_judge[Gate_b - 1]] == - '1') && - (Intermediate_temp_temp_F == "0")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - if (tt[2] == target) { - if ((Intermediate_temp[j][Gate_judge[Gate_b - 1]] == - '0') && - (Intermediate_temp_temp_F == "1")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - if (tt[3] == target) { - if ((Intermediate_temp[j][Gate_judge[Gate_b - 1]] == - '0') && - (Intermediate_temp_temp_F == "0")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - } - } - if (flag_1 == 1) { - Gate_judge[Gate_b - 1] = count_cdccl; - count_cdccl += 1; - Gate_temp.push_back(Gate_b); - } - } else if (flag_cdccl == 2) { - int flag_2 = 0; - for (int j = 0; j < Intermediate_temp.size(); j++) { - if (Gate_judge[Gate_f - 1] < 0) { - flag_2 = 1; - if (tt[0] == target) { - if (Intermediate_temp_temp_B == "1") { - string Intermediate_temp_temp1(Intermediate_temp[j]); - Intermediate_temp_temp1 += "1"; - Intermediate_temp_temp.push_back( - Intermediate_temp_temp1); - } - } - if (tt[1] == target) { - if (Intermediate_temp_temp_B == "1") { - string Intermediate_temp_temp1(Intermediate_temp[j]); - Intermediate_temp_temp1 += "0"; - Intermediate_temp_temp.push_back( - Intermediate_temp_temp1); - } - } - if (tt[2] == target) { - if (Intermediate_temp_temp_B == "0") { - string Intermediate_temp_temp1(Intermediate_temp[j]); - Intermediate_temp_temp1 += "1"; - Intermediate_temp_temp.push_back( - Intermediate_temp_temp1); - } - } - if (tt[3] == target) { - if (Intermediate_temp_temp_B == "0") { - string Intermediate_temp_temp1(Intermediate_temp[j]); - Intermediate_temp_temp1 += "0"; - Intermediate_temp_temp.push_back( - Intermediate_temp_temp1); - } - } - } else { - if (tt[0] == target) { - if ((Intermediate_temp[j][Gate_judge[Gate_f - 1]] == - '1') && - (Intermediate_temp_temp_B == "1")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - if (tt[1] == target) { - if ((Intermediate_temp[j][Gate_judge[Gate_f - 1]] == - '0') && - (Intermediate_temp_temp_B == "1")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - if (tt[2] == target) { - if ((Intermediate_temp[j][Gate_judge[Gate_f - 1]] == - '1') && - (Intermediate_temp_temp_B == "0")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - if (tt[3] == target) { - if ((Intermediate_temp[j][Gate_judge[Gate_f - 1]] == - '0') && - (Intermediate_temp_temp_B == "0")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - } - } - if (flag_2 == 1) { - Gate_judge[Gate_f - 1] = count_cdccl; - count_cdccl += 1; - Gate_temp.push_back(Gate_f); - } - } else { - for (int j = 0; j < Intermediate_temp.size(); j++) { - if (tt[0] == target) { - if ((Intermediate_temp_temp_F == "1") && - (Intermediate_temp_temp_B == "1")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - if (tt[1] == target) { - if ((Intermediate_temp_temp_F == "0") && - (Intermediate_temp_temp_B == "1")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - if (tt[2] == target) { - if ((Intermediate_temp_temp_F == "1") && - (Intermediate_temp_temp_B == "0")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - if (tt[3] == target) { - if ((Intermediate_temp_temp_F == "0") && - (Intermediate_temp_temp_B == "0")) - Intermediate_temp_temp.push_back(Intermediate_temp[j]); - } - } - } - } - Intermediate_temp.assign(Intermediate_temp_temp.begin(), - Intermediate_temp_temp.end()); - if (Intermediate_temp_temp.size() == 0) break; - } - temp1.Intermediate.assign(Intermediate_temp.begin(), - Intermediate_temp.end()); - temp1.Gate.assign(Gate_temp.begin(), Gate_temp.end()); - for (int l = 0; l < temp1.Gate.size(); l++) - temp1.Level[temp1.Gate[l] - 1] = level_current; - - int count = 0; // whether there is a PI assignment - for (int k = 0; k < temp1.Intermediate.size(); - k++) // mix the Result and the Intermediate information in one - // level - { - count = 1; - cdccl_impl temp2; - temp2.Level = temp1.Level; - string Result_temp(temp1.Result); - temp2.Gate.assign(temp1.Gate.begin(), temp1.Gate.end()); - string Intermediate_temp1(temp1.Intermediate[k]); - int count1 = 0, count2 = 0; // whether the assignment made - for (int k11 = 0; k11 < temp1.Gate.size(); k11++) { - if (temp1.Gate[k11] < - length3) // if the Gate is smaller than length3, it is PI - { - temp2.Level[temp1.Gate[k11] - 1].Ordinate = ordinate; - if ((temp1.Result[temp1.Gate[k11] - 1] == '2') || - (temp1.Result[temp1.Gate[k11] - 1] == - temp1.Intermediate[k][k11])) // whether the PI can be - // assigned a value - Result_temp[temp1.Gate[k11] - 1] = temp1.Intermediate[k][k11]; - else - count1 = 1; // if one assignment can't make, the count1 = 1 - Intermediate_temp1.erase(Intermediate_temp1.begin() + - (k11 - count2)); - temp2.Gate.erase(temp2.Gate.begin() + (k11 - count2)); - count++, count2++; - } - } - if (count1 == 0) { - temp2.Result = Result_temp; - temp2.Intermediate.push_back(Intermediate_temp1); - for (int k12 = 0; k12 < temp2.Gate.size(); k12++) - temp2.Level[temp2.Gate[k12] - 1].Ordinate = ordinate; - } - if (count == 1) - break; - else if (temp2.Result.size() > 0) { - list_temp1.push_back(temp2); - ordinate += 1; - if (temp2.Gate.empty()) flag += 1; - } - } - if (count == 1) { - list_temp1.push_back(temp1); - ordinate += 1; - if (temp1.Gate.empty()) flag += 1; - } - temp1.Intermediate.clear(); - } - } - list.push_back(list_temp1); // next level's information - if (flag == list[level + 1].size()) // in one level, if all node's Gate - // is empty, then break the loop - break; - } - - in.clear(); - for (int j = 0; j < list[list.size() - 1].size(); j++) // all result - in.push_back(list[list.size() - 1][j].Result); - } - - vector> bench_expansion(vector in) { - vector> in_expansion; - in_expansion.push_back(in); - string in_end = in[in.size() - 2]; - for (int i = 0; i < in_end.size(); i++) { - if (in_end[i] == '2') { - vector> in_expansion_temp; - for (int j = 0; j < in_expansion.size(); j++) { - vector in_temp_1(in_expansion[j]); - vector in_temp_0(in_expansion[j]); - in_temp_1[in_expansion[j].size() - 2][i] = '1'; - in_temp_0[in_expansion[j].size() - 2][i] = '0'; - in_expansion_temp.push_back(in_temp_1); - in_expansion_temp.push_back(in_temp_0); - } - in_expansion.assign(in_expansion_temp.begin(), in_expansion_temp.end()); - } - } - return in_expansion; - } - - private: - vector& tt; - int& input; -}; - -void exact_lut(vector& tt, int& input) { - exact_lut_impl p(tt, input); - p.run(); -} - -void exact_lut_enu(vector& tt, int& input) { - exact_lut_impl p(tt, input); - p.run_enu(); -} -} // namespace phyLS diff --git a/src/core/exact/exact_lut.hpp b/src/core/exact/exact_lut.hpp index 1c8bf8a..41b72d9 100644 --- a/src/core/exact/exact_lut.hpp +++ b/src/core/exact/exact_lut.hpp @@ -8,16 +8,3643 @@ #include #include #include +#include #include #include #include #include +#include "exact_dag.hpp" + using namespace std; +using namespace mockturtle; namespace phyLS { -void exact_lut(vector& tt, int& input); -void exact_lut_enu(vector& tt, int& input); +struct klut { + int node; + vector inputs; + string tt; +}; + +struct matrix_klut { + int eye = 0; + int node = 0; + int nr_input = 2; + string name; + bool input = false; +}; + +struct result_klut { + string computed_input; + vector possible_result; +}; + +class exact_lut_impl { + public: + exact_lut_impl(vector& tt, int& input, int& cut_size) + : tt(tt), input(input), cut_size(cut_size) {} + + void run() { exact_lut_network(); } + void run_enu() { exact_lut_network_enu(); } + void run_lut() { exact_lut_mapping(); } + void run_lut_mapping() { exactLutMapping(); } + vector> exact_lut_results; + vector exact_lut_result; + + private: + void exact_lut_network() { + // the DAG topology family of r nodes and k levels + // initialization + int num_node = input - 1; // first, number of node is number of input - 1 + int num_level = 2; + while (1) { + vector> lut; + create_dags(lut, num_node, num_level); + sort_dags(lut); + if (lut.empty()) { + if (num_level <= num_node) { + num_level += 1; + } + if (num_level > num_node) { + num_level = 2; + num_node += 1; + } + continue; + } + // AllSAT solving to judge the DAGs + stp_simulate(lut); + if (lut.size()) { + vector result_final; + for (int i = 0; i < lut.size(); i++) { + string result; + for (int j = 0; j < lut[i].size(); j++) { + result += to_string(lut[i][j].node); + result += " = 4'b"; + result += lut[i][j].tt; + result += " ("; + if (lut[i][j].left <= input) { + char temp; + temp = 'a' + lut[i][j].left - 1; + result.push_back(temp); + } else { + result += to_string(lut[i][j].left); + } + result += ", "; + if (lut[i][j].right <= input) { + char temp; + temp = 'a' + lut[i][j].right - 1; + result.push_back(temp); + } else { + result += to_string(lut[i][j].right); + } + result += ") "; + } + result_final.push_back(result); + } + tt.assign(result_final.begin(), result_final.end()); + break; + } else { + if (num_level <= num_node) { + num_level += 1; + } + if (num_level > num_node) { + num_level = 2; + num_node += 1; + } + } + } + } + + void exact_lut_network_enu() { + // the DAG topology family of r nodes and k levels + // initialization + int num_node = input - 1; // first, number of node is number of input - 1 + int num_level = 2; + while (1) { + vector> lut; + create_dags(lut, num_node, num_level); + sort_dags(lut); + + if (lut.empty()) { + if (num_level <= num_node) { + num_level += 1; + } + if (num_level > num_node) { + num_level = 2; + num_node += 1; + } + continue; + } + // AllSAT solving to judge the DAGs + stp_simulate_enu(lut); + if (lut.size()) { + vector result_final; + for (int i = 0; i < lut.size(); i++) { + string result; + for (int j = 0; j < lut[i].size(); j++) { + result += to_string(lut[i][j].node); + result += " = 4'b"; + result += lut[i][j].tt; + result += " ("; + if (lut[i][j].left <= input) { + char temp; + temp = 'a' + lut[i][j].left - 1; + result.push_back(temp); + } else { + result += to_string(lut[i][j].left); + } + result += ", "; + if (lut[i][j].right <= input) { + char temp; + temp = 'a' + lut[i][j].right - 1; + result.push_back(temp); + } else { + result += to_string(lut[i][j].right); + } + result += ") "; + } + result_final.push_back(result); + } + tt.assign(result_final.begin(), result_final.end()); + break; + } else { + if (num_level <= num_node) { + num_level += 1; + } + if (num_level > num_node) { + num_level = 2; + num_node += 1; + } + } + } + } + + void exact_lut_mapping() { + int num_node = compute_nr_node(); + int num_level = 2; + stopwatch<>::duration time{0}; + while (1) { + // create all possible k-LUT DAGs + vector> lut; + call_with_stopwatch(time, [&]() { + create_kluts(lut, num_node, num_level); + sort_luts(lut); + }); + + // cout << "lut size : " << lut.size() << endl; + + if (lut.empty()) { + if (num_level < num_node) { + num_level += 1; + } else { + num_level = 2; + num_node += 1; + } + continue; + } + + stp_simulate_klut(lut); + if (lut.size()) { + vector result_final; + for (int i = 0; i < lut.size(); i++) { + string result; + for (int j = 0; j < lut[i].size(); j++) { + result += to_string(lut[i][j].node); + result += " = "; + int num_input = pow(2, lut[i][j].inputs.size()); + result += to_string(num_input); + result += "'b"; + result += lut[i][j].tt; + result += " ("; + for (int k = 0; k < lut[i][j].inputs.size(); k++) { + if (lut[i][j].inputs[k] <= input) { + char temp; + temp = 'a' + lut[i][j].inputs[k] - 1; + result.push_back(temp); + } else { + result += to_string(lut[i][j].inputs[k]); + } + if (k != lut[i][j].inputs.size() - 1) result += ", "; + } + result += ") "; + } + result_final.push_back(result); + } + tt.assign(result_final.begin(), result_final.end()); + break; + } else { + if (num_level < num_node) { + num_level += 1; + } else { + num_level = 2; + num_node += 1; + } + } + } + std::cout << fmt::format("[LUT generation time]: {:5.3f} seconds\n", + to_seconds(time)); + } + + void exactLutMapping() { + int num_node = compute_nr_node(); + int num_level = 2; + while (1) { + // create all possible k-LUT DAGs + vector> lut; + create_kluts(lut, num_node, num_level); + sort_luts(lut); + if (lut.empty()) { + if (num_level < num_node) { + num_level += 1; + } else { + num_level = 2; + num_node += 1; + } + continue; + } + stp_simulate_klut(lut); + if (lut.size()) { + for (auto& x : lut[0]) { + for (auto& y : x.tt) { + if (y == '2') y = '0'; + } + } + exact_lut_result.assign(lut[0].begin(), lut[0].end()); + break; + } else { + if (num_level < num_node) { + num_level += 1; + } else { + num_level = 2; + num_node += 1; + } + } + } + } + + int compute_nr_node() { + int num_node = 1; + while (1) { + int empty_node = ((cut_size - 1) * num_node) + 1; + if (empty_node < input) + num_node += 1; + else + break; + } + return num_node; + } + + void create_dags(vector>& lut_dags, int node, + int level) { + phyLS::dag lut_dag_init; + lut_dag_init.node = node; + lut_dag_init.level = level; + lut_dag_init.count.resize(level + 1, 1); + lut_dag_init.count[0] = input; + int numnodes = node - level; + int numlevels = level - 1; + vector> q; + if (numlevels > 0) { + if (numnodes == 0) { + vector> lut_dags_temp; + bench_dag(lut_dag_init, lut_dags_temp); + lut_dags.insert(lut_dags.end(), lut_dags_temp.begin(), + lut_dags_temp.end()); + } else { + dag_classify(q, numnodes, numlevels); + for (int i = 0; i < q.size(); i++) { + phyLS::dag lut_dag_temp = lut_dag_init; + for (int j = 1, k = 0; j < level; j++, k++) { + lut_dag_temp.count[j] += q[i][k]; + } + judge_dag(lut_dag_temp); + if (lut_dag_temp.count.size() != 0) { + vector> lut_dags_temp; + bench_dag(lut_dag_temp, lut_dags_temp); + lut_dags.insert(lut_dags.end(), lut_dags_temp.begin(), + lut_dags_temp.end()); + } + } + } + } + } + + void create_kluts(vector>& lut_dags, int node, int level) { + phyLS::dag lut_dag_init; + lut_dag_init.node = node; + lut_dag_init.level = level; + lut_dag_init.count.resize(level + 1, 1); + lut_dag_init.count[0] = input; + int numnodes = node - level; + if (level > 1) { + if (numnodes == 0) { + klut_dag(lut_dag_init, lut_dags); + } else { + // enumerate the placement of all possible additional nodes + vector> q; + dag_classify(q, numnodes, level - 1); + // enumerate all situations + for (int i = 0; i < q.size(); i++) { + phyLS::dag lut_dag_temp = lut_dag_init; + for (int j = 1, k = 0; j < level; j++, k++) + lut_dag_temp.count[j] += q[i][k]; + // judge whether lut is legitimate + judge_lut(lut_dag_temp); + if (!lut_dag_temp.count.empty()) klut_dag(lut_dag_temp, lut_dags); + } + } + } else { + // TODO: only one LUT, generate directly + } + } + + void dag_classify(vector>& result, int numnodes, int numlevels) { + int q[numlevels]; + int x = numnodes; + int j; + for (int i = 0; i < numlevels; i++) { + q[i] = 0; + } + while (1) { + j = 0; + q[0] = x; + while (1) { + vector result_temp; + for (int i = numlevels - 1; i >= 0; i--) { + result_temp.push_back(q[i]); + } + result.push_back(result_temp); + if (j == 0) { + x = q[0] - 1; + j = 1; + } else if (q[0] == 0) { + x = q[j] - 1; + q[j] = 0; + j++; + } + if (j >= numlevels) { + return; + } else if (q[j] == numnodes) { + x = x + numlevels; + q[j] = 0; + j++; + if (j >= numlevels) { + return; + } + } + q[j]++; + if (x == 0) { + q[0] = 0; + continue; + } else { + break; + } + } + } + } + + void judge_dag(phyLS::dag& lut_dag) { + for (int i = 0; i < lut_dag.count.size(); i++) { + int sum = + accumulate(lut_dag.count.begin() + i + 1, lut_dag.count.end(), 0); + if (lut_dag.count[i] - 1 > sum) { + lut_dag.count.clear(); + break; + } + } + } + + void judge_lut(phyLS::dag& lut_dag) { + for (int i = 0; i < lut_dag.count.size() - 1; i++) { + int sum = + accumulate(lut_dag.count.begin() + i + 1, lut_dag.count.end() - 1, 0); + int nr_possible = cut_size * (sum + 1) - sum; + if (lut_dag.count[i] > nr_possible) { + lut_dag.count.clear(); + break; + } + } + } + + void bench_dag(phyLS::dag lut_dag, vector>& lut_dags) { + int sum = 0, level_temp = 0, self_temp = 1; + // 第一个for循环 + // 通过lut_dag的count,初始化lut_dag的lut + // 编号每一个节点,并且将其放置在对应的层中 + // 每一层就是lut的层 + for (int i = 0; i < lut_dag.count.size(); i++, level_temp++) { + vector node_vec; + sum += lut_dag.count[i]; + for (; self_temp < sum + 1; self_temp++) { + phyLS::node_inf node; + node.num = self_temp; + node.level = level_temp; + if (self_temp <= lut_dag.count[0]) { + node.fan_in = 1; + } else if (i == lut_dag.count.size() - 1) { + node.fan_out = 1; + } + node_vec.push_back(node); + } + lut_dag.lut.push_back(node_vec); + } + + /* + cout << "node information : " << endl; + for (auto x : lut_dag.lut) + { + for (auto y : x) + { + cout << y.num << " " << y.level << " " << y.fan_in << " " << + y.fan_out << endl; + } + } + */ + + // 第二个for循环 + // 生成所有满足的DAG结构 + for (int i = lut_dag.lut.size() - 1; i >= 0; i--) { + vector lut_dags_mid; + vector permutation; + // 第2.1个for循环 + // 从lut的最上层开始向下进行遍历 + // 若为输出节点,则直接构造节点,不排列组合并放入结果中 + // 若为输入节点,不构造,直接进行排列组合(permutation) + // 否则,先构造,再排列组合 + for (int j = lut_dag.lut[i].size() - 1; j >= 0; j--) { + if (lut_dag.lut[i][j].fan_out) { + phyLS::bench LUT_fanout; + LUT_fanout.node = lut_dag.lut[i][j].num; + vector lut_dags_fanout; + lut_dags_fanout.push_back(LUT_fanout); + lut_dags.push_back(lut_dags_fanout); + } else if (lut_dag.lut[i][j].fan_in) { + permutation.push_back(lut_dag.lut[i][j].num); + } else { + phyLS::bench LUT_mid; + LUT_mid.node = lut_dag.lut[i][j].num; + lut_dags_mid.push_back(LUT_mid); + permutation.push_back(lut_dag.lut[i][j].num); + } + } + // 排列组合算法 + // 仅针对中间节点进行排列组合 + if (permutation.size()) { + vector> lut_dags_result; + // 第2.2个for循环 + // 遍历已存在的所有结果(lut_dags) + for (int k = 0; k < lut_dags.size(); k++) { + vector lut_dags_rst_temp; // 尚未满足的节点 + vector lut_dags_rst; // 已满足的节点 + vector count; + // 第2.2.1个for循环 + // 为排列组合做准备 + // 判断还有哪些节点未填满,并确定剩余空间 + for (int l = 0; l < lut_dags[k].size(); l++) { + if (lut_dags[k][l].left == 0 || lut_dags[k][l].right == 0) { + int space_temp = 0; + if (lut_dags[k][l].right == 0) { + space_temp += 1; + } + if (lut_dags[k][l].left == 0) { + space_temp += 1; + } + count.push_back(space_temp); + lut_dags_rst_temp.push_back(lut_dags[k][l]); + } else { + lut_dags_rst.push_back(lut_dags[k][l]); + } + } + vector> result; + int numnodes = permutation.size(); + int space = accumulate(count.begin(), count.end(), 0); + if (space == numnodes) { + vector> result_temp; + dag_generate_complete(result, result_temp, permutation, count, 0); + } else if (space < numnodes) { + result.clear(); + } else { + vector> result_temp; + dag_generate_uncomplete(result, result_temp, permutation, + permutation, count, 0); + } + // result有结果 + if (result.size()) { + if (i == 0) { + for (int m = 0; m < result.size(); m++) { + bool target = 1; + vector result_temp1; + int n2 = 0; + for (int n1 = 0; n1 < lut_dags_rst_temp.size(); n1++) { + phyLS::bench result_temp_temp = lut_dags_rst_temp[n1]; + if (result_temp_temp.left == 0 && + result_temp_temp.right == 0) { + if (result[m][n2] != 0) { + result_temp_temp.left = result[m][n2]; + } else { + target = 0; + } + if (result[m][n2 + 1] != 0) { + result_temp_temp.right = result[m][n2 + 1]; + } else { + target = 0; + } + n2 += 2; + } else if (result_temp_temp.left == 0 && + result_temp_temp.right != 0) { + if (result[m][n2] != 0) { + result_temp_temp.left = result[m][n2]; + } else { + target = 0; + } + n2 += 1; + } + if (!target) { + break; + } + result_temp1.push_back(result_temp_temp); + } + if (target) { + if (lut_dags_mid.size()) { + result_temp1.insert(result_temp1.end(), + lut_dags_mid.begin(), + lut_dags_mid.end()); + } + if (lut_dags_rst.size()) { + result_temp1.insert(result_temp1.begin(), + lut_dags_rst.begin(), + lut_dags_rst.end()); + } + lut_dags_result.push_back(result_temp1); + } + } + } else { + for (int m = 0; m < result.size(); m++) { + vector result_temp1; + int n2 = 0; + for (int n1 = 0; n1 < lut_dags_rst_temp.size(); n1++) { + phyLS::bench result_temp_temp = lut_dags_rst_temp[n1]; + if (result_temp_temp.left == 0 && + result_temp_temp.right == 0) { + result_temp_temp.left = result[m][n2]; + result_temp_temp.right = result[m][n2 + 1]; + n2 += 2; + } else if (result_temp_temp.left == 0 && + result_temp_temp.right != 0) { + result_temp_temp.left = result[m][n2]; + n2 += 1; + } + result_temp1.push_back(result_temp_temp); + } + if (lut_dags_mid.size()) { + result_temp1.insert(result_temp1.end(), lut_dags_mid.begin(), + lut_dags_mid.end()); + } + if (lut_dags_rst.size()) { + result_temp1.insert(result_temp1.begin(), + lut_dags_rst.begin(), lut_dags_rst.end()); + } + lut_dags_result.push_back(result_temp1); + } + } + } + } + lut_dags.assign(lut_dags_result.begin(), lut_dags_result.end()); + } + } + } + + void klut_dag(phyLS::dag lut_dag, vector>& lut_dags) { + // 第一个for循环 + // 通过lut_dag的count,初始化lut_dag的lut + // 编号每一个节点,并且将其放置在对应的层中 + // 每一层就是lut的层 + int sum = 0, level_temp = 0, self_temp = 1; + for (int i = 0; i < lut_dag.count.size(); i++, level_temp++) { + vector node_vec; + sum += lut_dag.count[i]; + for (; self_temp < sum + 1; self_temp++) { + phyLS::node_inf node; + node.num = self_temp; + node.level = level_temp; + if (self_temp <= lut_dag.count[0]) { + node.fan_in = 1; + } else if (i == lut_dag.count.size() - 1) { + node.fan_out = 1; + } + node_vec.push_back(node); + } + lut_dag.lut.push_back(node_vec); + } + + // cout << "node information : " << endl; + // for (auto x : lut_dag.lut) { + // for (auto y : x) + // cout << y.num << " " << y.level << " " << y.fan_in << " " << + // y.fan_out + // << endl; + // } + + // 第二个for循环 + // 生成所有满足的DAG结构 + for (int i = lut_dag.lut.size() - 1; i >= 0; i--) { + vector lut_dags_mid; + vector permutation; + // 第2.1个for循环 + // 从lut的最上层开始向下进行遍历 + // 若为输出节点,则直接构造节点,不排列组合并放入结果中 + // 若为输入节点,不构造,直接进行排列组合(permutation) + // 否则,先构造,再排列组合 + for (int j = lut_dag.lut[i].size() - 1; j >= 0; j--) { + if (lut_dag.lut[i][j].fan_out) { + klut LUT_fanout; + LUT_fanout.node = lut_dag.lut[i][j].num; + vector lut_dags_fanout; + lut_dags_fanout.push_back(LUT_fanout); + lut_dags.push_back(lut_dags_fanout); + } else if (lut_dag.lut[i][j].fan_in) { + permutation.push_back(lut_dag.lut[i][j].num); + } else { + klut LUT_mid; + LUT_mid.node = lut_dag.lut[i][j].num; + lut_dags_mid.push_back(LUT_mid); + permutation.push_back(lut_dag.lut[i][j].num); + } + } + + // cout << "permutation:"; + // for (auto x : permutation) cout << x << " "; + // cout << endl; + + // 排列组合算法 + // 仅针对中间节点进行排列组合 + if (permutation.size()) { + vector> lut_dags_result; + // 第2.2个for循环 + // 遍历已存在的所有结果(lut_dags) + for (int k = 0; k < lut_dags.size(); k++) { + vector lut_dags_rst_temp; // 尚未满足的节点 + vector lut_dags_rst; // 已满足的节点 + vector count; + // 第2.2.1个for循环 + // 为排列组合做准备 + // 判断还有哪些节点未填满,并确定剩余空间 + for (int l = 0; l < lut_dags[k].size(); l++) { + if (lut_dags[k][l].inputs.size() < cut_size) { + count.push_back(cut_size - lut_dags[k][l].inputs.size()); + lut_dags_rst_temp.push_back(lut_dags[k][l]); + } else { + lut_dags_rst.push_back(lut_dags[k][l]); + } + } + + // cout << "rst_temp: "; + // for (auto x : lut_dags_rst_temp) { + // cout << x.node << "-"; + // for (auto y : x.inputs) { + // cout << y << ","; + // } + // cout << endl; + // } + + // cout << "rst: "; + // for (auto x : lut_dags_rst) { + // cout << x.node << "-"; + // for (auto y : x.inputs) { + // cout << y << ","; + // } + // cout << endl; + // } + + // cout << "count:"; + // for (auto x : count) cout << x << " "; + // cout << endl; + + vector> result; + int numnodes = permutation.size(); + int space = accumulate(count.begin(), count.end(), 0); + if (space == numnodes) { + vector> result_temp; + dag_generate_complete(result, result_temp, permutation, count, 0); + } else if (space < numnodes) { + result.clear(); + } else { + vector> result_temp; + dag_generate_uncomplete(result, result_temp, permutation, + permutation, count, 0); + } + // cout << "result:"; + // for (auto x : result) { + // for (auto y : x) { + // cout << y << " "; + // } + // cout << endl; + // } + // result有结果 + if (result.size()) { + if (i == 0) { // primary inputs + for (int m = 0; m < result.size(); m++) { + bool target = true; + vector result_temp1; + for (int n1 = 0; n1 < lut_dags_rst_temp.size(); n1++) { + klut result_temp_temp = lut_dags_rst_temp[n1]; + int nr_input_result = + nr_result_nodes(result_temp_temp.inputs); + while (nr_input_result < cut_size) { + if (result[m][0] != 0) + result_temp_temp.inputs.push_back(result[m][0]); + nr_input_result++; + result[m].erase(result[m].begin()); + } + if (nr_result_nodes(result_temp_temp.inputs) < 2) + target = false; + if (!target) break; + sort(result_temp_temp.inputs.begin(), + result_temp_temp.inputs.end()); + result_temp1.push_back(result_temp_temp); + } + if (target) { + if (lut_dags_mid.size()) { + result_temp1.insert(result_temp1.end(), + lut_dags_mid.begin(), + lut_dags_mid.end()); + } + if (lut_dags_rst.size()) { + result_temp1.insert(result_temp1.begin(), + lut_dags_rst.begin(), + lut_dags_rst.end()); + } + lut_dags_result.push_back(result_temp1); + } + } + } else { // intermediate nodes + for (int m = 0; m < result.size(); m++) { + vector result_temp1; + for (int n1 = 0; n1 < lut_dags_rst_temp.size(); n1++) { + klut result_temp_temp = lut_dags_rst_temp[n1]; + int nr_input_result = + nr_result_nodes(result_temp_temp.inputs); + while (nr_input_result < cut_size) { + if (result[m][0] != 0) + result_temp_temp.inputs.push_back(result[m][0]); + nr_input_result++; + result[m].erase(result[m].begin()); + } + result_temp1.push_back(result_temp_temp); + } + if (lut_dags_mid.size()) { + result_temp1.insert(result_temp1.end(), lut_dags_mid.begin(), + lut_dags_mid.end()); + } + if (lut_dags_rst.size()) { + result_temp1.insert(result_temp1.begin(), + lut_dags_rst.begin(), lut_dags_rst.end()); + } + lut_dags_result.push_back(result_temp1); + } + } + } + } + lut_dags.assign(lut_dags_result.begin(), lut_dags_result.end()); + } + } + } + + void dag_generate_complete(vector>& result, + vector>& rst, vector permutation, + vector count, int level) { + vector> result_temp; + vector q(count[level]); + combinate(0, 0, permutation.size(), count[level], permutation, q, + result_temp); + for (int j = 0; j < result_temp.size(); j++) { + vector elected(permutation); + vector result_1; + for (int k = 0; k < result_temp[j].size(); k++) { + result_1.push_back(result_temp[j][k]); + if (level + 1 < count.size()) { + // 从vector中删除指定的某一个元素 + for (vector::iterator iter = elected.begin(); + iter != elected.end(); iter++) { + if (*iter == result_temp[j][k]) { + elected.erase(iter); + break; + } + } + } + } + sort(result_1.begin(), result_1.end()); + if (level + 1 < count.size()) { + vector> rst_temp; + dag_generate_complete(result, rst_temp, elected, count, level + 1); + for (int l = 0; l < rst_temp.size(); l++) { + vector result_2(result_1); + result_2.insert(result_2.end(), rst_temp[l].begin(), + rst_temp[l].end()); + rst.push_back(result_2); + } + } else { + rst.push_back(result_1); + } + + if (level == 0) { + result.insert(result.end(), rst.begin(), rst.end()); + rst.clear(); + } + } + } + + void dag_generate_uncomplete(vector>& result, + vector>& rst, + vector permutation_f, + vector permutation_b, vector count, + int level) { + vector> result_temp2; + for (int i = 0; i <= count[level]; i++) { + vector> result_temp; + vector q(count[level]); + combinate(0, 0, permutation_f.size(), i, permutation_f, q, result_temp); + result_temp2.insert(result_temp2.end(), result_temp.begin(), + result_temp.end()); + } + for (int j = 0; j < result_temp2.size(); j++) { + vector permutation_b_b(permutation_b); + vector result_1; + for (int k = 0; k < result_temp2[j].size(); k++) { + result_1.push_back(result_temp2[j][k]); + // 从vector中删除指定的某一个元素 + for (vector::iterator iter = permutation_b_b.begin(); + iter != permutation_b_b.end(); iter++) { + if (*iter == result_temp2[j][k]) { + permutation_b_b.erase(iter); + break; + } + } + } + sort(result_1.begin(), result_1.end()); + if (level + 1 < count.size()) { + vector> rst_temp; + dag_generate_uncomplete(result, rst_temp, permutation_f, + permutation_b_b, count, level + 1); + for (int l = 0; l < rst_temp.size(); l++) { + vector result_2(result_1); + result_2.insert(result_2.end(), rst_temp[l].begin(), + rst_temp[l].end()); + rst.push_back(result_2); + } + } else { + if (permutation_b_b.empty()) { + rst.push_back(result_1); + } + } + if (level == 0) { + result.insert(result.end(), rst.begin(), rst.end()); + rst.clear(); + } + } + } + + void combinate(int iPos, int iProc, int numnodes, int numlevels, + vector data, vector des, + vector>& result) { + if (iProc > numnodes) { + return; + } + if (iPos == numlevels) { + result.push_back(des); + return; + } else { + combinate(iPos, iProc + 1, numnodes, numlevels, data, des, result); + des[iPos] = data[iProc]; + combinate(iPos + 1, iProc + 1, numnodes, numlevels, data, des, result); + } + } + + int nr_result_nodes(vector& result) { + int nr_result_node = 0; + for (auto& x : result) { + if (x != 0) nr_result_node += 1; + } + return nr_result_node; + } + + void sort_luts(vector>& luts) { + for (int i = 0; i < luts.size(); i++) { + Quicksort_lut(luts[i], 0, luts[i].size() - 1); + } + } + + void Quicksort_lut(vector& lut, int low, int hight) { + int mid; + if (low < hight) { + mid = part_lut(lut, low, hight); // 返回基准元素位置 + Quicksort_lut(lut, low, mid - 1); // 左区间递归快速排序 + Quicksort_lut(lut, mid + 1, hight); // 右区间递归快速排序 + } + } + + int part_lut(vector& lut, int low, int hight) // 划分函数 + { + int i = low, j = hight, pivot = lut[low].node; // 基准元素 + while (i < j) { + while (i < j && + lut[j].node < pivot) // 从右向左开始找一个 小于等于 pivot的数值 + { + j--; + } + if (i < j) { + swap(lut[i++], lut[j]); // r[i]和r[j]交换后 i 向右移动一位 + } + while (i < j && + lut[i].node >= pivot) // 从左向右开始找一个 大于 pivot的数值 + { + i++; + } + if (i < j) { + swap(lut[i], lut[j--]); // r[i]和r[j]交换后 i 向左移动一位 + } + } + return i; // 返回最终划分完成后基准元素所在的位置 + } + + void sort_dags(vector>& luts) { + for (int i = 0; i < luts.size(); i++) { + Quicksort(luts[i], 0, luts[i].size() - 1); + } + } + + void Quicksort(vector& lut, int low, int hight) { + int mid; + if (low < hight) { + mid = part(lut, low, hight); // 返回基准元素位置 + Quicksort(lut, low, mid - 1); // 左区间递归快速排序 + Quicksort(lut, mid + 1, hight); // 右区间递归快速排序 + } + } + + int part(vector& lut, int low, int hight) // 划分函数 + { + int i = low, j = hight, pivot = lut[low].node; // 基准元素 + while (i < j) { + while (i < j && + lut[j].node < pivot) // 从右向左开始找一个 小于等于 pivot的数值 + { + j--; + } + if (i < j) { + swap(lut[i++], lut[j]); // r[i]和r[j]交换后 i 向右移动一位 + } + while (i < j && + lut[i].node >= pivot) // 从左向右开始找一个 大于 pivot的数值 + { + i++; + } + if (i < j) { + swap(lut[i], lut[j--]); // r[i]和r[j]交换后 i 向左移动一位 + } + } + return i; // 返回最终划分完成后基准元素所在的位置 + } + + void stp_simulate(vector>& lut_dags) { + string tt_binary = tt[0]; + int flag_node = lut_dags[0][lut_dags[0].size() - 1].node; + vector> lut_dags_new; + for (int i = lut_dags.size() - 1; i >= 0; i--) { + string input_tt(tt_binary); + + vector matrix_form = + chain_to_matrix(lut_dags[i], flag_node); + matrix_computution(matrix_form); + + for (auto y : lut_dags[i]) { + cout << y.node << "-(" << y.left << ", " << y.right << ") "; + } + cout << "= "; + for (int i = 0; i < matrix_form.size(); i++) { + cout << matrix_form[i].name << "_" << matrix_form[i].node << "[I" + << matrix_form[i].eye << "] "; + } + cout << endl; + + vector bench_result; + phyLS::result_lut first_result; + first_result.computed_input = input_tt; + first_result.possible_result = lut_dags[i]; + bench_result.push_back(first_result); + for (int l = matrix_form.size() - 1; l >= 1; l--) { + int length_string = input_tt.size(); + if (matrix_form[l].input == 0) { + if (matrix_form[l].name == "W") { + if (matrix_form[l].eye == 0) { + string temp1, temp2; + temp1 = input_tt.substr(length_string / 4, length_string / 4); + temp2 = input_tt.substr(length_string / 2, length_string / 4); + input_tt.replace(length_string / 4, length_string / 4, temp2); + input_tt.replace(length_string / 2, length_string / 4, temp1); + } else { + int length2 = length_string / pow(2.0, matrix_form[l].eye + 2); + for (int l1 = pow(2.0, matrix_form[l].eye), add = 1; l1 > 0; + l1--) { + string temp1, temp2; + temp1 = input_tt.substr( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add - + length2, + length2); + temp2 = input_tt.substr( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add, + length2); + input_tt.replace( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add - + length2, + length2, temp2); + input_tt.replace( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add, + length2, temp1); + add += 2; + } + } + bench_result[0].computed_input = input_tt; + } else if (matrix_form[l].name == "R") { + if (matrix_form[l].eye == 0) { + string temp(length_string, '2'); + input_tt.insert(input_tt.begin() + (length_string / 2), + temp.begin(), temp.end()); + } else { + string temp(length_string / pow(2.0, matrix_form[l].eye), '2'); + for (int l2 = pow(2.0, matrix_form[l].eye), + add1 = pow(2.0, matrix_form[l].eye + 1) - 1; + l2 > 0; l2--) { + input_tt.insert( + input_tt.begin() + + ((length_string / pow(2.0, matrix_form[l].eye + 1)) * + add1), + temp.begin(), temp.end()); + add1 -= 2; + } + } + bench_result[0].computed_input = input_tt; + } else if (matrix_form[l].name == "M") { + vector bench_result_temp; + for (int q = bench_result.size() - 1; q >= 0; q--) { + int length_string2 = bench_result[q].computed_input.size(); + int length1 = length_string2 / + pow(2.0, matrix_form[l].eye + 2); // abcd的长度 + string standard(length1, '2'); + vector standard_int(4, 0); + vector> result; + + for (int l3 = 0; l3 < pow(2.0, matrix_form[l].eye); l3++) { + vector> result_t; + + int ind = (length_string2 / pow(2.0, matrix_form[l].eye)) * l3; + string a = bench_result[q].computed_input.substr(ind, length1); + string b = bench_result[q].computed_input.substr(ind + length1, + length1); + string c = bench_result[q].computed_input.substr( + ind + (2 * length1), length1); + string d = bench_result[q].computed_input.substr( + ind + (3 * length1), length1); + + if (a != standard) { + vector result_temp(4); // size为4的可能结果 + result_temp[0] = 0; // a=0 + if (compare_string(a, b)) // b=a + { + if (b == standard) + result_temp[1] = 2; + else + result_temp[1] = 0; // b=0 + if (compare_string(a, c) && + compare_string(b, c)) // c=(b=a) + { + if (c == standard) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + if (compare_string(a, d) && compare_string(b, d) && + compare_string(c, d)) // d=(c=b=a) + { + result_temp[0] = 2; + result_temp[1] = 2; + result_temp[2] = 2; + result_temp[3] = 2; + } else // d!=(c=b=a) + { + result_temp[3] = 1; // d=1 + if (compare_string(b, d)) result_temp[1] = 2; + if (compare_string(c, d)) result_temp[2] = 2; + } + } else // c!=(b=a) + { + result_temp[2] = 1; // c=1 + if (compare_string(b, c)) result_temp[1] = 2; + if (compare_string(a, d) && + compare_string(b, d)) // d=(b=a) + { + if (d == standard || compare_string(c, d)) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(c, d)) // d=c + { + result_temp[3] = 1; // d=1 + if (compare_string(b, d)) result_temp[1] = 2; + } else // 其他 + break; + } + } else // b!=a + { + result_temp[1] = 1; // b=1 + if (compare_string(a, c)) // c=a + { + if (c == standard || compare_string(b, c)) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + if (compare_string(a, d) && + compare_string(c, d)) // d=(c=a) + { + if (d == standard || compare_string(b, d)) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(b, d)) // d=b + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else if (compare_string(b, c)) // c=b + { + result_temp[2] = 1; // c=1 + if (compare_string(a, d)) // d=a + { + if (d == standard || + (compare_string(b, d) && compare_string(c, d))) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(b, d) && + compare_string(c, d)) // d=(c=b) + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else // 其他 + break; + } + if (result_t.empty()) + vector_generate(result_temp, result_t); + else { + vector> result_t_temp; + vector_generate(result_temp, result_t_temp); + for (int j = result_t.size() - 1; j >= 0; j--) { + for (int k = result_t_temp.size() - 1; k >= 0; k--) { + if (compare_vector(result_t[j], result_t_temp[k])) + result_t_temp.erase(result_t_temp.begin() + k); + } + } + if (!result_t_temp.empty()) { + result_t.insert(result_t.end(), result_t_temp.begin(), + result_t_temp.end()); + } + } + } + if (b != standard) { + vector result_temp(4); // size为4的可能结果 + result_temp[1] = 0; // b=0 + if (compare_string(a, b)) // a=b + { + if (a == standard) + result_temp[0] = 2; + else + result_temp[0] = 0; // a=0 + if (compare_string(a, c) && + compare_string(b, c)) // c=(a=b) + { + if (c == standard) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + if (compare_string(a, d) && compare_string(b, d) && + compare_string(c, d)) // d=(c=a=b) + { + result_temp[0] = 2; + result_temp[1] = 2; + result_temp[2] = 2; + result_temp[3] = 2; + } else // d!=(c=a=b) + { + result_temp[3] = 1; // d=1 + if (compare_string(a, d)) result_temp[0] = 2; + if (compare_string(c, d)) result_temp[2] = 2; + } + } else // c!=(a=b) + { + result_temp[2] = 1; // c=1 + if (compare_string(a, c)) result_temp[0] = 2; + if (compare_string(a, d) && + compare_string(b, d)) // d=(a=b) + { + if (d == standard || compare_string(c, d)) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(c, d)) // d=c + { + result_temp[3] = 1; // d=1 + if (compare_string(a, d)) result_temp[0] = 2; + } else // 其他 + break; + } + } else // a!=b + { + result_temp[0] = 1; // a=1 + if (compare_string(c, b)) // c=b + { + if (c == standard || compare_string(a, c)) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + if (compare_string(b, d) && + compare_string(c, d)) // d=(c=b) + { + if (d == standard || compare_string(a, d)) + result_temp[3] = 2; // d=0 + else + result_temp[3] = 0; // d=0 + } else if (compare_string(a, d)) // d=a + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else if (compare_string(a, c)) // c=a + { + result_temp[2] = 1; // c=1 + if (compare_string(b, d)) // d=b + { + if (d == standard || + (compare_string(a, d) && compare_string(c, d))) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(a, d) && + compare_string(c, d)) // d=(c=a) + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else // 其他 + break; + } + if (result_t.empty()) + vector_generate(result_temp, result_t); + else { + vector> result_t_temp; + vector_generate(result_temp, result_t_temp); + for (int j = result_t.size() - 1; j >= 0; j--) { + for (int k = result_t_temp.size() - 1; k >= 0; k--) { + if (compare_vector(result_t[j], result_t_temp[k])) + result_t_temp.erase(result_t_temp.begin() + k); + } + } + if (!result_t_temp.empty()) { + result_t.insert(result_t.end(), result_t_temp.begin(), + result_t_temp.end()); + } + } + } + if (c != standard) { + vector result_temp(4); // size为4的可能结果 + result_temp[2] = 0; // c=0 + if (compare_string(a, c)) // a=c + { + if (a == standard) + result_temp[0] = 2; + else + result_temp[0] = 0; // a=0 + if (compare_string(b, c) && + compare_string(b, a)) // b=(a=c) + { + if (b == standard) + result_temp[1] = 2; + else + result_temp[1] = 0; // b=0 + if (compare_string(a, d) && compare_string(b, d) && + compare_string(c, d)) // d=(b=a=c) + { + result_temp[0] = 2; + result_temp[1] = 2; + result_temp[2] = 2; + result_temp[3] = 2; + } else // d!=(b=a=c) + { + result_temp[3] = 1; // d=1 + if (compare_string(a, d)) result_temp[0] = 2; + if (compare_string(b, d)) result_temp[1] = 2; + } + } else // b!=(a=c) + { + result_temp[1] = 1; // b=1 + if (compare_string(a, b)) result_temp[0] = 2; + if (compare_string(a, d) && + compare_string(c, d)) // d=(a=c) + { + if (d == standard || compare_string(b, d)) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(b, d)) // d=b + { + result_temp[3] = 1; // d=1 + if (compare_string(a, d)) result_temp[0] = 2; + } else // 其他 + break; + } + } else // a!=c + { + result_temp[0] = 1; // a=1 + if (compare_string(b, c)) // b=c + { + if (b == standard || compare_string(b, a)) + result_temp[1] = 2; + else + result_temp[1] = 0; // b=0 + if (compare_string(b, d) && + compare_string(c, d)) // d=(b=c) + { + if (d == standard || compare_string(a, d)) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(a, d)) // d=a + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else if (compare_string(a, b)) // b=a + { + result_temp[1] = 1; // b=1 + if (compare_string(c, d)) // d=c + { + if (d == standard || + (compare_string(a, d) && compare_string(b, d))) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(a, d) && + compare_string(b, d)) // d=(b=a) + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else // 其他 + break; + } + if (result_t.empty()) + vector_generate(result_temp, result_t); + else { + vector> result_t_temp; + vector_generate(result_temp, result_t_temp); + for (int j = result_t.size() - 1; j >= 0; j--) { + for (int k = result_t_temp.size() - 1; k >= 0; k--) { + if (compare_vector(result_t[j], result_t_temp[k])) + result_t_temp.erase(result_t_temp.begin() + k); + } + } + if (!result_t_temp.empty()) { + result_t.insert(result_t.end(), result_t_temp.begin(), + result_t_temp.end()); + } + } + } + if (d != standard) { + vector result_temp(4); // size为4的可能结果 + result_temp[3] = 0; // d=0 + if (compare_string(a, d)) // a=d + { + if (a == standard) + result_temp[0] = 2; + else + result_temp[0] = 0; // a=0 + if (compare_string(b, a) && + compare_string(b, d)) // b=(a=d) + { + if (b == standard) + result_temp[1] = 2; + else + result_temp[1] = 0; // b=0 + if (compare_string(a, c) && compare_string(b, c) && + compare_string(d, c)) // c=(b=a=d) + { + result_temp[0] = 2; + result_temp[1] = 2; + result_temp[2] = 2; + result_temp[3] = 2; + } else // c!=(b=a=d) + { + result_temp[2] = 1; // c=1 + if (compare_string(a, c)) result_temp[0] = 2; + if (compare_string(b, c)) result_temp[1] = 2; + } + } else // b!=(a=d) + { + result_temp[1] = 1; // b=1 + if (compare_string(a, b)) result_temp[0] = 2; + if (compare_string(c, a) && + compare_string(c, d)) // c=(a=d) + { + if (c == standard || compare_string(c, b)) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + } else if (compare_string(c, b)) // c=b + { + result_temp[2] = 1; // c=1 + if (compare_string(a, c)) result_temp[0] = 2; + } else // 其他 + break; + } + } else // a!=d + { + result_temp[0] = 1; // a=1 + if (compare_string(b, d)) // b=d + { + if (b == standard || compare_string(b, a)) + result_temp[1] = 2; + else + result_temp[1] = 0; // b=0 + if (compare_string(c, d) && + compare_string(c, b)) // c=(b=d) + { + if (c == standard || compare_string(c, a)) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + } else if (compare_string(c, a)) // c=a + result_temp[2] = 1; // c=1 + else // 其他 + break; + } else if (compare_string(b, a)) // b=a + { + result_temp[1] = 1; // b=1 + if (compare_string(c, d)) // c=d + { + if (c == standard || + (compare_string(a, c) && compare_string(b, c))) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + } else if (compare_string(c, a) && + compare_string(c, b)) // c=(b=a) + result_temp[2] = 1; // c=1 + else // 其他 + break; + } else // 其他 + break; + } + if (result_t.empty()) + vector_generate(result_temp, result_t); + else { + vector> result_t_temp; + vector_generate(result_temp, result_t_temp); + for (int j = result_t.size() - 1; j >= 0; j--) { + for (int k = result_t_temp.size() - 1; k >= 0; k--) { + if (compare_vector(result_t[j], result_t_temp[k])) + result_t_temp.erase(result_t_temp.begin() + k); + } + } + if (!result_t_temp.empty()) { + result_t.insert(result_t.end(), result_t_temp.begin(), + result_t_temp.end()); + } + } + } + if (result.empty()) + result.assign(result_t.begin(), result_t.end()); + else { + for (int j = result.size() - 1; j >= 0; j--) { + if (result[j] == standard_int) { + result.assign(result_t.begin(), result_t.end()); + break; + } else { + bool target1 = 0, target2 = 0; + for (int k = result_t.size() - 1; k >= 0; k--) { + if (result_t[k] == standard_int) { + target1 = 1; + break; + } else { + if (compare_vector(result_t[k], result[j])) { + target2 = 1; + break; + } + } + } + if (target1) break; + if (!target2) result.erase(result.begin() + j); + } + } + if (result.empty()) break; + } + } + if (result.empty()) { + bench_result.erase(bench_result.begin() + q); + continue; + } else { + for (int m = 0; m < result.size(); m++) { + string count1, count2; + string res1, res2; + for (int n = 0; n < result[m].size(); n++) { + if (result[m][n] == 0) { + count1 += "1"; + count2 += "0"; + } else { + count1 += "0"; + count2 += "1"; + } + } + if (count1 == "0000" || count1 == "1111" || + count2 == "0000" || count2 == "1111") + continue; + for (int n = 0; n < pow(2.0, matrix_form[l].eye); n++) { + string s1(2 * length1, '2'); + string s2(2 * length1, '2'); + int ind = + (length_string2 / pow(2.0, matrix_form[l].eye)) * n; + string a, b, c, d; + a = bench_result[q].computed_input.substr(ind, length1); + b = bench_result[q].computed_input.substr(ind + length1, + length1); + c = bench_result[q].computed_input.substr( + ind + (length1 * 2), length1); + d = bench_result[q].computed_input.substr( + ind + (length1 * 3), length1); + + if (count1[0] == '0') { + if (s1.substr(length1, length1) == standard) + s1.replace(length1, length1, a); + } else { + if (s1.substr(0, length1) == standard) + s1.replace(0, length1, a); + } + if (count1[1] == '0') { + if (s1.substr(length1, length1) == standard) + s1.replace(length1, length1, b); + } else { + if (s1.substr(0, length1) == standard) + s1.replace(0, length1, b); + } + if (count1[2] == '0') { + if (s1.substr(length1, length1) == standard) + s1.replace(length1, length1, c); + } else { + if (s1.substr(0, length1) == standard) + s1.replace(0, length1, c); + } + if (count1[3] == '0') { + if (s1.substr(length1, length1) == standard) + s1.replace(length1, length1, d); + } else { + if (s1.substr(0, length1) == standard) + s1.replace(0, length1, d); + } + + if (count2[0] == '0') { + if (s2.substr(length1, length1) == standard) + s2.replace(length1, length1, a); + } else { + if (s2.substr(0, length1) == standard) + s2.replace(0, length1, a); + } + if (count2[1] == '0') { + if (s2.substr(length1, length1) == standard) + s2.replace(length1, length1, b); + } else { + if (s2.substr(0, length1) == standard) + s2.replace(0, length1, b); + } + if (count2[2] == '0') { + if (s2.substr(length1, length1) == standard) + s2.replace(length1, length1, c); + } else { + if (s2.substr(0, length1) == standard) + s2.replace(0, length1, c); + } + if (count2[3] == '0') { + if (s2.substr(length1, length1) == standard) + s2.replace(length1, length1, d); + } else { + if (s2.substr(0, length1) == standard) + s2.replace(0, length1, d); + } + res1 += s1; + res2 += s2; + } + phyLS::result_lut result_temp_1, result_temp_2; + result_temp_1.possible_result = + bench_result[q].possible_result; + result_temp_2.possible_result = + bench_result[q].possible_result; + for (int p = 0; p < result_temp_1.possible_result.size(); + p++) { + if (result_temp_1.possible_result[p].node == + matrix_form[l].node) + result_temp_1.possible_result[p].tt = count1; + if (result_temp_2.possible_result[p].node == + matrix_form[l].node) + result_temp_2.possible_result[p].tt = count2; + } + if (res1.size() == 4) { + for (int p = 0; p < result_temp_1.possible_result.size(); + p++) { + if (result_temp_1.possible_result[p].node == + matrix_form[0].node) + result_temp_1.possible_result[p].tt = res1; + if (result_temp_2.possible_result[p].node == + matrix_form[0].node) + result_temp_2.possible_result[p].tt = res2; + } + } else { + result_temp_1.computed_input = res1; + result_temp_2.computed_input = res2; + } + + bench_result_temp.push_back(result_temp_1); + bench_result_temp.push_back(result_temp_2); + } + } + } + if (bench_result_temp.empty()) + break; + else + bench_result.assign(bench_result_temp.begin(), + bench_result_temp.end()); + } + } + } + + for (int j = bench_result.size() - 1; j >= 0; j--) { + vector> mtxvec; + vector mtx1, mtx2; + vector in; + for (int k = bench_result[j].possible_result.size() - 1; k >= 0; k--) { + vector mtxvec_temp; + in.push_back(bench_result[j].possible_result[k].tt); + mtxvec_temp.push_back(bench_result[j].possible_result[k].left); + mtxvec_temp.push_back(bench_result[j].possible_result[k].right); + mtxvec_temp.push_back(bench_result[j].possible_result[k].node); + mtxvec.push_back(mtxvec_temp); + } + in.push_back("10"); + mtx1.push_back(bench_result[j].possible_result[0].node); + mtx2.push_back(input); + mtx2.push_back(1); + mtxvec.push_back(mtx1); + mtxvec.push_back(mtx2); + vector> in_expansion = bench_expansion(in); + vector bench_temp; + for (int k = in_expansion.size() - 1; k >= 0; k--) { + string tt_temp = in_expansion[k][in_expansion[k].size() - 2]; + bench_solve(in_expansion[k], mtxvec); + if (!compare_result(in_expansion[k], tt_binary)) { + in_expansion.erase(in_expansion.begin() + k); + } else { + phyLS::result_lut bench_temp_temp = bench_result[j]; + bench_temp_temp.possible_result[0].tt = tt_temp; + bench_temp.push_back(bench_temp_temp); + } + } + if (in_expansion.empty()) + bench_result.erase(bench_result.begin() + j); + else { + bench_result.erase(bench_result.begin() + j); + bench_result.insert(bench_result.end(), bench_temp.begin(), + bench_temp.end()); + } + } + + if (bench_result.size()) { + for (int j = 0; j < bench_result.size(); j++) + lut_dags_new.push_back(bench_result[j].possible_result); + break; + } + } + lut_dags.assign(lut_dags_new.begin(), lut_dags_new.end()); + } + + void stp_simulate_enu(vector>& lut_dags) { + string tt_binary = tt[0]; + int flag_node = lut_dags[0][lut_dags[0].size() - 1].node; + vector> lut_dags_new; + for (int i = lut_dags.size() - 1; i >= 0; i--) { + string input_tt(tt_binary); + + vector matrix_form = + chain_to_matrix(lut_dags[i], flag_node); + matrix_computution(matrix_form); + + vector bench_result; + phyLS::result_lut first_result; + first_result.computed_input = input_tt; + first_result.possible_result = lut_dags[i]; + bench_result.push_back(first_result); + for (int l = matrix_form.size() - 1; l >= 1; l--) { + int length_string = input_tt.size(); + if (matrix_form[l].input == 0) { + if (matrix_form[l].name == "W") { + if (matrix_form[l].eye == 0) { + string temp1, temp2; + temp1 = input_tt.substr(length_string / 4, length_string / 4); + temp2 = input_tt.substr(length_string / 2, length_string / 4); + input_tt.replace(length_string / 4, length_string / 4, temp2); + input_tt.replace(length_string / 2, length_string / 4, temp1); + } else { + int length2 = length_string / pow(2.0, matrix_form[l].eye + 2); + for (int l1 = pow(2.0, matrix_form[l].eye), add = 1; l1 > 0; + l1--) { + string temp1, temp2; + temp1 = input_tt.substr( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add - + length2, + length2); + temp2 = input_tt.substr( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add, + length2); + input_tt.replace( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add - + length2, + length2, temp2); + input_tt.replace( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add, + length2, temp1); + add += 2; + } + } + bench_result[0].computed_input = input_tt; + } else if (matrix_form[l].name == "R") { + if (matrix_form[l].eye == 0) { + string temp(length_string, '2'); + input_tt.insert(input_tt.begin() + (length_string / 2), + temp.begin(), temp.end()); + } else { + string temp(length_string / pow(2.0, matrix_form[l].eye), '2'); + for (int l2 = pow(2.0, matrix_form[l].eye), + add1 = pow(2.0, matrix_form[l].eye + 1) - 1; + l2 > 0; l2--) { + input_tt.insert( + input_tt.begin() + + ((length_string / pow(2.0, matrix_form[l].eye + 1)) * + add1), + temp.begin(), temp.end()); + add1 -= 2; + } + } + bench_result[0].computed_input = input_tt; + } else if (matrix_form[l].name == "M") { + vector bench_result_temp; + for (int q = bench_result.size() - 1; q >= 0; q--) { + int length_string2 = bench_result[q].computed_input.size(); + int length1 = length_string2 / + pow(2.0, matrix_form[l].eye + 2); // abcd的长度 + string standard(length1, '2'); + vector standard_int(4, 0); + vector> result; + + for (int l3 = 0; l3 < pow(2.0, matrix_form[l].eye); l3++) { + vector> result_t; + + int ind = (length_string2 / pow(2.0, matrix_form[l].eye)) * l3; + string a = bench_result[q].computed_input.substr(ind, length1); + string b = bench_result[q].computed_input.substr(ind + length1, + length1); + string c = bench_result[q].computed_input.substr( + ind + (2 * length1), length1); + string d = bench_result[q].computed_input.substr( + ind + (3 * length1), length1); + + if (a != standard) { + vector result_temp(4); // size为4的可能结果 + result_temp[0] = 0; // a=0 + if (compare_string(a, b)) // b=a + { + if (b == standard) + result_temp[1] = 2; + else + result_temp[1] = 0; // b=0 + if (compare_string(a, c) && + compare_string(b, c)) // c=(b=a) + { + if (c == standard) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + if (compare_string(a, d) && compare_string(b, d) && + compare_string(c, d)) // d=(c=b=a) + { + result_temp[0] = 2; + result_temp[1] = 2; + result_temp[2] = 2; + result_temp[3] = 2; + } else // d!=(c=b=a) + { + result_temp[3] = 1; // d=1 + if (compare_string(b, d)) result_temp[1] = 2; + if (compare_string(c, d)) result_temp[2] = 2; + } + } else // c!=(b=a) + { + result_temp[2] = 1; // c=1 + if (compare_string(b, c)) result_temp[1] = 2; + if (compare_string(a, d) && + compare_string(b, d)) // d=(b=a) + { + if (d == standard || compare_string(c, d)) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(c, d)) // d=c + { + result_temp[3] = 1; // d=1 + if (compare_string(b, d)) result_temp[1] = 2; + } else // 其他 + break; + } + } else // b!=a + { + result_temp[1] = 1; // b=1 + if (compare_string(a, c)) // c=a + { + if (c == standard || compare_string(b, c)) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + if (compare_string(a, d) && + compare_string(c, d)) // d=(c=a) + { + if (d == standard || compare_string(b, d)) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(b, d)) // d=b + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else if (compare_string(b, c)) // c=b + { + result_temp[2] = 1; // c=1 + if (compare_string(a, d)) // d=a + { + if (d == standard || + (compare_string(b, d) && compare_string(c, d))) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(b, d) && + compare_string(c, d)) // d=(c=b) + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else // 其他 + break; + } + if (result_t.empty()) + vector_generate(result_temp, result_t); + else { + vector> result_t_temp; + vector_generate(result_temp, result_t_temp); + for (int j = result_t.size() - 1; j >= 0; j--) { + for (int k = result_t_temp.size() - 1; k >= 0; k--) { + if (compare_vector(result_t[j], result_t_temp[k])) + result_t_temp.erase(result_t_temp.begin() + k); + } + } + if (!result_t_temp.empty()) { + result_t.insert(result_t.end(), result_t_temp.begin(), + result_t_temp.end()); + } + } + } + if (b != standard) { + vector result_temp(4); // size为4的可能结果 + result_temp[1] = 0; // b=0 + if (compare_string(a, b)) // a=b + { + if (a == standard) + result_temp[0] = 2; + else + result_temp[0] = 0; // a=0 + if (compare_string(a, c) && + compare_string(b, c)) // c=(a=b) + { + if (c == standard) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + if (compare_string(a, d) && compare_string(b, d) && + compare_string(c, d)) // d=(c=a=b) + { + result_temp[0] = 2; + result_temp[1] = 2; + result_temp[2] = 2; + result_temp[3] = 2; + } else // d!=(c=a=b) + { + result_temp[3] = 1; // d=1 + if (compare_string(a, d)) result_temp[0] = 2; + if (compare_string(c, d)) result_temp[2] = 2; + } + } else // c!=(a=b) + { + result_temp[2] = 1; // c=1 + if (compare_string(a, c)) result_temp[0] = 2; + if (compare_string(a, d) && + compare_string(b, d)) // d=(a=b) + { + if (d == standard || compare_string(c, d)) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(c, d)) // d=c + { + result_temp[3] = 1; // d=1 + if (compare_string(a, d)) result_temp[0] = 2; + } else // 其他 + break; + } + } else // a!=b + { + result_temp[0] = 1; // a=1 + if (compare_string(c, b)) // c=b + { + if (c == standard || compare_string(a, c)) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + if (compare_string(b, d) && + compare_string(c, d)) // d=(c=b) + { + if (d == standard || compare_string(a, d)) + result_temp[3] = 2; // d=0 + else + result_temp[3] = 0; // d=0 + } else if (compare_string(a, d)) // d=a + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else if (compare_string(a, c)) // c=a + { + result_temp[2] = 1; // c=1 + if (compare_string(b, d)) // d=b + { + if (d == standard || + (compare_string(a, d) && compare_string(c, d))) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(a, d) && + compare_string(c, d)) // d=(c=a) + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else // 其他 + break; + } + if (result_t.empty()) + vector_generate(result_temp, result_t); + else { + vector> result_t_temp; + vector_generate(result_temp, result_t_temp); + for (int j = result_t.size() - 1; j >= 0; j--) { + for (int k = result_t_temp.size() - 1; k >= 0; k--) { + if (compare_vector(result_t[j], result_t_temp[k])) + result_t_temp.erase(result_t_temp.begin() + k); + } + } + if (!result_t_temp.empty()) { + result_t.insert(result_t.end(), result_t_temp.begin(), + result_t_temp.end()); + } + } + } + if (c != standard) { + vector result_temp(4); // size为4的可能结果 + result_temp[2] = 0; // c=0 + if (compare_string(a, c)) // a=c + { + if (a == standard) + result_temp[0] = 2; + else + result_temp[0] = 0; // a=0 + if (compare_string(b, c) && + compare_string(b, a)) // b=(a=c) + { + if (b == standard) + result_temp[1] = 2; + else + result_temp[1] = 0; // b=0 + if (compare_string(a, d) && compare_string(b, d) && + compare_string(c, d)) // d=(b=a=c) + { + result_temp[0] = 2; + result_temp[1] = 2; + result_temp[2] = 2; + result_temp[3] = 2; + } else // d!=(b=a=c) + { + result_temp[3] = 1; // d=1 + if (compare_string(a, d)) result_temp[0] = 2; + if (compare_string(b, d)) result_temp[1] = 2; + } + } else // b!=(a=c) + { + result_temp[1] = 1; // b=1 + if (compare_string(a, b)) result_temp[0] = 2; + if (compare_string(a, d) && + compare_string(c, d)) // d=(a=c) + { + if (d == standard || compare_string(b, d)) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(b, d)) // d=b + { + result_temp[3] = 1; // d=1 + if (compare_string(a, d)) result_temp[0] = 2; + } else // 其他 + break; + } + } else // a!=c + { + result_temp[0] = 1; // a=1 + if (compare_string(b, c)) // b=c + { + if (b == standard || compare_string(b, a)) + result_temp[1] = 2; + else + result_temp[1] = 0; // b=0 + if (compare_string(b, d) && + compare_string(c, d)) // d=(b=c) + { + if (d == standard || compare_string(a, d)) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(a, d)) // d=a + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else if (compare_string(a, b)) // b=a + { + result_temp[1] = 1; // b=1 + if (compare_string(c, d)) // d=c + { + if (d == standard || + (compare_string(a, d) && compare_string(b, d))) + result_temp[3] = 2; + else + result_temp[3] = 0; // d=0 + } else if (compare_string(a, d) && + compare_string(b, d)) // d=(b=a) + result_temp[3] = 1; // d=1 + else // 其他 + break; + } else // 其他 + break; + } + if (result_t.empty()) + vector_generate(result_temp, result_t); + else { + vector> result_t_temp; + vector_generate(result_temp, result_t_temp); + for (int j = result_t.size() - 1; j >= 0; j--) { + for (int k = result_t_temp.size() - 1; k >= 0; k--) { + if (compare_vector(result_t[j], result_t_temp[k])) + result_t_temp.erase(result_t_temp.begin() + k); + } + } + if (!result_t_temp.empty()) { + result_t.insert(result_t.end(), result_t_temp.begin(), + result_t_temp.end()); + } + } + } + if (d != standard) { + vector result_temp(4); // size为4的可能结果 + result_temp[3] = 0; // d=0 + if (compare_string(a, d)) // a=d + { + if (a == standard) + result_temp[0] = 2; + else + result_temp[0] = 0; // a=0 + if (compare_string(b, a) && + compare_string(b, d)) // b=(a=d) + { + if (b == standard) + result_temp[1] = 2; + else + result_temp[1] = 0; // b=0 + if (compare_string(a, c) && compare_string(b, c) && + compare_string(d, c)) // c=(b=a=d) + { + result_temp[0] = 2; + result_temp[1] = 2; + result_temp[2] = 2; + result_temp[3] = 2; + } else // c!=(b=a=d) + { + result_temp[2] = 1; // c=1 + if (compare_string(a, c)) result_temp[0] = 2; + if (compare_string(b, c)) result_temp[1] = 2; + } + } else // b!=(a=d) + { + result_temp[1] = 1; // b=1 + if (compare_string(a, b)) result_temp[0] = 2; + if (compare_string(c, a) && + compare_string(c, d)) // c=(a=d) + { + if (c == standard || compare_string(c, b)) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + } else if (compare_string(c, b)) // c=b + { + result_temp[2] = 1; // c=1 + if (compare_string(a, c)) result_temp[0] = 2; + } else // 其他 + break; + } + } else // a!=d + { + result_temp[0] = 1; // a=1 + if (compare_string(b, d)) // b=d + { + if (b == standard || compare_string(b, a)) + result_temp[1] = 2; + else + result_temp[1] = 0; // b=0 + if (compare_string(c, d) && + compare_string(c, b)) // c=(b=d) + { + if (c == standard || compare_string(c, a)) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + } else if (compare_string(c, a)) // c=a + result_temp[2] = 1; // c=1 + else // 其他 + break; + } else if (compare_string(b, a)) // b=a + { + result_temp[1] = 1; // b=1 + if (compare_string(c, d)) // c=d + { + if (c == standard || + (compare_string(a, c) && compare_string(b, c))) + result_temp[2] = 2; + else + result_temp[2] = 0; // c=0 + } else if (compare_string(c, a) && + compare_string(c, b)) // c=(b=a) + result_temp[2] = 1; // c=1 + else // 其他 + break; + } else // 其他 + break; + } + if (result_t.empty()) + vector_generate(result_temp, result_t); + else { + vector> result_t_temp; + vector_generate(result_temp, result_t_temp); + for (int j = result_t.size() - 1; j >= 0; j--) { + for (int k = result_t_temp.size() - 1; k >= 0; k--) { + if (compare_vector(result_t[j], result_t_temp[k])) + result_t_temp.erase(result_t_temp.begin() + k); + } + } + if (!result_t_temp.empty()) { + result_t.insert(result_t.end(), result_t_temp.begin(), + result_t_temp.end()); + } + } + } + if (result.empty()) + result.assign(result_t.begin(), result_t.end()); + else { + for (int j = result.size() - 1; j >= 0; j--) { + if (result[j] == standard_int) { + result.assign(result_t.begin(), result_t.end()); + break; + } else { + bool target1 = 0, target2 = 0; + for (int k = result_t.size() - 1; k >= 0; k--) { + if (result_t[k] == standard_int) { + target1 = 1; + break; + } else { + if (compare_vector(result_t[k], result[j])) { + target2 = 1; + break; + } + } + } + if (target1) break; + if (!target2) result.erase(result.begin() + j); + } + } + if (result.empty()) break; + } + } + if (result.empty()) { + bench_result.erase(bench_result.begin() + q); + continue; + } else { + for (int m = 0; m < result.size(); m++) { + string count1, count2; + string res1, res2; + for (int n = 0; n < result[m].size(); n++) { + if (result[m][n] == 0) { + count1 += "1"; + count2 += "0"; + } else { + count1 += "0"; + count2 += "1"; + } + } + if (count1 == "0000" || count1 == "1111" || + count2 == "0000" || count2 == "1111") + continue; + for (int n = 0; n < pow(2.0, matrix_form[l].eye); n++) { + string s1(2 * length1, '2'); + string s2(2 * length1, '2'); + int ind = + (length_string2 / pow(2.0, matrix_form[l].eye)) * n; + string a, b, c, d; + a = bench_result[q].computed_input.substr(ind, length1); + b = bench_result[q].computed_input.substr(ind + length1, + length1); + c = bench_result[q].computed_input.substr( + ind + (length1 * 2), length1); + d = bench_result[q].computed_input.substr( + ind + (length1 * 3), length1); + + if (count1[0] == '0') { + if (s1.substr(length1, length1) == standard) + s1.replace(length1, length1, a); + } else { + if (s1.substr(0, length1) == standard) + s1.replace(0, length1, a); + } + if (count1[1] == '0') { + if (s1.substr(length1, length1) == standard) + s1.replace(length1, length1, b); + } else { + if (s1.substr(0, length1) == standard) + s1.replace(0, length1, b); + } + if (count1[2] == '0') { + if (s1.substr(length1, length1) == standard) + s1.replace(length1, length1, c); + } else { + if (s1.substr(0, length1) == standard) + s1.replace(0, length1, c); + } + if (count1[3] == '0') { + if (s1.substr(length1, length1) == standard) + s1.replace(length1, length1, d); + } else { + if (s1.substr(0, length1) == standard) + s1.replace(0, length1, d); + } + + if (count2[0] == '0') { + if (s2.substr(length1, length1) == standard) + s2.replace(length1, length1, a); + } else { + if (s2.substr(0, length1) == standard) + s2.replace(0, length1, a); + } + if (count2[1] == '0') { + if (s2.substr(length1, length1) == standard) + s2.replace(length1, length1, b); + } else { + if (s2.substr(0, length1) == standard) + s2.replace(0, length1, b); + } + if (count2[2] == '0') { + if (s2.substr(length1, length1) == standard) + s2.replace(length1, length1, c); + } else { + if (s2.substr(0, length1) == standard) + s2.replace(0, length1, c); + } + if (count2[3] == '0') { + if (s2.substr(length1, length1) == standard) + s2.replace(length1, length1, d); + } else { + if (s2.substr(0, length1) == standard) + s2.replace(0, length1, d); + } + res1 += s1; + res2 += s2; + } + phyLS::result_lut result_temp_1, result_temp_2; + result_temp_1.possible_result = + bench_result[q].possible_result; + result_temp_2.possible_result = + bench_result[q].possible_result; + for (int p = 0; p < result_temp_1.possible_result.size(); + p++) { + if (result_temp_1.possible_result[p].node == + matrix_form[l].node) + result_temp_1.possible_result[p].tt = count1; + if (result_temp_2.possible_result[p].node == + matrix_form[l].node) + result_temp_2.possible_result[p].tt = count2; + } + if (res1.size() == 4) { + for (int p = 0; p < result_temp_1.possible_result.size(); + p++) { + if (result_temp_1.possible_result[p].node == + matrix_form[0].node) + result_temp_1.possible_result[p].tt = res1; + if (result_temp_2.possible_result[p].node == + matrix_form[0].node) + result_temp_2.possible_result[p].tt = res2; + } + } else { + result_temp_1.computed_input = res1; + result_temp_2.computed_input = res2; + } + + bench_result_temp.push_back(result_temp_1); + bench_result_temp.push_back(result_temp_2); + } + } + } + if (bench_result_temp.empty()) + break; + else + bench_result.assign(bench_result_temp.begin(), + bench_result_temp.end()); + } + } + } + + for (int j = bench_result.size() - 1; j >= 0; j--) { + vector> mtxvec; + vector mtx1, mtx2; + vector in; + for (int k = bench_result[j].possible_result.size() - 1; k >= 0; k--) { + vector mtxvec_temp; + in.push_back(bench_result[j].possible_result[k].tt); + mtxvec_temp.push_back(bench_result[j].possible_result[k].left); + mtxvec_temp.push_back(bench_result[j].possible_result[k].right); + mtxvec_temp.push_back(bench_result[j].possible_result[k].node); + mtxvec.push_back(mtxvec_temp); + } + in.push_back("10"); + mtx1.push_back(bench_result[j].possible_result[0].node); + mtx2.push_back(input); + mtx2.push_back(1); + mtxvec.push_back(mtx1); + mtxvec.push_back(mtx2); + vector> in_expansion = bench_expansion(in); + vector bench_temp; + for (int k = in_expansion.size() - 1; k >= 0; k--) { + string tt_temp = in_expansion[k][in_expansion[k].size() - 2]; + bench_solve(in_expansion[k], mtxvec); + if (!compare_result(in_expansion[k], tt_binary)) { + in_expansion.erase(in_expansion.begin() + k); + } else { + phyLS::result_lut bench_temp_temp = bench_result[j]; + bench_temp_temp.possible_result[0].tt = tt_temp; + bench_temp.push_back(bench_temp_temp); + } + } + if (in_expansion.empty()) + bench_result.erase(bench_result.begin() + j); + else { + bench_result.erase(bench_result.begin() + j); + bench_result.insert(bench_result.end(), bench_temp.begin(), + bench_temp.end()); + } + } + + if (bench_result.size()) { + for (int j = 0; j < bench_result.size(); j++) + lut_dags_new.push_back(bench_result[j].possible_result); + } + } + lut_dags.assign(lut_dags_new.begin(), lut_dags_new.end()); + } + + void stp_simulate_klut(vector>& lut_dags) { + string tt_binary = tt[0]; + int flag_node = lut_dags[0][lut_dags[0].size() - 1].node; + vector> lut_dags_new; + for (int i = lut_dags.size() - 1; i >= 0; i--) { + string input_tt(tt_binary); // input function + vector matrix_form = klut_to_matrix( + lut_dags[i], flag_node); // STP-based phyLS::matrix form + matrix_computution_klut(matrix_form); + + // for (auto y : lut_dags[i]) { + // cout << y.node << "-("; + // for (auto z : y.inputs) { + // cout << z << ","; + // } + // cout << ") "; + // } + // cout << endl; + // for (int i = 0; i < matrix_form.size(); i++) { + // cout << matrix_form[i].name << "_" << matrix_form[i].node << "(" + // << matrix_form[i].nr_input << ")[I" << matrix_form[i].eye << + // "] "; + // } + // cout << endl; + + vector bench_result; + result_klut first_result; + first_result.computed_input = input_tt; + first_result.possible_result = lut_dags[i]; + bench_result.push_back(first_result); + for (int l = matrix_form.size() - 1; l >= 1; l--) { + if (!matrix_form[l].input) { + int length_string = input_tt.size(); + if (matrix_form[l].name == "W") { + if (matrix_form[l].eye == 0) { + string temp1, temp2; + temp1 = input_tt.substr(length_string / 4, length_string / 4); + temp2 = input_tt.substr(length_string / 2, length_string / 4); + input_tt.replace(length_string / 4, length_string / 4, temp2); + input_tt.replace(length_string / 2, length_string / 4, temp1); + } else { + int length2 = length_string / pow(2.0, matrix_form[l].eye + 2); + for (int l1 = pow(2.0, matrix_form[l].eye), add = 1; l1 > 0; + l1--) { + string temp1, temp2; + temp1 = input_tt.substr( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add - + length2, + length2); + temp2 = input_tt.substr( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add, + length2); + input_tt.replace( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add - + length2, + length2, temp2); + input_tt.replace( + (length_string / pow(2.0, matrix_form[l].eye + 1)) * add, + length2, temp1); + add += 2; + } + } + bench_result[0].computed_input = input_tt; + } else if (matrix_form[l].name == "R") { + if (matrix_form[l].eye == 0) { + string temp(length_string, '2'); + input_tt.insert(input_tt.begin() + (length_string / 2), + temp.begin(), temp.end()); + } else { + string temp(length_string / pow(2.0, matrix_form[l].eye), '2'); + for (int l2 = pow(2.0, matrix_form[l].eye), + add1 = pow(2.0, matrix_form[l].eye + 1) - 1; + l2 > 0; l2--) { + input_tt.insert( + input_tt.begin() + + ((length_string / pow(2.0, matrix_form[l].eye + 1)) * + add1), + temp.begin(), temp.end()); + add1 -= 2; + } + } + bench_result[0].computed_input = input_tt; + } else if (matrix_form[l].name == "M") { + vector bench_result_temp; + for (int q = bench_result.size() - 1; q >= 0; q--) { + int length_string2 = bench_result[q].computed_input.size(); + // cout << "computed input: " << bench_result[q].computed_input + // << endl; + int length1 = + length_string2 / + pow(2.0, matrix_form[l].eye + + matrix_form[l].nr_input); // abcd的长度 + vector patterns; + vector placements; + for (int l3 = 0; l3 < pow(2.0, matrix_form[l].eye); l3++) { + vector> result_t; + int ind = (length_string2 / pow(2.0, matrix_form[l].eye)) * l3; + vector input_parts; + for (int l4 = 0; l4 < pow(2.0, matrix_form[l].nr_input); l4++) { + string a = bench_result[q].computed_input.substr( + ind + (length1 * l4), length1); + input_parts.push_back(a); + } + // compare all input_parts have only two modes + bool enableFactor = true; + string pattern1, pattern2; + vector placement; + for (auto x : input_parts) { + if (pattern1.empty()) { + pattern1 = x; + placement.push_back(0); + } else if (!matchPattern(x, pattern1)) { + if (pattern2.empty()) { + pattern2 = x; + placement.push_back(1); + } else if (!matchPattern(x, pattern2)) { + enableFactor = false; + break; + } else { + replaceTwos(x, pattern2); + placement.push_back(1); + } + } else { + replaceTwos(x, pattern1); + placement.push_back(0); + } + } + if (enableFactor) { + // cout << "pattern 1/2: " << pattern1 << "/" << pattern2 + // << endl; + bool enableFactor2 = true; + if (patterns.empty()) { + patterns.push_back(pattern1); + patterns.push_back(pattern2); + placements.assign(placement.begin(), placement.end()); + } else { + enableFactor2 = compare_vector(placement, placements); + if (enableFactor2) { + patterns.push_back(pattern1); + patterns.push_back(pattern2); + } else { + patterns.clear(); + placement.clear(); + placements.clear(); + break; + } + } + } else { + patterns.clear(); + placement.clear(); + placements.clear(); + break; + } + } + if (patterns.empty()) { + bench_result.erase(bench_result.begin() + q); + continue; + } else { + // cout << "patterns: "; + // for (auto x : patterns) cout << x << " "; + // cout << endl; + // cout << "placements: "; + // for (auto x : placements) { + // cout << x << " "; + // } + // cout << endl; + string count1, count2, res1, res2; + for (int m = 0; m < placements.size(); m++) { + count1 += to_string(placements[m]); + count2 += to_string(1 - placements[m]); + } + // cout << "count 1/2: " << count1 << "/" << count2 << endl; + int tt_length = pow(2.0, matrix_form[l].nr_input); + string wrong_result1(tt_length, '1'); + string wrong_result2(tt_length, '0'); + if (count1 == wrong_result1 || count1 == wrong_result2 || + count2 == wrong_result1 || count2 == wrong_result2) { + bench_result.erase(bench_result.begin() + q); + continue; + } + for (int n = 0, p = 0; n < pow(2.0, matrix_form[l].eye); n++) { + if (placements[0] == 1) { + res1 += patterns[p]; + res1 += patterns[p + 1]; + res2 += patterns[p + 1]; + res2 += patterns[p]; + } else { + res1 += patterns[p + 1]; + res1 += patterns[p]; + res2 += patterns[p]; + res2 += patterns[p + 1]; + } + } + // cout << "res 1/2: " << res1 << "/" << res2 << endl; + result_klut result_t1, result_t2; + result_t1.possible_result = bench_result[q].possible_result; + result_t2.possible_result = bench_result[q].possible_result; + for (int p = 0; p < result_t1.possible_result.size(); p++) { + if (result_t1.possible_result[p].node == matrix_form[l].node) + result_t1.possible_result[p].tt = count1; + if (result_t2.possible_result[p].node == matrix_form[l].node) + result_t2.possible_result[p].tt = count2; + } + if (res1.size() == pow(2, matrix_form[0].nr_input)) { + for (int p = 0; p < result_t1.possible_result.size(); p++) { + if (result_t1.possible_result[p].node == + matrix_form[0].node) + result_t1.possible_result[p].tt = res1; + if (result_t2.possible_result[p].node == + matrix_form[0].node) + result_t2.possible_result[p].tt = res2; + } + } else { + result_t1.computed_input = res1; + result_t2.computed_input = res2; + } + bench_result_temp.push_back(result_t1); + bench_result_temp.push_back(result_t2); + } + } + if (bench_result_temp.empty()) + break; + else + bench_result.assign(bench_result_temp.begin(), + bench_result_temp.end()); + } + } + } + + if (bench_result.size()) { + for (int j = 0; j < bench_result.size(); j++) + lut_dags_new.push_back(bench_result[j].possible_result); + break; + } + } + lut_dags.assign(lut_dags_new.begin(), lut_dags_new.end()); + } + + vector chain_to_matrix(vector lut_dags, + int flag_node) { + vector matrix_form; + phyLS::matrix temp_node, temp_left, temp_right; + temp_node.node = lut_dags[0].node; + temp_node.name = "M"; + temp_left.node = lut_dags[0].left; + temp_right.node = lut_dags[0].right; + matrix_form.push_back(temp_node); + + if (lut_dags[0].right >= flag_node) { + vector matrix_form_temp2; + matrix_generate(lut_dags, matrix_form_temp2, lut_dags[0].right); + matrix_form.insert(matrix_form.end(), matrix_form_temp2.begin(), + matrix_form_temp2.end()); + } else { + temp_right.input = 1; + string str = to_string(lut_dags[0].right); + temp_right.name = str; + matrix_form.push_back(temp_right); + } + + if (lut_dags[0].left >= flag_node) { + vector matrix_form_temp1; + matrix_generate(lut_dags, matrix_form_temp1, lut_dags[0].left); + matrix_form.insert(matrix_form.end(), matrix_form_temp1.begin(), + matrix_form_temp1.end()); + } else { + temp_left.input = 1; + string str = to_string(lut_dags[0].left); + temp_left.name = str; + matrix_form.push_back(temp_left); + } + + return matrix_form; + } + + vector klut_to_matrix(vector lut_dags, int flag_node) { + vector matrix_form; + matrix_klut temp_node; + temp_node.node = lut_dags[0].node; + temp_node.name = "M"; + temp_node.nr_input = lut_dags[0].inputs.size(); + matrix_form.push_back(temp_node); + for (int i = lut_dags[0].inputs.size() - 1; i >= 0; i--) { + if (lut_dags[0].inputs[i] >= flag_node) { + vector matrix_form_temp2; + matrix_generate_klut(lut_dags, matrix_form_temp2, + lut_dags[0].inputs[i]); + matrix_form.insert(matrix_form.end(), matrix_form_temp2.begin(), + matrix_form_temp2.end()); + } else { + matrix_klut temp_node_input; + temp_node_input.node = lut_dags[0].inputs[i]; + temp_node_input.input = true; + string str = to_string(lut_dags[0].inputs[i]); + temp_node_input.name = str; + matrix_form.push_back(temp_node_input); + } + } + return matrix_form; + } + + void matrix_computution(vector& matrix_form) { + bool status = true; + while (status) { + status = false; + for (int i = matrix_form.size() - 1; i > 1; i--) { + // 两个变量交换 + if (((matrix_form[i].name != "M") && (matrix_form[i].name != "R") && + (matrix_form[i].name != "W")) && + ((matrix_form[i - 1].name != "M") && + (matrix_form[i - 1].name != "R") && + (matrix_form[i - 1].name != "W"))) { + int left, right; + left = atoi(matrix_form[i - 1].name.c_str()); + right = atoi(matrix_form[i].name.c_str()); + // 相等变量降幂 + if (left == right) { + status = true; + phyLS::matrix reduce_matrix; + reduce_matrix.name = "R"; + matrix_form.insert(matrix_form.begin() + (i - 1), reduce_matrix); + matrix_form.erase(matrix_form.begin() + i); + } else if (left < right) { + status = true; + phyLS::matrix swap_matrix; + swap_matrix.name = "W"; + swap(matrix_form[i - 1], matrix_form[i]); + matrix_form.insert(matrix_form.begin() + (i - 1), swap_matrix); + } + } + // 变量与矩阵交换 + if (((matrix_form[i].name == "M") || (matrix_form[i].name == "R") || + (matrix_form[i].name == "W")) && + ((matrix_form[i - 1].name != "M") && + (matrix_form[i - 1].name != "R") && + (matrix_form[i - 1].name != "W"))) { + status = true; + matrix_form[i].eye += 1; + swap(matrix_form[i - 1], matrix_form[i]); + } + } + } + } + + void matrix_computution_klut(vector& matrix_form) { + bool status = true; + while (status) { + status = false; + for (int i = matrix_form.size() - 1; i > 1; i--) { + // 两个变量交换 + if (((matrix_form[i].name != "M") && (matrix_form[i].name != "R") && + (matrix_form[i].name != "W")) && + ((matrix_form[i - 1].name != "M") && + (matrix_form[i - 1].name != "R") && + (matrix_form[i - 1].name != "W"))) { + int left, right; + left = atoi(matrix_form[i - 1].name.c_str()); + right = atoi(matrix_form[i].name.c_str()); + // 相等变量降幂 + if (left == right) { + status = true; + matrix_klut reduce_matrix; + reduce_matrix.name = "R"; + matrix_form.insert(matrix_form.begin() + (i - 1), reduce_matrix); + matrix_form.erase(matrix_form.begin() + i); + } else if (left < right) { + status = true; + matrix_klut swap_matrix; + swap_matrix.name = "W"; + swap(matrix_form[i - 1], matrix_form[i]); + matrix_form.insert(matrix_form.begin() + (i - 1), swap_matrix); + } + } + // 变量与矩阵交换 + if (((matrix_form[i].name == "M") || (matrix_form[i].name == "R") || + (matrix_form[i].name == "W")) && + ((matrix_form[i - 1].name != "M") && + (matrix_form[i - 1].name != "R") && + (matrix_form[i - 1].name != "W"))) { + status = true; + matrix_form[i].eye += 1; + swap(matrix_form[i - 1], matrix_form[i]); + } + } + } + } + + void matrix_generate(vector lut, + vector& matrix_form, int node) { + int flag = lut[lut.size() - 1].node; + for (int i = 0; i < lut.size(); i++) { + if (lut[i].node == node) { + phyLS::matrix temp_node, temp_left, temp_right; + temp_node.node = node; + temp_node.name = "M"; + matrix_form.push_back(temp_node); + if (lut[i].right >= flag) { + vector matrix_form_temp2; + matrix_generate(lut, matrix_form_temp2, lut[i].right); + matrix_form.insert(matrix_form.end(), matrix_form_temp2.begin(), + matrix_form_temp2.end()); + } else { + temp_right.input = 1; + temp_right.node = lut[i].right; + string str = to_string(lut[i].right); + temp_right.name = str; + matrix_form.push_back(temp_right); + } + if (lut[i].left >= flag) { + vector matrix_form_temp1; + matrix_generate(lut, matrix_form_temp1, lut[i].left); + matrix_form.insert(matrix_form.begin() + 1, matrix_form_temp1.begin(), + matrix_form_temp1.end()); + } else { + temp_left.input = 1; + temp_left.node = lut[i].left; + string str = to_string(lut[i].left); + temp_left.name = str; + matrix_form.push_back(temp_left); + } + } + } + } + + void matrix_generate_klut(vector lut, vector& matrix_form, + int node) { + int flag = lut[lut.size() - 1].node; + for (int i = 0; i < lut.size(); i++) { + if (lut[i].node == node) { + matrix_klut temp_node; + temp_node.node = node; + temp_node.name = "M"; + temp_node.nr_input = lut[i].inputs.size(); + matrix_form.push_back(temp_node); + for (int j = lut[i].inputs.size() - 1; j >= 0; j--) { + if (lut[i].inputs[j] >= flag) { + vector matrix_form_temp2; + matrix_generate_klut(lut, matrix_form_temp2, lut[i].inputs[j]); + matrix_form.insert(matrix_form.end(), matrix_form_temp2.begin(), + matrix_form_temp2.end()); + } else { + matrix_klut temp_node_input; + temp_node_input.node = lut[i].inputs[j]; + temp_node_input.input = 1; + string str = to_string(lut[i].inputs[j]); + temp_node_input.name = str; + matrix_form.push_back(temp_node_input); + } + } + } + } + } + + bool matchPattern(string str, string pattern) { + for (size_t i = 0; i < pattern.length(); i++) { + if (pattern[i] == '2' || str[i] == '2') continue; + if (pattern[i] != str[i]) return false; + } + return true; + } + + void replaceTwos(string str, string& pattern) { + for (size_t i = 0; i < pattern.length(); i++) { + if (pattern[i] == '2') pattern[i] = str[i]; + } + } + + bool compare_string(string a, string b) { + bool target = 1; + for (int i = 0; i < a.size(); i++) { + if ((a[i] != b[i]) && a[i] != '2' && b[i] != '2') { + target = 0; + } + } + return target; + } + + bool compare_vector(vector a, vector b) { + bool target = 0; + if (a == b) { + target = 1; + } else { + for (int i = 0; i < a.size(); i++) { + if (a[i] == 1) { + a[i] = 0; + } else if (a[i] == 0) { + a[i] = 1; + } + } + if (a == b) { + target = 1; + } + } + return target; + } + + bool compare_result(vector t1, string t2) { + bool target = false; + string t3(t2.size(), '0'); + for (int i = 0; i < t1.size(); i++) { + char temp; + for (int j = 0; j < t1[i].size() / 2; j++) { + temp = t1[i][j]; + t1[i][j] = t1[i][t1[i].size() - 1 - j]; + t1[i][t1[i].size() - 1 - j] = temp; + } + int value = stoi(t1[i], 0, 2); + int ind = t3.size() - value - 1; + t3[ind] = '1'; + } + if (t2 == t3) { + target = true; + } + return target; + } + + void vector_generate(vector result_b, vector>& result_a) { + for (int i = 0; i < result_b.size(); i++) { + if (result_b[i] != 2) { + if (result_a.empty()) { + vector temp; + temp.push_back(result_b[i]); + result_a.push_back(temp); + } else { + vector> result_a_temp; + for (int j = 0; j < result_a.size(); j++) { + vector temp(result_a[j]); + temp.push_back(result_b[i]); + result_a_temp.push_back(temp); + } + result_a.assign(result_a_temp.begin(), result_a_temp.end()); + } + } else { + if (result_a.empty()) { + vector temp1(1, 1); + vector temp2(1, 0); + result_a.push_back(temp1); + result_a.push_back(temp2); + } else { + vector> result_a_temp; + for (int j = 0; j < result_a.size(); j++) { + vector temp1(result_a[j]); + vector temp2(result_a[j]); + temp1.push_back(1); + temp2.push_back(0); + result_a_temp.push_back(temp1); + result_a_temp.push_back(temp2); + } + result_a.assign(result_a_temp.begin(), result_a_temp.end()); + } + } + } + } + + void bench_solve(vector& in, vector> mtxvec) { + int length1 = mtxvec[mtxvec.size() - 1][0]; // number of primary input + int length2 = mtxvec[mtxvec.size() - 1][1]; // number of primary output + int length3 = mtxvec[0][2]; // the minimum minuend + int length4 = + mtxvec[mtxvec.size() - 2 - length2][2]; // the maximum variable + vector> + list; // the solution space is two dimension vector + vector list_temp; + phyLS::cdccl_impl list_temp_temp; + + string Result_temp(length1, '2'); // temporary result + phyLS::coordinate Level_temp; + Level_temp.Abscissa = -1; + Level_temp.Ordinate = -1; + Level_temp.parameter_Intermediate = -1; + Level_temp.parameter_Gate = -1; + list_temp_temp.Level.resize( + length4, Level_temp); // Initialize level as a space with the size of + // variables(length4) + /* + * initialization + */ + phyLS::coordinate Gate_level; + Gate_level.Abscissa = 0; + Gate_level.Ordinate = 0; + Gate_level.parameter_Intermediate = -1; + Gate_level.parameter_Gate = -1; + string Intermediate_temp; + for (int i = mtxvec.size() - 1 - length2; i < mtxvec.size() - 1; + i++) // the original intermediate + { + if (mtxvec[i][0] < length3) { + if (in[i][0] == '1') + Result_temp[mtxvec[i][0] - 1] = '1'; + else + Result_temp[mtxvec[i][0] - 1] = '0'; + } else { + list_temp_temp.Gate.push_back(mtxvec[i][0]); + if (in[i][0] == '1') + Intermediate_temp += "1"; + else + Intermediate_temp += "0"; + } + list_temp_temp.Level[mtxvec[i][0] - 1] = Gate_level; + } + list_temp_temp.Result = Result_temp; + list_temp_temp.Intermediate.push_back(Intermediate_temp); + list_temp.push_back(list_temp_temp); // level 0 + list.push_back(list_temp); + /* + * The first level information + */ + int count1 = 0; + for (int level = 0;; level++) // the computation process + { + int flag = 0, ordinate = 0; // the flag of the end of the loop & the + // ordinate of each level's gate + vector list_temp1; + for (int k = 0; k < list[level].size(); k++) { + phyLS::cdccl_impl temp1; // temporary gate + temp1.Result = list[level][k].Result; // first, next level's Result is + // same as the front level + for (int j = 0; j < list[level][k].Intermediate.size(); j++) { + temp1.Level = list[level][k].Level; // next level's Level information + for (int j1 = 0; j1 < list[level][k].Gate.size(); j1++) { + temp1.Level[list[level][k].Gate[j1] - 1].parameter_Intermediate = j; + temp1.Level[list[level][k].Gate[j1] - 1].parameter_Gate = j1; + } + + phyLS::coordinate level_current; // new level + level_current.Abscissa = level + 1; + level_current.parameter_Intermediate = -1; + level_current.parameter_Gate = -1; + level_current.Ordinate = ordinate; + + temp1.Gate.assign(list[level][k].Gate.begin(), + list[level][k].Gate.end()); // need more!!!!! + temp1.Intermediate.push_back(list[level][k].Intermediate[j]); + + vector Intermediate_temp; + vector Gate_temp; + vector Gate_judge(length4, -1); + int count_cdccl = 0; + for (int i = 0; i < temp1.Gate.size(); i++) { + int length = temp1.Gate[i] - length3; + int Gate_f = mtxvec[length][0]; // the front Gate variable + int Gate_b = mtxvec[length][1]; // the behind Gate variable + string tt = in[length]; // the correndsponding Truth Table + char target = temp1.Intermediate[0][i]; // the SAT target + vector Intermediate_temp_temp; + + int flag_cdccl = 0; + string Intermediate_temp_temp_F, Intermediate_temp_temp_B; + if (temp1.Level[Gate_f - 1].Abscissa >= 0) { + if (Gate_f < length3) { + char contrast_R1 = list[temp1.Level[Gate_f - 1].Abscissa] + [temp1.Level[Gate_f - 1].Ordinate] + .Result[Gate_f - 1]; + Intermediate_temp_temp_F.push_back(contrast_R1); + } else { + char contrast_I1 = + list[temp1.Level[Gate_f - 1].Abscissa] + [temp1.Level[Gate_f - 1].Ordinate] + .Intermediate + [temp1.Level[Gate_f - 1].parameter_Intermediate] + [temp1.Level[Gate_f - 1].parameter_Gate]; + Intermediate_temp_temp_F.push_back(contrast_I1); + } + flag_cdccl += 1; + } + if (temp1.Level[Gate_b - 1].Abscissa >= 0) { + if (Gate_b < length3) { + char contrast_R2 = list[temp1.Level[Gate_b - 1].Abscissa] + [temp1.Level[Gate_b - 1].Ordinate] + .Result[Gate_b - 1]; + Intermediate_temp_temp_B.push_back(contrast_R2); + } else { + char contrast_I2 = + list[temp1.Level[Gate_b - 1].Abscissa] + [temp1.Level[Gate_b - 1].Ordinate] + .Intermediate + [temp1.Level[Gate_b - 1].parameter_Intermediate] + [temp1.Level[Gate_b - 1].parameter_Gate]; + Intermediate_temp_temp_B.push_back(contrast_I2); + } + flag_cdccl += 2; + } + if (Intermediate_temp.size() == 0) { + if (flag_cdccl == 0) { + Gate_judge[Gate_f - 1] = count_cdccl; + count_cdccl += 1; + Gate_judge[Gate_b - 1] = count_cdccl; + count_cdccl += 1; + Gate_temp.push_back(Gate_f); + Gate_temp.push_back(Gate_b); + if (tt[0] == target) Intermediate_temp_temp.push_back("11"); + if (tt[1] == target) Intermediate_temp_temp.push_back("01"); + if (tt[2] == target) Intermediate_temp_temp.push_back("10"); + if (tt[3] == target) Intermediate_temp_temp.push_back("00"); + } else if (flag_cdccl == 1) { + Gate_judge[Gate_b - 1] = count_cdccl; + count_cdccl += 1; + Gate_temp.push_back(Gate_b); + if (tt[0] == target) { + if (Intermediate_temp_temp_F == "1") + Intermediate_temp_temp.push_back("1"); + } + if (tt[1] == target) { + if (Intermediate_temp_temp_F == "0") + Intermediate_temp_temp.push_back("1"); + } + if (tt[2] == target) { + if (Intermediate_temp_temp_F == "1") + Intermediate_temp_temp.push_back("0"); + } + if (tt[3] == target) { + if (Intermediate_temp_temp_F == "0") + Intermediate_temp_temp.push_back("0"); + } + } else if (flag_cdccl == 2) { + Gate_judge[Gate_f - 1] = count_cdccl; + count_cdccl += 1; + Gate_temp.push_back(Gate_f); + if (tt[0] == target) { + if (Intermediate_temp_temp_B == "1") + Intermediate_temp_temp.push_back("1"); + } + if (tt[1] == target) { + if (Intermediate_temp_temp_B == "1") + Intermediate_temp_temp.push_back("0"); + } + if (tt[2] == target) { + if (Intermediate_temp_temp_B == "0") + Intermediate_temp_temp.push_back("1"); + } + if (tt[3] == target) { + if (Intermediate_temp_temp_B == "0") + Intermediate_temp_temp.push_back("0"); + } + } else { + int t0 = 0, t1 = 0, t2 = 0, t3 = 0; + if (tt[0] == target) { + if ((Intermediate_temp_temp_F == "1") && + (Intermediate_temp_temp_B == "1")) + t0 = 1; + } + if (tt[1] == target) { + if ((Intermediate_temp_temp_F == "0") && + (Intermediate_temp_temp_B == "1")) + t1 = 1; + } + if (tt[2] == target) { + if ((Intermediate_temp_temp_F == "1") && + (Intermediate_temp_temp_B == "0")) + t2 = 1; + } + if (tt[3] == target) { + if ((Intermediate_temp_temp_F == "0") && + (Intermediate_temp_temp_B == "0")) + t3 = 1; + } + if ((t0 == 1) || (t1 == 1) || (t2 == 1) || (t3 == 1)) { + Gate_judge[Gate_f - 1] = count_cdccl; + count_cdccl += 1; + Gate_judge[Gate_b - 1] = count_cdccl; + count_cdccl += 1; + Gate_temp.push_back(Gate_f); + Gate_temp.push_back(Gate_b); + if (t0 == 1) Intermediate_temp_temp.push_back("11"); + if (t1 == 1) Intermediate_temp_temp.push_back("01"); + if (t2 == 1) Intermediate_temp_temp.push_back("10"); + if (t3 == 1) Intermediate_temp_temp.push_back("00"); + } + } + } else { + if (flag_cdccl == 0) { + int count_Gate_f = 0, count_Gate_b = 0; + for (int j = 0; j < Intermediate_temp.size(); j++) { + int flag; + string t1, t2, t3, t4; + if (Gate_judge[Gate_f - 1] < 0) { + count_Gate_f = 1; + if (tt[0] == target) t1 = "1"; + if (tt[1] == target) t2 = "0"; + if (tt[2] == target) t3 = "1"; + if (tt[3] == target) t4 = "0"; + flag = 1; + } else { + int count_sat = 0; + if (tt[0] == target) { + if (Intermediate_temp[j][Gate_judge[Gate_f - 1]] == '1') { + t1 = "11"; + count_sat += 1; + } + } + if (tt[1] == target) { + if (Intermediate_temp[j][Gate_judge[Gate_f - 1]] == '0') { + t2 = "01"; + count_sat += 1; + } + } + if (tt[2] == target) { + if (Intermediate_temp[j][Gate_judge[Gate_f - 1]] == '1') { + t3 = "10"; + count_sat += 1; + } + } + if (tt[3] == target) { + if (Intermediate_temp[j][Gate_judge[Gate_f - 1]] == '0') { + t4 = "00"; + count_sat += 1; + } + } + if (count_sat == 0) continue; + flag = 2; + } + if (Gate_judge[Gate_b - 1] < 0) { + count_Gate_b = 1; + if (flag == 1) { + if (t1 == "1") { + t1 += "1"; + string result_temporary(Intermediate_temp[j]); + result_temporary += t1; + Intermediate_temp_temp.push_back(result_temporary); + } + if (t2 == "0") { + t2 += "1"; + string result_temporary(Intermediate_temp[j]); + result_temporary += t2; + Intermediate_temp_temp.push_back(result_temporary); + } + if (t3 == "1") { + t3 += "0"; + string result_temporary(Intermediate_temp[j]); + result_temporary += t3; + Intermediate_temp_temp.push_back(result_temporary); + } + if (t4 == "0") { + t4 += "0"; + string result_temporary(Intermediate_temp[j]); + result_temporary += t4; + Intermediate_temp_temp.push_back(result_temporary); + } + } + if (flag == 2) { + if (t1 == "11") { + t1 = "1"; + string result_temporary(Intermediate_temp[j]); + result_temporary += t1; + Intermediate_temp_temp.push_back(result_temporary); + } + if (t2 == "01") { + t2 = "1"; + string result_temporary(Intermediate_temp[j]); + result_temporary += t2; + Intermediate_temp_temp.push_back(result_temporary); + } + if (t3 == "10") { + t3 = "0"; + string result_temporary(Intermediate_temp[j]); + result_temporary += t3; + Intermediate_temp_temp.push_back(result_temporary); + } + if (t4 == "00") { + t4 = "0"; + string result_temporary(Intermediate_temp[j]); + result_temporary += t4; + Intermediate_temp_temp.push_back(result_temporary); + } + } + } else { + if (flag == 1) { + if (tt[0] == target) { + if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == + '1') { + string result_temporary(Intermediate_temp[j]); + result_temporary += t1; + Intermediate_temp_temp.push_back(result_temporary); + } + } + if (tt[1] == target) { + if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == + '1') { + string result_temporary(Intermediate_temp[j]); + result_temporary += t2; + Intermediate_temp_temp.push_back(result_temporary); + } + } + if (tt[2] == target) { + if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == + '0') { + string result_temporary(Intermediate_temp[j]); + result_temporary += t3; + Intermediate_temp_temp.push_back(result_temporary); + } + } + if (tt[3] == target) { + if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == + '0') { + string result_temporary(Intermediate_temp[j]); + result_temporary += t4; + Intermediate_temp_temp.push_back(result_temporary); + } + } + } + if (flag == 2) { + int count_sat1 = 0; + if (t1 == "11") { + if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == '1') + count_sat1 += 1; + } + if (t2 == "01") { + if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == '1') + count_sat1 += 1; + } + if (t3 == "10") { + if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == '0') + count_sat1 += 1; + } + if (t4 == "00") { + if (Intermediate_temp[j][Gate_judge[Gate_b - 1]] == '0') + count_sat1 += 1; + } + if (count_sat1 > 0) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + } + } + if (count_Gate_f == 1) { + Gate_judge[Gate_f - 1] = count_cdccl; + count_cdccl += 1; + Gate_temp.push_back(Gate_f); + } + if (count_Gate_b == 1) { + Gate_judge[Gate_b - 1] = count_cdccl; + count_cdccl += 1; + Gate_temp.push_back(Gate_b); + } + } else if (flag_cdccl == 1) { + int flag_1 = 0; + for (int j = 0; j < Intermediate_temp.size(); j++) { + if (Gate_judge[Gate_b - 1] < 0) { + flag_1 = 1; + if (tt[0] == target) { + if (Intermediate_temp_temp_F == "1") { + string Intermediate_temp_temp1(Intermediate_temp[j]); + Intermediate_temp_temp1 += "1"; + Intermediate_temp_temp.push_back( + Intermediate_temp_temp1); + } + } + if (tt[1] == target) { + if (Intermediate_temp_temp_F == "0") { + string Intermediate_temp_temp1(Intermediate_temp[j]); + Intermediate_temp_temp1 += "1"; + Intermediate_temp_temp.push_back( + Intermediate_temp_temp1); + } + } + if (tt[2] == target) { + if (Intermediate_temp_temp_F == "1") { + string Intermediate_temp_temp1(Intermediate_temp[j]); + Intermediate_temp_temp1 += "0"; + Intermediate_temp_temp.push_back( + Intermediate_temp_temp1); + } + } + if (tt[3] == target) { + if (Intermediate_temp_temp_F == "0") { + string Intermediate_temp_temp1(Intermediate_temp[j]); + Intermediate_temp_temp1 += "0"; + Intermediate_temp_temp.push_back( + Intermediate_temp_temp1); + } + } + } else { + if (tt[0] == target) { + if ((Intermediate_temp[j][Gate_judge[Gate_b - 1]] == + '1') && + (Intermediate_temp_temp_F == "1")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + if (tt[1] == target) { + if ((Intermediate_temp[j][Gate_judge[Gate_b - 1]] == + '1') && + (Intermediate_temp_temp_F == "0")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + if (tt[2] == target) { + if ((Intermediate_temp[j][Gate_judge[Gate_b - 1]] == + '0') && + (Intermediate_temp_temp_F == "1")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + if (tt[3] == target) { + if ((Intermediate_temp[j][Gate_judge[Gate_b - 1]] == + '0') && + (Intermediate_temp_temp_F == "0")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + } + } + if (flag_1 == 1) { + Gate_judge[Gate_b - 1] = count_cdccl; + count_cdccl += 1; + Gate_temp.push_back(Gate_b); + } + } else if (flag_cdccl == 2) { + int flag_2 = 0; + for (int j = 0; j < Intermediate_temp.size(); j++) { + if (Gate_judge[Gate_f - 1] < 0) { + flag_2 = 1; + if (tt[0] == target) { + if (Intermediate_temp_temp_B == "1") { + string Intermediate_temp_temp1(Intermediate_temp[j]); + Intermediate_temp_temp1 += "1"; + Intermediate_temp_temp.push_back( + Intermediate_temp_temp1); + } + } + if (tt[1] == target) { + if (Intermediate_temp_temp_B == "1") { + string Intermediate_temp_temp1(Intermediate_temp[j]); + Intermediate_temp_temp1 += "0"; + Intermediate_temp_temp.push_back( + Intermediate_temp_temp1); + } + } + if (tt[2] == target) { + if (Intermediate_temp_temp_B == "0") { + string Intermediate_temp_temp1(Intermediate_temp[j]); + Intermediate_temp_temp1 += "1"; + Intermediate_temp_temp.push_back( + Intermediate_temp_temp1); + } + } + if (tt[3] == target) { + if (Intermediate_temp_temp_B == "0") { + string Intermediate_temp_temp1(Intermediate_temp[j]); + Intermediate_temp_temp1 += "0"; + Intermediate_temp_temp.push_back( + Intermediate_temp_temp1); + } + } + } else { + if (tt[0] == target) { + if ((Intermediate_temp[j][Gate_judge[Gate_f - 1]] == + '1') && + (Intermediate_temp_temp_B == "1")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + if (tt[1] == target) { + if ((Intermediate_temp[j][Gate_judge[Gate_f - 1]] == + '0') && + (Intermediate_temp_temp_B == "1")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + if (tt[2] == target) { + if ((Intermediate_temp[j][Gate_judge[Gate_f - 1]] == + '1') && + (Intermediate_temp_temp_B == "0")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + if (tt[3] == target) { + if ((Intermediate_temp[j][Gate_judge[Gate_f - 1]] == + '0') && + (Intermediate_temp_temp_B == "0")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + } + } + if (flag_2 == 1) { + Gate_judge[Gate_f - 1] = count_cdccl; + count_cdccl += 1; + Gate_temp.push_back(Gate_f); + } + } else { + for (int j = 0; j < Intermediate_temp.size(); j++) { + if (tt[0] == target) { + if ((Intermediate_temp_temp_F == "1") && + (Intermediate_temp_temp_B == "1")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + if (tt[1] == target) { + if ((Intermediate_temp_temp_F == "0") && + (Intermediate_temp_temp_B == "1")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + if (tt[2] == target) { + if ((Intermediate_temp_temp_F == "1") && + (Intermediate_temp_temp_B == "0")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + if (tt[3] == target) { + if ((Intermediate_temp_temp_F == "0") && + (Intermediate_temp_temp_B == "0")) + Intermediate_temp_temp.push_back(Intermediate_temp[j]); + } + } + } + } + Intermediate_temp.assign(Intermediate_temp_temp.begin(), + Intermediate_temp_temp.end()); + if (Intermediate_temp_temp.size() == 0) break; + } + temp1.Intermediate.assign(Intermediate_temp.begin(), + Intermediate_temp.end()); + temp1.Gate.assign(Gate_temp.begin(), Gate_temp.end()); + for (int l = 0; l < temp1.Gate.size(); l++) + temp1.Level[temp1.Gate[l] - 1] = level_current; + + int count = 0; // whether there is a PI assignment + for (int k = 0; k < temp1.Intermediate.size(); + k++) // mix the Result and the Intermediate information in one + // level + { + count = 1; + phyLS::cdccl_impl temp2; + temp2.Level = temp1.Level; + string Result_temp(temp1.Result); + temp2.Gate.assign(temp1.Gate.begin(), temp1.Gate.end()); + string Intermediate_temp1(temp1.Intermediate[k]); + int count1 = 0, count2 = 0; // whether the assignment made + for (int k11 = 0; k11 < temp1.Gate.size(); k11++) { + if (temp1.Gate[k11] < + length3) // if the Gate is smaller than length3, it is PI + { + temp2.Level[temp1.Gate[k11] - 1].Ordinate = ordinate; + if ((temp1.Result[temp1.Gate[k11] - 1] == '2') || + (temp1.Result[temp1.Gate[k11] - 1] == + temp1.Intermediate[k][k11])) // whether the PI can be + // assigned a value + Result_temp[temp1.Gate[k11] - 1] = temp1.Intermediate[k][k11]; + else + count1 = 1; // if one assignment can't make, the count1 = 1 + Intermediate_temp1.erase(Intermediate_temp1.begin() + + (k11 - count2)); + temp2.Gate.erase(temp2.Gate.begin() + (k11 - count2)); + count++, count2++; + } + } + if (count1 == 0) { + temp2.Result = Result_temp; + temp2.Intermediate.push_back(Intermediate_temp1); + for (int k12 = 0; k12 < temp2.Gate.size(); k12++) + temp2.Level[temp2.Gate[k12] - 1].Ordinate = ordinate; + } + if (count == 1) + break; + else if (temp2.Result.size() > 0) { + list_temp1.push_back(temp2); + ordinate += 1; + if (temp2.Gate.empty()) flag += 1; + } + } + if (count == 1) { + list_temp1.push_back(temp1); + ordinate += 1; + if (temp1.Gate.empty()) flag += 1; + } + temp1.Intermediate.clear(); + } + } + list.push_back(list_temp1); // next level's information + if (flag == list[level + 1].size()) // in one level, if all node's Gate + // is empty, then break the loop + break; + } + + in.clear(); + for (int j = 0; j < list[list.size() - 1].size(); j++) // all result + in.push_back(list[list.size() - 1][j].Result); + } + + vector> bench_expansion(vector in) { + vector> in_expansion; + in_expansion.push_back(in); + string in_end = in[in.size() - 2]; + for (int i = 0; i < in_end.size(); i++) { + if (in_end[i] == '2') { + vector> in_expansion_temp; + for (int j = 0; j < in_expansion.size(); j++) { + vector in_temp_1(in_expansion[j]); + vector in_temp_0(in_expansion[j]); + in_temp_1[in_expansion[j].size() - 2][i] = '1'; + in_temp_0[in_expansion[j].size() - 2][i] = '0'; + in_expansion_temp.push_back(in_temp_1); + in_expansion_temp.push_back(in_temp_0); + } + in_expansion.assign(in_expansion_temp.begin(), in_expansion_temp.end()); + } + } + return in_expansion; + } + + private: + vector& tt; + int& input; + int& cut_size; +}; + +void exact_lut(vector& tt, int& input, int& cut_size) { + exact_lut_impl p(tt, input, cut_size); + p.run(); +} + +void exact_lut_enu(vector& tt, int& input, int& cut_size) { + exact_lut_impl p(tt, input, cut_size); + p.run_enu(); +} + +void exact_lut_mapping(vector& tt, int& input, int& cut_size) { + exact_lut_impl p(tt, input, cut_size); + p.run_lut(); +} } // namespace phyLS -#endif +#endif \ No newline at end of file diff --git a/src/phyLS.cpp b/src/phyLS.cpp index b377b82..0e3a9e4 100644 --- a/src/phyLS.cpp +++ b/src/phyLS.cpp @@ -76,7 +76,7 @@ #include "commands/xag/xagrs.hpp" #include "commands/xmg/xmgrs.hpp" #include "commands/xmg/xmgrw.hpp" -#include "commands/exact/exact_multi.hpp" +// #include "commands/exact/exact_multi.hpp" #include "commands/exact/exact_klut.hpp" #include "commands/exact/exactlut.hpp" #include "commands/to_npz.hpp"