#include "light.hpp" #include "workers/basekissat.hpp" #include "workers/sharer.hpp" #include #include #include #include auto clk_st = std::chrono::high_resolution_clock::now(); char* worker_sign = ""; std::mutex mtx; std::atomic terminated; int result = 0; int winner; vec model; void * read_worker(void *arg) { basesolver * sq = (basesolver *)arg; if (worker_sign == "") sq->import_original_clause(sq->controller->pre); else sq->parse_dimacs(worker_sign); return NULL; } void * solve_worker(void *arg) { basesolver * sq = (basesolver *)arg; while (!terminated) { int res = sq->solve(); vec seq_model; if (res == 10) { sq->get_model(seq_model); } if (res && !terminated) { printf("c result: %d, winner is %d\n", res, sq->id); terminated = 1; sq->controller->terminate_workers(); result = res; winner = sq->id; if (res == 10) seq_model.copyTo(model); } seq_model.clear(); // printf("get result %d with res %d\n", sq->id, res); } return NULL; } void light::init_workers() { terminated = 0; for (int i = 0; i < OPT(threads); i++) { basekissat* kissat = new basekissat(i, this); workers.push(kissat); } } void light::diversity_workers() { for (int i = 0; i < OPT(threads); i++) { workers[i]->diversity(i); } } void light::terminate_workers() { for (int i = 0; i < OPT(threads); i++) { workers[i]->terminate(); } for (int i = 0; i < sharers.size(); i++) { sharers[i]->set_terminated(); } } void light::parse_input() { pthread_t *ptr = new pthread_t[OPT(threads)]; for (int i = 0; i < OPT(threads); i++) { pthread_create(&ptr[i], NULL, read_worker, workers[i]); } for (int i = 0; i < OPT(threads); i++) { pthread_join(ptr[i], NULL); } delete []ptr; } int light::solve() { printf("c -----------------solve start----------------------\n"); pthread_t *ptr = new pthread_t[OPT(threads)]; for (int i = 0; i < OPT(threads); i++) { pthread_create(&ptr[i], NULL, solve_worker, workers[i]); } thread_inf unimprove[OPT(threads)]; auto clk_sol_st = std::chrono::high_resolution_clock::now(); int pre_time = std::chrono::duration_cast(clk_sol_st - clk_st).count(); int sol_thd = 0, intv_time = OPT(reset_time); while (!terminated) { usleep(100000); auto clk_now = std::chrono::high_resolution_clock::now(); int solve_time = std::chrono::duration_cast(clk_now - clk_st).count(); if (solve_time >= OPT(times)) { terminated = 1; terminate_workers(); } if (OPT(reset) && solve_time >= pre_time + intv_time) { pre_time = solve_time; intv_time += OPT(reset_time); sol_thd = 0; for (int i = 0; i < OPT(threads); i++) { unimprove[sol_thd++] = (thread_inf) {i, workers[i]->get_reset_data()}; } std::sort(unimprove, unimprove + sol_thd); printf("Reset thread (%d): ", solve_time); for (int i = 0; i < sol_thd / 2; i++) { workers[i]->reset(); printf("%d(%d) ", unimprove[i].id, unimprove[i].inf); } puts("\n"); } } // printf("ending solve\n"); terminate_workers(); for (int i = 0; i < OPT(threads); i++) { pthread_join(ptr[i], NULL); } delete []ptr; return result; } int light::run() { init_workers(); diversity_workers(); if (OPT(simplify)) { pre = new preprocess(); int res = pre->do_preprocess(filename); if (!res) return 20; } else worker_sign = filename; parse_input(); if (OPT(share)) share(); int res = solve(); if (res == 10 && OPT(simplify)) { for (int i = 1; i <= pre->orivars; i++) if (pre->mapto[i]) pre->mapval[i] = (model[abs(pre->mapto[i])-1] > 0 ? 1 : -1) * (pre->mapto[i] > 0 ? 1 : -1); pre->get_complete_model(); model.clear(); for (int i = 1; i <= pre->orivars; i++) { model.push(i * pre->mapval[i]); } } return res; } void print_model(vec &model) { printf("v"); for (int i = 0; i < model.size(); i++) { printf(" %d", model[i]); } puts(" 0"); } void solve(int argc, char **argv) { light* S = new light(); S->arg_parse(argc, argv); int res = S->run(); if (res == 10) { printf("s SATISFIABLE\n"); print_model(model); } else if (res == 20) { printf("s UNSATISFIABLE\n"); } else { printf("s UNKNOWN\n"); } delete(S); return; }