#ifndef CCBS_H
#define CCBS_H 
#include <stdbool.h>
#include <stddef.h>
#include <alloca.h>
#include <stdio.h>
#include <stdlib.h>
#include "array.h"
#include "ohash.h"
#include "term.h"
#include "sharing.h"
#include "folsubst.h"
#include "kbo.h"
#include "clause.h"
typedef intptr_t CCBS_LABEL;
typedef TERM CCBS_CLASS;
typedef enum {BTBS_UNION, BTBS_SIG_ENTER, BTBS_SIG_REMOVE, BTBS_STATUS, BTBS_POINT, BTBS_FLAG_CHG, BTBS_INEQ, BTBS_PRED} BTBS_TYPE;
typedef enum {BS_PFALSE, BS_PTRUE, BS_PUNDEF, BS_CONST} BS_FLAG;
#define BSTERM_NULL ((TERM) 0)
#define BSLABEL_NULL ((CCBS_LABEL) 0)
#define BSCLASS_NULL ((CCBS_CLASS) 0)
typedef struct BTBS_INFO
{
  BTBS_TYPE type;
  TERM term[2];
  BS_FLAG flags[2];
} BTBS_INFO;
typedef struct CCBS_TREENODE_TYPE
{
  TERM next;
  bool tmp;
  CCBS_LABEL label;
} CCBS_TREENODE_TYPE, *CCBS_TREENODE;
typedef struct CCBS_EQUATION_TYPE
{
  TERM term[2];
  CCBS_LABEL label;
} CCBS_EQUATION_TYPE, *CCBS_EQUATION;
typedef struct CCBS_CLASSINFO_TYPE
{
  TERM term;
  unsigned arity;
  BS_FLAG ineq_flag;
  bool def;
  bool value;
  unsigned elem_nb;
  TERM elem;
  ARRAY pred;
  ARRAY diseqs;
  BOOL is_input;
  TERM nxt_pred_cls;
  TERM prv_pred_cls;
} CCBS_CLASSINFO_TYPE, *CCBS_CLASSINFO;
typedef struct CCBS_TYPE {
  MEMORY memory;
  TERMSTATE termstate;
  FOLSTATE folstate;
  SYMBSTATE symbstate;
  ARRAY class;
  ARRAY class_info;
  BOOL status;
  CCBS_EQUATION conflict;
  ARRAY confl_labels;
  ARRAY pending;
  OHASH prooftree;
  OHASH hash_bucket;
  ARRAY zero_arity;
  ARRAY merge_queue;
  ARRAY btstack;
  ARRAY tmp_stack_term;
  ARRAY diseqs;
  ARRAY pending_preds;
  ARRAY cons;
  ARRAY conc;
  ARRAY prem;
  ARRAY pred_cls;
  unsigned cur_index;
#ifdef SPASS_CHECK
  unsigned cst_iterators;
#endif
} CCBS_TYPE, *CCBS_STATE;
typedef struct CCBS_ITERATOR_TYPE
{
  CCBS_CLASS cur_cls;
#ifdef SPASS_CHECK
  unsigned btstacksize;
  BS_FLAG flag;
#endif
} CCBS_ITERATOR_TYPE, *CCBS_ITERATOR;
CCBS_STATE congrbs_Init(MEMORY Mem, TERMSTATE Termstate, FOLSTATE Folstate, SYMBSTATE Symbstate);
void congrbs_Done(CCBS_STATE State);
void congrbs_BacktrackPush(CCBS_STATE State);
void congrbs_BacktrackPop(CCBS_STATE State);
void congrbs_Backtrack(CCBS_STATE State, unsigned Steps);
void congrbs_BuildTerm(CCBS_STATE State, TERM Term, BS_FLAG IneqTrue);
BOOL congrbs_AssertEqualConst(CCBS_STATE State, TERM Term0, TERM Term1, CCBS_LABEL Label);
BOOL congrbs_AssertNotEqualConst(CCBS_STATE State, TERM Term0, TERM Term1, CCBS_LABEL Label);
BOOL congrbs_AssertEqualBSPred(CCBS_STATE State, TERM Term, CCBS_LABEL Label);
BOOL congrbs_AssertNotEqualBSPred(CCBS_STATE State, TERM Term, CCBS_LABEL Label);
BOOL congrbs_AssertLiteral(CCBS_STATE State, TERM Atom, FOLSTATE Folstate, BOOL IsPositive);
CLAUSE congrbs_AssertArrayCheckConflict(CCBS_STATE State, FOLSTATE Folstate, ARRAY Positive, ARRAY Negative);
void congrbs_ExploreConflict(CCBS_STATE State);
BOOL congrbs_CheckEq(CCBS_STATE State, TERM Term0, TERM Term1);
TERM congrbs_GetClass(CCBS_STATE State, TERM Term);
ARRAY congrbs_GetAllClasses(CCBS_STATE State);
ARRAY congrbs_GetClassTerms(CCBS_STATE State, TERM Term);
ARRAY congrbs_GetSignatures(CCBS_STATE State, TERM Term);
SUBST congrbs_CheckClauseFalseInst(CCBS_STATE State, FOLSTATE Folstate, SUBSTSTATE SState, CLAUSE Clause);
CLAUSE congrbs_CreateClauseFromConflict(CCBS_STATE State, unsigned Id);
CLAUSE congrbs_CreateClauseFromConflictClause(CCBS_STATE State, SHARER Sharer, FOLSTATE Folstate, CLAUSE Clause, SUBST Subst, unsigned Id);
void congrbs_PrintClasses(CCBS_STATE State);
unsigned congrbs_GetNumClasses(CCBS_STATE State);
void congrbs_Watch(CCBS_STATE State, TERM Term0, TERM Term1);
extern void (*CCBS_watch_notify) (CCBS_STATE State, TERM Term0, TERM Term1, bool Polarity);
#endif
