Python and Z3: integers and floating, how to manage them in the correct way?

醉酒当歌 提交于 2021-01-28 19:15:42

问题


need help with Z3 and Python...it looks I'm too dumb for this. My code:

from z3 import *

num1 = Int('num1')
num2 = Int('num2')
num3 = Int('num3')

s = Solver()
s.add( 2 * num1 - num2 + 0.5 * num3 == 5412.0)
s.add( 2 * num1 + 3 * num2 + 4 * num3 == 28312.0)

The result is the following:

[num3 = 1, num1 = 5568, num2 = 5724]

Which is not completely correct: the first expression actually returns 5412.5, not 5412.0. I guess it has to do with the mixed usage of "Int" with some "point numbers" (0.5). I actually need to keep the "numX" as "Int", since they are integers (this is a constraint). I guess I'm missing how to manage this mixed situation. Someone can help me?

Thanks,

Edited

Thanks to "alias" answer I got the right direction:

adding

cc1 = RealVal(0.5)

and then using that constant in the expression, I got the correct result.

Thanks to all!


回答1:


You're absolutely correct that Python bindings to Z3 suffer from weakly typing. This comes back to bite quite often, when least expected.

In these cases, sexpr() method is your friend. Add print s.sexpr() to the end of your program. It prints the following:

(declare-fun num3 () Int)
(declare-fun num2 () Int)
(declare-fun num1 () Int)
(assert (= (+ (- (* 2 num1) num2) (* 0 num3)) 5412))
(assert (= (+ (* 2 num1) (* 3 num2) (* 4 num3)) 28312))

And you can see your 0.5 became 0! Which is totally not what you wanted. Welcome to the world of "I'll coerce to make things fit behind your back."

To solve this, you really need to be very clear on conversions. Z3 supports floating-point and also real numbers. (i.e., with infinite precision.) And arithmetic doesn't mix-and-match in the SMTLib land, so you have to be very careful on how you construct the proper constants.




回答2:


Int declares (mathematical) integers, nothing else, so the model value will always be an integer. The expression 0.5 * num3 is automatically converted to integers (there's an option to disable these automatic conversions and instead throw an error). If you need fractional values, use Real instead of Int.



来源:https://stackoverflow.com/questions/60568329/python-and-z3-integers-and-floating-how-to-manage-them-in-the-correct-way

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!