Exemple #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))
Exemple #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))
Exemple #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)
Exemple #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)
Exemple #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 ')
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)
Exemple #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
Exemple #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
Exemple #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)
Exemple #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)
Exemple #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)
Exemple #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')
    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")
Exemple #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)
    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"))),
        )
Exemple #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))
Exemple #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)
Exemple #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)
Exemple #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)
Exemple #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)
Exemple #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)
Exemple #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)
Exemple #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")
Exemple #27
0
    def test_simple_math_expression(self):

        f = ExpressionFunction('a + b ')
        self.assertEqual(f.expression, 'a + b ')
Exemple #28
0
    def test_callable(self):

        f = ExpressionFunction('a / b ')
        self.assertEqual(f(a=4, b=2), 2)
Exemple #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')))
Exemple #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)