Использование массива в Z3PY

Я использую z3 для своего исследования, и у меня есть следующая проблема. Я анализирую модель выполнимой формулы, которая содержит массивы, но я не понимаю результатов модели. Например, у меня есть две переменные 'pkgcounter' и 'rxlen' и два предложения p1 и p2. Моя цель - выяснить, существует ли модель, которая удовлетворяет обоим положениям.

 pkgcounter = Array('pkgcounter',IntSort(),BitVecSort(8))

 rxlen = Array('rxlen',IntSort(),BitVecSort(8))

 s = Solver()

 p1 = (pkgcounter < rxlen)

 p2 = (pkgcounter == rxlen)


 s.add(p1,p2)

 if s.check() == sat:

    print s.model()

В результате получается следующая модель: [rxlen = [else -> 0], pkgcounter = [else -> 0], k!0 = [else -> 0]]

Может ли кто-нибудь помочь мне интерпретировать этот результат? Потому что если rxlen и pkgcounter имеют все поля, равные нулю, предложение p1 не имеет модели.

1 ответ

В зависимости от версий Z3 и Python, которые вы используете, эта проблема будет давать разные результаты, все они вызваны

p1 = (pkgcounter < rxlen)

В Python 2.7 (pkgcounter < rxlen) упрощает до False, так как ArrayRef объекты не имеют < оператор и объекты разные. И наоборот, Python 3.5 жалуется на то, что эти объекты не упорядочены (TypeError: unorderable types: ArrayRef() < ArrayRef()).

Обратите внимание, что массивы в Z3 не имеют размера; если они индексируются целыми числами, они действительно имеют бесконечный размер. Так, (pkgcounter < rxlen) не имеет смысла в этом контексте, так как эти массивы нельзя сравнивать таким образом. (См. Также Теория SMT ArraysEx).

Причина того, что этот тестовый сценарий был удовлетворительным, вероятно, в том, что использовалась старая версия Z3. В последней версии (главная ветка на GitHub) это неудовлетворительно, но опять же, это потому, что p1 является False,

В общем, модели для переменных Array сообщаются, например, как определения функций rxlen = [else -> 0] означает, что функция для поиска элемента в массиве rxlen это функция, которая всегда возвращает 0, Добавляя

p3 = (rxlen[0] == 1)

Мы можем заставить rxlen иметь другое значение в первой позиции, и модель будет сообщена как rxlen = [0 -> 1, else -> 1]; т.е. 1 на позиции 0 а также 1 где-либо еще.

Другие вопросы по тегам