Можете ли вы ограничить реальную переменную между двумя границами? - PullRequest
3 голосов
/ 28 февраля 2020

Можете ли вы ограничить вещественную переменную между двумя границами?

    s = Solver()
    input = Reals('input')
    s.add(input >= -2, input <= 2)

Этот пример возвращает unsat для меня.

1 Ответ

3 голосов
/ 28 февраля 2020

В подобных случаях метод sexpr класса Solver - ваш друг!

Вы запутались из-за крайне слабо типизированной привязки z3py. Вызов Reals возвращает несколько результатов, которые вы присваиваете одному элементу. То есть ваша переменная input теперь является списком, содержащим одну переменную. Это, в свою очередь, делает всю программу бессмысленной, поскольку вы можете наблюдать за собой:

from z3 import *
s = Solver()
input = Reals('input')
s.add(input >= -2, input <= 2)
print s.sexpr()

Это печатает:

(assert true)
(assert false)

Почему? Поскольку ваша переменная input является списком, и причудливые правила продвижения типов решили, что список больше или равен -2, но меньше 2. (Это совершенно бессмысленно, просто то, как работают привязки. Там нет рифмы или причины, почему так должно быть. Можно утверждать, что это должно сделать больше проверки типов и дать вам правильную ошибку. Но я отступаю.)

Чтобы решить, просто измените свой вызов Reals на Real:

from z3 import *
s = Solver()
input = Real('input')
s.add(input >= -2, input <= 2)
print s.sexpr()
print s.check()
print s.model()

Это напечатает:

(declare-fun input () Real)
(assert (>= input (- 2.0)))
(assert (<= input 2.0))

sat
[input = 0]

, что именно то, что вы хотели сказать.

...