#ifndef _ccadical_h_INCLUDED
#define _ccadical_h_INCLUDED

/*------------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
/*------------------------------------------------------------------------*/

#include <stdint.h>
#include <stdio.h>

// C wrapper for CaDiCaL's C++ API following IPASIR.

typedef struct CCaDiCaL CCaDiCaL;

const char *ccadical_signature (void);
CCaDiCaL *ccadical_init (void);
void ccadical_release (CCaDiCaL *);

void ccadical_add (CCaDiCaL *, int lit);
void ccadical_assume (CCaDiCaL *, int lit);
int ccadical_solve (CCaDiCaL *);
int ccadical_val (CCaDiCaL *, int lit);
int ccadical_failed (CCaDiCaL *, int lit);

void ccadical_set_terminate (CCaDiCaL *, void *state,
                             int (*terminate) (void *state));

void ccadical_set_learn (CCaDiCaL *, void *state, int max_length,
                         void (*learn) (void *state, int *clause));

/*------------------------------------------------------------------------*/

// Non-IPASIR conformant 'C' functions.

void ccadical_constrain (CCaDiCaL *, int lit);
int ccadical_constraint_failed (CCaDiCaL *);
void ccadical_set_option (CCaDiCaL *, const char *name, int val);
void ccadical_limit (CCaDiCaL *, const char *name, int limit);
int ccadical_get_option (CCaDiCaL *, const char *name);
void ccadical_print_statistics (CCaDiCaL *);
int64_t ccadical_active (CCaDiCaL *);
int64_t ccadical_irredundant (CCaDiCaL *);
int ccadical_fixed (CCaDiCaL *, int lit);
int ccadical_trace_proof (CCaDiCaL *, FILE *, const char *);
int ccadical_trace_proof_callback (CCaDiCaL *, void* state,
                                   const void (*process) (void* state, uint64_t id,
                                                          const int*, unsigned long long,
                                                          const uint64_t*, unsigned long long));
// int ccadical_trace_proof_callback (CCaDiCaL *, const void*(uint64_t, const int*, unsigned long long, const uint64_t*, unsigned long long));
void ccadical_close_proof (CCaDiCaL *);
void ccadical_conclude (CCaDiCaL *);
void ccadical_terminate (CCaDiCaL *);
void ccadical_freeze (CCaDiCaL *, int lit);
int ccadical_frozen (CCaDiCaL *, int lit);
void ccadical_melt (CCaDiCaL *, int lit);
int ccadical_simplify (CCaDiCaL *);

// Extending C API (Christoph Jabs)

// This value is returned from _solve_mem, _add_mem, _constrain_mem, and _assume_mem
const int OUT_OF_MEM = 50;

int ccadical_add_mem (CCaDiCaL *, int lit);
int ccadical_assume_mem (CCaDiCaL *, int lit);
int ccadical_constrain_mem (CCaDiCaL *, int lit);
int ccadical_solve_mem (CCaDiCaL *);
bool ccadical_configure (CCaDiCaL *, const char *);
void ccadical_phase (CCaDiCaL *, int lit);
void ccadical_unphase (CCaDiCaL *, int lit);
int ccadical_vars (CCaDiCaL *);
bool ccadical_set_option_ret (CCaDiCaL *, const char *name, int val);
bool ccadical_limit_ret (CCaDiCaL *, const char *name, int val);
int64_t ccadical_redundant (CCaDiCaL *);
int ccadical_simplify_rounds (CCaDiCaL *, int rounds);
int ccadical_reserve (CCaDiCaL *, int min_max_var);
int64_t ccadical_propagations (CCaDiCaL *);
int64_t ccadical_decisions (CCaDiCaL *);
int64_t ccadical_conflicts (CCaDiCaL *);
bool ccadical_flip (CCaDiCaL *, int lit);
bool ccadical_flippable (CCaDiCaL *, int lit);

/*------------------------------------------------------------------------*/

// Support legacy names used before moving to more IPASIR conforming names.

#define ccadical_reset ccadical_release
#define ccadical_sat ccadical_solve
#define ccadical_deref ccadical_val

/*------------------------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
/*------------------------------------------------------------------------*/

#endif
