#include "decide.h" #include "inline.h" #include static unsigned last_enqueued_unassigned_variable (kissat * solver) { assert (solver->unassigned); const links *links = solver->links; const value *values = solver->values; unsigned res = solver->queue.search.idx; if (values[LIT (res)]) { do { res = links[res].prev; assert (!DISCONNECTED (res)); } while (values[LIT (res)]); kissat_update_queue (solver, links, res); } #ifdef LOGGING const unsigned stamp = links[res].stamp; LOG ("last enqueued unassigned variable %u stamp %u", res, stamp); #endif #ifdef CHECK_QUEUE for (unsigned i = links[res].next; !DISCONNECTED (i); i = links[i].next) assert (VALUE (LIT (i))); #endif return res; } static unsigned largest_score_unassigned_variable (kissat * solver, heap * heap) { unsigned res = kissat_max_heap (heap); const value *values = solver->values; while (values[LIT (res)]) { kissat_pop_heap (solver, heap, res); res = kissat_max_heap (heap); } // MAB if(solver->mab) { solver->mab_decisions++; if(!solver->mab_chosen[res]){ solver->mab_chosen_tot++; solver->mab_chosen[res] = 1; } } #if defined(LOGGING) || defined(CHECK_HEAP) const double score = kissat_get_heap_score (heap, res); #endif LOG ("largest score unassigned variable %u score %g", res, score); #ifdef CHECK_HEAP for (all_variables (idx)) { if (VALUE (LIT (idx))) continue; const double idx_score = kissat_get_heap_score (heap, idx); assert (score >= idx_score); } #endif return res; } unsigned kissat_next_decision_variable (kissat * solver) { unsigned res; if (solver->stable) res = largest_score_unassigned_variable (solver,solver->heuristic==0?&solver->scores:&solver->scores_chb); else res = last_enqueued_unassigned_variable (solver); LOG ("next decision variable %u", res); return res; } static inline value decide_phase (kissat * solver, unsigned idx) { bool force = GET_OPTION (forcephase); bool target; if (force) target = false; else if (!GET_OPTION (target)) target = false; else if (solver->stable) target = true; else target = (GET_OPTION (target) > 1); const bool saved = !force && GET_OPTION (phasesaving); const phase *phase = PHASE (idx); value res = 0; if (target && (res = phase->target)) { LOG ("variable %u uses target decision phase %d", idx, (int) res); INC (target_decisions); } if (saved && !res && (res = phase->saved)) { LOG ("variable %u uses saved decision phase %d", idx, (int) res); INC (saved_decisions); } if (!res) { res = INITIAL_PHASE; LOG ("variable %u uses initial decision phase %d", idx, (int) res); INC (initial_decisions); } assert (res); return res; } void kissat_decide (kissat * solver) { START (decide); assert (solver->unassigned); INC (decisions); assert (solver->level < MAX_LEVEL); solver->level++; const unsigned idx = kissat_next_decision_variable (solver); const value value = decide_phase (solver, idx); unsigned lit = LIT (idx); if (value < 0) lit = NOT (lit); kissat_push_frame (solver, lit); assert (solver->level < SIZE_STACK (solver->frames)); LOG ("decide literal %s", LOGLIT (lit)); kissat_assign_decision (solver, lit); STOP (decide); } void kissat_internal_assume (kissat * solver, unsigned lit) { assert (solver->unassigned); assert (!VALUE (lit)); assert (solver->level < MAX_LEVEL); solver->level++; kissat_push_frame (solver, lit); assert (solver->level < SIZE_STACK (solver->frames)); LOG ("assuming literal %s", LOGLIT (lit)); kissat_assign_decision (solver, lit); }