Есть ли какая-либо функция для расчета логарифма по основанию 2 в Z3/cvc4?
Я хочу доказать упрощение, которое включает вычисление log для базы 2. Есть ли в z3/cvc4 какая-либо функция для ее вычисления?
2 ответа
Короткий ответ: поддержка недоступна для целых чисел ни в одном инструменте. Для неограниченных целых чисел существуют процедуры принятия решений для возведения в степень Пресбургера фиксированной константой. Из этого вы можете построить функцию логарифма (или наоборот). Я не эксперт, но я понимаю, что это довольно сложно. Для дополнительной информации:
- http://www.logique.jussieu.fr/~point/papiers/Pres.pdf
- http://dx.doi.org/10.2307/2586704
- https://mathoverflow.net/questions/103896/beyond-presburger-arithmetic
Я не знаю ни о какой существующей реализации этих алгоритмов.
Для ограниченных целых чисел, т. Е. X в [a,b], где a и b - цифры, не существует решающей поддержки, но вы можете смоделировать это. Сначала вы создаете константу сколем s типа Integer. Затем вы форсируете интерпретацию s, используя утверждение:
(and (=> (2^0 <= x < 2^1) (= s 0))
(=> (2^1 <= x < 2^2) (= s 1))
...
(=> (2^i <= x < 2^{i+1}) (s = i)) ; for all 2^i in [a,b] and i >= 0.
)
Это не интерпретирует s, если x <= 0 (что я считаю разумным). Это очень неудовлетворительно, но оно линейно. (Если кто-то знает лучшую кодировку, я хотел бы знать об этом!) Вы также можете кодировать вышеуказанные аксиомы, используя квантификаторы для ограниченных или неограниченных целых чисел. Сначала вы кодируете функцию 2^i как неинтерпретируемую функцию, используя квантификаторы. Затем вы определяете функцию журнала, используя функцию 2^i. Это может привести к тому, что решатель вернет неизвестное, и вам, вероятно, придется поиграть с опциями решателя для модулей квантификаторов, если вы пойдете по этому пути.
Для битовых векторов вам необходимо решить, являются ли числа знаковыми или беззнаковыми. Для значений без знака длины k вы можете смоделировать это с помощью правого сдвига.
(=> (bvugt x (_ bv0 k))) (= (bvlshr x s) (_ bv1 k))
Снова x <= 0 (без знака) не интерпретируется. Подписанные битовые векторы похожи:
(=> (bvsgt x (_ bv0 k))) (= (bvlshr x s) (_ bv1 k))
В Alive действительно есть функция log2(foo). Он использует линейное кодирование, подобное тому, которое дал Тим.