208 lines
4.5 KiB
C
Raw Normal View History

2022-08-30 15:42:35 +08:00
#ifndef _watch_h_INCLUDED
#define _watch_h_INCLUDED
#include "endianess.h"
#include "reference.h"
#include "stack.h"
#include "vector.h"
#include <stdbool.h>
#define INVALID_WATCH INVALID_VECTOR_ELEMENT
typedef union watch watch;
typedef struct watch_type watch_type;
typedef struct binary_watch binary_watch;
typedef struct blocking_watch blocking_watch;
typedef struct large_watch large_watch;
struct watch_type
{
#ifdef KISSAT_IS_BIG_ENDIAN
bool binary:1;
unsigned padding:2;
unsigned lit:29;
#else
unsigned lit:29;
unsigned padding:2;
bool binary:1;
#endif
};
struct binary_watch
{
#ifdef KISSAT_IS_BIG_ENDIAN
bool binary:1;
bool redundant:1;
bool hyper:1;
unsigned lit:29;
#else
unsigned lit:29;
bool hyper:1;
bool redundant:1;
bool binary:1;
#endif
};
struct large_watch
{
#ifdef KISSAT_IS_BIG_ENDIAN
bool binary:1;
unsigned ref:31;
#else
unsigned ref:31;
bool binary:1;
#endif
};
struct blocking_watch
{
#ifdef KISSAT_IS_BIG_ENDIAN
bool binary:1;
unsigned padding:2;
unsigned lit:29;
#else
unsigned lit:29;
unsigned padding:2;
bool binary:1;
#endif
};
union watch
{
watch_type type;
binary_watch binary;
blocking_watch blocking;
large_watch large;
unsigned raw;
};
typedef vector watches;
typedef struct litwatch litwatch;
typedef struct litpair litpair;
// *INDENT-OFF*
typedef STACK (litwatch) litwatches;
typedef STACK (litpair) litpairs;
// *INDENT-ON*
struct litwatch
{
unsigned lit;
watch watch;
};
struct litpair
{
unsigned lits[2];
};
static inline litpair
kissat_litpair (unsigned lit, unsigned other)
{
litpair res;
res.lits[0] = lit < other ? lit : other;
res.lits[1] = lit < other ? other : lit;
return res;
}
static inline watch
kissat_binary_watch (unsigned lit, bool redundant, bool hyper)
{
assert (redundant || !hyper);
watch res;
res.binary.lit = lit;
res.binary.redundant = redundant;
res.binary.hyper = hyper;
res.binary.binary = true;
assert (res.type.binary);
return res;
}
static inline watch
kissat_large_watch (reference ref)
{
watch res;
res.large.ref = ref;
res.large.binary = false;
assert (!res.type.binary);
return res;
}
static inline watch
kissat_blocking_watch (unsigned lit)
{
watch res;
res.blocking.lit = lit;
res.blocking.padding = 0;
res.blocking.binary = false;
assert (!res.type.binary);
return res;
}
#define PUSH_WATCHES(W,E) \
do { \
assert (sizeof (E) == sizeof (unsigned)); \
kissat_push_vectors (solver, &solver->vectors, &(W), (E).raw); \
} while (0)
#define LAST_WATCH_POINTER(WS) \
(watch *) kissat_last_vector_pointer (&solver->vectors, &WS)
#define BEGIN_WATCHES(WS) \
((union watch*) kissat_begin_vector (&solver->vectors, &(WS)))
#define END_WATCHES(WS) \
((union watch*) kissat_end_vector (&solver->vectors, &(WS)))
#define RELEASE_WATCHES(WS) \
kissat_release_vector (solver, &solver->vectors, &(WS))
#define SET_END_OF_WATCHES(WS,P) \
do { \
sector SIZE = (unsigned*)(P) - kissat_begin_vector (&solver->vectors, &WS); \
kissat_resize_vector (solver, &solver->vectors, &WS, SIZE); \
} while (0)
#define REMOVE_WATCHES(W,E) \
kissat_remove_from_vector (solver, &solver->vectors, &(W), (E).raw)
#define WATCHES(LIT) (solver->watches[assert ((LIT) < LITS), (LIT)])
#define all_binary_blocking_watch_ref(WATCH,REF,WATCHES) \
watch WATCH, \
* WATCH ## _PTR = (assert (solver->watching), BEGIN_WATCHES (WATCHES)), \
* WATCH ## _END = END_WATCHES (WATCHES); \
WATCH ## _PTR != WATCH ## _END && \
((WATCH = *WATCH ## _PTR), \
(REF = WATCH.type.binary ? INVALID_REF : \
WATCH ## _PTR[1].large.ref), true); \
WATCH ## _PTR += 1u + !WATCH.type.binary
#define all_binary_blocking_watches(WATCH,WATCHES) \
watch WATCH, \
* WATCH ## _PTR = (assert (solver->watching), BEGIN_WATCHES (WATCHES)), \
* WATCH ## _END = END_WATCHES (WATCHES); \
WATCH ## _PTR != WATCH ## _END && ((WATCH = *WATCH ## _PTR), true); \
WATCH ## _PTR += 1u + !WATCH.type.binary
#define all_binary_large_watches(WATCH,WATCHES) \
watch WATCH, \
* WATCH ## _PTR = (assert (!solver->watching), BEGIN_WATCHES (WATCHES)), \
* WATCH ## _END = END_WATCHES (WATCHES); \
WATCH ## _PTR != WATCH ## _END && ((WATCH = *WATCH ## _PTR), true); \
++WATCH ## _PTR
void kissat_remove_blocking_watch (struct kissat *, watches *, reference);
void kissat_flush_large_watches (struct kissat *);
void kissat_watch_large_clauses (struct kissat *);
void kissat_connect_irredundant_large_clauses (struct kissat *);
void kissat_flush_large_connected (struct kissat *);
#endif