cloud-sat/workers/basekissat.cpp
2023-03-01 22:05:44 +08:00

209 lines
5.6 KiB
C++

#include "basekissat.hpp"
#include "sharer.hpp"
#include <thread>
#include <condition_variable>
extern "C" {
#include "src/application.h"
#include "src/parse.h"
#include "src/internal.h"
#include "src/witness.h"
#include "src/import.h"
}
void basekissat::add(int l) {
kissat_add(solver, l);
}
void basekissat::configure(const char* name, int id) {
kissat_set_option(solver, name, id);
}
int basekissat::solve() {
return kissat_solve(solver);
}
void basekissat::terminate() {
kissat_terminate(solver);
}
int basekissat::val(int l) {
int v = abs(l);
int tmp = kissat_value(solver, v);
if (!tmp) tmp = v;
if (l < 0) tmp = -tmp;
return tmp;
}
void basekissat::exp_clause(void* cl, int lbd) {
cvec *c = (cvec *) cl;
clause_store* cls = new clause_store(c->sz);
for (int i = 0; i < c->sz; i++) {
int v = cvec_data(c, i);
int eidx = PEEK_STACK(solver->exportk, (v >> 1));
cls->data[i] = v & 1 ? -eidx : eidx;
}
// ++S->x2;
// if (S->id == 0) puts("");
cls->lbd = lbd;
export_clause.push(cls);
}
void call_back_out(void *solver, int lbd, cvec *c) {
basekissat* S = (basekissat *) solver;
// ++S->x1;
// if (S->solver->nconflict != S->x1 - 1) printf("%d %d\n", S->solver->nconflict, S->x1);
if (lbd <= S->good_clause_lbd) {
S->exp_clause(c, lbd);
}
}
bool basekissat::imp_clause(clause_store *cls, void *cl) {
cvec *c = (cvec *) cl;
for (int i = 0; i < cls->size; i++) {
// S->outimport << cls->data[i] << std::endl;
int eidx = abs(cls->data[i]);
import *import = &PEEK_STACK (solver->import, eidx);
if (import->eliminated) return false;
else {
int ilit = import->lit;
if (cls->data[i] < 0) ilit = ilit ^ 1;
cvec_push(c, ilit);
}
}
return true;
}
int call_back_in(void *solver, int *lbd, cvec *c) {
basekissat* S = (basekissat *) solver;
clause_store* cls = NULL;
if (S->import_clause.pop(cls) == false) return -1;
*lbd = cls->lbd;
bool res = S->imp_clause(cls, c);
cls->free_clause();
if (!res) return -10;
return 1;
}
void kissat_wait_sharing(void *solver) {
auto clk_st = std::chrono::high_resolution_clock::now();
basekissat* S = (basekissat *) solver;
// printf("c %d into Light wait\n", S->id);
S->x1 = S->x2 = 0;
sharer *s = S->in_sharer;
{
boost::mutex::scoped_lock lock(s->mtx);
if (s->terminated) return;
s->waitings += 1;
lock.unlock();
// printf("c %d start wait with number %d\n", S->id, s->waitings);
}
if (s->should_sharing()) s->cond.notify_one();
boost::mutex::scoped_lock lock(s->mtx);
while (s->waitings > 0) {
s->cond.wait(lock);
}
auto clk_now = std::chrono::high_resolution_clock::now();
int solve_time = std::chrono::duration_cast<std::chrono::milliseconds>(clk_now - clk_st).count();
S->waiting_time += 0.001 * solve_time;
// printf("c %d wait for %d.%03ds\n", S->id, solve_time / 1000, solve_time % 1000);
// printf("c %d finish sharing\n", S->id);
}
double basekissat::get_waiting_time() {
return waiting_time;
}
basekissat::basekissat(int id, light* light) : basesolver(id, light) {
good_clause_lbd = 2;
// outexport.open("export.txt");
// outimport.open("import.txt");
// outfree.open("free.txt");
solver = kissat_init();
solver -> issuer = this;
solver -> cbkImportClause = NULL;
solver -> cbkExportClause = NULL;
solver -> cbkWaitSharing = NULL;
if (light->opt->share) {
solver -> cbkImportClause = call_back_in;
solver -> cbkExportClause = call_back_out;
solver -> cbkWaitSharing = kissat_wait_sharing;
solver -> share_dps = light->opt->DPS;
solver -> share_dps_period= light->opt->DPS_period;
}
}
basekissat::~basekissat(){
delete solver;
}
void basekissat::parse_from_CNF(char* filename) {
strictness strict = NORMAL_PARSING;
file in;
uint64_t lineno;
kissat_open_to_read_file(&in, filename);
kissat_parse_dimacs(solver, strict, &in, &lineno, &solver->max_var);
kissat_close_file(&in);
}
void basekissat::parse_from_PAR(preprocess* pre) {
solver->max_var = pre->vars;
kissat_reserve(solver, pre->vars);
for (int i = 1; i <= pre->clauses; i++) {
int l = pre->clause[i].size();
for (int j = 0; j < l; j++)
add(pre->clause[i][j]);
add(0);
}
}
void basekissat::export_clauses_to(vec<clause_store *> &clauses) {
clause_store *cls;
while (export_clause.pop(cls)) {
clauses.push(cls);
// outexport << id << ": ";
// for (int i = 0; i < cls->size; i++)
// outexport << cls->data[i] << " ";
// outexport << std::endl;
}
}
void basekissat::import_clauses_from(vec<clause_store *> &clauses) {
for (int i = 0; i < clauses.size(); i++) {
import_clause.push(clauses[i]);
// outimport << id << ": ";
// for (int j = 0; j < clauses[i]->size; j++)
// outimport << clauses[i]->data[j] << " ";
// outimport << std::endl;
}
}
void basekissat::get_model(vec<int> &model) {
model.clear();
for (int i = 1; i <= solver->max_var; i++) {
model.push(val(i));
}
}
void basekissat::broaden_export_limit() {
++good_clause_lbd;
}
void basekissat::restrict_export_limit() {
if (good_clause_lbd > 2)
--good_clause_lbd;
}
int basekissat::get_conflicts() {
return solver->nconflict;
}
// int basekissat::get_reset_data() {
// return solver->best_assigned;
// }
// void basekissat::reset() {
// solver->reseting = 1;
// }