Z3py — Создать выражение Z3py из строки, или Что происходит с «не» в eval?

Я пытаюсь решить ограничения в выражении if или while с помощью Z3py. Поскольку Z3py ожидает таких выражений, как True, False или Z3py-Boolean, мне пришлось решить, как преобразовать ограничения, которые являются просто строками, в правильную форму.
Я нашел эту тему, z3python: преобразование строки в выражение, в котором говорится, что вы должны использовать eval.
Теперь, упрощенно, что я делать следующее:

a = Real("a")
constr = "a < 1000"
ds = eval(constr)
print(ds)
solve(ds)

Это красиво распечатывает:

реал_а ‹ 1000

[реальное_а = 0]

Теперь я также хочу решить отрицание этого ограничения, а именно:

constr = "not(a < 1000)"

Результатом этого является:

Ложь

нет решения

Честно говоря, я не понимаю, почему появляется такой результат. Я ожидал, что все выражение внутри not будет инвертировано, и поэтому решение будет что-то вроде a = 1000. Но это явно не так.
Теперь мой вопрос: что именно там происходит, что происходит такой результат? И, что еще более важно: как я могу это исправить? Есть ли обходной путь?
Я знаю, что могу просто заменить каждый ‹ на ›=, каждый › на ‹=, каждый и на или и наоборот, удалить все не и так далее. Но это выглядит как много работы, и я сначала хочу убедиться, что нет другого пути.


person M0rgenstern    schedule 02.08.2014    source источник
comment
каково значение a?   -  person Padraic Cunningham    schedule 02.08.2014
comment
Ну, a вообще не имеет значения. Это тоже не имело бы смысла. Потому что тогда eval просто заменит переменную ее значением и вернет True или False. Но мне нужна строка, которую можно использовать в качестве ограничения, которое должен решить Z3py. И поэтому переменная, для которой я хочу знать значение, должна оставаться в ограничении как есть.   -  person M0rgenstern    schedule 02.08.2014