def test_nested(): formula = (smt.Symbol("x", smt.REAL) * smt.Real(2) + smt.Real(5.125)) * smt.Real(-1.25) positive = (smt.Symbol("x", smt.REAL) * smt.Real(2) + smt.Real(5.125)) * smt.Real(1.25) result = make_coefficients_positive(formula) assert Polynomial.from_smt(positive) == Polynomial.from_smt(result)
def concrete_integrate(self, expression: Expression, var: FNode, lb: FNode, ub: FNode, prefix) -> Expression: logger.debug("%s integrate %s, %s <= %s <= %s", prefix, expression, lb, var, ub) algebra = self.pool.algebra lb = Polynomial.from_smt(lb).to_expression(algebra) ub = Polynomial.from_smt(ub).to_expression(algebra) var_name = var.symbol_name() result = algebra.integrate_poly(expression, [var_name], {var_name: (lb, ub)}) logger.debug("%s \t = %s", prefix, result) return result
def test_polynomial_from_smt(): x, y, z = [Symbol(n, REAL) for n in "xyz"] formula = (x * 2 + y * y * 3 + 3) * (x * 0.5 + z + 5) should_be = { ("x", "x"): 1.0, ("x", "z"): 2.0, ("x", "y", "y"): 1.5, ("y", "y", "z"): 3.0, ("y", "y"): 15.0, ("x",): 11.5, ("z",): 3.0, (): 15.0 } assert Polynomial.from_smt(formula).poly_dict == should_be
def integrate(self, domain, convex_bounds: List[LinearInequality], polynomial: Polynomial): formula = smt.And(*[i.to_smt() for i in convex_bounds]) if self.bounding_box > 0: if self.bounding_box == 1: a_matrix = numpy.zeros( (len(convex_bounds), len(domain.real_vars))) b_matrix = numpy.zeros((len(convex_bounds), )) for i, bound in enumerate(convex_bounds): for j in range(len(domain.real_vars)): a_matrix[i, j] = bound.a(domain.real_vars[j]) b_matrix[i] = bound.b() lb_ub_bounds = {} c = numpy.zeros((len(domain.real_vars), )) for j in range(len(domain.real_vars)): c[j] = 1 # noinspection PyTypeChecker lb = scipy.optimize.linprog(c, a_matrix, b_matrix).x[j] # noinspection PyTypeChecker ub = scipy.optimize.linprog(-c, a_matrix, b_matrix).x[j] c[j] = 0 lb_ub_bounds[domain.real_vars[j]] = (lb, ub) elif self.bounding_box == 2: samples = uniform(domain, self.sample_count, rand_gen=self.rand_gen) labels = evaluate(domain, formula, samples) samples = samples[labels == 1] try: samples.sort(axis=0) std = abs(samples[0:-1, :] - samples[1:, :]).std(axis=0) lbs = samples[0, :] - std ubs = samples[-1, :] + std except ValueError: return 0 lb_ub_bounds = { domain.variables[j]: (lbs[j], ubs[j]) for j in range(len(domain.variables)) } else: raise ValueError("Illegal bounding box value {}".format( self.bounding_box)) domain = Domain(domain.variables, domain.var_types, lb_ub_bounds) engine = RejectionEngine(domain, formula, polynomial.to_smt(), self.sample_count, seed=self.seed) result = engine.compute_volume() if self.bounding_box: result = result return result
def test_latte_backend(): print(xadd_installed) x, y = [Symbol(n, REAL) for n in "xy"] inequalities = [LinearInequality.from_smt(f) for f in [(x >= 0), (x <= y), (y <= 1)]] polynomial = Polynomial.from_smt((x*2/3 + 13/15) * (y*1/8 + x)) domain = Domain.make([], ["x", "y"], [(0, 1), (0, 1)]) result = LatteIntegrator().integrate(domain, inequalities, polynomial) xadd_result = EngineConvexIntegrationBackend(PyXaddEngine()).integrate(domain, inequalities, polynomial) print(result, xadd_result) assert result == pytest.approx(xadd_result, rel=0.001)
def get_variable_groups_poly( cls, weight: Polynomial, real_vars: List[str] ) -> List[Tuple[Set[str], Polynomial]]: if isinstance(weight, Polynomial): if len(real_vars) > 0: result = [] found_vars = weight.variables for v in real_vars: if v not in found_vars: result.append(({v}, Polynomial.from_constant(1))) return result + cls.get_variable_groups_poly(weight, []) if len(weight.poly_dict) > 1: return [(weight.variables, weight)] elif len(weight.poly_dict) == 0: return [(set(), Polynomial.from_constant(0))] else: result = defaultdict(lambda: Polynomial.from_constant(1)) for name, value in weight.poly_dict.items(): if len(name) == 0: result[frozenset()] *= Polynomial.from_constant(value) else: for v in name: result[frozenset((v,))] *= Polynomial.from_smt( smt.Symbol(v, smt.REAL) ) result[frozenset()] *= Polynomial.from_constant(value) return list(result.items()) else: raise NotImplementedError
def integrate_convex(self, convex_support, polynomial_weight): try: domain = Domain( self.domain.real_vars, {v: REAL for v in self.domain.real_vars}, self.domain.var_domains, ) return self.backend.integrate( domain, BoundsWalker.get_inequalities(convex_support), Polynomial.from_smt(polynomial_weight), ) except ZeroDivisionError: return 0
def walk_literal(self, node): literal = node.literal var = self.literals.inv_numbered[abs(literal)] # var as abstracted in SDD abstraction = self.literals[var] if isinstance(abstraction, str): if abstraction in self.labels: expr = Polynomial.from_smt( self.labels[abstraction][0 if (literal > 0) else 1] ).to_expression(self.algebra) return expr, set() else: return self.algebra.one(), {abstraction} else: if literal < 0: abstraction = ~abstraction # expr = LinearInequality.from_smt(f).scale_to_integer().to_expression(self.algebra) expr = self.algebra.parse_condition(abstraction) return expr, set()
def integrate(self, domain: Domain, convex_bounds: List[LinearInequality], polynomial: Polynomial): formula = smt.And(*[i.to_smt() for i in convex_bounds]) return self.engine.copy(domain, formula, polynomial.to_smt()).compute_volume()
def test_polynomial_hash(): polynomial = Polynomial({("x", "x"): 2.0}) hash(polynomial)
def test_polynomial_from_smt_constant(): try: assert Polynomial.from_smt(Real(1.0)).to_smt() == Real(1.0) except Exception: assert False
def test_polynomial_from_smt_pow(): x, y, z = [Symbol(n, REAL) for n in "xyz"] formula = Pow(x, Real(2)) * 2 should_be = {("x", "x"): 2.0} assert Polynomial.from_smt(formula).poly_dict == should_be