如何在ACSL中写“ 2的幂”谓词?

问题描述

我尝试写一个Acsl谓词以查看整数是否为2的幂是这样的:

Football.ydstogo[Football.ydstogo.between('11','19')] = '10-plus'

但是,当我在随机函数添加一些断言行时,会出现一些超时(即失败)。我不明白为什么?

/*@
  predicate positive_power_of_2 (integer i) =
    i > 0 &&
    (i == 1 || ((i & 1) == 0 && positive_power_of_2 (i >> 1)));
 */

解决方法

请注意,对于此类纯逻辑属性,可以使用lemma而不是assert,就像//@ lemma pow2_1: positive_power_of_2(1);一样。由于lemma是全局注释,因此您不必为了持有assert而编写函数。

现在回到问题本身。将按位运算与算术运算(小于比较)混合会混淆自动定理证明。您没有指定使用哪个(一个或多个),但是如果您仅使用一个(一个或多个),则可能要尝试安装其他(现在,alt-ergo,z3和cvc4的混合会提供良好的结果)。也就是说,对WP内部简化程序QED的一个小的交互式帮助也已足够:通过使用GUI(请参见WP manual的2.4节),您可以通过在每个菜单中展开positive_power_of_2的定义来得出结论。目标(据我所知,没有命令行选项可以做到这一点)。

基本上,一旦进入GUI的WP Proofs面板,就必须双击与要处理的证明义务相对应的行的Script列,这将使您进入交互式证明模式,如下面的屏幕截图所示:

WP interactive proof mode in Frama-C GUI

现在,重点是可用策略的列表(在右侧)是上下文相关的:仅显示与在举证义务中选择的术语相关的策略(在左侧)。有些策略总是相关的,例如Cut,它可以让您证明一个辅助语句,可以在证明的其余部分中用作假设,但是展开定义仅在您有定义要展开时才有意义选择。因此,您必须单击P_positive_power_of_2才能显示该策略。然后,只需单击相应的三角形,以使WP展开定义,然后尝试完成证明。