def _getVariable(self, symbolic_var): name = symbolic_var.name if name in self.cvc_vars: return self.cvc_vars[name] variable = None if isinstance(symbolic_var, SymbolicInteger): variable = CVCInteger.variable(name, self.solver) elif isinstance(symbolic_var, SymbolicStr): variable = CVCString.variable(name, self.solver) self.cvc_vars[name] = variable return variable
def _astToCVCExpr(self, expr, env=None): if isinstance(expr, list): op = expr[0] args = [self._astToCVCExpr(a, env) for a in expr[1:]] cvc_l = args[0] cvc_r = args[1] if len(args) > 1 else None cvc_3 = args[2] if len(args) > 2 else None # arithmetical operations if op == "+": return cvc_l + cvc_r elif op == "-": return cvc_l - cvc_r elif op == "*": return cvc_l * cvc_r elif op == "//": return cvc_l / cvc_r elif op == "%": return cvc_l % cvc_r # bitwise elif op == "<<": return cvc_l << cvc_r elif op == ">>": return cvc_l >> cvc_r elif op == "^": return cvc_l ^ cvc_r elif op == "|": return cvc_l | cvc_l elif op == "&": return cvc_l & cvc_r # string elif op == "str.len": return cvc_l.len() elif op == "str.find": return cvc_l.find(cvc_r, cvc_3) elif op == "str.replace": return cvc_l.replace(cvc_r, cvc_3) elif op == "str.startswith": return self._wrapIf(cvc_l.startswith(cvc_r), env) # collection operators elif op == "getitem": return cvc_l[cvc_r] elif op == "slice": return cvc_l[cvc_r:cvc_3] # equality gets coerced to integer elif op == "==": if cvc_l is None or cvc_r is None: # forces false condition no model contains None return self._wrapIf( self._astToCVCExpr(0, env) != self._astToCVCExpr( 0, env), env) else: return self._wrapIf((cvc_l == cvc_r), env) elif op == "!=": if cvc_l is None or cvc_r is None: return self._wrapIf( self._astToCVCExpr(0, env) == self._astToCVCExpr(0, env), env) else: return self._wrapIf((cvc_l != cvc_r), env) elif op == "<": return self._wrapIf((cvc_l < cvc_r), env) elif op == ">": return self._wrapIf((cvc_l > cvc_r), env) elif op == "<=": return self._wrapIf((cvc_l <= cvc_r), env) elif op == ">=": return self._wrapIf((cvc_l >= cvc_r), env) elif op == "in": return self._wrapIf((cvc_l.__contains__(cvc_r)), env) else: utils.crash( "Unknown BinOp during conversion from ast to CVC (expressions): %s" % op) elif isinstance(expr, SymbolicObject): if expr.isVariable(): if env is None: variable = self._getVariable(expr) return variable else: return env[expr.name] else: return self._astToCVCExpr(expr.expr, env) elif isinstance(expr, int) | isinstance(expr, str): if env is None: if isinstance(expr, int): return CVCInteger.constant(expr, self.solver) elif isinstance(expr, str): return CVCString.constant(expr, self.solver) else: return expr elif expr is None: return None else: utils.crash( "Unknown node during conversion from ast to CVC (expressions): %s" % expr)
def _astToCVCExpr(self, expr, env=None): log.debug("Converting %s (type: %s) to CVC expression" % (expr, type(expr))) if isinstance(expr, list): op = expr[0] args = [self._astToCVCExpr(a, env) for a in expr[1:]] cvc_l = args[0] cvc_r = args[1] if len(args) > 1 else None cvc_3 = args[2] if len(args) > 2 else None log.debug("Building %s" % args) # arithmetical operations if op == "+": return cvc_l + cvc_r elif op == "-": return cvc_l - cvc_r elif op == "*": return cvc_l * cvc_r elif op == "//": return cvc_l / cvc_r elif op == "%": return cvc_l % cvc_r # bitwise elif op == "<<": return cvc_l << cvc_r elif op == ">>": return cvc_l >> cvc_r elif op == "^": return cvc_l ^ cvc_r elif op == "|": return cvc_l | cvc_l elif op == "&": return cvc_l & cvc_r # string elif op == "str.len": return cvc_l.len() elif op == "str.find": return cvc_l.find(cvc_r) elif op == "str.replace": return cvc_l.replace(cvc_r, cvc_3) # collection operators elif op == "getitem": return cvc_l[cvc_r] elif op == "slice": return cvc_l[cvc_r:cvc_3] # equality gets coerced to integer elif op == "==": return self._wrapIf((cvc_l == cvc_r), env) elif op == "!=": return self._wrapIf((cvc_l != cvc_r), env) elif op == "<": return self._wrapIf((cvc_l < cvc_r), env) elif op == ">": return self._wrapIf((cvc_l > cvc_r), env) elif op == "<=": return self._wrapIf((cvc_l <= cvc_r), env) elif op == ">=": return self._wrapIf((cvc_l >= cvc_r), env) elif op == "in": return self._wrapIf((cvc_l.__contains__(cvc_r)), env) else: utils.crash("Unknown BinOp during conversion from ast to CVC (expressions): %s" % op) elif isinstance(expr, SymbolicObject): if expr.isVariable(): if env is None: variable = self._getVariable(expr) return variable else: return env[expr.name] else: return self._astToCVCExpr(expr.expr, env) elif isinstance(expr, int) | isinstance(expr, str): if env is None: if isinstance(expr, int): return CVCInteger.constant(expr, self.solver) elif isinstance(expr, str): return CVCString.constant(expr, self.solver) else: return expr else: utils.crash("Unknown node during conversion from ast to CVC (expressions): %s" % expr)