只是想知道z3py,如何检查给定的常量表达式是变量还是值?例如
x = Int('x')
x_ = IntVal(7)
ColorVal, (White,Black) = EnumSort("ColorVal",["While","Black"])
mycolor = Const("mycolor",ColorVal)
所以x,mycolor都是变量而x_,True,False,White,Black都是值而不是变量。
z3py有is_var谓词,但用途不同。如果我想将公式中的所有变量重命名为其他变量,这将非常有用。
答案 0 :(得分:5)
你所谓的变量(技术上)在Z3中被称为未解释的常量。值(例如1
,true
,#x01
)称为解释常量。因此,原则上,使用以下代码可以快速检查a
是否为“变量”:
is_const(a) and a.decl().kind() == Z3_OP_UNINTERPRETED
这段代码适用于所有内容,但适用于数据类型。在尝试了您的示例之后,我意识到Z3错误地为数据类型构造函数返回Z3_OP_UNINTERPRETED
。我修复了Z3 4.2的问题。
在此期间,您可以使用以下解决方法,其中函数is_datatype_const_value(a)
返回True
a
是一个常量构造函数。
def is_datatype_sort(s):
return s.kind() == Z3_DATATYPE_SORT
def is_datatype_constructor(x):
s = x.sort()
if is_datatype_sort(s):
n = s.num_constructors()
f = x.decl()
for i in range(n):
c = s.constructor(i)
if eq(c, f):
return True
return False
# Return True if x is a constant constructor, that is, a constructor without arguments.
def is_datatype_const_value(x):
return is_const(x) and is_datatype_constructor(x)
然后,以下代码捕获所有未解释的常量:
is_const(a) and a.decl().kind() == Z3_OP_UNINTERPRETED and not is_datatype_const_value(a)
以下链接包含完整示例。 http://rise4fun.com/Z3Py/vjb
答案 1 :(得分:0)
对整数执行此操作的一种方法是使用is_int
和is_int_value
:
x = Int('x')
print "x types"
print is_int(x) # true, is of sort int
print is_int_value(x) # false, not a "value"
x_ = IntVal(7)
print "x_ types"
print is_int(x_) # true, is also of sort int
print is_int_value(x_) # true, is a value
对于实际,您可以使用is_real
检查变量排序,并使用({1}}和is_algebraic_value
的分离值(我没有看到函数类似于API中的is_rational_value
,但我认为这个析取会做到这一点)。对于位向量,您可以使用is_real_value
作为值,使用is_bv_value
检查变量排序。
.NET API有is_bv
,您可以在此处看到这些是如何在API中实现的(例如,Expr.IsNumeral
[相当于Python Expr.IsIntNum
]检查两者是否{ {1}}和is_int_value
为真):http://research.microsoft.com/en-us/um/redmond/projects/z3/_expr_8cs_source.html
我没有立即看到为自定义枚举排序执行此操作的方法。作为一种替代方法,您可以使用bitvectors对枚举进行编码,并使用Expr.IsNumeral
比较变量/值。但是,作为更好的解决方法,您似乎需要使用更一般的代数数据类型及其自动创建的“识别器”。如果您将它们声明为枚举排序,Python API似乎无法正确创建识别器。这是实现有效枚举排序的一种方法(但声明为更通用的数据类型)。
以下的Z3Py编码:http://rise4fun.com/Z3Py/ELtn
Expr.IsInt