软件验证中的变量与运行时注解检查
1. 模型变量与幽灵变量
1.1 模型变量
模型变量不仅在指定接口行为时很有用,还能在更抽象的层面(通常以更数学化的方式)指定程序的行为。例如,在指定一个使用多个具体变量来编码一个抽象数学值的类时,模型变量就发挥了重要作用。
以 Decimal
类为例,该类使用 intPart
和 decPart
变量来实现十进制变量,但规范是通过一个表示组合十进制数的值的单一模型变量来给出的。这体现了模型变量能够对状态进行抽象表示,当底层状态发生变化时,模型变量也会隐式地改变,并且这种关系有时可以明确定义为一种转换,有时只能以非构造性的方式给出。
1.2 幽灵变量
幽灵变量是仅用于规范的变量,可以通过在关键字 ghost
之前的赋值或指令在规范中进行更新。幽灵变量通常用于编码关于状态的一些控制信息,常见的用例包括:
- 明确程序控制流的属性;
- 存储关于程序行为的额外信息(如内存使用和执行时间);
- 表明程序遵循某些协议。
1.2.1 跟踪程序流属性
可以使用幽灵变量来跟踪程序流属性,如循环迭代次数。例如,幽灵变量 z
可以跟踪循环中的迭代次数,并用于指定循环迭代次数的边界。
1.2.2 跟踪内存使用
假设我们有一种方法来估计为指针声明保留的内存块,就可以使用幽灵变量 MEM
来跟踪程序声明的总内存大小。这对于检查程