1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
import pytest
from snakeoil.constraints import Problem
def any_of(**kwargs):
return any(kwargs.values())
def all_of(**kwargs):
return all(kwargs.values())
def test_readd_variables():
p = Problem()
p.add_variable((True, False), "x", "y")
with pytest.raises(AssertionError, match="variable 'y' was already added"):
p.add_variable((True, False), "y", "z")
def test_constraint_unknown_variable():
p = Problem()
p.add_variable((True, False), "x", "y")
with pytest.raises(AssertionError, match="unknown variable 'z'"):
p.add_constraint(any_of, ("y", "z"))
def test_empty_problem():
p = Problem()
assert tuple(p) == ({},)
def test_empty_constraints():
p = Problem()
p.add_variable((True, False), "x", "y")
p.add_variable((True,), "z")
assert len(tuple(p)) == 4
def test_domain_prefer_later():
p = Problem()
p.add_variable((False, True), "x", "y")
p.add_constraint(any_of, ("x", "y"))
assert next(iter(p)) == {"x": True, "y": True}
def test_constraint_single_variable():
p = Problem()
p.add_variable((True, False), "x", "y")
p.add_constraint(lambda x: x, ("x",))
p.add_constraint(lambda y: not y, ("y",))
assert tuple(p) == ({"x": True, "y": False},)
def test_no_solution():
p = Problem()
p.add_variable((True,), "x")
p.add_variable((True, False), "y", "z")
p.add_constraint(lambda x, y: not x or y, ("x", "y"))
p.add_constraint(lambda y, z: not y or not z, ("y", "z"))
p.add_constraint(lambda x, z: not x or z, ("x", "z"))
assert not tuple(p)
def test_forward_check():
p = Problem()
p.add_variable(range(2, 10), "x", "y", "z")
p.add_constraint(lambda x, y: (x + y) % 2 == 0, ("x", "y"))
p.add_constraint(lambda x, y, z: (x * y * z) % 2 != 0, ("x", "y", "z"))
p.add_constraint(lambda y, z: y < z, ("y", "z"))
p.add_constraint(lambda z, x: x**2 <= z, ("x", "z"))
assert tuple(p) == (
{"x": 3, "y": 7, "z": 9},
{"x": 3, "y": 5, "z": 9},
{"x": 3, "y": 3, "z": 9},
)
|