#pragma once #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 block; 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 std::vector local_search(const std::vector &faults); // incremental flip struct ll flip_total_weight; int* flip_weight; int* flip_need_update; std::vector flip_update_queue; // incremental stem struct ll stem_total_weight; int* stem_weight; int* stem_satisfied; ll fault_total_weight; int** fault_weight; int** fault_detected; void ls_init_circuit(); void ls_init_weight(const std::vector &faults); void ls_init_data_structs(); void ls_block_recal(Gate* stem); void ls_flip(Gate* stem); void ls_update(Gate* stem); int ls_score(Gate* stem); };