Z3Py 学习

一、数据类型

  • integer 整型 ToInt(arg)转换为整型

创建对象的方式:

x = Int('x')

x,y = Ints('x y')

 

  • real 实数 ToReal(arg)转换为有理数

x = Real('x')

x ,y = Reals('x y')

 

例:

x = Real('x')

solve(3*x==1)

# 启用精度

set_option(rational_to_decimal=True)

solve(3*x==1)

# 设置精度

set_option(precision=30)

solve(3*x==1)

输出:

[x = 1/3]

[x = 0.3333333333?]

[x = 0.333333333333333333333333333333?]

 

  • bool 布尔值

p = Bool('p')

p,q = Bool('p q')

 

Z3支持布尔运算符:And,Or,Not,Implies(蕴涵), If(if-then-else)。 使用等式 == 表示双重含义。

p,q,r = Bools('p q r')

solve(Implies(p, q), r == Not(q), Or(Not(p), r))

 

 

  • Solver 求解器

 

例:

x = Int('x')

y = Int('y')

 

s = Solver()

print s # []

 

s.add(x > 10, y == x + 2)

print s # [x > 10, y == x + 2]

print "Solving constraints in the solver s ..."

print s.check() #sat [ returns : sat unsat unknown ]

 

print "Create a new scope..."

s.push()

s.add(y < 11)

print s # [x > 10, y == x + 2, y < 11]

print "Solving updated set of constraints..."

print s.check() # unsat

 

print "Restoring state..."

s.pop()

print s # [x > 10, y == x + 2]

print "Solving restored set of constraints..."

print s.check() # sat

 

以下示例说明如何遍历声明为求解器的约束,以及如何收集check方法的性能统计信息。

x = Real('x')

y = Real('y')

s = Solver()

s.add(x > 1, y > 1, Or(x + y > 3, x - y < 2))

print "asserted constraints..."

for c in s.assertions():

print c

# 输出:

# x > 1

# y > 1

# Or(x + y > 3, x - y < 2)

print s.check() # sat

 

print "statistics for the last check method..."

print s.statistics()

# (:add-rows 1

# :assert-lower 4

# :decisions 2

# :final-checks 1

# :max-memory 2.91

# :memory 2.27

# :mk-bool-var 9

# :num-allocs 208770603

# :pivots 1

# :rlimit-count 3042)

 

# Traversing statistics

for k, v in s.statistics():

print "%s : %s" % (k, v)

 

 

以下示例显示了检查模型的基本方法:

x, y, z = Reals('x y z')

s = Solver()

s.add(x > 1, y > 1, x + y > 3, z - x < 10)

print s.check() # sat

 

m = s.model()

print "x = %s" % m[x] # x=2

print "y = %s" % m[y] # y=2

 

print "traversing model..."

for d in m.decls():

print "%s = %s" % (d.name(), m[d])

输出:

z = 0

y = 2

x = 2

 

  • 算术

x = Real('x')

y = Int('y')

a, b, c = Reals('a b c')

s, r = Ints('s r')

print x + y + 1 + (a + s) # x + ToReal(y) + 1 + a + ToReal(s)

print ToReal(y) + c # ToReal(y) + c

 

a, b, c = Ints('a b c')

d, e = Reals('d e')

solve(a > b + 2,

a == 2*c + 10,

c + b <= 1000,

d >= e)

# [b = 0, c = 0, e = 0, d = 0, a = 10]

 

simplify化简:

x, y = Reals('x y')

# Put expression in sum-of-monomials form

t = simplify((x + y)**3, ':som', True)

# t = simplify((x + y)**3,som=True)

print t

# Use power operator

t = simplify(t, mul_to_power=True)

print t

# x*x*x + 3*x*x*y + 3*x*y*y + y*y*y

# x**3 + 3*x**2*y + 3*x*y**2 + y**3

 

  • 可满足性和有效性

p, q = Bools('p q')

demorgan = And(p, q) == Not(Or(Not(p), Not(q)))

print demorgan # And(p, q) == Not(Or(Not(p), Not(q)))

def prove(f):

s = Solver()

s.add(Not(f))

if s.check() == unsat:

print "proved"

else:

print "failed to prove"

 

print "Proving demorgan..."

 

prove(demorgan)

输出:

# Proving demorgan...

# proved

你可能感兴趣的:(形式化方法,Coq)