检查C中的两个“简单”“if语句”是否相同

时间:2013-03-06 21:50:22

标签: python c parsing equivalence

我有来自两个不同来源的'if statements',它试图以不同的方式实现相同的条件。 'if语句'是C. 如果可能的话,我需要一个python脚本来决定条件对是否相等。 一个基本的例子:

source1:((op1 != v1) || ((op2 != v2) || (op3 != v3)))

source2:((op2 != v2) || (op1 != v1) || (op3 != v3))

当然,任何操作符都是允许的,函数调用,当然还有括号。

欢迎任何想法。

编辑1:函数调用没有副作用。

2 个答案:

答案 0 :(得分:5)

这就是问题,问题可能(或可能不是)NP完全但除非这是在重要事物的内循环内(并且变量的数量很小),构建整个真值表< / em>的!这很容易做到。它明显增长为2 ^ n,但对于小n,这是完全可行的。与评论建议一样,我假设函数调用没有副作用,只需输出TrueFalse

我发布了一个模拟示例,可以解决您所说的问题,并根据需要进行调整。我依靠pythons解析器来处理表达式的评估。

import pyparsing as pypar
import itertools

def python_equiv(s):
    return s.replace('||',' or ').replace('&&',' and ')

def substitute(s,truth_table, VARS):
    for v,t in zip(VARS,truth_table):
        s = s.replace(v,t)
    return s

def check_statements(A1,A2):  
    VARS = set()
    maths    = pypar.oneOf("( ! = | & )")
    keywords = pypar.oneOf("and or")
    variable = pypar.Word(pypar.alphanums)
    variable.setParseAction(lambda x: VARS.add(x[0]))
    grammar  = pypar.OneOrMore(maths | keywords | variable)

    # Determine the variable names
    grammar.parseString(A1)
    grammar.parseString(A2)

    A1 = python_equiv(A1)
    A2 = python_equiv(A2)

    bool_vals = map(str, [False,True])

    for table in itertools.product(bool_vals,repeat=len(VARS)):
        T1 = substitute(A1,table,VARS)
        T2 = substitute(A2,table,VARS)
        if eval(T1) != eval(T2):
            print "FAIL AT ", table,
            return False

    print "Statements equiv:",

    return True


# Original example
A1 = '''((op1 != v1) || ((op2 != v2) || (op3 != v3)))'''
A2 = '''((op2 != v2) ||  (op1 != v1) || (op3 != v3))'''
print check_statements(A1,A2)

# Example with a failure
A1 = '''((op1 != v1) || ((op2 != v2) || (op3 != v3)))'''
A2 = '''((op2 != v2) ||  (op1 != v1) && (op3 != v3))'''
print check_statements(A1,A2)

作为输出:

Statements equiv: True
FAIL AT  ('False', 'False', 'False', 'False', 'False', 'True') False

答案 1 :(得分:2)

要做到这一点,您需要控制流anlaysis来确定这两个条件是否具有相同的控制依赖性(否则它们不会在相同的数据上下文中执行),完整的数据流分析包括C代码的分析点函数的副作用分析,跨函数调用从条件的根到表达式的叶子的反向能力,然后是一个考虑C语义的布尔等价匹配器(例如短路,溢出,... 。)

这远远超出了你从C解析器获得的东西。