#include "circuit.h" #include #include #include #include "assert.h" std::vector Circuit::local_search(const std::vector &faults) { // local search vector ls_init_circuit(); printf("local search!\n"); //ls_flip(PIs[0]); print_gates(); return std::vector(); } bool cmp(Gate* a, Gate *b) { return a->topo > b->topo; } void Circuit::ls_flip(Gate* stem) { printf("flip: %s\n", stem->name.c_str()); //stem->value = !stem->value; if(stem->isPO) { stem->sa[!stem->value] = true; stem->sa[stem->value] = false; } std::queue q; std::unordered_map used; std::vector suc_stems; q.push(stem); while(!q.empty()) { Gate* g = q.front(); q.pop(); used[g] = false; for(Gate* out : g->outputs) { if(out->stem) { suc_stems.push_back(out); continue; } out->value = out->cal_value(); if(!used[out]) { used[out] = true; q.push(out); } } } assert(q.empty()); used.clear(); // update path info std::vector update_list; for(Gate* stem : suc_stems) { q.push(stem); //printf("suc: %s\n", stem->name.c_str()); } while(!q.empty()) { Gate *g = q.front(); q.pop(); used[g] = false; bool right_value = (g->cal_value() == g->value); for(Gate* in : g->inputs) { in->value = !in->value; bool input_detected = (g->cal_value() != g->value); in->value = !in->value; bool sa0 = right_value && input_detected && g->sa[!g->value] && in->value; bool sa1 = right_value && input_detected && g->sa[!g->value] && !in->value; //printf("gate: %s -> %s rv: %d id: %d p:%d sa0: %d sa1: %d\n", in->name.c_str(), g->name.c_str(), right_value, input_detected, g->is_propagated(), sa0, sa1); in->sa_by_out[g] = std::make_pair(sa0, sa1); bool old_sa[2]; old_sa[0] = in->sa[0]; old_sa[1] = in->sa[1]; in->sa[0] = in->sa[1] = 0; for(Gate* out : in->outputs) { auto &p = in->sa_by_out[out]; //printf("%d %d\n", p.first, p.second); in->sa[0] |= p.first; in->sa[1] |= p.second; } if(in->stem && (in->sa[0] != old_sa[0] || in->sa[0] != old_sa[0])) { for(Gate* pre : in->pre_stems) { if(!tmp_used[pre]) { tmp_used[pre] = true; tmp.push(pre); } } } //printf("gate: %s -> %s rv: %d id: %d p:%d sa0: %d sa1: %d\n", in->name.c_str(), g->name.c_str(), right_value, input_detected, g->is_propagated(), in->sa[0], in->sa[1]); if(!in->stem && !used[in]) { used[in] = true; q.push(in); } } } } void Circuit::ls_init_circuit() { // for(auto pi : PIs) { // pi->value = rand() % 2; // } for(Gate* s : stems) { s->value = rand() % 2; } for(int i=stems.size()-1; i>=0; i--) { stems[i]->value = !stems[i]->value; ls_flip(stems[i]); } while(!tmp.empty()) { Gate* g = tmp.front(); tmp.pop(); tmp_used[g] = false; ls_flip(g); } }