frama-c - 在 Frama C 上使用 Alt-ergo 证明 WP 时超时
问题描述
我试图使用 Frama-c 验证以下程序的正确性我是 frama-C 的新用户。
问题:
输入员工的基本工资,并根据以下公式计算其总工资:
基本工资 <= 10000 : HRA = 20%, DA = 80%
基本工资 <= 20000:HRA = 25%,DA = 90%
基本工资 > 20000 : HRA = 30%, DA = 95%
#include <limits.h>
/*@requires sal >= 0 && sal <= INT_MAX/2;
ensures \result > sal && \result <= INT_MAX[enter image description here][1];
behavior sal1:
assumes sal <= 10000;
ensures \result == sal+(sal*0.2*0.8);
behavior sal2:
assumes sal <= 20000;
ensures \result == sal+(sal*0.25*0.9);
behavior sal3:
assumes sal >20000;
ensures \result == sal+(sal*0.3*0.95);
complete behaviors sal1,sal2,sal3;
*/
double salary(double sal){
if(sal<=10000){return (sal+(sal*0.2*0.8));}
else if(sal<=20000){return (sal+(sal*0.25*0.9));}
else{return (sal+(sal*0.3*0.95));}
}
我在这里犯了什么错误?前提条件是否应该更精确。
控制台消息:
[wp] [Alt-Ergo 2.3.3] Goal typed_salary_ensures : Timeout (Qed:57ms) (10s)
(cached)
[wp] [Alt-Ergo 2.3.3] Goal typed_salary_assert_rte_is_nan_or_infinite_3 :
Timeout (Qed:20ms) (10s) (cached)
[wp] [Alt-Ergo 2.3.3] Goal typed_salary_assert_rte_is_nan_or_infinite_6 :
Timeout (Qed:2ms) (10s) (cached)
[wp] [Alt-Ergo 2.3.3] Goal typed_salary_assert_rte_is_nan_or_infinite_5 :
Timeout (Qed:2ms) (10s) (cached)
[wp] [Alt-Ergo 2.3.3] Goal typed_salary_assert_rte_is_nan_or_infinite_4 :
Timeout (Qed:17ms) (10s) (cached)
[wp] [Alt-Ergo 2.3.3] Goal typed_salary_assert_rte_is_nan_or_infinite_7 :
Timeout (Qed:15ms) (10s) (cached)
[wp] [Alt-Ergo 2.3.3] Goal typed_salary_sal1_ensures : Timeout (Qed:33ms)
(10s) (cached)
[wp] [Alt-Ergo 2.3.3] Goal typed_salary_assert_rte_is_nan_or_infinite_9 :
Timeout (Qed:2ms) (10s) (cached)
[wp] [Alt-Ergo 2.3.3] Goal typed_salary_assert_rte_is_nan_or_infinite_8 :
Timeout (Qed:4ms) (10s) (cached)
[wp] [Alt-Ergo 2.3.3] Goal typed_salary_sal2_ensures : Timeout (Qed:42ms)
(10s) (cached)
[wp] [Alt-Ergo 2.3.3] Goal typed_salary_sal3_ensures : Timeout (Qed:35ms)
(10s) (cached)
解决方案
当面对浮点计算时,自动定理证明器的表现通常很差(例如,参见本报告)。如果您真的非常需要它们,您可能需要安装专门用于此目的的Gappa,或者希望使用 CVC4、Z3 和 Alt-Ergo(而不仅仅是 Alt-Ergo)可以让您至少拥有一个证明者能够履行每一项证明义务。但我建议坚持整数算术,例如使用美分作为单位,以便在计算百分比时只操作整数(编辑:因为你乘以百分比,这意味着使用 1/10000 单位,但它仍然不应该是个问题)。实际上,如果您坚持使用双精度数,那么要求具有小于的值INT_MAX
并没有多大意义。
同样,如果您使用整数类型,可能更容易选择 for unsigned
,这将自动满足具有非负薪水的要求。
最后,您的规范是模棱两可的:对于任何低于 10000 的薪水,您有两个不同的公式来计算结果。assumes
行为条款sal2
可能应该是:assumes 10000 < sal <= 20000;
推荐阅读
- django - 姜戈法盖特。在此服务器上找不到请求的资源
- julia - 如何在 Julia 的 Markdown 字符串中插入多个变量
- python - 如何做到这一点,如果表单中有错误,我在字段中键入的所有数据都会保留,并且只会弹出错误
- html - 无法使用 Bootstrap 在底部移动轮播标题和导航
- javascript - React 17 更新后,渲染没有返回任何内容
- javascript - 如何在 React 中定位 DOM 元素列表
- python - 如何将带有偏移量的箭头注释添加到带有日期时间 x 轴的散景图中
- javascript - 如何使用 laravel 插入和上传多个文件?
- javascript - 如何从 xmlhttprequest javascript 返回响应
- assembly - 为什么`add rax, 4294967` 会在 x86 十六进制中生成 `48 05 37 89 41 00`?