#ifndef _dynctrl_h_INCLUDED
#define _dynctrl_h_INCLUDED

#include <assert.h>
#include <stdbool.h>

struct kissat;

#define DYNOPTS \
  DYN_OPTION (bump) \
  DYN_OPTION (clause) \
  DYN_OPTION (inc) \
  DYN_OPTION (latest_it) \
  DYN_OPTION (mab_dc) \
  DYN_OPTION (pred) \
  DYN_OPTION (sc2022_bulky) \
  DYN_OPTION (sc2024_it) \
  DYN_OPTION (sc2025) \
  DYN_OPTION (stable)

#define DYN_OPTION(N) dyn_##N,

typedef enum { DYNOPTS dyn_max } dynopt;

#undef DYN_OPTION

struct dynctrl {
  bool disable[dyn_max];
  bool active[dyn_max];
  int dynseq[6];
};

typedef struct dynctrl dynctrl;

void kissat_dyn_on (struct kissat *solver, dynopt opt);
void kissat_dyn_off (struct kissat *solver, dynopt opt);
void kissat_dyn_init (struct kissat *solver);
void kissat_dyn_state (struct kissat *solver, int state);

#define DYN_ON(opt) kissat_dyn_on (solver, dyn_##opt)
#define DYN_OFF(opt) kissat_dyn_off (solver, dyn_##opt)

#define DYN_INIT(opt) if (!solver->dyn.disable[dyn_##opt])
#define DYN_IF(opt) if (solver->dyn.active[dyn_##opt])
#define DYN_IF_NOT(opt) if (!solver->dyn.active[dyn_##opt])
#define DYN_CHOICE(opt, t, f) (solver->dyn.active[dyn_##opt] ? (t) : (f))

#endif
