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)
Example #6
0
    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
Example #8
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