void Proof::traverse(ProofTraverser& trav, ClauseId goal) { assert(!fp.null()); // Switch to read mode: fp.setMode(READ); fp.seek(0); // Traverse proof: if (goal == ClauseId_NULL) goal = last(); uint64 tmp; int idx; for(ClauseId id = 0; id <= goal; id++){ tmp = getUInt(fp); if ((tmp & 1) == 0){ // Root clause: clause.clear(); idx = tmp >> 1; clause.push(toLit(idx)); for(;;){ tmp = getUInt(fp); if (tmp == 0) break; idx += tmp; clause.push(toLit(idx)); } trav.root(clause); }else{
void add_clauses_with_variable_shift( std::vector< std::vector<Lit> > &clauses2add, Solver &S,int shift){ unsigned i; vec<Lit> lits; lits.clear(); i=clauses2add.size(); while(i--){//PRINT(i); /*ckhong: no change in orig_clauses*/ int j=clauses2add[i].size();//PRINT(j); while(j--){//PRINT(toInt(clauses2add[i][j])); PRINT(toInt(clauses2add[i][j]) + (shift+shift)); lits.push(toLit( toInt(clauses2add[i][j]) + (shift+shift) )); } /* j=lits.size(); while(j--){ PRINT(toInt(lits[j])); } */ S.addClause(lits); lits.clear(); } }
void Slave::splitJob() { vec<int> message; int num_splits; //fprintf(stderr, "%d: Split job called, assumptions.size()=%d, DL=%d!\n", thread_no, engine.assumptions.size(), engine.decisionLevel()); profile_start(); MPI_Recv(&num_splits, 1, MPI_INT, 0, STEAL_TAG, MPI_COMM_WORLD, &s); int max_splits = engine.decisionLevel() - engine.assumptions.size() - 1; if (num_splits > max_splits) num_splits = max_splits; if (num_splits < 0) num_splits = 0; if (FULL_DEBUG) fprintf(stderr, "%d: Splitting %d jobs\n", thread_no, num_splits); for (int i = 0; i < num_splits; i++) { engine.assumptions.push(toInt(sat.decLit(engine.assumptions.size()+1))); sat.incVarUse(engine.assumptions.last()/2); } assert(num_splits == 0 || engine.decisionLevel() > engine.assumptions.size()); vec<Lit> ps; for (int i = 0; i < engine.assumptions.size(); i++) ps.push(toLit(engine.assumptions[i])); Clause *c = Clause_new(ps); sat.convertToSClause(*c); free(c); message.push(num_splits); sat.temp_sc->pushInVec(message); MPI_Bsend((int*) message, message.size(), MPI_INT, 0, SPLIT_TAG, MPI_COMM_WORLD); profile_end("send split job", message.size()); if (FULL_DEBUG) fprintf(stderr, "%d: Sent %d split job to master\n", thread_no, message[0]); }
inline void Engine::makeDecision(DecInfo& di, int alt) { ++nodes; if (di.var) ((IntVar*) di.var)->set(di.val, di.type ^ alt); else sat.enqueue(toLit(di.val ^ alt)); if (so.ldsb && di.var && di.type == 1) ldsb.processDec(sat.trail.last()[0]); // if (opt_var && di.var == opt_var && ((IntVar*) di.var)->isFixed()) printf("objective = %d\n", ((IntVar*) di.var)->getVal()); }
static bool parse_BCNF(cchar* filename, Solver& S) { FILE* in = fopen(filename, "rb"); if (in == NULL) fprintf(stderr, "ERROR! Could not open file: %s\n", filename), exit(1); char header[16]; fread(header, 1, 16, in); if (strncmp(header, "BCNF", 4) != 0) fprintf(stderr, "ERROR! Not a BCNF file: %s\n", filename), exit(1); if (*(int*)(header+4) != 0x01020304) fprintf(stderr, "ERROR! BCNF file in unsupported byte-order: %s\n", filename), exit(1); int n_vars = *(int*)(header+ 8); //int n_clauses = *(int*)(header+12); int* buf = xmalloc<int>(CHUNK_LIMIT); int buf_sz; vec<Lit> c; for (int i = 0; i < n_vars; i++) S.newVar(); for(;;){ int n = fread(&buf_sz, 4, 1, in); if (n != 1) break; assert(buf_sz <= CHUNK_LIMIT); fread(buf, 4, buf_sz, in); int* p = buf; while (*p != -1){ int size = *p++; c.clear(); c.growTo(size); for (int i = 0; i < size; i++) c[i] = toLit(p[i]); p += size; S.addClause(c); // Add clause. if (!S.okay()){ xfree(buf); fclose(in); return false; } } } xfree(buf); fclose(in); S.simplifyDB(); return S.okay(); }
bool SAT::propagate() { int num_props = 0; int& qhead = this->qhead.last(); vec<Lit>& trail = this->trail.last(); while (qhead < trail.size()) { num_props++; Lit p = trail[qhead++]; // 'p' is enqueued fact to propagate. vec<WatchElem>& ws = watches[toInt(p)]; if (ws.size() == 0) continue; WatchElem *i, *j, *end; for (i = j = ws, end = i + ws.size(); i != end; ) { WatchElem& we = *i; switch (we.d.type) { case 1: { // absorbed binary clause *j++ = *i++; Lit q = toLit(we.d.d2); switch (toInt(value(q))) { case 0: enqueue(q, ~p); break; case -1: setConfl(q, ~p); qhead = trail.size(); while (i < end) *j++ = *i++; break; default:; } continue; } case 2: { // wake up FD propagator *j++ = *i++; engine.propagators[we.d.d2]->wakeup(we.d.d1, 0); continue; } default: Clause& c = *we.pt; i++; // Check if already satisfied if (value(c[0]) == l_True || value(c[1]) == l_True) { *j++ = &c; continue; } Lit false_lit = ~p; // Make sure the false literal is data[1]: if (c[0] == false_lit) c[0] = c[1], c[1] = false_lit; // Look for new watch: for (int k = 2; k < c.size(); k++) if (value(c[k]) != l_False) { c[1] = c[k]; c[k] = false_lit; watches[toInt(~c[1])].push(&c); goto FoundWatch; } // Did not find watch -- clause is unit under assignment: *j++ = &c; if (value(c[0]) == l_False) { confl = &c; qhead = trail.size(); while (i < end) *j++ = *i++; } else { enqueue(c[0], &c); } FoundWatch:; } } ws.shrink(i-j); } propagations += num_props; return (confl == NULL); }
int glp_minisat1(glp_prob *P) { /* solve CNF-SAT problem with MiniSat solver */ solver *s; GLPAIJ *aij; int i, j, len, ret, *ind; double sum; /* check problem object */ if (P == NULL || P->magic != GLP_PROB_MAGIC) xerror("glp_minisat1: P = %p; invalid problem object\n", P); if (P->tree != NULL) xerror("glp_minisat1: operation not allowed\n"); /* integer solution is currently undefined */ P->mip_stat = GLP_UNDEF; P->mip_obj = 0.0; /* check that problem object encodes CNF-SAT instance */ if (glp_check_cnfsat(P) != 0) { xprintf("glp_minisat1: problem object does not encode CNF-SAT " "instance\n"); ret = GLP_EDATA; goto done; } #if 1 /* 07/XI-2015 */ if (sizeof(void *) != sizeof(int)) { xprintf("glp_minisat1: sorry, MiniSat solver is not supported " "on 64-bit platforms\n"); ret = GLP_EFAIL; goto done; } #endif /* solve CNF-SAT problem */ xprintf("Solving CNF-SAT problem...\n"); xprintf("Instance has %d variable%s, %d clause%s, and %d literal%" "s\n", P->n, P->n == 1 ? "" : "s", P->m, P->m == 1 ? "" : "s", P->nnz, P->nnz == 1 ? "" : "s"); /* if CNF-SAT has no clauses, it is satisfiable */ if (P->m == 0) { P->mip_stat = GLP_OPT; for (j = 1; j <= P->n; j++) P->col[j]->mipx = 0.0; goto fini; } /* if CNF-SAT has an empty clause, it is unsatisfiable */ for (i = 1; i <= P->m; i++) { if (P->row[i]->ptr == NULL) { P->mip_stat = GLP_NOFEAS; goto fini; } } /* prepare input data for the solver */ s = solver_new(); solver_setnvars(s, P->n); ind = xcalloc(1+P->n, sizeof(int)); for (i = 1; i <= P->m; i++) { len = 0; for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) { ind[++len] = toLit(aij->col->j-1); if (aij->val < 0.0) ind[len] = lit_neg(ind[len]); } xassert(len > 0); xassert(solver_addclause(s, &ind[1], &ind[1+len])); } xfree(ind); /* call the solver */ s->verbosity = 1; if (solver_solve(s, 0, 0)) { /* instance is reported as satisfiable */ P->mip_stat = GLP_OPT; /* copy solution to the problem object */ xassert(s->model.size == P->n); for (j = 1; j <= P->n; j++) { P->col[j]->mipx = s->model.ptr[j-1] == l_True ? 1.0 : 0.0; } /* compute row values */ for (i = 1; i <= P->m; i++) { sum = 0; for (aij = P->row[i]->ptr; aij != NULL; aij = aij->r_next) sum += aij->val * aij->col->mipx; P->row[i]->mipx = sum; } /* check integer feasibility */ for (i = 1; i <= P->m; i++) { if (P->row[i]->mipx < P->row[i]->lb) { /* solution is wrong */ P->mip_stat = GLP_UNDEF; break; } } } else { /* instance is reported as unsatisfiable */ P->mip_stat = GLP_NOFEAS; } solver_delete(s); fini: /* report the instance status */ if (P->mip_stat == GLP_OPT) { xprintf("SATISFIABLE\n"); ret = 0; } else if (P->mip_stat == GLP_NOFEAS) { xprintf("UNSATISFIABLE\n"); ret = 0; } else { xprintf("glp_minisat1: solver failed\n"); ret = GLP_EFAIL; } done: return ret; }
static inline lit lit_read (int s) { return s > 0 ? toLit(s-1) : lit_neg(toLit(-s-1)); }
RESULT Engine::search() { int starts = 0; int nof_conflicts = so.restart_base; int conflictC = 0; while (true) { if (so.parallel && slave.checkMessages()) return RES_UNK; if (!propagate()) { clearPropState(); Conflict: conflicts++; conflictC++; if (time(NULL) > so.time_out) { printf("Time limit exceeded!\n"); return RES_UNK; } if (decisionLevel() == 0) { return RES_GUN; } // Derive learnt clause and perform backjump if (so.lazy) { sat.analyze(); } else { sat.confl = NULL; DecInfo& di = dec_info.last(); sat.btToLevel(decisionLevel()-1); makeDecision(di, 1); } if (!so.vsids && !so.toggle_vsids && conflictC >= so.switch_to_vsids_after) { if (so.restart_base >= 1000000000) so.restart_base = 100; sat.btToLevel(0); toggleVSIDS(); } } else { if (conflictC >= nof_conflicts) { starts++; nof_conflicts += getRestartLimit((starts+1)/2); sat.btToLevel(0); sat.confl = NULL; if (so.lazy && so.toggle_vsids && (starts % 2 == 0)) toggleVSIDS(); continue; } if (decisionLevel() == 0) { topLevelCleanUp(); if (opt_var && so.verbosity >= 3) { printf("%% root level bounds on objective: min %d max %d\n", opt_var->getMin(), opt_var->getMax()); } } DecInfo *di = NULL; // Propagate assumptions while (decisionLevel() < assumptions.size()) { int p = assumptions[decisionLevel()]; if (sat.value(toLit(p)) == l_True) { // Dummy decision level: assert(sat.trail.last().size() == sat.qhead.last()); engine.dec_info.push(DecInfo(NULL, p)); newDecisionLevel(); } else if (sat.value(toLit(p)) == l_False) { return RES_LUN; } else { di = new DecInfo(NULL, p); break; } } if (!di) di = branching->branch(); if (!di) { solutions++; if (so.print_sol) { problem->print(); printf("----------\n"); fflush(stdout); } if (!opt_var) { if (solutions == so.nof_solutions) return RES_SAT; if (so.lazy) blockCurrentSol(); goto Conflict; } if (!constrain()) { return RES_GUN; } continue; } engine.dec_info.push(*di); newDecisionLevel(); doFixPointStuff(); makeDecision(*di, 0); delete di; } } }
static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts) { int* levels = s->levels; double var_decay = 0.95; double clause_decay = 0.999; double random_var_freq = 0.02; int conflictC = 0; veci learnt_clause; assert(s->root_level == solver_dlevel(s)); s->stats.starts++; s->var_decay = (float)(1 / var_decay ); s->cla_decay = (float)(1 / clause_decay); veci_resize(&s->model,0); veci_new(&learnt_clause); for (;;){ clause* confl = solver_propagate(s); if (confl != 0){ /* CONFLICT */ int blevel; #ifdef VERBOSEDEBUG printf(L_IND"**CONFLICT**\n", L_ind); #endif s->stats.conflicts++; conflictC++; if (solver_dlevel(s) == s->root_level){ veci_delete(&learnt_clause); return l_False; } veci_resize(&learnt_clause,0); solver_analyze(s, confl, &learnt_clause); blevel = veci_size(&learnt_clause) > 1 ? levels[lit_var(veci_begin(&learnt_clause)[1])] : s->root_level; blevel = s->root_level > blevel ? s->root_level : blevel; solver_canceluntil(s,blevel); solver_record(s,&learnt_clause); act_var_decay(s); act_clause_decay(s); }else{ /* NO CONFLICT */ int next; if (nof_conflicts >= 0 && conflictC >= nof_conflicts){ /* Reached bound on number of conflicts: */ s->progress_estimate = solver_progress(s); solver_canceluntil(s,s->root_level); veci_delete(&learnt_clause); return l_Undef; } if (solver_dlevel(s) == 0) /* Simplify the set of problem clauses: */ solver_simplify(s); if (nof_learnts >= 0 && vecp_size(&s->learnts) - s->qtail >= nof_learnts) /* Reduce the set of learnt clauses: */ solver_reducedb(s); /* New variable decision: */ s->stats.decisions++; next = order_select(s,(float)random_var_freq); if (next == var_Undef){ /* Model found: */ lbool* values = s->assigns; int i; for (i = 0; i < s->size; i++) veci_push(&s->model,(int)values[i]); solver_canceluntil(s,s->root_level); veci_delete(&learnt_clause); /* veci apa; veci_new(&apa); for (i = 0; i < s->size; i++) veci_push(&apa,(int)(s->model.ptr[i] == l_True ? toLit(i) : lit_neg(toLit(i)))); printf("model: "); printlits((lit*)apa.ptr, (lit*)apa.ptr + veci_size(&apa)); printf("\n"); veci_delete(&apa); */ return l_True; } assume(s,lit_neg(toLit(next))); } } #if 0 /* by mao; unreachable code */ return l_Undef; /* cannot happen */ #endif }