#include "analyze.h" #include "decide.h" #include "eliminate.h" #include "internal.h" #include "logging.h" #include "print.h" #include "probe.h" #include "propsearch.h" #include "search.h" #include "reduce.h" #include "reluctant.h" #include "report.h" #include "restart.h" #include "terminate.h" #include "trail.h" #include "walk.h" #include static void start_search(kissat *solver) { START(search); INC(searches); REPORT(0, '*'); bool stable = (GET_OPTION(stable) == 2); solver->stable = stable; kissat_phase(solver, "search", GET(searches), "initializing %s search after %" PRIu64 " conflicts", (stable ? "stable" : "focus"), CONFLICTS); kissat_init_averages(solver, &AVERAGES); if (solver->stable) kissat_init_reluctant(solver); kissat_init_limits(solver); unsigned seed = GET_OPTION(seed); solver->random = seed; LOG("initialized random number generator with seed %u", seed); kissat_reset_rephased(solver); const unsigned eagersubsume = GET_OPTION(eagersubsume); if (eagersubsume && !solver->clueue.elements) kissat_init_clueue(solver, &solver->clueue, eagersubsume); #ifndef QUIET limits *limits = &solver->limits; limited *limited = &solver->limited; if (!limited->conflicts && !limited->decisions) kissat_very_verbose(solver, "starting unlimited search"); else if (limited->conflicts && !limited->decisions) kissat_very_verbose(solver, "starting search with conflicts limited to %" PRIu64, limits->conflicts); else if (!limited->conflicts && limited->decisions) kissat_very_verbose(solver, "starting search with decisions limited to %" PRIu64, limits->decisions); else kissat_very_verbose(solver, "starting search with decisions limited to %" PRIu64 " and conflicts limited to %" PRIu64, limits->decisions, limits->conflicts); if (stable) { START(stable); REPORT(0, '['); } else { START(focused); REPORT(0, '{'); } #endif } static void stop_search(kissat *solver, int res) { if (solver->limited.conflicts) { LOG("reset conflict limit"); solver->limited.conflicts = false; } if (solver->limited.decisions) { LOG("reset decision limit"); solver->limited.decisions = false; } if (solver->terminate) { kissat_very_verbose(solver, "termination forced externally"); solver->terminate = 0; } #ifndef QUIET LOG("search result %d", res); if (solver->stable) { REPORT(0, ']'); STOP(stable); solver->stable = false; } else { REPORT(0, '}'); STOP(focused); } char type = (res == 10 ? '1' : res == 20 ? '0' : '?'); REPORT(0, type); #else (void)res; #endif STOP(search); } static void iterate(kissat *solver) { assert(solver->iterating); solver->iterating = false; REPORT(0, 'i'); } static bool conflict_limit_hit(kissat *solver) { if (!solver->limited.conflicts) return false; if (solver->limits.conflicts > solver->statistics.conflicts) return false; kissat_very_verbose(solver, "conflict limit %" PRIu64 " hit after %" PRIu64 " conflicts", solver->limits.conflicts, solver->statistics.conflicts); return true; } static bool decision_limit_hit(kissat *solver) { if (!solver->limited.decisions) return false; if (solver->limits.decisions > solver->statistics.decisions) return false; kissat_very_verbose(solver, "decision limit %" PRIu64 " hit after %" PRIu64 " decisions", solver->limits.decisions, solver->statistics.decisions); return true; } int kissat_search(kissat *solver) { start_search(solver); int res = kissat_walk_initially(solver); while (!res) { if (!solver->level && solver->reseting) { kissat_shuffle_score(solver); solver->reseting = 0; } if (!solver->level) { int should_free = 0; if (!kissat_importUnitClauses(solver)) return 20; if (!kissat_importClauses(solver)) return 20; if (solver->dps == 1) solver->cbk_free_clauses(solver->issuer); } clause *conflict = kissat_search_propagate(solver); if (conflict) res = kissat_analyze(solver, conflict); else if (solver->iterating) iterate(solver); else if (!solver->unassigned) res = 10; else if (TERMINATED(11)) break; else if (conflict_limit_hit(solver)) break; else if (kissat_reducing(solver)) res = kissat_reduce(solver); else if (kissat_restarting(solver)) kissat_restart(solver); else if (kissat_rephasing(solver)) kissat_rephase(solver); else if (kissat_eliminating(solver)) res = kissat_eliminate(solver); else if (kissat_probing(solver)) res = kissat_probe(solver); else if (!solver->level && solver->unflushed) kissat_flush_trail(solver); else if (decision_limit_hit(solver)) break; else kissat_decide(solver); } stop_search(solver, res); return res; }