Z3 Python:订购模型并访问它们的元素
Z3 Python: ordering models and accessing their elements
在 Z3 (Python) 中,假设我得到一个具有以下形状的模型:
[c_0 = True, c_3 = False, c_1 = False, c_2 = False]
如何对变量进行排序,以便赋值按字母顺序排列? [c_0 = True, c_1 = False, c_2 = False, c_3 = False]
如何访问模型的任何元素?我的意思是,如果我这样做:
m = s.model() #equivalent to [c_0 = True, c_3 = False, c_1 = False, c_2 = False]
a = m[0]
print(a)
我得到 c_0
,而不是预期的 c_0 = True
。
为了使这个 post 尽可能简单,我不再添加代码,c
变量只是示例。
我最后的objective是一个方法,给定[c_0 = True, c_3 = False, c_1 = False, c_2 = False]
returns一个数组a=[True, False, False, False]
,其中a[0]
对应于[=14的值=]、a[1]
对应c_1
等值
编辑
对于 (1),我尝试了 sorted(m, key=str.lower)
,但出现以下错误:descriptor 'lower' requires a 'str' object but received a 'FuncDeclRef'
。这意味着我应该将每个元素转换为我不想要的 str
。
我更喜欢 Z3 的 'native' 方法,它不会对变量类型产生任何修改。
如果要按键对模型进行排序,则必须将其转换为不同的数据结构。 (这实际上与 z3 没有太大关系,而是字典在内部是如何完成的。)您尝试的几乎就在那里,您只需要确保同时保留变量和值。这是一个例子:
from z3 import *
a, b = Bools('a b')
s = Solver()
s.add(And(a, Not(b)))
print(s.check())
m = s.model()
nicer = sorted ([(d, m[d]) for d in m], key = lambda x: str(x[0]))
print(nicer)
这会打印:
sat
[(a, True), (b, False)]
请注意,它会保持一切不变,也就是说,您不会丢失对象属性:
print(type(nicer[0][0]))
print(type(nicer[0][1]))
打印:
<class 'z3.z3.FuncDeclRef'>
<class 'z3.z3.BoolRef'>
对于你的第二个问题,你可以通过变量本身来访问:注意模型是字典,所以它们可以通过变量来查找。对于上面的程序,你可以说:
print(m[a])
print(m[b])
这会打印:
True
False
获得对列表后,您可以简单地获取值:
print([v for (d, v) in nicer])
这会打印:
[True, False]
现在你有了一个配对列表,你可以随意使用它做任何事情。
旁注:我理解在您的问题中加入“最少”代码量的动机;这很诱人,我自己也做过!但最好还是提供一个最小的完整示例,即本论坛的读者可以按原样 运行 的内容。这样可以确保他们不必猜测您可能正在做的其他事情,或导致误解。请尽可能 post 一个最小的完整示例来说明您面临的问题。此外,如果每个 post 只问一个问题,stack-overflow 的效果最好;否则细节会变得模糊。最好的办法是提出一个具体的问题和一个最小的完整示例,尽管我知道这可能并不总是可行的。谢谢!
在 Z3 (Python) 中,假设我得到一个具有以下形状的模型:
[c_0 = True, c_3 = False, c_1 = False, c_2 = False]
如何对变量进行排序,以便赋值按字母顺序排列?
[c_0 = True, c_1 = False, c_2 = False, c_3 = False]
如何访问模型的任何元素?我的意思是,如果我这样做:
m = s.model() #equivalent to [c_0 = True, c_3 = False, c_1 = False, c_2 = False]
a = m[0]
print(a)
我得到 c_0
,而不是预期的 c_0 = True
。
为了使这个 post 尽可能简单,我不再添加代码,c
变量只是示例。
我最后的objective是一个方法,给定[c_0 = True, c_3 = False, c_1 = False, c_2 = False]
returns一个数组a=[True, False, False, False]
,其中a[0]
对应于[=14的值=]、a[1]
对应c_1
等值
编辑
对于 (1),我尝试了 sorted(m, key=str.lower)
,但出现以下错误:descriptor 'lower' requires a 'str' object but received a 'FuncDeclRef'
。这意味着我应该将每个元素转换为我不想要的 str
。
我更喜欢 Z3 的 'native' 方法,它不会对变量类型产生任何修改。
如果要按键对模型进行排序,则必须将其转换为不同的数据结构。 (这实际上与 z3 没有太大关系,而是字典在内部是如何完成的。)您尝试的几乎就在那里,您只需要确保同时保留变量和值。这是一个例子:
from z3 import *
a, b = Bools('a b')
s = Solver()
s.add(And(a, Not(b)))
print(s.check())
m = s.model()
nicer = sorted ([(d, m[d]) for d in m], key = lambda x: str(x[0]))
print(nicer)
这会打印:
sat
[(a, True), (b, False)]
请注意,它会保持一切不变,也就是说,您不会丢失对象属性:
print(type(nicer[0][0]))
print(type(nicer[0][1]))
打印:
<class 'z3.z3.FuncDeclRef'>
<class 'z3.z3.BoolRef'>
对于你的第二个问题,你可以通过变量本身来访问:注意模型是字典,所以它们可以通过变量来查找。对于上面的程序,你可以说:
print(m[a])
print(m[b])
这会打印:
True
False
获得对列表后,您可以简单地获取值:
print([v for (d, v) in nicer])
这会打印:
[True, False]
现在你有了一个配对列表,你可以随意使用它做任何事情。
旁注:我理解在您的问题中加入“最少”代码量的动机;这很诱人,我自己也做过!但最好还是提供一个最小的完整示例,即本论坛的读者可以按原样 运行 的内容。这样可以确保他们不必猜测您可能正在做的其他事情,或导致误解。请尽可能 post 一个最小的完整示例来说明您面临的问题。此外,如果每个 post 只问一个问题,stack-overflow 的效果最好;否则细节会变得模糊。最好的办法是提出一个具体的问题和一个最小的完整示例,尽管我知道这可能并不总是可行的。谢谢!