Skip to content

Commit 0611907

Browse files
committed
Unbounded rotate for SMT-LIB2
1 parent 79ac19a commit 0611907

File tree

3 files changed

+50
-9
lines changed

3 files changed

+50
-9
lines changed

src/api/yices_api.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7334,6 +7334,37 @@ bool yices_check_bitshift(bvlogic_buffer_t *b, int32_t s) {
73347334
}
73357335

73367336

7337+
/*
7338+
* Check whether s is a valid shift amount for rotate_left/rotate_right in SMT-LIB2
7339+
* - SMT allows rotate by arbitrary amounts: ((_ rotate_left k) t) is the same
7340+
* as ((_ rotate_left (k % n) t)) where n = number of bits in t.
7341+
*
7342+
* This function
7343+
* - return true if 0 <= s and store the normalize shift (s % b->nbits) in *s
7344+
* - otherwise set the error report and return false.
7345+
*/
7346+
bool yices_check_smt2_rotate(bvlogic_buffer_t *b, int32_t *s) {
7347+
int32_t shift;
7348+
uint32_t n;
7349+
7350+
shift = *s;
7351+
if (shift < 0) {
7352+
error_report_t *error = get_yices_error();
7353+
error->code = INVALID_BITSHIFT;
7354+
error->badval = shift;
7355+
return false;
7356+
}
7357+
7358+
n = bvlogic_buffer_bitsize(b);
7359+
if (shift >= n && n > 0) {
7360+
shift = shift % n;
7361+
*s = shift;
7362+
}
7363+
7364+
return true;
7365+
}
7366+
7367+
73377368
/*
73387369
* Check whether [i, j] is a valid segment for a vector of n bits
73397370
* - return true if 0 <= i <= j <= n

src/api/yices_extensions.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,18 @@ extern bool yices_check_bvmul_buffer(bvarith_buffer_t *b1, bvarith_buffer_t *b2)
423423
extern bool yices_check_bitshift(bvlogic_buffer_t *b, int32_t s);
424424

425425

426+
/*
427+
* Check whether s is a valid shift amount for rotate_left/rotate_right in SMT-LIB2
428+
* - SMT allows rotate by arbitrary amounts: ((_ rotate_left k) t) is the same
429+
* as ((_ rotate_left (k % n) t)) where n = number of bits in t.
430+
*
431+
* This function
432+
* - return true if 0 <= s and store the normalize shift (s % b->nbits) in *s
433+
* - otherwise set the error report and return false.
434+
*/
435+
extern bool yices_check_smt2_rotate(bvlogic_buffer_t *b, int32_t *s) ;
436+
437+
426438
/*
427439
* Check whether [i, j] is a valid segment for a bitvector of size n
428440
* - return true if 0 <= i <= j < n

src/frontend/smt2/smt2_term_stack.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,12 @@ static void eval_smt2_mk_bv_rotate_left(tstack_t *stack, stack_elem_t *f, uint32
216216
index = get_integer(stack, f);
217217
b = tstack_get_bvlbuffer(stack);
218218
bvl_set_elem(stack, b, f+1);
219-
if (! yices_check_bitshift(b, index)) {
219+
if (! yices_check_smt2_rotate(b, &index)) {
220220
report_yices_error(stack);
221221
}
222222
// we known 0 <= index <= bitsize of b
223-
if (index < bvlogic_buffer_bitsize(b)) {
224-
bvlogic_buffer_rotate_left(b, index);
225-
}
223+
bvlogic_buffer_rotate_left(b, index);
224+
226225
tstack_pop_frame(stack);
227226
set_bvlogic_result(stack, b);
228227
}
@@ -245,13 +244,12 @@ static void eval_smt2_mk_bv_rotate_right(tstack_t *stack, stack_elem_t *f, uint3
245244
index = get_integer(stack, f);
246245
b = tstack_get_bvlbuffer(stack);
247246
bvl_set_elem(stack, b, f+1);
248-
if (! yices_check_bitshift(b, index)) {
247+
if (! yices_check_smt2_rotate(b, &index)) {
249248
report_yices_error(stack);
250249
}
251-
// we known 0 <= index <= bitsize of b
252-
if (index < bvlogic_buffer_bitsize(b)) {
253-
bvlogic_buffer_rotate_right(b, index);
254-
}
250+
// we known 0 <= index < bitsize of b
251+
bvlogic_buffer_rotate_right(b, index);
252+
255253
tstack_pop_frame(stack);
256254
set_bvlogic_result(stack, b);
257255
}

0 commit comments

Comments
 (0)