我们常常会遇见一种伪代码,长达数百行数千行,只有单纯的加减乘除
很显然,这种又臭又长的代码需要一个工具来辅助处理:z3
简介
z3相当于利用计算机解方程,对于上图情况即解行列式问题
这是一种由微软开发的SMT求解器,C++开发,提供.NET、C、C++、Java、Python 等语言调用接口
网络上常见的教程是以python接口为例
安装
这里讲解一种相对比较简单的安装方式
在电脑已有python、pip环境时,只需利用pip安装即可
pip install z3-solver
python自带的IDLE可调用
语法
z3中有3种类型的变量,分别是整型(Int)/实型(Real)和向量(BitVec)
基本API:Ints (names, ctx=None),创建多个整数变量,names是空格分隔名字
BitVecs(name,bv,ctx=None),创建一个有多变量的位向量,name是名字,bv表示大小
基础例子:
from z3 import *
x, y = Reals('x y')
solve(x-y == 3, 3*x-8*y == 4)
#[y = 1, x = 4]
常用函数:
s=solver():创建一个解的对象。
s.add(条件):为解增加一个限制条件
s.check():检查解是否存在,如果存在,会返回"sat"
modul():输出解得结果
参考脚本
from z3 import *
Destination, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 = BitVecs('Destination v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 v20 v21 v22 v23 v24 v25 v26 v27 v28 v29', 32)
s=Solver()
s.add( 181 * v28 + 14 * v26 + 118 * v24 + 170 * v19 + 2 * v18 + 240 * v17 + 155 * v16 + 251 * v15 + 51 * v14 + 173 * v13 + 250 * v12 + 76 * v11 + 106 * v10 + 198 * v9 + 146 * v8 + 183 * v7 + 78 * v6 + 186 * Destination + 188 * v20 + 73 * v21 + 101 * v22 + 33 * v23 + 210 * v25 + 224 * v27 + 86 * v29 == 333521, 228 * v28 + 210 * v27 + 140 * v24 + 243 * v21 + 100 * v20 + 22 * v19 + 202 * v12 + 44 * v11 + 53 * v10 + 29 * v9 + 116 * v8 + 72 * v6 + 118 * Destination + 80 * v7 + 149 * v13 + 96 * v14 + 61 * v15 + 27 * v16 + 35 * v17 + 81 * v18 + 245 * v22 + 27 * v23 + 248 * v25 + 24 * v26 + 46 * v29 == 252689, 231 * v28 + 70 * v27 + 222 * v26 + 177 * v25 + 166 * v24 + 126 * v23 + 150 * v22 + 148 * v21 + 175 * v20 + (v19 << 7) + 126 * v18 + 188 * v17 + 66 * v16 + 80 * v14 + 194 * v12 + 79 * v9 + 217 * v8 + 253 * v7 + 175 * v6 + Destination + 197 * v10 + 73 * v11 + 208 * v13 + 12 * v15 + 188 * v29 == 349414, 114 * v28 + 91 * v25 + 166 * v24 + 121 * v21 + 132 * v20 + 249 * v19 + 109 * v18 + 146 * v15 + 226 * v14 + 71 * v11 + 125 * v10 + 230 * v9 + 146 * v8 + 131 * v7 + 181 * v6 + 130 * Destination + 139 * v12 + 9 * v13 + 208 * v16 + 80 * v17 + 74 * v22 + 24 * v23 + 198 * v26 + 65 * v27 + 111 * v29 == 308723, 175 * v28 + 230 * v27 + 132 * v26 + 247 * v25 + 244 * v24 + 189 * v23 + 124 * v22 + 241 * v21 + 83 * v20 + 187 * v19 + 90 * v18 + 205 * v17 + 123 * v16 + 80 * v12 + 247 * v10 + 212 * v9 + 176 * v6 + 242 * Destination + 221 * v7 + 63 * v8 + 177 * v11 + 20 * v13 + 107 * v14 + 11 * v15 + 208 * v29 == 386261, 16 * v26 + 53 * v25 + 220 * v24 + 116 * v23 + 230 * v22 + 172 * v21 + 248 * v20 + 26 * v19 + 150 * v18 + 188 * v15 + 185 * v14 + 189 * v13 + 105 * v12 + 22 * v11 + 146 * v10 + 39 * v9 + 142 * v6 + 108 * Destination + 190 * v7 + 36 * v8 + 246 * v16 + 17 * v17 + 55 * v27 + 48 * v28 + 119 * v29 == 297697,106 * v28 + 68 * v27 + 66 * v24+ 111 * v21 + 222 * v20 + 188 * v19 + 241 * v18 + 124 * v17 + 156 * v16 + 185 * v15 + 85 * v12 + 59 * v11 + 240 * v10 + 55 * v9 + 220 * v8 + 166 * v7 + 212 * v6 + 145 * Destination + 171 * v13 + 129 * v14 + 155 * v22 + 20 * v23 + 78 * v25 + 96 * v26 + 59 * v29 == 318281, 45 * v28 + 8 * v27 + 178 * v26 + 107 * v25 + 231 * v22 + 148 * v21 + 49 * v20 + 130 * v19 + 57 * v18 + 238 * v17 + 43 * v16 + 26 * v15 + 199 * v14 + 245 * v13 + 39 * v12 + 54 * v11 + 84 * v10 + 213 * v9 + 47 * v8 + 254 * v7 + 134 * v6 + 95 * v23 + 13 * v24 + 196 * v29 == 275034, 94 * v27 + 71 * v26 + 211 * v25 + 27 * v23 + 4 * v21 + 26 * v20 + (v19 << 8) + 34 * v16 + 220 * v15 + 237 * v10 + 169 * v7 + 216 * v6 + 107 * Destination + 225 * v8 + 96 * v9 + 87 * v11 + 73 * v12 + 70 * v13 + 36 * v14 + 148 * v17 + 33 * v18 + 163 * v22 + 112 * v24 + 178 * v28 + 40 * v29 == 270636, 85 * v28 + 39 * v27 + 91 * v26 + 114 * v25 + 178 * v22 + 110 * v21 + 43 * v20 + 253 * v19 + 3 * v17 + 110 * v15 + 189 * v12 + 247 * v11 + 39 * v10 + 90 * v9 + 239 * v8 + 126 * v7 + 38 * v6 + 16 * Destination + 92 * v13 + 9 * v14 + 165 * v16 + 40 * v18 + 91 * v23 + 129 * v24 + 140 * v29 == 263543, 196 * v28 + 154 * v27 + 165 * v26 + 227 * v25 + 105 * v24 + 241 * v23 + 242 * v22 + 130 * v21 + 116 * v18 + 198 * v17 + 227 * v16 + 193 * v15 + 201 * v14 + 126 * v13 + 51 * v12 + 107 * v11 + 82 * v10 + 177 * v9 + 227 * v8 + 60 * v7 + 191 * Destination + 20 * v6 + 202 * v19 + 15 * v20 + 4 * v29 == 349830, 88 * v28 + 72 * v26 + 63 * v25 + 86 * v23 + 37 * v21 + 16 * v19 + 209 * v18 + 251 * v17 + 213 * v16 + 115 * v11 + 214 * v6 + 177 * Destination + 77 * v7 + 12 * v8 + 89 * v9 + 3 * v10 + 223 * v12 + 10 * v13 + 227 * v14 + 13 * v15 + 109 * v20 + 63 * v22 + 39 * v24 + 5 * v27 + 150 * v29 == 240308, 131 * v28 + 71 * v27 + 221 * v24 + 44 * v23 + 78 * v22 + 42 * v21 + 93 * v20 + 172 * v19 + 251 * v18 + 57 * v17 + 232 * v16 + 254 * v15 + 155 * v14 + 213 * v13 + 35 * v12 + 109 * v11 + 190 * v10 + 74 * v9 + 121 * v8 + 134 * v7 + 217 * v6 + 34 * Destination + 110 * v25 + 36 * v26 + 254 * v29 == 322590, 143 * v28 + 158 * v27 + 133 * v24 + 168 * v23 + 239 * v22 + 223 * v21 + 200 * v20 + 16 * v19 + 192 * v17 + 13 * v16 + 69 * v14 + 253 * v13 + 148 * v12 + 16 * v11 + 144 * v9 + 252 * v7 + 74 * v6 + 82 * Destination + 52 * v8 + 192 * v10 + 230 * v15 + 73 * v18 + 149 * v25 + 37 * v26 + 245 * v29 == 342399, 243 * v28 + 62 * v27 + 88 * v24 + 4 * v23 + 38 * v22 + 209 * v21 + 207 * v20 + 195 * v17 + 165 * v16 + 47 * v15 + 247 * v14 + 199 * v13 + 230 * v12 + 148 * v11 + 2 * v10 + 140 * v9 + 116 * v8 + 51 * v7 + 205 * v6 + 204 * Destination + 62 * v18 + 36 * v19 + 169 * v25 + 36 * v26 + 136 * v29 == 298230, 203 * v28 + 212 * v27 + 150 * v26 + 139 * v25 + 76 * v22 + 30 * v21 + 155 * v20 + 185 * v17 + 126 * v16 + 225 * v15 + 163 * v14 + 143 * v13 + 236 * v12 + 121 * v9 + (v8 << 7) + 52 * v7 + 135 * v6 + 141 * Destination + 251 * v10 + 28 * v11 + 153 * v18 + 36 * v19 + 189 * v23 + 127 * v24 + 162 * v29 == 347118, 47 * v28 + 103 * v27 + 124 * v26 + 32 * v25 + 159 * v24 + 71 * v23 + 217 * v22 + 182 * v21 + 91 * v20 + 214 * v17 + 194 * v16 + 68 * v15 + 242 * v14 + 16 * v13 + 42 * v12 + 143 * v11 + 120 * v10 + 190 * v9 + 234 * v8 + 68 * v7 + 132 * v6 + 63 * Destination + 97 * v18 + 10 * v19 + 245 * v29 == 303489, 105 * v28 + 205 * v27 + 57 * v26 + 166 * v25 + 205 * v24 + 179 * v23 + 176 * v22 + 113 * v17 + 85 * v16 + 179 * v15 + 176 * v14 + 43 * v13 + 152 * v12 + 78 * v11 + 148 * v10 + 231 * v7 + 119 * v6 + 93 * Destination + 247 * v8 + 129 * v9 + 146 * v18 + 224 * v19 + 119 * v20 + 41 * v21 + 229 * v29 == 354654, 30 * v28 + 142 * v25 + 58 * v24 + 104 * v23 + 9 * v19 + 63 * v18 + 65 * v17 + 166 * v15 + 232 * v14 + 234 * v13 + 114 * v12 + 8 * v11 + 216 * v10 + 247 * v9 + 94 * v8 + 206 * v7 + 94 * v6 + 40 * Destination + 179 * v16 + 37 * v20 + 154 * v21 + 56 * v22 + 200 * v26 + 112 * v27 + 109 * v29 == 289980, 97 * v28 + 239 * v27 + 219 * v26 + 146 * v25 + 95 * v24 + 59 * v23 + 5 * v21 + 9 * v20 + 221 * v18 + 255 * v16 + 117 * v14 + 244 * v13 + 216 * v12 + 112 * v10 + 3 * v9 + 231 * v7 + 248 * v6 + 53 * Destination + 213 * v8 + 28 * v11 + 147 * v15 + 21 * v17 + 170 * v19 + 19 * v22 + 107 * v29 == 314367, 38 * v24 + 139 * v23 + 102 * v22 + 198 * v21 + 200 * v20 + 11 * v18 + 223 * v14 + 186 * v13 + 25 * v9 + 150 * v7 + 47 * v6 + 44 * Destination + 167 * v8 + 10 * v10 + 94 * v11 + 63 * v12 + 187 * v15 + 7 * v16 + 103 * v17 + 80 * v19 + 180 * v25 + 10 * v26 + 249 * v27 + 33 * v28 + 162 * v29 == 272305, 88 * v28 + 219 * v27 + 30 * v26 + 123 * v25 + 148 * v24 + 87 * v23 + 228 * v22 + 40 * v20 + 109 * v18 + 130 * v17 + 142 * v16 + 254 * v15 + 151 * v14 + 120 * v13 + 78 * v12 + 152 * v11 + 252 * v10 + 237 * v9 + (v8 << 8) + 54 * v7 + 84 * v6 + 113 * Destination + 219 * v19 + 13 * v21 + 166 * v29 == 344020, 29 * v28 + 76 * v25 + 214 * v24 + 61 * v23 + 135 * v22 + 124 * v19 + 124 * v18 + 162 * v17 + 227 * v16 + 148 * v15 + 81 * v11 + 191 * v9 + 34 * v8 + 29 * v7 + 239 * Destination + 4 * v6 + 234 * v10 + 37 * v12 + 123 * v13 + 37 * v14 + 126 * v20 + 15 * v21 + 235 * v26 + 36 * v27 + 244 * v29 == 300053, 173 * v26 + 100 * v25 + 241 * v22 + 102 * v21 + 243 * v18 + 25 * v16 + 229 * v14 + 181 * v13 + 2 * v12 + 204 * v11 + 185 * v10 + 130 * v6 + 18 * Destination + 129 * v7 + 219 * v8 + 11 * v9 + 202 * v15 + 73 * v17 + 178 * v19 + 160 * v20 + 32 * v23 + 25 * v24 + 49 * v27 + 96 * v28 + 150 * v29 == 308586, 114 * v27 + (v26 << 7) + 235 * v25 + 154 * v24 + 172 * v23 + 125 * v22 + 74 * v21 + 168 * v20 + 194 * v19 + 102 * v16 + 100 * v15 + 74 * v14 + 210 * v13 + 211 * v12 + 152 * v11 + 242 * v8 + 95 * Destination + 50 * v6 + 25 * v7 + 213 * v9 + 80 * v10 + 216 * v17 + 63 * v18 + 206 * v28 + 56 * v29 == 335291)
if solver.check() == sat:
print("结果:", solver.model())
else:
print(solver.check())
print(chr(m[Destination].as_long()%256)+chr(m[v6].as_long()%256)+chr(m[v7].as_long()%256)+chr(m[v8].as_long()%256)+chr(m[v9].as_long()%256)+chr(m[v10].as_long()%256)+chr(m[v11].as_long()%256)+chr(m[v12].as_long()%256)+chr(m[v13].as_long()%256)+chr(m[v14].as_long()%256)+chr(m[v15].as_long()%256)+chr(m[v16].as_long()%256)+chr(m[v17].as_long()%256)+chr(m[v18].as_long()%256)+chr(m[v19].as_long()%256)+chr(m[v20].as_long()%256)+chr(m[v21].as_long()%256)+chr(m[v22].as_long()%256)+chr(m[v23].as_long()%256)+chr(m[v24].as_long()%256)+chr(m[v25].as_long()%256)+chr(m[v26].as_long()%256)+chr(m[v27].as_long()%256)+chr(m[v28].as_long()%256)+chr(m[v29].as_long()%256))
IDLE可用