我有来自两个不同来源的“if 语句”,它们试图以不同的方式实现相同的条件。“if 语句”是 C。如果可能的话,我需要一个 python 脚本来决定成对条件是否相等。一个基本的例子:
来源1:((op1 != v1) || ((op2 != v2) || (op3 != v3)))
来源2:((op2 != v2) || (op1 != v1) || (op3 != v3))
当然,任何运算符都是允许的,函数调用,当然还有括号。
欢迎任何想法。
编辑 1:函数调用没有副作用。
我有来自两个不同来源的“if 语句”,它们试图以不同的方式实现相同的条件。“if 语句”是 C。如果可能的话,我需要一个 python 脚本来决定成对条件是否相等。一个基本的例子:
来源1:((op1 != v1) || ((op2 != v2) || (op3 != v3)))
来源2:((op2 != v2) || (op1 != v1) || (op3 != v3))
当然,任何运算符都是允许的,函数调用,当然还有括号。
欢迎任何想法。
编辑 1:函数调用没有副作用。
事情就是这样,问题可能(也可能不是)是 NP 完全的,但除非这是在重要事物的内部循环中(并且变量的数量很小),否则请构建整个真值表!这非常容易做到。它显然增长为 2^n,但对于小的 n,这是完全可行的。就像评论所暗示的那样,我假设函数调用没有副作用,只是输出True
or False
。
我已经发布了一个模型示例,可以解决您提出的问题,根据需要进行调整。我依靠 python 解析器来处理表达式的评估。
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
为此,您需要控制流分析以确定两个条件是否具有相同的控制依赖关系(否则它们不会在相同的数据上下文中执行),完整的数据流分析包括 C 代码的点对点分析, - 函数的效果分析,在函数调用中从条件的根到表达式的叶子进行反向切片的能力,然后是一个解释 C 语义的布尔等价匹配器(例如短路、溢出……)
这远远超出了您从 C 解析器中得到的。