Z3求解器指南(一)

申明:本文翻译自rise4fun,翻译与原文存在一些差异。

z3是由微软公司开发的一个优秀的SMT求解器(也就定理证明器),它能够检查逻辑表达式的可满足性。

使用方式

z3是一个底层的工具,它最好是作为一个组件应用到其它需要求解逻辑公式的工具中。为了方便使用,z3提供了很多的API,这些api支持的语言有C, .NET, and OCaml。当然,z3也可以通过命令行的方式来执行。(最新版本的z3可以到这里下载,微软官网上只更新到4.1)

基本命令

Z3的输入格式是SMT-LIB2.0标准(想进一步了解smt-lib标准,可以参考这个网站)的一个拓展,一个Z3脚本就是一个命令序列。你可以使用help命令去查看一系列可用的命令。echo命令用于显示一个信息。Z3的内部维持着一个栈,这个栈里面保存着用户输入的公式和申明(常量的和函数的)。declare-const命令用于申明一个给定类型的常量,declare-fun命令则用于申明一个函数。

(echo "starting Z3...")
(declare-const a Int)
(declare-fun f (Int Bool) Int)

这个例子中申明了一个函数,有两个参数,分别为Int型和Bool型,返回一个Int型的值

命令assert用于添加一个公式到z3的栈中,如果对于输入的所有公式,z3能够给出一种解释(对于用户定义的常量和函数),使得所有的公式都成立,那么我么说这个公式集是可满足的。看下面这个例子:

(declare-const a Int)
(declare-fun f (Int Bool) Int)
(assert (> a 10))
(assert (< (f a true) 100))
(check-sat)

这个例子中第一个断言表示常量a必须大于10,第二个断言表示参数为a和true的函数f必须返回一个小于100的值。check-sat命令告诉求解器去求解当前z3栈中公式的可满足性。如果栈中的公式是可满足的,z3返回sat;如果不满足,z3返回unsat;当求解器无法判断当前公式是不是可满足的就返回unknown。

如果命令集是可满足的,我们可以使用get-model命令去获取一个使z3栈中所有公式集成立解释。

(declare-const a Int)
(declare-fun f (Int Bool) Int)
(assert (> a 10))
(assert (< (f a true) 100))
(check-sat)
(get-model)

我们用z3去求解这个公式集,得到的结果如下:

sat
(model 
  (define-fun a () Int
    11)
  (define-fun f ((x!1 Int) (x!2 Bool)) Int
    (ite (and (= x!1 11) (= x!2 true)) 0
      0))
)

结果中sat指的是该公式集是可满足的,而model中的内容则是对公式集的一个解释,看起来不太好理解,我们下面对model中的解释方式进行说明。

model中的解释是通过定义的方式给定的,例如

(define-fun a () Int [val])

这个定义申明函数a的返回值为[val]

(define-fun f ((x!1 Int) (x!2 Bool)) Int
   ...
)

这个定义跟编程语言中的函数申明类似。其中x1和x2是z3给出的函数f的参数解释。在上面的例子中,对f的定义使用了ite(if-than-else)的方式。

(ite (and (= x!1 11) (= x!2 false)) 21 0)

这个表达式是说当x1=11并且x2=false的时候函数返回21,否则返回0。这样就给出了一个使得公式集满足的解。

使用范围

有时候在解决一些相似的问题的时候,我们希望去复用一些定义和断言,z3提供了pushpop命令去实现这个功能。上面也提到了,z3会维持一个全局的栈,定义和断言就存储在栈中。Push命令通过保存当前栈大小的方式创建一个范围。Pop命令则是移除与之相匹配的push之间的所有断言和申明。

(declare-const x Int)
(declare-const y Int)
(declare-const z Int)
(push)
(assert (= (+ x y) 10))
(assert (= (+ x (* 2 y)) 20))
(check-sat)
(pop) ; remove the two assertions
(push) 
(assert (= (+ (* 3 x) y) 10))
(assert (= (+ (* 2 x) (* 2 y)) 21))
(check-sat)
(declare-const p Bool)
(pop)
(assert p) ; error, since declaration of p was removed from the stack

未完待续。。。。。。

你可能感兴趣的:(SMT-Solver,z3,z3求解器)