#if !defined(QUIET) || !defined(NDEBUG) #include "internal.h" #endif #ifndef QUIET #include "resources.h" #include "utilities.h" #include #include #include // *INDENT-OFF* void kissat_statistics_print (kissat * solver, bool verbose) { #ifndef QUIET statistics *statistics = &solver->statistics; const double time = kissat_process_time (); size_t variables = SIZE_STACK (solver->import); #ifndef NMETRICS const double rss = kissat_maximum_resident_set_size (); #endif /*------------------------------------------------------------------------*/ #define RELATIVE(FIRST,SECOND) \ kissat_average (statistics->FIRST, statistics->SECOND) /*------------------------------------------------------------------------*/ #define CONF_INT(NAME) \ RELATIVE (conflicts, NAME) #define NO_SECONDARY(NAME) \ 0 /*------------------------------------------------------------------------*/ #define PER_BIN_RESOLVED(NAME) \ RELATIVE (NAME, hyper_binary_resolved) #define PER_CLS_ADDED(NAME) \ RELATIVE (NAME, clauses_added) #define PER_CLS_LEARNED(NAME) \ RELATIVE (NAME, learned) #define PER_CONFLICT(NAME) \ RELATIVE (NAME, conflicts) #ifdef NSTATISTICS #define PER_FLIPPED(NAME) \ -1 #else #define PER_FLIPPED(NAME) \ RELATIVE (NAME, flipped) #endif #define PER_FIXED(NAME) \ RELATIVE (NAME, units) #define PER_PROPAGATION(NAME) \ RELATIVE (NAME, propagations) #define PER_REUSED_TRAIL(NAME) \ RELATIVE (NAME, restarts_reused_trails) #define PER_SECOND(NAME) \ kissat_average (statistics->NAME, time) #ifdef NMETRICS #define PER_TRN_RESOLVED(NAME) \ -1 #else #define PER_TRN_RESOLVED(NAME) \ RELATIVE (NAME, hyper_ternary_resolved) #endif #define PER_VARIABLE(NAME) \ kissat_average (statistics->NAME, variables) #define PER_VIVIFICATION_CHECK(NAME) \ RELATIVE (NAME, vivification_checks) #ifdef NSTATISTICS #define PER_WALKS(NAME) \ -1 #else #define PER_WALKS(NAME) \ RELATIVE (NAME, walks) #endif /*------------------------------------------------------------------------*/ #define PERCENT(FIRST,SECOND) \ kissat_percent (statistics->FIRST, statistics->SECOND) /*------------------------------------------------------------------------*/ #define PCNT_ARENA_RESIZED(NAME) \ PERCENT (NAME, arena_resized) #define PCNT_BIN_RESOLVED(NAME) \ PERCENT (NAME, hyper_binary_resolved) #define PCNT_CLS_ADDED(NAME) \ PERCENT (NAME, clauses_added) #define PCNT_COLLECTIONS(NAME) \ PERCENT (NAME, garbage_collections) #define PCNT_CONFLICTS(NAME) \ PERCENT (NAME, conflicts) #define PCNT_DECISIONS(NAME) \ PERCENT (NAME, decisions) #define PCNT_DEFRAGS(NAME) \ PERCENT (NAME, defragmentations) #define PCNT_ELIMINATED(NAME) \ PERCENT (NAME, eliminated) #define PCNT_TRN_ADDED(NAME) \ PERCENT (NAME, hyper_ternaries_added) #define PCNT_TRN_RESOLVED(NAME) \ PERCENT (NAME, hyper_ternary_resolved) #ifdef NSTATISTICS #define PCNT_TICKS(NAME) \ -1 #else #define PCNT_TICKS(NAME) \ PERCENT (NAME, ticks) #endif #define PCNT_LITERALS_DEDUCED(NAME) \ PERCENT (NAME, literals_deduced) #define PCNT_PROPS(NAME) \ PERCENT (NAME, propagations) #define PCNT_REDUCTIONS(NAME) \ PERCENT (NAME, reductions) #define PCNT_REDUNDANT_CLAUSES(NAME) \ PERCENT (NAME, clauses_redundant) #define PCNT_RESIDENT_SET(NAME) \ kissat_percent (statistics->NAME, rss) #define PCNT_RESTARTS(NAME) \ PERCENT (NAME, restarts) #define PCNT_SEARCHES(NAME) \ PERCENT (NAME, searches) #define PCNT_STR(NAME) \ PERCENT (NAME, strengthened) #define PCNT_SUB(NAME) \ PERCENT (NAME, subsumed) #define PCNT_SUBSUMPTION_CHECK(NAME) \ PERCENT (NAME, subsumption_checks) #define PCNT_VARIABLES(NAME) \ kissat_percent (statistics->NAME, variables) #define PCNT_VIVIFICATION_CHECK(NAME) \ PERCENT (NAME, vivification_checks) #define PCNT_VIVIFIED(NAME) \ PERCENT (NAME, vivified) #define PCNT_VIVIFY_PROBES(NAME) \ PERCENT (NAME, vivify_probes) #define PCNT_VIVIFY_STR(NAME) \ PERCENT (NAME, vivify_strengthened) #define PCNT_VIVIFY_SUB(NAME) \ PERCENT (NAME, vivify_subsumed) #define PCNT_WALKS(NAME) \ PERCENT (NAME, walks) #define COUNTER(NAME,VERBOSE,OTHER,UNITS,TYPE) \ if (verbose || !VERBOSE || (VERBOSE == 1 && statistics->NAME)) \ PRINT_STAT (#NAME, statistics->NAME, OTHER(NAME), UNITS, TYPE); #define IGNORE(...) STATISTICS #undef COUNTER #undef METRIC #undef STATISTIC fflush (stdout); #else (void) verbose; (void) statistics; #endif } // *INDENT-ON* #elif defined(NDEBUG) int kissat_statistics_dummy_to_avoid_warning; #endif /*------------------------------------------------------------------------*/ #ifndef NDEBUG void kissat_check_statistics (kissat * solver) { if (solver->inconsistent) return; size_t redundant = 0; size_t irredundant = 0; size_t hyper_ternaries = 0; size_t arena_garbage = 0; for (all_clauses (c)) { if (c->garbage) { arena_garbage += kissat_actual_bytes_of_clause (c); continue; } if (c->hyper) hyper_ternaries++; if (c->redundant) redundant++; else irredundant++; } size_t redundant_binary_watches = 0; size_t irredundant_binary_watches = 0; size_t hyper_binaries = 0; if (solver->watching) { for (all_literals (lit)) { watches *watches = &WATCHES (lit); for (all_binary_blocking_watches (watch, *watches)) { if (watch.type.binary) { if (watch.binary.redundant) { redundant_binary_watches++; if (watch.binary.hyper) hyper_binaries++; } else irredundant_binary_watches++; } } } } else { for (all_literals (lit)) { watches *watches = &WATCHES (lit); for (all_binary_large_watches (watch, *watches)) { if (watch.type.binary) { if (watch.binary.redundant) { redundant_binary_watches++; if (watch.binary.hyper) hyper_binaries++; } else irredundant_binary_watches++; } } } } assert (!(redundant_binary_watches & 1)); assert (!(irredundant_binary_watches & 1)); assert (!(hyper_binaries & 1)); redundant += redundant_binary_watches / 2; irredundant += irredundant_binary_watches / 2; hyper_binaries /= 2; statistics *statistics = &solver->statistics; assert (statistics->clauses_redundant == redundant); assert (statistics->clauses_irredundant == irredundant); #ifndef NMETRICS assert (statistics->hyper_binaries == hyper_binaries); assert (statistics->hyper_ternaries == hyper_ternaries); assert (statistics->arena_garbage == arena_garbage); #else (void) hyper_binaries; (void) hyper_ternaries; (void) arena_garbage; #endif } #endif