У меня есть функция C ++, которая содержит выражение (проверка переполнения), которое просто доказуемо вручную.Я имею в виду оптимизацию, которая мне кажется правильной, и я не могу найти контрпример к ней, но я хотел бы быть уверен, что это правильно.Я слышал о Z3, и он, кажется, идеально подходит.Я написал формулу, и Z3 сказал unsat
, но проблема в том, что я не доверяю полученным результатам, потому что я не совсем понимаю, правильно ли я поступил (страх, основанный на предыдущих необычных результатах, которые я получил, но этобыла моя ошибка, и я ее узнал).
Функция C ++:
template <typename T>
bool add(int radix, int digit, T& n)
{
assert(radix > 2);
assert(radix <= 36);
assert(digit >= 0);
assert(digit < radix);
T max = std::numeric_limits<T>::max();
assert(max >= radix);
// the overflows check
if ((n > (max / radix)) || ((n * radix) > (max - digit)))
return false;
n = n * radix + digit;
return true;
}
Я хочу доказать (деления целые, вещественной части нет):
(n > (max / radix)) || ((n * radix) > (max - digit))
<=> n > ((max - digit) / radix)
или в более общем случае, если эти выражения всегда истинны, когда (n * radix) > max
или (n * radix + digit) > max
Z3-код, который у меня есть:
(declare-const radix Int)
(assert (>= radix 2))
(assert (<= radix 36)) ; this is the upper bound we officially support
(declare-const digit Int)
(assert (>= digit 0))
(assert (< digit radix))
(declare-const max Int)
(assert (> max 0))
(assert (>= max radix)) ; this is a reasonable requirement
;(assert (>= max 256)) ; the smallest upper bound for C++ fundamentals, but UDTs can have it lower
(declare-const n Int)
(assert (<= n max))
;(assert (>= n 0)) ; not really, but usually
; our current check
;(assert (not (or
; (> n (div max radix))
; (> (* n radix) (- max digit))
;)))
; our optimized check
(assert (not
(> n (div (- max digit) radix))
))
(assert (or
(> (* n radix) max) ; check no mul overflow
(> (+ n digit) max) ; check no add overflow
(> (+ (* n radix) digit) max) ; check no muladd overflow
))
(check-sat)
(get-model)
(exit)
https://rise4fun.com/Z3/po1h