Пример #1
0
    def test_hash_fixed_vars(self):
        f1 = ExpressionFunction('a + b', b=1)
        f2 = ExpressionFunction('a + b', b=2)
        f3 = ExpressionFunction('a + b')

        self.assertNotEqual(hash(f1), hash(f2))
        self.assertNotEqual(hash(f1), hash(f3))
Пример #2
0
    def test_from_repr_on_partial(self):
        f = ExpressionFunction('a + b')
        fp = f.partial(a=2)

        r = simple_repr(fp)
        f1 = from_repr(r)
        print(r)

        self.assertEqual(f1(b=3), 5)
        self.assertEqual(f1(b=5), f(a=2, b=5))
Пример #3
0
    def test_simple_repr_on_partial(self):
        f = ExpressionFunction('a + b')
        fp = f.partial(a=2)

        r = simple_repr(fp)
        print(r)

        self.assertEqual(r['expression'], 'a + b')
        self.assertIn('a', r['fixed_vars'])
        self.assertEqual(r['fixed_vars']['a'], 2)
Пример #4
0
    def test_with_expression_based_cost_func(self):
        domain = VariableDomain('d', 'd', [1, 2, 3, 4])
        cost_func = ExpressionFunction('v +1')
        v = VariableWithCostFunc('v', domain, cost_func=cost_func)

        self.assertEqual(v.cost_for_val(1), 2)
        self.assertEqual(v.cost_for_val(3), 4)
Пример #5
0
    def test_simple_repr(self):
        f = ExpressionFunction('a + b ')
        self.assertEqual(f.expression, 'a + b ')

        r = simple_repr(f)

        self.assertEqual(r['expression'], 'a + b ')
Пример #6
0
def constraint_from_str(name: str, expression: str,
                        all_variables: Iterable[Variable]):
    """
    Generate a relation object from a string expression and a list of
    available variable objects.

    Example:
    r = relation_from_str('test_rel', 's1 * s2', [s1, s2, s3, l1])

    :param name: name of the relation
    :param expression: python string expression representing the function of
    the relation
    :param all_variables: list of all available variable objects the relation
    could depend on. The exact scope of the relation depends on the content of
    the expression, but any variable used in the expression must be in this
    list.

    :return: a relation object whose function implements the expression
    """
    f_exp = ExpressionFunction(expression)
    relation_variables = []
    for v in f_exp.variable_names:
        found = False
        for s in all_variables:
            if s.name == v:
                relation_variables.append(s)
                found = True
        if not found:
            raise Exception('Missing variable {} for string-based function '
                            '"{}"'.format(v, expression))

    return NAryFunctionRelation(f_exp, relation_variables, name, f_kwargs=True)
Пример #7
0
def _build_variables(loaded, dcop) -> Dict[str, Variable]:
    variables = {}
    if 'variables' in loaded:
        for v_name in loaded['variables']:
            v = loaded['variables'][v_name]
            domain = dcop.domain(v['domain'])
            initial_value = v['initial_value'] if 'initial_value' in v \
                else None
            if initial_value and initial_value not in domain.values:
                raise ValueError('initial value {} is not in the domain {} '
                                 'of the variable {}'.format(
                                     initial_value, domain.name, v_name))

            if 'cost_function' in v:
                cost_expression = v['cost_function']
                cost_func = ExpressionFunction(cost_expression)
                if 'noise_level' in v:
                    variables[v_name] = VariableNoisyCostFunc(
                        v_name,
                        domain,
                        cost_func,
                        initial_value,
                        noise_level=v['noise_level'])
                else:
                    variables[v_name] = VariableWithCostFunc(
                        v_name, domain, cost_func, initial_value)

            else:
                variables[v_name] = Variable(v_name, domain, initial_value)
    return variables
Пример #8
0
def _build_variables(loaded, dcop) -> Dict[str, Variable]:
    variables = {}
    if "variables" in loaded:
        for v_name in loaded["variables"]:
            v = loaded["variables"][v_name]
            domain = dcop.domain(v["domain"])
            initial_value = v["initial_value"] if "initial_value" in v else None
            if initial_value and initial_value not in domain.values:
                raise ValueError("initial value {} is not in the domain {} "
                                 "of the variable {}".format(
                                     initial_value, domain.name, v_name))

            if "cost_function" in v:
                cost_expression = v["cost_function"]
                cost_func = ExpressionFunction(cost_expression)
                if "noise_level" in v:
                    variables[v_name] = VariableNoisyCostFunc(
                        v_name,
                        domain,
                        cost_func,
                        initial_value,
                        noise_level=v["noise_level"],
                    )
                else:
                    variables[v_name] = VariableWithCostFunc(
                        v_name, domain, cost_func, initial_value)

            else:
                variables[v_name] = Variable(v_name, domain, initial_value)
    return variables
Пример #9
0
    def test_variable_names(self):

        f = ExpressionFunction('a + b ')
        names = f.variable_names

        self.assertEqual(len(list(names)), 2)
        self.assertIn('a', names)
        self.assertIn('b', names)
Пример #10
0
 def test_raise_on_expression_with_many_variable(self):
     domain = VariableDomain('d', 'd', [1, 2, 3, 4])
     cost_func = ExpressionFunction('v+ w +1')
     self.assertRaises(ValueError,
                       VariableWithCostFunc,
                       'v',
                       domain,
                       cost_func=cost_func)
Пример #11
0
    def test_expression_function(self):

        f = ExpressionFunction('a + b + v1')
        var_list = func_args(f)

        self.assertIn('a', var_list)
        self.assertIn('b', var_list)
        self.assertIn('v1', var_list)
        self.assertEqual(len(var_list), 3)
def test_multiline_expression_with_fromimport():
    exp = ExpressionFunction("""from math import pi
return pi + a""")

    import math
    assert exp(a=2) == math.pi + 2

    with pytest.raises(TypeError) as exception:
        exp(2)
Пример #13
0
    def test_simple_repr_with_expression_function(self):
        domain = VariableDomain('d', 'd', [1, 2, 3, 4])
        cost_func = ExpressionFunction('v / 2')
        v = VariableNoisyCostFunc('v', domain, cost_func=cost_func)

        r = simple_repr(v)

        self.assertEquals(r['name'], 'v')
        self.assertEquals(r['cost_func']['expression'], 'v / 2')
Пример #14
0
    def test_simple_repr_with_expression_function(self):
        domain = VariableDomain("d", "d", [1, 2, 3, 4])
        cost_func = ExpressionFunction("v / 2")
        v = VariableNoisyCostFunc("v", domain, cost_func=cost_func)

        r = simple_repr(v)

        self.assertEqual(r["name"], "v")
        self.assertEqual(r["cost_func"]["expression"], "v / 2")
Пример #15
0
    def test_from_repr_with_expression_function(self):
        domain = VariableDomain('d', 'd', [1, 2, 3, 4])
        cost_func = ExpressionFunction('v / 2')
        v = VariableWithCostFunc('v', domain, cost_func=cost_func)

        r = simple_repr(v)
        v2 = from_repr(r)

        self.assertEqual(v2.cost_for_val(2), v.cost_for_val(2))
        self.assertEqual(v2, v)
Пример #16
0
    def test_hash(self):
        d1 = VariableDomain("d", "foo", [1, 2, 3])
        v1 = VariableNoisyCostFunc("v1", d1, cost_func=ExpressionFunction("v1/2"))
        v1_othercosts = VariableNoisyCostFunc(
            "v1", d1, cost_func=ExpressionFunction("v1/3")
        )

        self.assertNotEqual(hash(v1), hash(v1_othercosts))

        v1_othername = VariableNoisyCostFunc(
            "v1_other", d1, cost_func=ExpressionFunction("v1_other/2")
        )

        self.assertNotEqual(hash(v1), hash(v1_othername))

        self.assertEqual(
            hash(v1),
            hash(VariableNoisyCostFunc("v1", d1, cost_func=ExpressionFunction("v1/2"))),
        )
Пример #17
0
    def test_should_work_with_partial(self):

        f = ExpressionFunction('a * (b -c)')

        fp = partial(f, c=2)
        self.assertEqual(f(a=2, b=5, c=2), 6)
        self.assertEqual(f(a=2, b=5, c=2), fp(a=2, b=5))

        fp = partial(f, c=1, a=3)
        self.assertEqual(f(a=3, b=5, c=1), fp(b=5))
Пример #18
0
    def test_complex_oneline_exp(self):

        # This kind of expression is exactly what we use when modelling an
        # hard constraint:
        f = ExpressionFunction('0 if round(0.2*a + 0.5*b + 0.8*c) == M '
                               'else 1000')

        self.assertEqual(f(a=10, b=10, c=10, M=15), 0)
        self.assertEqual(f(a=10, b=10, c=10, M=13), 1000)
        self.assertEqual(f(a=5, b=2, c=3, M=4), 0)
Пример #19
0
    def test_from_simple_repr(self):
        f = ExpressionFunction('a + b ')
        self.assertEqual(f.expression, 'a + b ')

        r = simple_repr(f)
        f2 = from_repr(r)

        self.assertEqual(f(a=2, b=3), f2(a=2, b=3))
        self.assertEqual(f2(a=2, b=3), 5)
        self.assertEqual(f, f2)
def test_multiline_expression_no_newline_at_start():
    exp = ExpressionFunction("""a=3
return a + 2""")

    assert exp() == 5

    # As f has no arg, it must raise an error :
    with pytest.raises(TypeError):
        exp(a=4, b=3, c=2)
    with pytest.raises(TypeError):
        exp(a=4)
    with pytest.raises(TypeError):
        exp(4)
Пример #21
0
    def test_from_repr_with_expression_function(self):
        domain = VariableDomain('d', 'd', [1, 2, 3, 4])
        cost_func = ExpressionFunction('v / 2')
        v = VariableNoisyCostFunc('v', domain, cost_func=cost_func)

        r = simple_repr(v)
        v2 = from_repr(r)

        # Due to the noise, the cost will de different
        c1 = v2.cost_for_val(2)
        c2 = v.cost_for_val(2)
        self.assertLessEqual(abs(c1 - c2), v.noise_level * 2)

        self.assertEquals(v2, v)
Пример #22
0
    def test_hash(self):
        d1 = VariableDomain('d', 'foo', [1, 2, 3])
        v1 = VariableNoisyCostFunc('v1',
                                   d1,
                                   cost_func=ExpressionFunction('v1/2'))
        v1_othercosts = \
            VariableNoisyCostFunc('v1', d1,
                                  cost_func=ExpressionFunction('v1/3'))

        self.assertNotEqual(hash(v1), hash(v1_othercosts))

        v1_othername = \
            VariableNoisyCostFunc('v1_other', d1,
                                  cost_func=ExpressionFunction('v1_other/2'))

        self.assertNotEqual(hash(v1), hash(v1_othername))

        self.assertEqual(
            hash(v1),
            hash(
                VariableNoisyCostFunc('v1',
                                      d1,
                                      cost_func=ExpressionFunction('v1/2'))))
def test_multiline_expression_one_var():
    exp = ExpressionFunction("""a=3
return a * b""")

    assert exp(b=2) == 6

    with pytest.raises(TypeError) as exception:
        exp()
    assert "Missing named argument(s)" in str(exception.value)

    with pytest.raises(TypeError) as exception:
        exp(4)
    assert "takes 1 positional argument but 2 were given" in str(
        exception.value)
Пример #24
0
    def test_str_with_function_call(self):
        r = ExpressionFunction('abs(s1 - s2)')

        self.assertEqual(len(list(r.variable_names)), 2)
        self.assertEqual(r(s1=2, s2=3), 1)
        self.assertEqual(r(s1=3, s2=2), 1)
Пример #25
0
    def test_non_numeric_variable(self):

        f = ExpressionFunction("1 if a == 'A' else 2")
        self.assertEqual(f(a='A'), 1)
        self.assertEqual(f(a='B'), 2)
Пример #26
0
    def test_oneline_python_expression(self):

        f = ExpressionFunction(' "ko" if a+b > 10 else a+b')

        self.assertEqual(f(a=2, b=3), 5)
        self.assertEqual(f(a=4, b=8), "ko")
Пример #27
0
    def test_simple_math_expression(self):

        f = ExpressionFunction('a + b ')
        self.assertEqual(f.expression, 'a + b ')
Пример #28
0
    def test_callable(self):

        f = ExpressionFunction('a / b ')
        self.assertEqual(f(a=4, b=2), 2)
Пример #29
0
    def test_hash(self):
        f = ExpressionFunction('a + b')
        h = hash(f)

        self.assertEqual(h, hash(ExpressionFunction('a + b')))
        self.assertNotEqual(h, hash(ExpressionFunction('a + c')))
Пример #30
0
    def test_fixed_vars(self):
        f = ExpressionFunction('a + b ', b=3)
        self.assertEqual(f(a=5), 8)

        self.assertNotIn('b', f.variable_names)