Language agnostic 多个if语句(条件)的静态分析
我的代码类似于:Language agnostic 多个if语句(条件)的静态分析,language-agnostic,math,static-analysis,boolean-logic,Language Agnostic,Math,Static Analysis,Boolean Logic,我的代码类似于: if conditionA(x, y, z) then doA() else if conditionB(x, y, z) then doB() ... else if conditionZ(x, y, z) then doZ() else throw ShouldNeverHappenException 我想验证两件事(使用静态分析): 如果所有条件conditionA、conditionB、…、conditionZ都是互斥的(即不可能同时有两个或多个条件为真)
if conditionA(x, y, z) then doA()
else if conditionB(x, y, z) then doB()
...
else if conditionZ(x, y, z) then doZ()
else throw ShouldNeverHappenException
我想验证两件事(使用静态分析):
conditionA、conditionB、…、conditionZ
都是互斥的(即不可能同时有两个或多个条件为真)假设
conditionA,conditionB,…,conditionZ
是(纯)函数,x,y,z有“本原”类型。这似乎同构于求解3-sat方程,这是NP难问题。不幸的是,静态分析器不太可能尝试覆盖这个域 在一般情况下,这是因为@Michael Donohue提出了一个NP难问题
但是,如果您只需要检查合理数量的条件,您可以编写一个程序来检查所有这些条件
for (int x = lowestX; x <= highestX; x++)
for (int y ...)
for (int z ...)
{
int conditionsMet = 0;
if conditionA(x, y, z) then conditionsMet++;
if conditionB(x, y, z) then conditionsMet++;
...
if conditionZ(x, y, z) then conditionsMet++;
if (conditionsMet != 1)
PrintInBlinkingRed("Found an exception!", x, y, z)
}
对于(int x=lowestX;x第1项。您想做的是一个风格问题。即使条件不是唯一的,该程序也是有意义的。就个人而言,作为静态分析工具的作者,我认为用户在不强制使用样式的情况下会收到足够多的假警报(由于另一个程序员会故意编写重叠的条件,所以您向另一个程序员提出的要求将是错误的警报)也就是说,有一些工具是可配置的:对于其中之一,您可以编写一条规则,说明遇到此构造时,情况必须是独占的。正如Jeffrey所建议的,您可以将代码包装在一个上下文中,在没有重叠的情况下,您可以计算一个布尔条件,并检查该条件
项2.不是样式问题:您想知道是否可以引发异常
这个问题在理论上和实践中都很困难,因此工具通常至少会放弃一个正确性(如果存在问题,绝不会不发出警告)或完整性(对于非问题,绝不会发出警告)。如果变量的类型是无界整数,可计算性理论将说明分析器不可能对所有输入程序都正确、完整并终止。但这一理论已经足够了。一些工具放弃了正确性和完整性,这并不意味着它们也没有用
一个正确的工具示例是的值分析:如果它说某个语句(如elseifs序列中的最后一个case)不可访问,那么您知道它不可访问。它不完整,所以当它没有说最后一个语句不可访问时,您不知道
完整工具的一个例子是:它使用所谓的方法自动生成测试用例,目标是结构覆盖率(也就是说,它将或多或少地尝试生成测试,一旦所有其他用例都被接受,就会激活最后一个用例)。因为它生成测试用例(每一个都是一个单一的、明确的输入向量,代码实际上是在其上执行的),它从不警告没有问题。这就是完整性的含义。但它可能无法找到导致到达最后一个语句的测试用例,即使有一个:它不正确。假设您的条件是布尔表达式(和/或/或非)对于布尔值谓词X、Y、Z,您的问题可以通过符号布尔求值引擎轻松解决
关于它们是否涵盖所有情况的问题,可以通过对所有条件进行析取并询问是否是重言式来回答。王的算法做得很好
关于它们是否相交的问题是两两回答的;对于公式a和b,
象征性地构造a&b==false并再次应用王的重言式测试
我们使用了在C中对预处理器条件执行类似的布尔值计算(部分求值)。DMS提供了解析源代码的能力(如果您打算在大型代码库中执行此操作和/或随着时间的推移修改程序时重复执行此操作,这一点很重要),提取程序片段,用符号组合它们,然后应用重写规则(执行布尔简化或Wang等算法).如果没有变量x
、y
和z
的信息,它是不可判定的。如果它们是布尔变量,这只是某种SAT。理论上不可判定并不意味着工具不能在实践中为人们真正感兴趣的案例提供有用的答案。在快速更新之后,我确认可满足性问题涉及布尔变量,并且3-SAT涉及其中的3个以上。3是布尔公式的CNF中一个子句中出现的变量数。我预计最多有10个变量(x,y,z…)。我不认为“NP硬度”这是一个问题。你知道更多关于ConditionX的信息吗?例如,如果它们都是简单的表达式,这将给出与任意函数调用不同的答案。我真的希望看到它澄清标记“布尔逻辑”是否意味着x、y、z是布尔变量(在这种情况下,这三个变量有8个赋值:做一个彻底的检查!)或者,比如说,无界整数(在这种情况下,正如我所评论的,我非常确定问题是不可判定的,这并不排除实践中有用的答案)。第1项不是样式问题。这是用于验证/测试的。