zoukankan      html  css  js  c++  java
  • <VCC笔记> 关于Assertion

    这篇博客开始介绍VCC的用法,先用简单的例子介绍VCC的基本语法,当然面对更复杂的程序时,VCC也是将他简化然后分析的。

      1.Assertion

    #include <vcc.h>
    int main() {
        int x,y,z;
        if (x <= y) z = x;
        else z = y;
        _(assert z <= x)
        return 0;
    }

      上面的代码使z成为x和y之中的最小值。其中被_(  )包围的注释就是VCC所需要的注释,而且C语言编译器会无视这些注释。因为include的<vcc.h>中定义了#define _(...) /∗nothing∗/

    一个类似_(assert E)的注释就是一个Assertion,他要求VCC证明注释中的表达式E是成立(hold)。所以_(assert z <= x)要求当代码执行到这一行时,z应该小于等于x。需要注意的是,如果VCC验证通过了这一条Assertion,这表示VCC证明不管什么时候,不管执行多少次,这条Assertion都会成立。

         C语言自身也有类似的东西 assert(E)。微软的文档中这样介绍两者的区别。

    It is instructive to compare_(assert E)with the macro assert(E) (defined in <assert.h>), which evaluates E at runtime and aborts execution if E doesn’t hold. First, assert(E) requires runtime overhead (at least in builds where the check is made), whereas_(assert E)doesnot.Second,assert(E)will catch failure of the assertion only when it actually fails in an execution, whereas _(assert E) is guaranteed to catch the failure if it is possible in any execution. Third, because _(assert E) is not actually executed, E can include unimplementable mathematical operations, such as quantification over infinite domains.

      如果要在cmd命令行中用VCC验证这个函数,你可以把代码保存为minimum.c,在命令行中使用VCC大致如下,**表示代码文件目录。

    C:**> vcc.exe minimum.c

    Verification of main succeeded.

       如果装了VCC的Visual Studio插件,用VS打开文件之后,空白处右击,在菜单中选择Verify minimum.c就可以验证这个文件,验证结果会在VS底部给出。如果在函数内点击也可以只验证这个函数。

      2.VCC的原理部分

      要理解VCC的工作原理,可以去了解每一步执行中VCC掌握了什么信息。在上面的例子中VCC一开始什么都不知道,然后知道了if的第一个条件x<=y, 然后是z==x, 所以VCC知道z<=x。在else分支中,类似的,VCC知道y<x, z==y, 所以VCC知道z<=x。if的每个分支VCC都发现Assertion成立,最后他就会验证通过这个Assertion。

      我们说VCC知道什么,指的是VCC知道代码提供的信息,并且可以通过当前已知的信息可以直接推断出新的信息。在这种理想状态下,当你新增一个正确的Assertion,肯定不会影响他后面的Assertion的正确性。但是,VCC只完成了对基本公式的继续推断,包括相等,不等,加减乘除等简单的运算,而没有完成对所有运算公式的自动推断,是有其局限性的。不然的话,他自己全部都能推断完,我们的工作量就很小了。

      所以,在现实情况中,有时候,即使VCC“知道”了足够的信息,也没法证明一条Assertion。当你新增一个正确的Assertion,有可能会影响他后面的Assertion的正确性。当然,这个概率是比较低的,而且往往是涉及非线性算法的代码会出问题。

      所以,VCC验证顺序代码或者条件语句时一般不会丢失信息,但是VCC验证循环语句的时候,容易丢失信息。这里的丢失是指他没有继续推断出更多信息,提供注释有助于减少这种情况。如果VCC没有通过你认为肯定能通过验证的代码,那就有可能是VCC不知道或者忽视了你以为它肯定知道的东西。这时候一个Assertion也是一个提醒,VCC验证他的时候可能就会恍然大悟,这个条件也是要成立的啊!

  • 相关阅读:
    排序——字符串怀疑人生
    广搜的变形+最短路思想 变色龙
    阿斯顿发发顺丰
    莫队暴力 一知半解
    P3384 【模板】树链剖分
    U74201 旅行计划 树上找链长度
    数据结构:线性表基本操作和简单程序
    数据结构:循环链表实现约瑟夫环
    Codeforces 215D. Hot Days(贪心)
    Codeforces 1080C- Masha and two friends
  • 原文地址:https://www.cnblogs.com/aureate-sunshine/p/5010572.html
Copyright © 2011-2022 走看看