/* pattern: lower <= j <= upper && range_cond ? j : a[j] */ static inline BtorNode * create_pattern_itoi (Btor * btor, BtorNode * lower, BtorNode * upper, BtorNode * array, BtorBitVector * offset) { assert (lower); assert (upper); assert (BTOR_REAL_ADDR_NODE (lower)->kind == BTOR_REAL_ADDR_NODE (upper)->kind); assert (BTOR_IS_BV_CONST_NODE (BTOR_REAL_ADDR_NODE (lower)) || BTOR_IS_ADD_NODE (BTOR_REAL_ADDR_NODE (lower))); assert (BTOR_REAL_ADDR_NODE (lower)->sort_id == BTOR_REAL_ADDR_NODE (upper)->sort_id); assert (btor_get_codomain_fun_sort ( &btor->sorts_unique_table, array->sort_id) == BTOR_REAL_ADDR_NODE (lower)->sort_id); assert (offset); BtorNode *res, *param, *ite, *read, *cond; param = btor_param_exp (btor, btor_get_exp_width (btor, lower), 0); read = btor_read_exp (btor, array, param); cond = create_range (btor, lower, upper, param, offset);; ite = btor_cond_exp (btor, cond, param, read); res = btor_lambda_exp (btor, param, ite); btor_release_exp (btor, param); btor_release_exp (btor, read); btor_release_exp (btor, cond); btor_release_exp (btor, ite); return res; }
static BtorNode * parse_acond (BtorBTORParser * parser, int len) { BtorNode *c, *t, *e, *res; int idxlen; if (parse_space (parser)) return 0; if (parse_positive_int (parser, &idxlen)) return 0; if (parse_space (parser)) return 0; if (!(c = parse_exp (parser, 1, 0))) return 0; if (parse_space (parser)) { RELEASE_C_AND_RETURN_ERROR: btor_release_exp (parser->btor, c); return 0; } if (!(t = parse_array_exp (parser, len))) goto RELEASE_C_AND_RETURN_ERROR; if (idxlen != btor_get_index_exp_len (parser->btor, t)) { (void) btor_perr_btor (parser, "mismatch of index bit width of 'then' array"); RELEASE_C_AND_T_AND_RETURN_ERROR: btor_release_exp (parser->btor, t); goto RELEASE_C_AND_RETURN_ERROR; } if (parse_space (parser)) goto RELEASE_C_AND_T_AND_RETURN_ERROR; if (!(e = parse_array_exp (parser, len))) goto RELEASE_C_AND_T_AND_RETURN_ERROR; if (idxlen != btor_get_index_exp_len (parser->btor, e)) { (void) btor_perr_btor (parser, "mismatch of index bit width of 'else' array"); btor_release_exp (parser->btor, e); goto RELEASE_C_AND_T_AND_RETURN_ERROR; } res = btor_cond_exp (parser->btor, c, t, e); btor_release_exp (parser->btor, e); btor_release_exp (parser->btor, t); btor_release_exp (parser->btor, c); return res; }
BtorNode * boolector_cond (Btor * btor, BtorNode * e_cond, BtorNode * e_if, BtorNode * e_else) { BtorNode *real_e_if, *real_e_else; int is_array_e_if, is_array_e_else; BTOR_ABORT_ARG_NULL_BOOLECTOR (btor); BTOR_ABORT_ARG_NULL_BOOLECTOR (e_cond); BTOR_ABORT_ARG_NULL_BOOLECTOR (e_if); BTOR_ABORT_ARG_NULL_BOOLECTOR (e_else); BTOR_ABORT_REFS_NOT_POS_BOOLECTOR (e_cond); BTOR_ABORT_REFS_NOT_POS_BOOLECTOR (e_if); BTOR_ABORT_REFS_NOT_POS_BOOLECTOR (e_else); e_cond = btor_pointer_chase_simplified_exp (btor, e_cond); e_if = btor_pointer_chase_simplified_exp (btor, e_if); e_else = btor_pointer_chase_simplified_exp (btor, e_else); BTOR_ABORT_ARRAY_BOOLECTOR (e_cond); BTOR_ABORT_BOOLECTOR (BTOR_REAL_ADDR_NODE (e_cond)->len != 1, "bit-width of 'e_cond' must be equal to 1"); real_e_if = BTOR_REAL_ADDR_NODE (e_if); real_e_else = BTOR_REAL_ADDR_NODE (e_else); is_array_e_if = BTOR_IS_ARRAY_NODE (real_e_if); is_array_e_else = BTOR_IS_ARRAY_NODE (real_e_else); BTOR_ABORT_BOOLECTOR (is_array_e_if != is_array_e_else, "array must not be combined with bit-vector"); BTOR_ABORT_BOOLECTOR (!is_array_e_if && real_e_if && real_e_else && real_e_if->len != real_e_else->len, "bit-vectors must not have unequal bit-width"); BTOR_ABORT_BOOLECTOR (is_array_e_if && real_e_if && real_e_else && real_e_if->len != real_e_else->len, "arrays must not have unequal element bit-width"); BTOR_ABORT_BOOLECTOR (is_array_e_if && real_e_if && real_e_else && real_e_if->index_len != real_e_else->index_len, "arrays must not have unequal index bit-width"); btor->external_refs++; return btor_cond_exp (btor, e_cond, e_if, e_else); }
static BtorNode * parse_cond (BtorBTORParser * parser, int len) { BtorNode *c, *t, *e, *res; if (parse_space (parser)) return 0; if (!(c = parse_exp (parser, 1, 0))) return 0; if (parse_space (parser)) { RELEASE_C_AND_RETURN_ERROR: btor_release_exp (parser->btor, c); return 0; } if (!(t = parse_exp (parser, len, 0))) goto RELEASE_C_AND_RETURN_ERROR; if (parse_space (parser)) { RELEASE_C_AND_T_AND_RETURN_ERROR: btor_release_exp (parser->btor, t); goto RELEASE_C_AND_RETURN_ERROR; } if (!(e = parse_exp (parser, len, 0))) goto RELEASE_C_AND_T_AND_RETURN_ERROR; res = btor_cond_exp (parser->btor, c, t, e); btor_release_exp (parser->btor, e); btor_release_exp (parser->btor, t); btor_release_exp (parser->btor, c); return res; }
static inline BtorNode * create_pattern_cpy (Btor * btor, BtorNode * lower, BtorNode * upper, BtorNode * src_array, BtorNode * dst_array, BtorNode * src_addr, BtorNode * dst_addr, BtorBitVector * offset) { assert (!BTOR_IS_INVERTED_NODE (lower)); assert (!BTOR_IS_INVERTED_NODE (upper)); assert (BTOR_IS_ADD_NODE (lower)); assert (BTOR_IS_ADD_NODE (upper)); BtorNode *res, *param, *ite, *read, *cond, *read_src, *add, *sub; param = btor_param_exp (btor, btor_get_exp_width (btor, lower), 0); read = btor_read_exp (btor, dst_array, param); cond = create_range (btor, lower, upper, param, offset); sub = btor_sub_exp (btor, param, dst_addr); add = btor_add_exp (btor, src_addr, sub); read_src = btor_read_exp (btor, src_array, add); ite = btor_cond_exp (btor, cond, read_src, read); res = btor_lambda_exp (btor, param, ite); btor_release_exp (btor, param); btor_release_exp (btor, read); btor_release_exp (btor, cond); btor_release_exp (btor, sub); btor_release_exp (btor, add); btor_release_exp (btor, read_src); btor_release_exp (btor, ite); 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]); } }