我正在处理一个Z3 Python脚本,其中我试图根据涉及另一个变量x的条件更改一个变量y.以下是这个问题的一个简化版本:

from z3 import *

x = BitVec('x', 64)
y = BitVec('y', 64) # or y = BitVecVal(0, 64)

solver = Solver()
solver.add(x > 5555)

lsvec = [...] 

for i in range(1, 64):
    for j in range(i, 64):
        solver.add(y == If(x > 0, y + 1, y)) # I want to increment y if x > 0
        # Of course don't work because y == y + 1 cannot be satisfied
if solver.check() == sat:
        model = solver.model()
        x_value = model[x].as_long()    
        y_value = model[y].as_long()

我们的目标是在x > 0的情况下增加y.然而,目前的配方导致了无法满足的问题.

我正在寻求指导,了解如何使用Z3根据值x和其他条件正确建模条件增量y.

实际上,我正在try 解一个与下面的函数类似的函数.然而,对于XOR操作,我面临着同样的问题.

def f_evaluate2(x, bits):
    y = 0
    cursor = 0
    for i in range(1, bits + 1):  # 1-64
        for j in range(i, 65):
            if (x & (1 << (64 - i))) and (x & (1 << (64 - j))):
                y ^= lsvec[cursor] # unsat
            cursor += 1

    return y

任何关于如何在Z3中处理这些类型的约束的建议或例子都将不胜感激!

首先要感谢您的帮助.

推荐答案

这类事情在符号编程和代码生成/编译器算法中经常发生.标准的解决方案是使用所谓的"静态单一赋值表",也就是SSA.请参见https://en.wikipedia.org/wiki/Static_single-assignment_form以进行讨论.

其基本思想是首先编写算法,以便每个变量只赋值一次.这是通过为现有变量的每个赋值创建一个新变量来实现的.所以,在你的 case 中:

y = y + 1

将成为:

y1 = y + 1

然后使用y1作为对y的下一个引用.当你有一个条件时,你就会根据条件"合并"分配.(所谓的Φ函数.)当您有一个循环时,您将"展开"该循环,这要求您知道循环将迭代多少次(或者至少是迭代次数的上限),这样您就可以动态地展开.

您可以计算主导 node 以最小化SSA表示.幸运的是,您通常不必总是这样做:大多数情况下,假设问题的控制 struct 足够简单,您可以简单地线性化代码并进行动态转换.

下面是一个简单的例子,使用您关于建模的问题

y = if x > 0 then y+1 else y

你可以把它写成:

y1 = If(x > 0, y+1, y)`

并在后续表达式中使用y1.

希望这能让你开始学习.将命令式程序转换为符号友好的程序可能会很棘手,但如果您专门使用SSA样式,则应该会更容易.(即,首先以SSA形式编写原始程序,一旦确定它是正确的,然后将其转换为约束.)

Python相关问答推荐

如何分割我的收件箱,以便连续的数字各自位于自己的收件箱中?

如果在第一行之前不存在其他条件,如何获得满足口罩条件的第一行?

在有限数量的唯一字母的长字符串中,找到包含重复不超过k次的所有唯一字母的最长子字符串

在Python中,如何才能/应该使用decorator 来实现函数多态性?

socket.gaierror:[Errno -2]名称或服务未知|Firebase x Raspberry Pi

Docker-compose:为不同项目创建相同的容器

使用imap-tools时错误,其邮箱地址包含域名中的非默认字符

如何在vercel中指定Python运行时版本?

有没有方法可以修复删除了换码字符的无效的SON记录?

使用argsorted索引子集索引数组

Matplotlib轮廓线值似乎不对劲

给定数据点,制定它们的关系

try 与gemini-pro进行多轮聊天时出错

Odoo 14 hr. emergency.public内的二进制字段

连接两个具有不同标题的收件箱

PywinAuto在Windows 11上引发了Memory错误,但在Windows 10上未引发

将输入管道传输到正在运行的Python脚本中

如何设置视频语言时上传到YouTube与Python API客户端

在Python中,从给定范围内的数组中提取索引组列表的更有效方法

Numpyro AR(1)均值切换模型抽样不一致性