File: test_solver.py

package info (click to toggle)
python-gaphas 5.1.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,560 kB
  • sloc: python: 5,839; makefile: 17; sh: 2
file content (156 lines) | stat: -rw-r--r-- 3,341 bytes parent folder | download
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
"""Test constraint solver."""

from gaphas.constraint import EqualsConstraint, LessThanConstraint
from gaphas.solver import REQUIRED, MultiConstraint, Solver, Variable
from gaphas.solver.constraint import Constraint, ContainsConstraints


def test_solver_implements_constraint_protocol():
    solver = Solver()

    assert isinstance(solver, Constraint)
    assert isinstance(solver, ContainsConstraints)


def test_weakest_list_order():
    solver = Solver()
    a = Variable(1, 30)
    b = Variable(2, 10)
    c_eq = EqualsConstraint(a, b)
    solver.add_constraint(c_eq)
    a.value = 4

    b.value = 5
    assert c_eq.weakest() == b

    a.value = 6
    assert c_eq.weakest() == b

    b.value = 6
    assert c_eq.weakest() == a


def test_minimal_size_constraint():
    solver = Solver()
    v1 = Variable(0)
    v2 = Variable(10)
    v3 = Variable(10)
    c1 = EqualsConstraint(a=v2, b=v3)
    c2 = LessThanConstraint(smaller=v1, bigger=v3, delta=10)
    solver.add_constraint(c1)
    solver.add_constraint(c2)

    # Check everything is ok on start
    solver.solve()
    assert 0 == v1
    assert 10 == v2
    assert 10 == v3

    # Change v1 to 2, after solve it should be 0 again due to LT constraint
    v1.value = 2
    solver.solve()

    assert 0 == v1
    assert 10 == v2
    assert 10 == v3

    # Change v3 to 20, after solve v2 will follow thanks to EQ constraint
    v3.value = 20
    solver.solve()

    assert 0 == v1
    assert 20 == v2
    assert 20 == v3

    # Change v3 to 0, after solve it should be 10 due to LT.delta = 10, v2
    # should also be 10 due to EQ constraint
    v3.value = 0
    solver.solve()

    assert 0 == v1
    assert 10 == v2
    assert 10 == v3


def test_constraints_can_not_be_resolved():
    solver = Solver()
    a = Variable()
    b = Variable()
    c = Variable(40, strength=REQUIRED)
    d = Variable(30, strength=REQUIRED)

    solver.add_constraint(EqualsConstraint(a, b))
    solver.add_constraint(EqualsConstraint(a, c))
    solver.add_constraint(EqualsConstraint(b, d))

    solver.solve()

    assert a.value == 40.0
    assert b.value == 30.0


def test_notify_for_nested_constraint():
    events = []
    solver = Solver()
    a = Variable()
    b = Variable()
    nested = EqualsConstraint(a, b)
    multi = MultiConstraint(nested)

    solver.add_constraint(multi)
    solver.solve()

    def handler(constraint):
        events.append(constraint)

    solver.add_handler(handler)

    a.value = 10

    solver.solve()

    assert multi in events
    assert nested not in events


def test_notify_for_double_nested_constraint():
    events = []
    solver = Solver()
    a = Variable()
    b = Variable()
    nested = EqualsConstraint(a, b)
    multi = MultiConstraint(nested)
    outer = MultiConstraint(multi)

    solver.add_constraint(outer)
    solver.solve()

    def handler(constraint):
        events.append(constraint)

    solver.add_handler(handler)

    a.value = 10

    solver.solve()

    assert outer in events


def test_needs_solving():
    solver = Solver()
    a = Variable()
    b = Variable()
    eq = EqualsConstraint(a, b)

    solver.add_constraint(eq)
    assert solver.needs_solving

    solver.solve()
    assert not solver.needs_solving

    a.value = 3
    assert solver.needs_solving

    solver.solve()
    assert not solver.needs_solving