我不太了解FramaC中的slevel
选项。任何人都可以解释更多关于slevel
的价值与用户断言(例如//@assert ...;
)或状态的关系,以及导致状态数量上升的因素有哪些?
例如,我有一个程序,它不包含循环,但包含if..else
分支,go to
语句,并且在程序的某些点上也有一些用户断言,例如: / p>
...
a = Frama_C_unsigned_int_interval(0, 100);
//@ assert a == 0 || a == 1 || a == 2 || a == 3 || ... || a == 100;
...
b = Frama_C_unsigned_int_interval(a, 200);
//@ assert b == 0 || b == 1 || b == 2 || b == 3 || ... || b == 200;
...
在分析的输出中(我将slevel
设置为~100000),可能有一些像:Semantic level unrolling superposing up to 100 states
,然后这个语句可能会重复多次,状态更多。
任何人都可以解释这个semantic level unrolling
如何计算和
如何获得分析的最佳slevel
。谢谢。
答案 0 :(得分:6)
值分析执行程序的抽象执行。它不是使用任意值测试程序,而是使用包含所有可能的具体执行的抽象值来执行它。例如,抽象状态将x
与间隔[0;10]
相关联。当到达if
语句时,例如if (x<=5) y = 1; else y=2;
,根据条件分割抽象状态。例如,then
分支将以间隔[0;5]
和else
分支执行,间隔为[6;10]
。相反,在整个if
的末尾,你必须加入两个抽象状态。这意味着我们将每个变量与包含来自两者的所有可能值的最小间隔相关联(例如,在switch
的父状态的情况下更多)。
例如,在if
之后,x
中的[0;10]
和y
中的[1;2]
。此外,请注意,Value会看到C代码的规范化版本,在该版本中,您始终需要if
的分支(源{ if (c) { s }}
,其值为if (c) { s } else { }
)。
将-slevel
设置为N
意味着Value不会像上面那样加入状态,而是传播到N
个单独的状态。在我们的示例中,这意味着我们现在有两个状态,一个x
位于[0;5]
和y==1
,另一个位于x
位于[6;10]
和y==2
。这允许更高的精度(例如它排除诸如x==0 && y == 2
之类的状态),但是以计算时间和内存消耗为代价。此外,可能的不同状态的数量随着程序中选择的点数呈指数增长。实际上,如果你有一个不相关的第二个if
,那么来自第一个的两个状态将被分开,之后会产生4个状态(假设为N>=4
)。 Value指示它正在使用的不同状态的数量,以便您可以在日志中看到slevel
所花费的时间,并可能调整它以满足更好的精度/计算时间比。
最后,if
不是唯一将分开状态的结构。任何分支语句,特别是循环,都将导致状态分离。类似地,ACSL注释表示为析取,如您的问题中所示,将产生相同的效果:如果您有足够的slevel
,则最终会得到每个析取元素的状态。