/********************************/
/* Functions called by satbox */
/********************************/

// Get the reason, which is a list of literals, why lit is conflicting, 
// store the reason in lits and return the number of literals in the reason
int dpllt_reason_satbox ( int lit, int *lits );

// Literal lit's weight is increased by 1 due a new lemma
void weight_add1_satbox ( int lit );

// Return 1 if a user-provided model is read; otherwise 0; 
int model_read_satbox();

// Return the value of the variable in the user-provided model
int model_value_satbox(int variable);

// Report a newly watched literal
void sblit_add_watched_satbox (int sblit);

/********************************/
/* Functions provided by satbox */
/********************************/

/* satbox_init_flags() initializes satbox's flags;  */
void satbox_init_flags();
/* return the value of flag */
int satbox_flag ( int flag );
/* change the value of flag to val */
void satbox_set_flag( int flag, int val );

/* satbox_init_input(max_atom) tells satbox ready to accept input clauses */
void satbox_init_input ( int max_atom );

/* combine the two initiations */
#define satbox_init(max_atom) satbox_init_flags(); satbox_init_input(max_atom)

/*
  void satbox_insert_clause (cl_arr, size, type)
  where 
    cl_arr is an array of literals; each literal is represented by
      an integer whose lowest bit is the sign of the literal and the rest is
      the variable name (a positive integer);
      For instance, if a variable x is named by 5, then its positive literal is 
      11 and its negative literal is 10.
      Assuming no duplicates in cl_arr.
    size is the number of literals in cl_arr;
    type is the type of clause (see common.h for definition). For ordinary 
      propositional clauses, type is 0 (NORM).
*/
void satbox_insert_clause( int *cl_arr, int size, int type );

/* satbox_insert_unit_clause(x) treats x as a true-literal.
   The same effect as when cl_arr[0] = x, and satbox_insert_clause(cl_arr,1,0) is called. */
void satbox_insert_unit_clause( int x );

/* Tell satbox to start BCP and then search. 
   satbox_init_search(output), where output is an array of integers,
   the first element should be 0, the top level;
   the second element is the number of new literals to be asserted at this level;
   the rest are those literals such that the last assigned literal in the satbox 
   comes first in output (the first literal is in output[2]). 
   Return 0 (UNSAT) if unsatisfiable.
*/
int satbox_init_search ( int *output );

/* Tell satbox to restart the search. */
void satbox_restart_search();

/* Return 0 if every clause is true in the current model; otherwise return 1; */
int satbox_check_model();

/*  satbox_strategy (SELECT) returns the next unsigned literal selected by satbox,
    where is an integer from 2 to 7 */
int satbox_strategy();

/* A function used by the next three macros */
int satbox_assert_aux ( int x, int *array, int flag );

/* Ask the satbox to backtrack 
   satbox_backtrack(sblit, output), where sblit is either a false sblit, or zero,
   or the negation of the level to be backed, and output is an array of integers ( 
   the first element is the current level of the search tree;
   the second element is the number of new literals to be asserted at the current level;
   the rest are those literals and the last assigned literal in the satbox comes first
   in output (it's output[2])). 
   Return 0 (UNSAT) if the search tree is closed with unsatisfiable.
   Return 3 (SAT) if the search has found a consistent state (no conflict with unit clauses).
*/
#define satbox_backtrack(lit,output) satbox_assert_aux(lit,output,0)

/* Ask the satbox to assert a list of unassigned literals in io to be true and then
   do BCP. The output BCP is returned.

   How to use it:
      satbox_assert_true(num,io) 
   where num is the number of literal to be asserted true and io contains those
   literals from number 1 (io[0]) to number num (io[num-1]), assuming the last
   assigned literal comes first (io[0]) and the first assigned literal comes last (io[num-1]).

   When finished, the second parameter io contains the same information
   as output in satbox_backtrack(lit, output) 
   Return 0 (UNSAT) if the search tree is closed with unsatisfiable.
   Return 2 (UNCHANGE) if only one literal is asserted true and no new unit clauses were 
         found by making this literal true.
   Return 3 (SAT) if the search has found a consistent state (no conflict with unit clauses).
*/
#define satbox_assert_true(num,output) satbox_assert_aux(0,output,num+2)

/* Increase the search level by one, assert an unassigned literal to be true and
   then do BCP. The output of BCP is returned.

   How to use it:
   satbox_decide_true(lit,output) where lit is the literal to be asserted true.
   output has similar format and meaning as in satbox_backtrack(lit, output).
   Return 0 (UNSAT) if the search tree is closed with unsatisfiable.
   Return 2 (UNCHANGE) if no new unit clauses were found by making "lit" true.
   Return 3 (SAT) if the search has found a consistent state (no conflict with unit clauses).
*/
#define satbox_decide_true(lit,output) satbox_assert_aux(lit,output,1)

/* Increase the search level by one, assert an unassigned literal to be true.
   Similar to satbox_decide_true but not doing BCP */
void satbox_decide_true_simple ( int sblit );

/*
  int satbox_insert_lemma (cl_arr, size, output)
  where 
    cl_arr is an array of literals; each literal is represented by
      an integer whose lowest bit is the sign of the literal and the rest is
      the variable name (a positive integer).  Assuming no duplicates in cl_arr.
    size is the number of literals in cl_arr;
   output is the same as in satbox_backtrack(lit, output).
   This function will set the default level for unit clauses (the unit clause
   forces a literal to be true at the default level) to the current level.
   Return 0 (UNSAT) if the search tree is closed with unsatisfiable.
*/
int satbox_insert_lemma( int *cl_arr, int size, int *output );

/* Remove the last n lemmas inserted by calling satbox_insert_lemma */
int satbox_remove_last_lemmas (int n);

/*
  satbox_back_to(int level) returns to level without taking 
  the opposite value of the decision literal at that level.
*/
void satbox_back_to(int level);

/* Return the level of variable */
int satbox_var_level (int variable);

/* Return the boolean value of a literal or a variable inside the satbox */
int satbox_lit_value( int literal );
int satbox_var_value( int variable );

/* Return the status if variable is watched:
   0: unassigned and variable is not watched
   1: unassigned and watched by its positive literal
   2: unassigned and watched by its negative literal
   3: unassigned and watched by both positive and negative literals
   10: assigned false
   11: assigned true
   The difference between satbox_var_is_watched() and satbox_var_is_watched_neat()
   is that the latter doesn't count a literal as watched if the other watched literal
   in the same clause is true.
*/
int satbox_var_is_watched( int variable );
int satbox_var_is_watched_neat( int variable );

/* A function for implementing random jumping */
void satbox_skip_guide_path();

/* Stats Functions */
int satbox_delete_num();
int satbox_lemma_num();
int satbox_branch_open();
int satbox_branch_jump();
long satbox_branch_fail();
int satbox_memory_count();
int satbox_conflict_cl_level();
void satbox_set_conflict_cl_level(int l);


