Z3的安装
是python,如果安装失败,多半是网速太慢,不妨开热点试试?
pip install z3-solver
Z3的使用
首先导入包
from z3 import *
然后讲讲几个基础指令,挑用的多的来说
BitVec,就是设置一个未知整数,未知数的名字是name,未知数的位数就是bv,假如我们想定义一个int类型的变量,我们知道int是4个,32位,也就可以定义 x=BitVec(x,32)
BitVec(name, bv):
BitVecs,用法跟BitVec差不多,但是多了一个s,也就说明它可以一次性定义多个变量,配合python语法糖有奇效(可惜我不会,只能老老实实常规思路)
x,y,z=BitVecs("x y z",32)
BitVecVal,定义一个常量整数,val是常量值,bv是常量的位数
BitVecVal(val, bv, ctx=None):
Solver,创建一个解题类,我们可以利用他来解题
s = Solver()
解题类,有一个add方法,添加约束条件的意思,我们的解跟添加的约束条件有关
s.add(x+y=1)
至于check方法,就是计算未知数,并且返回一个数据用来判断是否有解。
s.check()
model则是获取计算结果。当然,获取的前提必定是先计算,不然调用会异常
s.model()
接下来引入一道小学数学题,来讲解Z3的使用
可以看到,出现了x,y,z三个未知数,我们先定义,然后构建约束器
x,y,z=BitVecs("x y z",32)
s = Solver()
根据方程添加约束条件
x = BitVec("x", 32)
y = BitVec("y", 32)
z = BitVec("z", 32)
s = Solver()
s.add((y + z - x) * x == 18 - 2 * x * x)
s.add(y * (z + x - y) == 27 - 2 * y * y)
s.add((x + y - z) * z == 36 - 2 * z * z)
s.check()
print(s.model())
ok,结果输出,一看就不对劲,但是吧,没有问题,因为是这里表示的是32位无符号整数,所以也就导致了这个结果(也算是一种值得注意的bug吧),那么我们该怎么办呢?
我们可以定义Int
Int(name, ctx=None):
修改一下定义,完事
x = Int("x")
y = Int("y")
z = Int("z")
s = Solver()
s.add((y + z - x) * x == 18 - 2 * x * x)
s.add(y * (z + x - y) == 27 - 2 * y * y)
s.add((x + y - z) * z == 36 - 2 * z * z)
s.check()
print(s.model())
正常输出,但是可能不止有一组解
我们可以加一个约束s.add(z!=-4),然后求另一组解
结尾
Z3是一个很好的逃课框架,很有值得学习的价值,各种运算问题都可以利用Z3,我所介绍的不过是冰山一角,Z3的强大,还等待着各位自己去探索。