static BtorNode * parse_consth (BtorBTORParser * parser, int len) { char * tmp, * extended; BtorNode *res; int ch, clen; if (parse_space (parser)) return 0; assert (BTOR_EMPTY_STACK (parser->constant)); while (!isspace (ch = btor_nextch_btor (parser)) && ch != EOF && ch != ';') { if (!isxdigit (ch)) { (void) btor_perr_btor (parser, "expected hexidecimal digit"); return 0; } BTOR_PUSH_STACK (parser->mem, parser->constant, ch); } btor_savech_btor (parser, ch); clen = BTOR_COUNT_STACK (parser->constant); BTOR_PUSH_STACK (parser->mem, parser->constant, 0); BTOR_RESET_STACK (parser->constant); tmp = btor_hex_to_const_n (parser->mem, parser->constant.start, clen); clen = (int) strlen (tmp); if (clen > len) { (void) btor_perr_btor (parser, "hexadecimal constant '%s' exceeds bit width %d", parser->constant.start, len); btor_freestr (parser->mem, tmp); return 0; } if (clen < len) { extended = btor_uext_const (parser->mem, tmp, len - clen); btor_delete_const (parser->mem, tmp); tmp = extended; } assert (len == (int) strlen (tmp)); res = btor_const_exp (parser->btor, tmp); btor_freestr (parser->mem, tmp); assert (btor_get_exp_len (parser->btor, res) == len); return res; }
BtorNode * boolector_const (Btor * btor, const char *bits) { BTOR_ABORT_ARG_NULL_BOOLECTOR (btor); BTOR_ABORT_ARG_NULL_BOOLECTOR (bits); BTOR_ABORT_BOOLECTOR (*bits == '\0', "'bits' must not be empty"); btor->external_refs++; return btor_const_exp (btor, bits); }
static BtorNode * parse_const (BtorBTORParser * parser, int len) { BtorNode *res; int ch, clen; if (parse_space (parser)) return 0; assert (BTOR_EMPTY_STACK (parser->constant)); while (!isspace (ch = btor_nextch_btor (parser)) && ch != EOF && ch != ';') { if (ch != '0' && ch != '1') { (void) btor_perr_btor (parser, "expected '0' or '1'"); return 0; } BTOR_PUSH_STACK (parser->mem, parser->constant, ch); } btor_savech_btor (parser, ch); clen = BTOR_COUNT_STACK (parser->constant); BTOR_PUSH_STACK (parser->mem, parser->constant, 0); BTOR_RESET_STACK (parser->constant); if (clen != len) { (void) btor_perr_btor (parser, "binary constant '%s' exceeds bit width %d", parser->constant.start, len); return 0; } res = btor_const_exp (parser->btor, parser->constant.start); return res; }
static BtorNode * btor_map_node_internal (Btor * btor, BtorNodeMap * map, BtorNode * exp) { assert (btor); assert (exp); assert (BTOR_IS_REGULAR_NODE (exp)); BtorNode * m[3], * src, * dst, * real_exp; int i; m[0] = m[1] = m[2] = 0; for (i = 0; i < exp->arity; i++) { src = exp->e[i]; dst = btor_mapped_node (map, src); m[i] = dst ? dst : src; assert (BTOR_REAL_ADDR_NODE (m[i])->btor == btor); } assert (exp->kind != BTOR_PROXY_NODE); switch (exp->kind) { case BTOR_BV_CONST_NODE: // FIXME real_exp = exp weil BTOR_IS_REGULAR_NODE (exp) real_exp = BTOR_REAL_ADDR_NODE (exp); if (real_exp->btor != btor) { BtorNode * res = btor_const_exp (btor, btor_const_get_bits (exp)); if (real_exp != exp) res = BTOR_INVERT_NODE (res); return res; } // ELSE FALL THROUGH!!! case BTOR_BV_VAR_NODE: case BTOR_UF_NODE: return btor_copy_exp (btor, exp); case BTOR_SLICE_NODE: return btor_slice_exp (btor, m[0], btor_slice_get_upper (exp), btor_slice_get_lower (exp)); case BTOR_AND_NODE: return btor_and_exp (btor, m[0], m[1]); case BTOR_BEQ_NODE: case BTOR_FEQ_NODE: return btor_eq_exp (btor, m[0], m[1]); case BTOR_ADD_NODE: return btor_add_exp (btor, m[0], m[1]); case BTOR_MUL_NODE: return btor_mul_exp (btor, m[0], m[1]); case BTOR_ULT_NODE: return btor_ult_exp (btor, m[0], m[1]); case BTOR_SLL_NODE: return btor_sll_exp (btor, m[0], m[1]); case BTOR_SRL_NODE: return btor_srl_exp (btor, m[0], m[1]); case BTOR_UDIV_NODE: return btor_udiv_exp (btor, m[0], m[1]); case BTOR_UREM_NODE: return btor_urem_exp (btor, m[0], m[1]); case BTOR_CONCAT_NODE: return btor_concat_exp (btor, m[0], m[1]); case BTOR_LAMBDA_NODE: return btor_lambda_exp (btor, m[0], m[1]); default: assert (BTOR_IS_BV_COND_NODE (exp)); return btor_cond_exp (btor, m[0], m[1], m[2]); } }
static BtorNode * parse_constd (BtorBTORParser * parser, int len) { char ch, *tmp, * extended; BtorNode *res; int clen; if (parse_space (parser)) return 0; assert (BTOR_EMPTY_STACK (parser->constant)); ch = btor_nextch_btor (parser); if (!isdigit (ch)) { (void) btor_perr_btor (parser, "expected digit"); return 0; } BTOR_PUSH_STACK (parser->mem, parser->constant, ch); if (ch == '0') { ch = btor_nextch_btor (parser); if (isdigit (ch)) { (void) btor_perr_btor (parser, "digit after '0'"); return 0; } tmp = btor_strdup (parser->mem, ""); } else { while (isdigit (ch = btor_nextch_btor (parser))) BTOR_PUSH_STACK (parser->mem, parser->constant, ch); clen = BTOR_COUNT_STACK (parser->constant); tmp = btor_decimal_to_const_n (parser->mem, parser->constant.start, clen); } BTOR_PUSH_STACK (parser->mem, parser->constant, 0); BTOR_RESET_STACK (parser->constant); btor_savech_btor (parser, ch); clen = (int) strlen (tmp); if (clen > len) { (void) btor_perr_btor (parser, "decimal constant '%s' exceeds bit width %d", parser->constant.start, len); btor_freestr (parser->mem, tmp); return 0; } if (clen < len) { extended = btor_uext_const (parser->mem, tmp, len - clen); btor_delete_const (parser->mem, tmp); tmp = extended; } assert (len == (int) strlen (tmp)); res = btor_const_exp (parser->btor, tmp); btor_delete_const (parser->mem, tmp); assert (btor_get_exp_len (parser->btor, res) == len); return res; }
/* * * diff: d * l,....,u * l <= i && i <= u && (u - i) % d == 0 * * optimization if d is power of two * l <= i && i <= u && (u - i) & (d - 1) = 0 * * l <= i && i <= u && (u - i)[bits(d) - 1 - 1: 0] = 0 * * d: 1 * l <= i && i <= u * * d: 2 * l <= i && i <= u && (u - i)[0:0] = 0 * * d: 4 * l <= i && i <= u && (u - i)[1:0] = 0 * * d: 8 * l <= i && i <= u && (u - i)[2:0] = 0 */ static inline BtorNode * create_range (Btor * btor, BtorNode * lower, BtorNode * upper, BtorNode * param, BtorBitVector * offset) { assert (lower); assert (upper); assert (param); assert (BTOR_IS_REGULAR_NODE (param)); assert (BTOR_IS_PARAM_NODE (param)); assert (BTOR_IS_BV_CONST_NODE (BTOR_REAL_ADDR_NODE (lower)) || BTOR_IS_ADD_NODE (BTOR_REAL_ADDR_NODE (lower))); assert (BTOR_IS_BV_CONST_NODE (BTOR_REAL_ADDR_NODE (upper)) || BTOR_IS_ADD_NODE (BTOR_REAL_ADDR_NODE (upper))); assert (BTOR_REAL_ADDR_NODE (lower)->sort_id == BTOR_REAL_ADDR_NODE (upper)->sort_id); assert (offset); int pos; BtorNode *res, *le0, *le1, *and, *off, *sub, *rem, *eq, *zero, *slice; le0 = btor_ulte_exp (btor, lower, param); le1 = btor_ulte_exp (btor, param, upper); and = btor_and_exp (btor, le0, le1); /* increment by one */ if (btor_is_one_bv (offset)) res = btor_copy_exp (btor, and); /* increment by power of two */ else if ((pos = btor_is_power_of_two_bv (offset)) > -1) { assert (pos > 0); sub = btor_sub_exp (btor, upper, param); slice = btor_slice_exp (btor, sub, pos - 1, 0); zero = btor_zero_exp (btor, btor_get_exp_width (btor, slice)); eq = btor_eq_exp (btor, slice, zero); res = btor_and_exp (btor, and, eq); btor_release_exp (btor, zero); btor_release_exp (btor, slice); btor_release_exp (btor, sub); btor_release_exp (btor, eq); } /* increment by some arbitrary value */ else { zero = btor_zero_exp (btor, btor_get_exp_width (btor, lower)); off = btor_const_exp (btor, offset); assert (BTOR_REAL_ADDR_NODE (off)->sort_id == BTOR_REAL_ADDR_NODE (lower)->sort_id); sub = btor_sub_exp (btor, upper, param); rem = btor_urem_exp (btor, sub, off); eq = btor_eq_exp (btor, rem, zero); res = btor_and_exp (btor, and, eq); btor_release_exp (btor, zero); btor_release_exp (btor, off); btor_release_exp (btor, sub); btor_release_exp (btor, rem); btor_release_exp (btor, eq); } btor_release_exp (btor, le0); btor_release_exp (btor, le1); btor_release_exp (btor, and); return res; }