如何检查z3中的const是变量还是值?

时间:2012-09-03 19:26:18

标签: python z3

只是想知道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谓词,但用途不同。如果我想将公式中的所有变量重命名为其他变量,这将非常有用。

2 个答案:

答案 0 :(得分:5)

你所谓的变量(技术上)在Z3中被称为未解释的常量。值(例如1true#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_intis_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