“在C中断言”和“像CBMC一样在模型检查中断言”有什么区别?

时间:2016-08-27 14:12:47

标签: c testing assert model-checking

在像CBMC这样的模型检查器(C的有界模型检查器)中,用户定义的断言语句采用布尔条件,模型检查器检查条件对于程序的所有可能执行是真还是假。

在C编程中,我们使用头文件assert.h定义assert()宏。如果assert()宏的参数计算为TRUE,则返回TRUE,如果计算FALSE,则返回某种操作。许多编译器将在失败的assert()中止该程序。

有人可以在模型检查和编程世界中澄清这两个断言之间的区别吗?

3 个答案:

答案 0 :(得分:2)

在模型检查中,断言(如您所说)验证所有可能的运行(这是模型检查器的主要目的)。所以,如果这是真的,你就会知道条件将始终保持不变。这是形式验证的领域。

在C语言中,断言在运行时验证,即对于给定的运行实例,则不保证在另一次运行中它将为真。这是测试的领域。

答案 1 :(得分:1)

在C中的声明(请参见https://en.wikipedia.org/wiki/Assert.h)与在模型检查中的声明不同。例如

transactions = ['001','002','003']
transaction_dates = ['01-01-2019','01-02-2019','01-03-2019']
transaction_amounts = ['27.00','35.00','36.00']

is_empty(zip(transactions,transaction_dates,transaction_amounts))
# False

在C中,程序被执行,并且当assert语句被评估为false时,执行将中止。实际上assert()将错误消息打印为标准错误,并通过调用abort()终止程序。

相反,实际上,在模型检查器中,assert语句采用布尔条件,并检查该条件对于程序的所有运行是否为true。在模型检查算法中(对于CBMC / HiFrog,...),不执行程序(因为它是静态分析的一部分)。高层的模型检查算法如下:

首先,模型检查器将整个程序连同声明的否定一起转换为逻辑公式(布尔值,LRA等),然后将整个公式传递给诸如SAT / SMT求解器之类的决策程序。如果公式不满足要求(无解),则表示程序中的有效保持,对于程序的所有可能输入,x> 0。否则,至少有一个输入使x在assert中变得小于零。

如上所述,在模型检查中,针对所有可能的运行验证断言(模型检查器的主要目标)。因此,如果模型检查器将assert验证为true,我们将知道assert语句将始终对程序的任何输入/运行成立。

答案 2 :(得分:0)

对于C,它取决于在NDEBUG被包含时是否定义了assert.h

如果未定义NDEBUG,则assert导致false将在标准错误上打印消息并终止该程序。

如果定义了NDEBUGassert将不会生成任何代码,即会跳过检查。

另见http://man7.org/linux/man-pages/man3/assert.3.html