/* * Merge the classes of x and y * - both terms must be roots, present in the table * - x and y must be distinct and at least one of them * must be a free root */ static void partition_merge(intern_tbl_t *tbl, term_t x, term_t y) { uint8_t r_x, r_y; type_t tau_x, tau_y, tau; assert(intern_tbl_is_root(tbl, x) && intern_tbl_is_root(tbl, y) && x != y); tau_x = ai32_get(&tbl->type, index_of(x)); tau_y = ai32_get(&tbl->type, index_of(y)); assert(tau_x != NULL_TYPE && tau_y != NULL_TYPE); // intersection type tau = inf_type(tbl->types, tau_x, tau_y); assert(tau != NULL_TYPE); r_x = au8_read(&tbl->rank, index_of(x)); r_y = au8_read(&tbl->rank, index_of(y)); assert(r_x < 255 || r_y < 255); if (r_x < r_y) { // y stays root and is made parent of x in the union-find tree assert(term_kind(tbl->terms, x) == UNINTERPRETED_TERM); ai32_write(&tbl->map, index_of(x), (y ^ polarity_of(x))); // update type[y] if needed if (tau != tau_y) { ai32_write(&tbl->type, index_of(y), tau); } } else { // x stays root and is made parent of y in the tree assert(term_kind(tbl->terms, y) == UNINTERPRETED_TERM); ai32_write(&tbl->map, index_of(y), (x ^ polarity_of(y))); // update type[x] if needed if (tau != tau_x) { ai32_write(&tbl->type, index_of(x), tau); } // increase rank[x] if needed if (r_x == r_y) { assert(r_x < 254); au8_write(&tbl->rank, index_of(x), r_x + 1); } } }
/* * Print what's mapped to t in the context's internalization table. * - if t is mapped to a Boolean, the corresponding DIMACS literal is printed * - if t is mapped to a bitvector then the corresponding literal array is printed * - otherwise we print "non boolean" */ void dimacs_print_internalized_term(FILE *f, context_t *ctx, term_t t) { intern_tbl_t *intern; type_table_t *types; term_t r; type_t tau; int32_t code; uint32_t polarity; intern = &ctx->intern; types = ctx->types; r = intern_tbl_get_root(intern, t); if (t != r) { // substitution: t --> r (can't deal with this) fputs("eliminated", f); } else if (intern_tbl_root_is_mapped(intern, r)) { // t = r is mapped to something polarity = polarity_of(r); r = unsigned_term(r); tau = intern_tbl_type_of_root(intern, r); if (is_boolean_type(tau)) { // Boolean term code = intern_tbl_map_of_root(intern, r); assert(code_is_valid(code)); dimacs_print_bool_code(f, code, polarity); } else if (is_bv_type(types, tau)) { // Bitvector term code = intern_tbl_map_of_root(intern, r); assert(code_is_valid(code)); assert(polarity == 0); dimacs_print_bv_code(f, ctx, code); } else { // Can't be converted to DIMACS fputs("non boolean", f); } } else { // r not mapped to anything fputs("not internalized", f); } }
// write p as parent of t in tbl static inline void intern_tbl_write_parent(intern_tbl_t *tbl, term_t t, term_t p) { ai32_write(&tbl->map, index_of(t), p ^ polarity_of(t)); }
static inline term_t intern_tbl_get_parent(intern_tbl_t *tbl, term_t t) { return ai32_get(&tbl->map, index_of(t)) ^ polarity_of(t); }