2022-08-30 15:42:35 +08:00

255 lines
5.7 KiB
C

#ifndef _limits_h_INCLUDED
#define _limits_h_INCLUDED
#include <stdbool.h>
#include <stdint.h>
typedef struct bounds bounds;
typedef struct changes changes;
typedef struct delays delays;
typedef struct delay delay;
typedef struct enabled enabled;
typedef struct limited limited;
typedef struct limits limits;
typedef struct waiting waiting;
struct bounds
{
struct
{
uint64_t max_bound_completed;
unsigned additional_clauses;
unsigned clause_size;
unsigned occurrences;
} eliminate;
struct
{
unsigned clause_size;
unsigned occurrences;
} subsume;
struct
{
unsigned clause_size;
} xork;
};
struct changes
{
struct
{
uint64_t added;
uint64_t removed;
unsigned units;
} variables;
struct
{
unsigned additional_clauses;
} eliminate;
};
struct limits
{
uint64_t conflicts;
uint64_t decisions;
uint64_t reports;
union
{
uint64_t ticks;
uint64_t conflicts;
} mode;
struct
{
struct
{
uint64_t added;
uint64_t removed;
} variables;
uint64_t conflicts;
} eliminate;
struct
{
uint64_t conflicts;
} probe, reduce, rephase, restart;
};
struct limited
{
bool conflicts;
bool decisions;
};
struct enabled
{
bool autarky;
bool eliminate;
bool focus;
bool mode;
bool probe;
};
struct delay
{
unsigned count;
unsigned current;
};
struct delays
{
delay autarky;
delay eliminate;
delay failed;
delay probe;
delay substitute;
delay ternary;
};
struct waiting
{
struct
{
uint64_t reduce;
} eliminate, probe;
};
struct kissat;
changes kissat_changes (struct kissat *);
bool kissat_changed (changes before, changes after);
void kissat_init_limits (struct kissat *);
uint64_t kissat_scale_delta (struct kissat *, const char *, uint64_t);
uint64_t kissat_scale_limit (struct kissat *,
const char *, uint64_t count, int base);
#define SCALE_LIMIT(COUNT,NAME) \
kissat_scale_limit (solver, #NAME, \
solver->statistics.COUNT, GET_OPTION (NAME))
uint64_t kissat_logn (uint64_t);
uint64_t kissat_ndivlogn (uint64_t);
uint64_t kissat_linear (uint64_t);
uint64_t kissat_nlogn (uint64_t);
uint64_t kissat_nlognlogn (uint64_t);
uint64_t kissat_quadratic (uint64_t);
#define NDIVLOGN(COUNT) kissat_ndivlogn (COUNT)
#define LINEAR(COUNT) kissat_linear (COUNT)
#define NLOGN(COUNT) kissat_nlogn (COUNT)
#define NLOGNLOGN(COUNT) kissat_nlognlogn (COUNT)
#define QUADRATIC(COUNT) kissat_quadratic (COUNT)
#define INIT_CONFLICT_LIMIT(NAME,SCALE) \
do { \
const uint64_t DELTA = GET_OPTION (NAME ## init); \
const uint64_t SCALED = !(SCALE) ? DELTA : \
kissat_scale_delta (solver, #NAME, DELTA); \
limits->NAME.conflicts = CONFLICTS + SCALED; \
kissat_very_verbose (solver, \
"initial " #NAME " limit of %s conflicts", \
FORMAT_COUNT (limits->NAME.conflicts)); \
} while (0)
#define UPDATE_CONFLICT_LIMIT(NAME,COUNT,SCALE_COUNT_FUNCTION,SCALE_DELTA) \
do { \
if (solver->inconsistent) \
break; \
struct statistics *statistics = &solver->statistics; \
struct limits *limits = &solver->limits; \
uint64_t DELTA = GET_OPTION (NAME ## int); \
DELTA *= SCALE_COUNT_FUNCTION (statistics->COUNT) + 1; \
const uint64_t SCALED = !(SCALE_DELTA) ? DELTA : \
kissat_scale_delta (solver, #NAME, DELTA); \
limits->NAME.conflicts = CONFLICTS + SCALED; \
kissat_phase (solver, #NAME, \
GET (COUNT), \
"new limit of %s after %s conflicts", \
FORMAT_COUNT (limits->NAME.conflicts), \
FORMAT_COUNT (SCALED)); \
} while (0)
#include <inttypes.h>
#define SET_EFFICIENCY_BOUND(BOUND,NAME,START,REFERENCE,ADDITIONAL) \
uint64_t BOUND = solver->statistics.START; \
do { \
const uint64_t REFERENCE = solver->statistics.REFERENCE; \
const uint64_t MINIMUM = GET_OPTION (NAME ## mineff); \
const uint64_t MAXIMUM = MINIMUM * GET_OPTION (NAME ## maxeff); \
const double EFFICIENCY = (double) GET_OPTION (NAME ## releff) / 1e3; \
const uint64_t ADJUSTMENT = (ADDITIONAL); \
const uint64_t PRODUCT = REFERENCE * EFFICIENCY; \
uint64_t DELTA = PRODUCT + ADJUSTMENT; \
if (DELTA < MINIMUM) \
DELTA = MINIMUM; \
if (DELTA > MAXIMUM) \
DELTA = MAXIMUM; \
BOUND += DELTA; \
kissat_very_verbose (solver, \
#NAME " efficiency limit %s delta %s = %s + %s", \
FORMAT_COUNT (BOUND), FORMAT_COUNT (DELTA), \
FORMAT_COUNT (PRODUCT), FORMAT_COUNT (ADJUSTMENT)); \
} while (0)
#define RETURN_IF_DELAYED(NAME) \
do { \
assert (!solver->inconsistent); \
if (!GET_OPTION (NAME ## delay)) \
break; \
delay * DELAY = &solver->delays.NAME; \
assert (DELAY->count <= DELAY->current); \
if (!DELAY->count) \
break; \
kissat_very_verbose (solver, \
#NAME " delayed %u more time%s", \
DELAY->count, DELAY->count > 1 ? "s" : ""); \
DELAY->count--; \
return; \
} while (0)
#define UPDATE_DELAY(SUCCESS,NAME) \
do { \
if (solver->inconsistent) \
break; \
if (!GET_OPTION (NAME ## delay)) \
break; \
delay * DELAY = &solver->delays.NAME; \
unsigned MAX_DELAY = GET_OPTION (delay); \
assert (DELAY->count <= DELAY->current); \
if (SUCCESS) \
{ \
if (DELAY->current) \
{ \
kissat_very_verbose (solver, #NAME " delay reset"); \
DELAY->current = DELAY->count = 0; \
} \
else \
assert (!DELAY->count); \
} \
else \
{ \
if (DELAY->current < MAX_DELAY) \
{ \
DELAY->current++; \
kissat_very_verbose (solver, \
#NAME " delay increased to %u", \
DELAY->current); \
} \
else \
kissat_very_verbose (solver, \
"keeping " #NAME " delay at maximum %u", \
DELAY->current); \
DELAY->count = DELAY->current; \
} \
assert (DELAY->count <= DELAY->current); \
} while (0)
#endif