BtorNode * boolector_ulte (Btor * btor, BtorNode * e0, BtorNode * e1) { BTOR_ABORT_ARG_NULL_BOOLECTOR (btor); BTOR_ABORT_ARG_NULL_BOOLECTOR (e0); BTOR_ABORT_ARG_NULL_BOOLECTOR (e1); BTOR_ABORT_REFS_NOT_POS_BOOLECTOR (e0); BTOR_ABORT_REFS_NOT_POS_BOOLECTOR (e1); e0 = btor_pointer_chase_simplified_exp (btor, e0); e1 = btor_pointer_chase_simplified_exp (btor, e1); BTOR_ABORT_ARRAY_BOOLECTOR (e0); BTOR_ABORT_ARRAY_BOOLECTOR (e1); BTOR_ABORT_NE_BW (e0, e1); btor->external_refs++; return btor_ulte_exp (btor, e0, e1); }
/* * * 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; }