コード例 #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
ファイル: yamldcop.py プロジェクト: qslim/pyDcop
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)
コード例 #12
0
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)
コード例 #20
0
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'))))
コード例 #23
0
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)