def test_contains(self): self.assertTrue( PyVar('x') in PyEnvironment([PyVar('x')], [PyVar('y')])) self.assertFalse(PyVar('y') in PyEnvironment([PyVar('x')])) self.assertFalse( PyVar('x') not in PyEnvironment([PyVar('x')], [PyVar('y')])) self.assertTrue(PyVar('y') not in PyEnvironment([PyVar('x')]))
def test_deepcopy(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) x0 = PyLinexpr1(e) x1 = deepcopy(x0) x2 = x0 self.assertNotEqual(id(x0), id(x1)) self.assertEqual(id(x0), id(x2))
def test_make(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) x = PyLinexpr1(e) x.set_coeff(PyVar('x0'), PyDoubleScalarCoeff(3)) x.set_coeff(PyVar('z'), PyDoubleScalarCoeff(-9)) x.set_cst(PyDoubleScalarCoeff(8)) c = PyTcons1.make(PyTexpr1(x), ConsTyp.AP_CONS_SUPEQ) self.assertEqual(str(c), '8.0 + 3.0 · x0 - 9.0 · z >= 0')
def test_init(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) x = PyLinexpr1(e) x0 = PyLinexpr1(e, 0) self.assertEqual(str(PyTexpr1(x)), '0.0') self.assertEqual(str(PyTexpr1(x0)), '0.0 + 0.0 · x0 + 0.0 · y + 0.0 · z') x.set_coeff(PyVar('x0'), PyDoubleScalarCoeff(-1)) x.set_coeff(PyVar('z'), PyDoubleScalarCoeff(-9)) x.set_cst(PyDoubleScalarCoeff(8)) self.assertEqual(str(PyTexpr1(x)), '8.0 - 1.0 · x0 - 9.0 · z')
def test_is_unsat(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) x = PyLinexpr1(e) x.set_coeff(PyVar('x0'), PyDoubleScalarCoeff(3)) x.set_coeff(PyVar('z'), PyDoubleScalarCoeff(-9)) x.set_cst(PyDoubleScalarCoeff(8)) c = PyLincons1(ConsTyp.AP_CONS_SUPEQ, x) self.assertFalse(c.is_unsat()) self.assertTrue(PyLincons1.unsat(e).is_unsat()) self.assertTrue(PyLincons1(ConsTyp.AP_CONS_DISEQ, PyLinexpr1(e)).is_unsat())
def test_init(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) x = PyLinexpr1(e) x.set_coeff(PyVar('x0'), PyDoubleScalarCoeff(3)) x.set_coeff(PyVar('z'), PyDoubleScalarCoeff(-9)) x.set_cst(PyDoubleScalarCoeff(8)) c = PyLincons1(ConsTyp.AP_CONS_SUPEQ, x) self.assertEqual(str(c), '3.0·x0 - 9.0·z + 8.0 >= 0') self.assertEqual(str(PyLincons1.unsat(e)), '-1.0 >= 0') self.assertEqual(str(PyLincons1(ConsTyp.AP_CONS_DISEQ, PyLinexpr1(e))), '0.0 != 0')
def test_deepcopy(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) man: PyManager = PyBoxDManager() b0 = PyBox(man, e, variables=[PyVar('x0')], intervals=[PyDoubleInterval(-2.5, 2.5)]) b1 = deepcopy(b0) b2 = b0 self.assertNotEqual(id(b0), id(b1)) self.assertEqual(id(b0), id(b2))
def test_deepcopy(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) x = PyLinexpr1(e) x.set_coeff(PyVar('x0'), PyDoubleScalarCoeff(3)) x.set_coeff(PyVar('z'), PyDoubleScalarCoeff(-9)) x.set_cst(PyDoubleScalarCoeff(8)) c0 = PyTcons1.make(PyTexpr1(x), ConsTyp.AP_CONS_SUPEQ) c1 = deepcopy(c0) c2 = c0 self.assertNotEqual(id(c0), id(c1)) self.assertEqual(id(c0), id(c2))
def _assign_variable(self, left: VariableIdentifier, right: Expression) -> 'APRONStateWithSummarization': expr = self._lyra2apron.visit(right, self.environment) if isinstance(expr, PyTexpr1): self.state = self.state.assign(PyVar(left.name), expr) else: assert isinstance(expr, Set) state = deepcopy(self.state).bottom(self.manager, self.environment) for item in expr: state = state.join( deepcopy(self.state).assign(PyVar(left.name), item)) self.state = state return self
def test_len(self): self.assertEqual( len(PyEnvironment([PyVar('x')], [PyVar('y'), PyVar('z')])), 3) self.assertEqual(len(PyEnvironment([], [PyVar('y'), PyVar('z')])), 2) self.assertEqual( len(PyEnvironment(real_vars=[PyVar('y'), PyVar('z')])), 2) self.assertEqual(len(PyEnvironment([PyVar('x')], [])), 1) self.assertEqual(len(PyEnvironment([PyVar('x')])), 1) self.assertEqual(len(PyEnvironment()), 0)
def __init__(self, manager: PyManager, variables: Set[VariableIdentifier], precursory: State = None): super().__init__(precursory=precursory) r_vars = list() for variable in variables: r_vars.append(PyVar(variable.name)) self.environment = PyEnvironment([], r_vars) self.polka = PyPolka(manager, self.environment)
def _assign(self, left: Expression, right: Expression) -> 'APRONState': if isinstance(left, VariableIdentifier): expr = self._lyra2apron.visit(right, self.environment) self.state = self.state.assign(PyVar(left.name), expr) return self elif isinstance(left, list): assert all(isinstance(lhs, VariableIdentifier) for lhs in left) assert isinstance(right, list) vars = [PyVar(lhs.name) for lhs in left] exprs = [ self._lyra2apron.visit(rhs, self.environment) for rhs in right ] self.state = self.state.assign(vars, exprs) return self raise NotImplementedError( f"Assignment to {left.__class__.__name__} is unsupported!")
def _substitute(self, left: Expression, right: Expression) -> 'BiasState': if isinstance(left, VariableIdentifier): var = PyVar(left.name) expr = self._lyra2apron.visit(right, self.environment) self.polka = self.polka.substitute(var, expr) # self.mirror = self.mirror.substitute(var, expr) return self elif isinstance(left, list): assert all(isinstance(lhs, VariableIdentifier) for lhs in left) assert isinstance(right, list) vars = [PyVar(lhs.name) for lhs in left] exprs = [self._lyra2apron.visit(rhs, self.environment) for rhs in right] self.polka = self.polka.substitute(vars, exprs) # self.mirror = self.mirror.substitute(vars, exprs) return self raise NotImplementedError(f"Substitution of {left.__class__.__name__} is unsupported!")
def _substitute(self, left: Expression, right: Expression) -> 'APRONState': if isinstance(left, VariableIdentifier): expr = self._lyra2apron.visit(right, self.environment) self.state = self.state.substitute(PyVar(left.name), expr) return self raise NotImplementedError( f"Substitution of {left.__class__.__name__} is unsupported!")
def itv(dim): bound = state.bound_variable(PyVar(var(dim))) interval = bound.interval.contents inf = '{}'.format(interval.inf.contents) lower = inf if inf != '-1/0' else '-inf' sup = '{}'.format(interval.sup.contents) upper = sup if sup != '1/0' else 'inf' return '[{}, {}]'.format(lower, upper)
def visit_Assignment(self, stmt: 'Assignment', environment=None, usub=False) -> Tuple[PyTexpr1, PyTexpr1]: assert not usub left = PyVar( stmt.left.variable.name ) # self.visit(stmt.left, environment=environment, usub=usub) right = self.visit(stmt.right, environment=environment, usub=usub) return left, right
def outcome(self, outcomes: Set[VariableIdentifier]): found = None for chosen in outcomes: outcome = self.bound_variable(PyVar(chosen.name)) inf = str(outcome.interval.contents.inf.contents) lower = eval(inf) if inf != '-1/0' else -sys.maxsize unique = True remaining = outcomes - {chosen} for discarded in remaining: alternative = self.bound_variable(PyVar(discarded.name)) sup = str(alternative.interval.contents.sup.contents) upper = eval(sup) if sup != '1/0' else sys.maxsize if lower <= upper: unique = False break if unique: found = chosen break return found
def __init__(self, domain: Type[PyAbstract1], variables: Set[VariableIdentifier], precursory: State = None): super().__init__(precursory=precursory) self.domain = domain _variables = list() for variable in variables: _variables.append(PyVar(variable.name)) self.environment = PyEnvironment([], _variables) self.state = self.domain(self.manager, self.environment)
def test_bound_variable(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) self.assertEqual(str(b.bound_variable(PyVar('y'))), '[-2,2]')
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 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_forget(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) self.assertEqual(str(b.forget([PyVar('y')])), '1·x0 + 3 >= 0 ∧ -1·x0 + 2 >= 0')
def test_is_real(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) x0 = PyLinexpr1(e) x0.set_coeff(PyVar('x0'), PyDoubleScalarCoeff(3)) self.assertFalse(x0.is_real()) x1 = PyLinexpr1(e) x1.set_coeff(PyVar('x0'), PyDoubleScalarCoeff(3)) x1.set_coeff(PyVar('z'), PyDoubleScalarCoeff(-9)) self.assertFalse(x1.is_real()) x2 = PyLinexpr1(e) x2.set_coeff(PyVar('z'), PyDoubleScalarCoeff(-9)) self.assertTrue(x2.is_real())
def main(self, path, forced_active=None, forced_inactive=None): self.path = path with open(self.path, 'r') as source: self.source = source.read() self.tree = ast.parse(self.source) self.cfg = ast_to_cfg(self.tree) _, variables, _ = self.variables r_vars = list() for variable in variables: r_vars.append(PyVar(variable.name)) environment = PyEnvironment([], r_vars) self.lyra2apron(environment) self.run(forced_active=forced_active, forced_inactive=forced_inactive)
def test_init(self): e = PyEnvironment([PyVar('x'), PyVar('y')], [PyVar('z')]) x1 = PyLinexpr1(e) x1.set_coeff(PyVar('x'), PyDoubleScalarCoeff(3)) x1.set_coeff(PyVar('z'), PyDoubleScalarCoeff(-9)) x1.set_cst(PyDoubleScalarCoeff(8)) c1 = PyLincons1(ConsTyp.AP_CONS_SUPEQ, x1) x2 = PyLinexpr1(e) x2.set_coeff(PyVar('x'), PyDoubleScalarCoeff(1)) c2 = PyLincons1(ConsTyp.AP_CONS_SUP, x2) a = PyLincons1Array([c1, c2]) self.assertEqual(str(a), '3.0·x - 9.0·z + 8.0 >= 0 ∧ 1.0·x + 0.0 > 0')
def test_get(self): e = PyEnvironment([PyVar('x'), PyVar('y')], [PyVar('z')]) x1 = PyLinexpr1(e) x1.set_coeff(PyVar('x'), PyDoubleScalarCoeff(3)) x1.set_coeff(PyVar('z'), PyDoubleScalarCoeff(-9)) x1.set_cst(PyDoubleScalarCoeff(8)) c1 = PyLincons1(ConsTyp.AP_CONS_SUPEQ, x1) x2 = PyLinexpr1(e) x2.set_coeff(PyVar('x'), PyDoubleScalarCoeff(1)) c2 = PyLincons1(ConsTyp.AP_CONS_SUP, x2) a = PyLincons1Array([c1, c2]) c = a.get(1) self.assertNotEqual(str(c), str(c1)) self.assertEqual(str(c), str(c2))
def test_is_quasilinear(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) x0 = PyLinexpr1(e) x0.set_coeff(PyVar('x0'), PyDoubleScalarCoeff(3)) x0.set_cst(PyDoubleScalarCoeff(-9)) self.assertTrue(x0.is_quasilinear()) x1 = PyLinexpr1(e) x1.set_coeff(PyVar('x0'), PyDoubleIntervalCoeff(3, 3)) x1.set_cst(PyDoubleIntervalCoeff(-9, 9)) self.assertFalse(x1.is_quasilinear()) x2 = PyLinexpr1(e) x2.set_coeff(PyVar('x0'), PyDoubleScalarCoeff(3)) x2.set_cst(PyDoubleIntervalCoeff(-9, 9)) self.assertTrue(x2.is_quasilinear())
def test_substitute(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) x0 = PyLinexpr1(e) x0.set_coeff(PyVar('x0'), PyMPQScalarCoeff(1)) x0.set_cst(PyMPQScalarCoeff(3)) t0 = PyTexpr1(x0) self.assertEqual(str(t0), '3 + 1 · x0') x1 = PyLinexpr1(e) x1.set_coeff(PyVar('x0'), PyMPQScalarCoeff(1)) x1.set_cst(PyMPQScalarCoeff(-1)) t1 = PyTexpr1(x1) self.assertEqual(str(t1), '-1 + 1 · x0') self.assertEqual(str(t0.substitute(PyVar('x0'), t1)), '3 + 1 · (-1 + 1 · x0)') x2 = PyLinexpr1(e) x2.set_coeff(PyVar('x0'), PyMPQScalarCoeff(1)) x2.set_cst(PyMPQScalarCoeff(2)) t2 = PyTexpr1(x2) self.assertEqual(str(t2), '2 + 1 · x0')
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 test_substitute(self): e = PyEnvironment([PyVar('x0'), PyVar('y')], [PyVar('z')]) x0 = PyLinexpr1(e) x0.set_coeff(PyVar('x0'), PyMPQScalarCoeff(1)) x0.set_cst(PyMPQScalarCoeff(3)) t0 = PyTexpr1(x0) c0 = PyTcons1.make(t0, ConsTyp.AP_CONS_SUPEQ) self.assertEqual(str(c0), '3 + 1 · x0 >= 0') x1 = PyLinexpr1(e) x1.set_coeff(PyVar('x0'), PyMPQScalarCoeff(1)) x1.set_cst(PyMPQScalarCoeff(-1)) t1 = PyTexpr1(x1) c1 = PyTcons1.make(t1, ConsTyp.AP_CONS_SUPEQ) self.assertEqual(str(c1), '-1 + 1 · x0 >= 0') self.assertEqual(str(c0.substitute(PyVar('x0'), t1)), '3 + 1 · (-1 + 1 · x0) >= 0')