ACSL可以表示应隐藏作业吗?

时间:2018-11-19 10:13:51

标签: frama-c acsl

此函数模拟一个函数,该函数返回一个连续上升的值,直到发生溢出为止。就像Arduino中的millis()函数一样。

为了证明其实现,我需要增加(因此分配)静态变量以保持两次调用之间的状态。但是,调用mock_millis()的函数仍然应该能够assign \nothing

有没有一种方法可以使WP忽略Assigns子句?

static int64_t milliseconds = 0;

/*@ assigns milliseconds;

    behavior normal:
      assumes milliseconds < INT64_MAX;
      ensures \result == \old(milliseconds) + 1;
      ensures milliseconds == \old(milliseconds) + 1;
    behavior overflow:
      assumes milliseconds == INT64_MAX;
      ensures \result == 0;
      ensures milliseconds == 0;

    complete behaviors normal, overflow;
    disjoint behaviors normal, overflow;
*/
int64_t mock_millis() {
    if (milliseconds < INT64_MAX) {
        milliseconds++;
    } else {
        milliseconds = 0;
    }
    return milliseconds;
}

我尝试使用重影变量执行此操作,并注意到分配重影变量的函数不能为assigns \nothing。我认为鬼变量完全独立于程序的实现。有特殊原因吗?

1 个答案:

答案 0 :(得分:3)

我假设您的static变量被称为milliseconds,而不是现在的microseconds

您对鬼变量的假设确实是错误的:鬼代码不应干扰实际代码,反之亦然(请注意,此时Frama-C并未强制执行此操作)。因此,如果将milliseconds声明为ghost,则对其的任何分配都应该在ghost代码内进行。但是从规范的角度来看,这种分配仍然是副作用,需要在assigns子句中提及。