def deMorganize(a):
"""Apply De Morgan's law throughout the code in order to canonicalize"""
if not isinstance(a, ast.AST):
return a
# We only care about statements beginning with not
if type(a) == ast.UnaryOp and type(a.op) == ast.Not:
oper = a.operand
top = type(oper)
# not (blah and gah) == (not blah or not gah)
if top == ast.BoolOp:
oper.op = negate(oper.op)
for i in range(len(oper.values)):
oper.values[i] = deMorganize(negate(oper.values[i]))
oper.negated = not oper.negated if hasattr(oper, "negated") else True
transferMetaData(a, oper)
return oper
# not a < b == a >= b
elif top == ast.Compare:
oper.left = deMorganize(oper.left)
oper.ops = [negate(oper.ops[0])]
oper.comparators = [deMorganize(oper.comparators[0])]
oper.negated = not oper.negated if hasattr(oper, "negated") else True
transferMetaData(a, oper)
return oper
# not not blah == blah
elif top == ast.UnaryOp and type(oper.op) == ast.Not:
oper.operand = deMorganize(oper.operand)
if eventualType(oper.operand) != bool:
return a
oper.operand.negated = not oper.operand.negated if hasattr(oper.operand, "negated") else True
return oper.operand
elif top == ast.NameConstant:
if oper.value in [True, False]:
oper = negate(oper)
transferMetaData(a, oper)
return oper
elif oper.value == None:
tmp = ast.NameConstant(True)
transferMetaData(a, tmp)
tmp.negated = True
return tmp
else:
log("Unknown NameConstant: " + str(oper.value), "bug")
return applyToChildren(a, deMorganize)
##### CLEANUP FUNCTIONS #####
评论列表
文章目录