我用Z3_ast fs = Z3_parse_smtlib2_file(ctx,arg[1],0,0,0,0,0,0)
来读取文件。
此外,添加到求解器中使用了expr F = to_expr(ctx,fs)
then s.add(F)
。
我的问题是如何获得每个实例中的总约束数?
我也试过了F.num_args()
,但是在某些情况下它给出了错误的尺寸。
有没有办法计算总约束?
我用Z3_ast fs = Z3_parse_smtlib2_file(ctx,arg[1],0,0,0,0,0,0)
来读取文件。
此外,添加到求解器中使用了expr F = to_expr(ctx,fs)
then s.add(F)
。
我的问题是如何获得每个实例中的总约束数?
我也试过了F.num_args()
,但是在某些情况下它给出了错误的尺寸。
有没有办法计算总约束?
添加到某个目标之后,使用Goal.size()
可能会做你想做的事。F
这是 Python API 描述的链接,我相信您可以在 C/C++ API 中找到等价物:http ://research.microsoft.com/en-us/um/redmond/projects/z3/z3.html #目标大小
Anexpr F
表示抽象语法树,因此F.num_args()
返回具有的(一步)子级的数量F
,这可能就是您一直在尝试的方法并不总是有效的原因。例如,假设F = a + b
,则F.num_args() = 2
。而且,如果F = a + b*c
,那么F.num_args() = 2
还有,孩子们将在哪里a
和b*c
(假设通常的操作顺序)。因此,要计算约束的数量(如果您的定义与Goal.size()
产生的不同),您可以使用遍历树的递归方法。
我在下面包含了一个突出所有这些的示例(此处的 z3py 链接:http ://rise4fun.com/Z3Py/It5E )。
例如,我对约束的定义(或者更确切地说,某种意义上的表达式的复杂性)可能是叶的数量或表达式的深度。您可以根据需要获得尽可能详细的信息,例如,计算不同类型的操作数以适应您对约束的定义,因为您的问题并不完全清楚。例如,您可以将约束定义为表达式中出现的等式和/或不等式的数量。这可能需要修改以适用于带有量词、数组或未解释函数的公式。另请注意,Z3 可能会自动简化事情(例如,在下面的示例中1 - 1
被简化为0
)。
a, b, c = Reals('a b c')
F = a + b
print F.num_args() # 2
F = a + b * c
print F.num_args() # 2
print F.children() # [a,b*c]
g = Goal()
g.add(F == 0)
print g.size() # number of constraints = 1
g.add(Or(F == 0, F == 1, F == 2, F == 3))
print g.size() # number of constraints = 2
print g
g.add(And(F == 0, F == 1, F == 2, F == 3))
print g.size() # number of constraints = 6
print g
def count_constraints(c,d,f):
print 'depth: ' + str(d) + ' expr: ' + str(f)
if f.num_args() == 0:
return c + 1
else:
d += 1
for a in f.children():
c += count_constraints(0, d, a)
return c
exp = a + b * c + a + c * c
print count_constraints(0,0,exp)
exp = And(a == b, b == c, a == 0, c == 0, b == 1 - 1)
print count_constraints(0,0,exp)
q, r, s = Bools('q r s')
exp = And(q, r, s)
print count_constraints(0,0,exp)