141 lines
3.5 KiB
C++
141 lines
3.5 KiB
C++
#include "light.hpp"
|
|
#include "workers/basekissat.hpp"
|
|
#include <unistd.h>
|
|
#include <chrono>
|
|
char* worker_sign = "";
|
|
atomic<int> terminated;
|
|
auto clk_st = std::chrono::high_resolution_clock::now();
|
|
int result = 0;
|
|
int winner;
|
|
vec<int> 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<int> seq_model;
|
|
if (res == 10) {
|
|
sq->get_model(seq_model);
|
|
}
|
|
if (res && !terminated) {
|
|
sq->controller->terminate_solvers();
|
|
terminated = 1;
|
|
result = res;
|
|
winner = sq->id;
|
|
if (res == 10) seq_model.copyTo(model);
|
|
}
|
|
seq_model.clear();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void light::init_solvers() {
|
|
for (int i = 0; i < OPT(threads); i++) {
|
|
basekissat* kissat = new basekissat(i, this);
|
|
solvers.push(kissat);
|
|
}
|
|
}
|
|
|
|
void light::diversity_solvers() {
|
|
for (int i = 0; i < OPT(threads); i++) {
|
|
solvers[i]->diversity(i);
|
|
}
|
|
}
|
|
|
|
void light::terminate_solvers() {
|
|
for (int i = 0; i < OPT(threads); i++) {
|
|
solvers[i]->terminate();
|
|
}
|
|
}
|
|
|
|
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, solvers[i]);
|
|
}
|
|
for (int i = 0; i < OPT(threads); i++) {
|
|
pthread_join(ptr[i], NULL);
|
|
}
|
|
delete []ptr;
|
|
}
|
|
|
|
int light::solve() {
|
|
printf("c -----------------solve start----------------------\n");
|
|
terminated = 0;
|
|
pthread_t *ptr = new pthread_t[OPT(threads)];
|
|
for (int i = 0; i < OPT(threads); i++) {
|
|
pthread_create(&ptr[i], NULL, solve_worker, solvers[i]);
|
|
}
|
|
while (!terminated) {
|
|
usleep(100000);
|
|
auto clk_now = std::chrono::high_resolution_clock::now();
|
|
int solve_time = std::chrono::duration_cast<std::chrono::seconds>(clk_now - clk_st).count();
|
|
if (solve_time >= OPT(times)) {
|
|
terminated = 1;
|
|
terminate_solvers();
|
|
}
|
|
}
|
|
for (int i = 0; i < OPT(threads); i++) {
|
|
pthread_join(ptr[i], NULL);
|
|
}
|
|
delete []ptr;
|
|
return result;
|
|
}
|
|
|
|
int light::run() {
|
|
init_solvers();
|
|
diversity_solvers();
|
|
if (OPT(simplify)) {
|
|
pre = new preprocess();
|
|
int res = pre->do_preprocess(filename);
|
|
if (!res) return 20;
|
|
}
|
|
else worker_sign = filename;
|
|
parse_input();
|
|
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<int> &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;
|
|
} |