在下面,当相关的C代码被注释掉时,行为neg_limit的后置条件如何被证明为真?
安全 - >检查算术溢出之一是不可证实的,如预期的那样,但似乎neg_limit也应该是不可证明的。
背景:我正在使用Frama-C-Boron,Jessie以及通过gWhy,Alt-Ergo来学习如何编写规范并证明函数符合它们。关于规范策略,工具等的任何cluebatting,RTFMing等也是受欢迎的。到目前为止,我正在阅读ACSL 1.7实施手册(最近的-Boron)和Jessie教程& REF。手册。
谢谢!
/*@ behavior non_neg:
assumes v >= 0;
ensures \result == v;
behavior neg_in_range:
assumes INT32_MIN < v < 0;
ensures \result == -v;
behavior neg_limit:
assumes v == INT32_MIN;
ensures \result == INT32_MAX;
disjoint behaviors;
complete behaviors;
*/
int32_t my_abs32(int32_t v)
{
if (v >= 0)
return v;
//if (v == INT32_MIN)
// return INT32_MAX;
return -v;
}
这是第一个后置条件的gWhy目标:
goal my_abs32_ensures_neg_limit_po_1:
forall v_2:int32.
(integer_of_int32(v_2) = ((-2147483647) - 1)) ->
(integer_of_int32(v_2) >= 0) ->
forall __retres:int32.
(__retres = v_2) ->
forall return:int32.
(return = __retres) ->
("JC_13": (integer_of_int32(return) = 2147483647))
和第二个:
goal my_abs32_ensures_neg_limit_po_2:
forall v_2:int32.
(integer_of_int32(v_2) = ((-2147483647) - 1)) ->
(integer_of_int32(v_2) < 0) ->
forall result:int32.
(integer_of_int32(result) = (-integer_of_int32(v_2))) ->
forall __retres:int32.
(__retres = result) ->
forall return:int32.
(return = __retres) ->
("JC_13": (integer_of_int32(return) = 2147483647))
答案 0 :(得分:2)
关于文档,您可能需要查看Fraunhofer FOKUS' ACSL示例:http://www.fokus.fraunhofer.de/de/quest/_download_quest/_projekte/acsl_by_example.pdf
关于你的问题,我已经用Frama-C Fluorine重复你的结果(BTW,你在代码中遗漏了#include <stdint.h>"
),Jessie + Alt-ergo仍设法证明后置条件。但请记住,在发生运行时错误的假设下证明后置条件,这不是您的代码的情况,因为失败的安全PO显示。
即,第二个后置条件包含假设(integer_of_int32(result) = (-integer_of_int32(v_2)))
,可以将其重写为(integer_of_int32(result) = 2147483648)
。这与杰西的序曲中的一个公理相矛盾,即说明这一点
forall v:int32. integer_of_int32(v)<=2147483647
。
我想这再次概述了,只要一些证明义务未经检查,即使它们不直接源于此注释,也不能声称已经验证了ACSL注释。