SMT-LIB语言简介
smt-lib是smt solver的输入语言
用来定义"决策问题实例"(decision procedure problem instance)
SMT-LIB支持的theory
- QF: for the restriction to quantifier-free formulas
- A or AX: for arrays without or with extensionality
- BV: for fixed-size bit-vectors
- FP: for Floating-Point
- IA: for integer arithmetic
- RA: for real arithmetic
- IRA: for mixed integer arithmetic
- IDL: for integer difference logic
- RDL: for rational difference logic
- L before IA, RA, or IRA: for the linear fragment of those arithmetics
- N before IA, RA, or IRA: for the nonlinear fragment of those arithmetics
- UF: for the extension allowing free sort and function symbols
举例:命题逻辑(Boolean)
用SMT-LIB语言表达如下问题:
验证表达式 \((a\lor b)\land\neg a\) 是否可满足
SMT-LIB语言中定义函数(从定义域到值域的映射)
(declare-fun <函数名> <定义域> <值域>)
SMT-LIB语言中定义变量 (定义域为空的函数)
如下声明一个布尔变量a
(declare-fun a () Bool)
SMT-LIB语言中的布尔常量和逻辑联结词
定义布尔变量之间的约束关系时需要用到:
布尔theory SMT-LIB语言 \(TRUE\) true
\(FALSE\) false
\(\neg a\) (not a)
\(a\Rightarrow b\) (=> a b)
\(a\land b\) (and a b)
\(a\lor b\) (or a b)
\(a\oplus b\) (xor a b)
\((a\lor b)\land\neg a\) 可以用以上SMT-LIB语言表示为
(and (or a b) (not a))
SMT-LIB语言中定义约束
用assert声明约束
(assert (and (or a b) (not a)))
声明了全部约束后,可以用
(check-sat)
检查所有约束是否可以同时满足;
若sat/满足,可以用
(get-model)
获得一组满足约束的变量赋值;
若unsat/不满足,可以用
(get-unsat-core)
获得所有约束条件的一个子集,该子集是不可满足的
算术理论(Arithmetic)
SMT-LIB语言支持定义整数和实数 之上的算术逻辑
变量的类型在SMT-LIB中被记为sort
SMT-LIB语法中有一些是对所有变量类型有效的
如:(= x y)
,表示两个相同类型的变量相等
注:不等关系(disequal a b c)
表示a
, b
, c
两两不相等
SMT-LIB中的ite表达式
(ite c x y)
其中c
为布尔表达式,x
和y
为相同类型的表达式
SMT-LIB语言提供算术逻辑的定义和操作
类型定义: 整数类型Int
和实数类型Real
操作符:
操作名 SMT-LIB语言 addition +
subtraction -
unary minus -
multiplication *
division /
(reals)div
(integers)remainder mod
(integers only)relations < > <= >=
大部分操作符支持多个操作数,如(+ x y z)
, 表示三个相同类型的数相加
整数和十进制小数可以写成字面量, 如(+ (* 2 x) 3.15)
注:负数可以用一元操作符得到,如(- 2)
, 不支持直接写成-2
比特向量算术理论(Bit-Vector Arithmetic)
SMT-LIB语言提供了一种带参数的类型 BitVec
,参数即为BitVec
的位长
BitVec
表示一个比特向量,不同位长的BitVec
为不同类型
如下定义一种BitVec的变量,下划线_
标识参数化类型,8
表示这种BitVec的位长为8:
(declare-fun a () (_ BitVec 8))
比特向量常量可以用2进制或16进制给出,如下给上面定义的变量a赋值:
(assert (= a #b11110000))
(assert (= a #xf0))
比特向量的操作:
比特向量可以看作是一个整数的原码或是补码
因此有些操作会对应两种不同操作符
操作名 原码 补码 addition bvadd bvadd subtraction bvsub bvsub multiplication bvmul bvmul division bvudiv bvsdiv remainder bvurem bvsrem relations bvult, bvugt,
bvule,bvugebvslt, bvsgt,
bvsle,bvsgeleft shift bvshl bvshl right shift bvlshr bvashr 比特向量还支持拼接
concat
和提取extract
操作
数组理论(Arrays)
数组:从索引(数组中为数组下标)类型到数组元素类型的映射
所以数组变量定义形如:(declare-fun a () (Array Int Real))
取对应下标的元素\(a[i]\):(select a i)
更新对应下标中元素的值\(a\{i\leftarrow e\}\): (store a i e)
等式(Equalities)
自定义类型:
如下所示:其中0
是指该类型my_sort
的元素维度(arity, 上述Array类型的元素维度为2, 如果有Set类型的话,其元素维度为1)
(declare-sort my_sort 0)
; 定义变量
(declare-fun a () my_sort)
(declare-fun b () my_sort)
(declare-fun c () my_sort)
; 声明等式和不等式约束
(assert (= a b))
(assert (disequal a b c))