#ifndef _watch_h_INCLUDED #define _watch_h_INCLUDED #include "endianess.h" #include "reference.h" #include "stack.h" #include "vector.h" #include #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