#pragma once #include #include #include #include #include using ll = long long; class Gate { public: int id; std::string name; enum Type { AND, NAND, OR, NOR, XOR, XNOR, NOT, BUF, INPUT } type; int value; bool sa[2]; bool stem; bool isPI; bool isPO; std::unordered_map> sa_by_out; std::vector pre_stems; std::vector suc_stems; std::vector outputs; std::vector inputs; bool is_propagated(); int cal_value(); }; class Fault { public: Gate* gate; enum Type { SA0, SA1 } type; Fault(Gate* gate, Type type):gate(gate),type(type) {} }; class Circuit { public: std::vector PIs; std::vector POs; std::vector gates; std::vector stems; // PI + stems std::unordered_map name2gate; std::queue tmp; std::unordered_map tmp_used; void parse_from_file(const char *filename); void print_gates(); bool is_valid_circuit(); void init_topo_index(); void init_stems(); // local search bool local_search(std::unordered_set &faults); // incremental flip struct const double SP = 0.01; const int FLIP_INC = 1; const int FLIP_WEIGHT_MAX = 1e9; int* CC; ll flip_total_weight; int flip_total_cnt; int* flip_weight; int* flip_need_update; std::vector flip_update_queue; // incremental stem struct const int STEM_INC = 20; const int STEM_WEIGHT_MAX = 1e9; ll stem_total_weight; int stem_total_cnt; int* stem_weight; int* stem_satisfied; const int FAULT_INC = 1; const int FAULT_WEIGHT_MAX = 20; ll fault_total_weight; int fault_total_cnt; int** fault_weight; int** fault_detected; void ls_init_circuit(); void ls_init_weight(const std::unordered_set &faults); void ls_update_weight(); void ls_init_data_structs(); void ls_block_recal(Gate* stem); void ls_flip(Gate* stem); void ls_update(Gate* stem); ll ls_pick_score(Gate* stem); ll ls_score(); };