def dict_to_texpr(todict, env): texpr = PyTexpr1.cst(env, PyMPQScalarCoeff(PyMPQScalar(todict['_']))) for var, val in reversed(list(todict.items())): if var != '_': coeff = PyTexpr1.cst(env, PyMPQScalarCoeff(PyMPQScalar(val))) dim = PyTexpr1.var(env, PyVar(var)) term = PyTexpr1.binop(TexprOp.AP_TEXPR_MUL, coeff, dim, TexprRtype.AP_RTYPE_REAL, TexprRdir.AP_RDIR_RND) texpr = PyTexpr1.binop(TexprOp.AP_TEXPR_ADD, term, texpr, TexprRtype.AP_RTYPE_REAL, TexprRdir.AP_RDIR_RND) return texpr
def test_bound_texpr(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) man: PyManager = PyBoxMPQManager() variables = [PyVar('x0'), PyVar('y')] intervals = [PyMPQInterval(-3, 2), PyMPQInterval(-2, 2, 1, 1)] b = PyBox(man, e, variables=variables, intervals=intervals) x0 = PyTexpr1.var(e, PyVar('x0')) x1 = PyTexpr1.var(e, PyVar('y')) add = PyTexpr1.binop(TexprOp.AP_TEXPR_ADD, x0, x1, TexprRtype.AP_RTYPE_REAL, TexprRdir.AP_RDIR_RND) self.assertEqual(str(b.bound_texpr(add)), '[-5,4]')
def visit_Call(self, stmt: 'Call', environment=None, usub=False): assert not usub if stmt.name == 'usub': return self.visit(stmt.arguments[0], environment=environment, usub=True) elif stmt.name == 'add': left = self.visit(stmt.arguments[0], environment=environment, usub=usub) right = self.visit(stmt.arguments[1], environment=environment, usub=usub) return PyTexpr1.binop(TexprOp.AP_TEXPR_ADD, left, right, TexprRtype.AP_RTYPE_REAL, TexprRdir.AP_RDIR_RND) elif stmt.name == 'sub': left = self.visit(stmt.arguments[0], environment=environment, usub=usub) right = self.visit(stmt.arguments[1], environment=environment, usub=usub) return PyTexpr1.binop(TexprOp.AP_TEXPR_SUB, left, right, TexprRtype.AP_RTYPE_REAL, TexprRdir.AP_RDIR_RND) elif stmt.name == 'mult': left = self.visit(stmt.arguments[0], environment=environment, usub=usub) right = self.visit(stmt.arguments[1], environment=environment, usub=usub) return PyTexpr1.binop(TexprOp.AP_TEXPR_MUL, left, right, TexprRtype.AP_RTYPE_REAL, TexprRdir.AP_RDIR_RND) elif stmt.name == 'ReLU': return PyVar( stmt.arguments[0].variable.name ) # self.visit(stmt.arguments[0], environment=environment, usub=usub) raise ValueError(f"Conversion of {stmt} to APRON is unsupported!")
def visit_BinaryArithmeticOperation(self, expr, environment=None, usub=False) -> PyTexpr1: assert not usub expr1 = self.visit(expr.left, environment) expr2 = self.visit(expr.right, environment) op2op = { BinaryArithmeticOperation.Operator.Add: TexprOp.AP_TEXPR_ADD, BinaryArithmeticOperation.Operator.Sub: TexprOp.AP_TEXPR_SUB, BinaryArithmeticOperation.Operator.Mult: TexprOp.AP_TEXPR_MUL, BinaryArithmeticOperation.Operator.Div: TexprOp.AP_TEXPR_DIV } op = op2op[expr.operator] return PyTexpr1.binop(op, expr1, expr2, TexprRtype.AP_RTYPE_REAL, TexprRdir.AP_RDIR_RND)
def affine(self, left: List[PyVar], right: List[PyTexpr1]) -> 'Symbolic1State': array = list() assignments = dict() for lhs, expr in zip(left, right): rhs = expr for sym, val in self.symbols.values(): rhs = rhs.substitute(sym, val) assignments[str(lhs)] = (lhs, rhs) var = PyTexpr1.var(self.environment, lhs) binop = PyTexpr1.binop(TexprOp.AP_TEXPR_SUB, var, rhs, rtype, rdir) cond = PyTcons1.make(binop, ConsTyp.AP_CONS_EQ) array.append(cond) self.symbols = assignments self.state = self.state.meet(PyTcons1Array(array)) return self