Example #1
0
 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
Example #2
0
 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
Example #3
0
    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)
Example #4
0
    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)