1 # Copyright 2014 MINES ParisTech
3 # This file is part of LinPy.
5 # LinPy is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # LinPy is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with LinPy. If not, see <http://www.gnu.org/licenses/>.
20 from ..domains
import And
, Or
21 from ..linexprs
import Symbol
, symbols
22 from ..polyhedra
import Empty
, Eq
, Ge
, Polyhedron
25 class TestDomain(unittest
.TestCase
):
29 self
.square1
= Polyhedron(inequalities
=[x
, 2 - x
, y
, 2 - y
])
30 self
.square2
= Polyhedron(inequalities
=[x
- 1, 3 - x
, y
- 1, 3 - y
])
31 self
.square3
= Polyhedron(inequalities
=[x
, 3 - x
, y
, 3 - y
])
32 self
.square4
= Polyhedron(inequalities
=[x
- 1, 2 - x
, y
- 1, 2 - y
])
33 self
.square5
= Polyhedron(inequalities
=[x
- 3, 6 - x
, y
- 3, 6 - y
])
34 self
.square6
= Polyhedron(equalities
=[3 - y
],
35 inequalities
=[x
- 1, 3 - x
, y
- 1])
36 self
.unbound_poly
= Polyhedron(inequalities
=[x
, 3 - x
, y
])
37 self
.universe
= Polyhedron([])
39 self
.disjoint
= And(Ge(x
, 0), Ge(-x
+ 2, 0), Ge(y
, 0), Ge(-y
+ 2, 0))
40 self
.complement
= Or(Ge(-x
- 1, 0), Ge(x
- 3, 0),
41 And(Ge(x
, 0), Ge(-x
+ 2, 0), Ge(-y
- 1, 0)),
42 And(Ge(x
, 0), Ge(-x
+ 2, 0), Ge(y
- 3, 0)))
43 self
.hull
= And(Ge(x
, 0), Ge(-x
+ 2, 0), Ge(y
, 0), Ge(-y
+ 2, 0))
44 self
.dropped
= And(Ge(y
, 0), Ge(-y
+ 2, 0))
45 self
.intersection
= And(Ge(x
- 1, 0), Ge(-x
+ 2, 0), Ge(y
- 1, 0),
47 self
.union
= Or(And(Ge(x
, 0), Ge(-x
+ 2, 0), Ge(y
, 0), Ge(-y
+ 2, 0)),
48 And(Ge(x
- 1, 0), Ge(-x
+ 3, 0), Ge(y
- 1, 0),
50 self
.sum1
= Or(And(Ge(x
, 0), Ge(-x
+ 2, 0), Ge(y
, 0), Ge(-y
+ 2, 0)),
51 And(Ge(x
- 1, 0), Ge(-x
+ 3, 0), Ge(y
- 1, 0),
53 self
.sum2
= And(Ge(x
, 0), Ge(y
, 0), Ge(-y
+ 3, 0), Ge(-x
+ 3, 0),
54 Ge(x
- y
+ 2, 0), Ge(-x
+ y
+ 2, 0))
55 self
.difference1
= Or(And(Eq(x
- 3, 0), Ge(y
- 1, 0), Ge(-y
+ 3, 0)),
56 And(Eq(y
- 3, 0), Ge(x
- 1, 0), Ge(-x
+ 2, 0)))
57 self
.difference2
= And(Ge(x
+ y
- 4, 0), Ge(-x
+ 3, 0), Ge(-y
+ 3, 0))
58 self
.lexmin
= And(Eq(y
, 0), Eq(x
, 0))
59 self
.lexmax
= And(Eq(y
- 2, 0), Eq(x
- 2, 0))
62 with self
.assertRaises(TypeError):
65 def test_disjoint(self
):
66 self
.assertEqual(self
.square1
.make_disjoint(), self
.disjoint
)
67 self
.assertEqual(self
.empty
.make_disjoint(), Empty
)
68 self
.assertEqual(self
.universe
.make_disjoint(), self
.universe
)
70 def test_isempty(self
):
71 self
.assertFalse(self
.square1
.isempty())
72 self
.assertTrue(self
.empty
.isempty())
73 self
.assertFalse(self
.universe
.isempty())
75 def test_isuniverse(self
):
76 self
.assertFalse(self
.square1
.isuniverse())
77 self
.assertTrue(self
.universe
.isuniverse())
79 def test_isbounded(self
):
80 self
.assertTrue(self
.square1
.isbounded())
81 self
.assertFalse(self
.unbound_poly
.isbounded())
84 self
.assertTrue(self
.square1
== self
.square1
)
85 self
.assertFalse(self
.square1
== self
.square2
)
86 self
.assertFalse(self
.empty
== self
.universe
)
88 def test_isdisjoint(self
):
89 self
.assertFalse(self
.square1
.isdisjoint(self
.square2
))
90 self
.assertFalse(self
.universe
.isdisjoint(self
.square1
))
91 self
.assertTrue(self
.square1
.isdisjoint(self
.square5
))
92 self
.assertTrue(self
.empty
.isdisjoint(self
.square1
))
94 def test_issubset(self
):
95 self
.assertTrue(self
.square4
.issubset(self
.unbound_poly
))
96 self
.assertFalse(self
.square1
.issubset(self
.square2
))
97 self
.assertTrue(self
.square1
.issubset(self
.universe
))
98 self
.assertTrue(self
.empty
.issubset(self
.square1
))
101 self
.assertTrue(self
.square4
<= self
.square3
)
102 self
.assertFalse(self
.square3
<= self
.square4
)
103 self
.assertTrue(self
.empty
<= self
.square1
)
104 self
.assertTrue(self
.square1
<= self
.universe
)
107 self
.assertTrue(self
.square4
< self
.square3
)
108 self
.assertFalse(self
.square3
< self
.square4
)
109 self
.assertTrue(self
.empty
< self
.square1
)
110 self
.assertTrue(self
.square1
< self
.universe
)
112 def test_complement(self
):
113 self
.assertEqual(~self
.square1
, self
.complement
)
114 self
.assertEqual(~self
.universe
, Empty
)
115 self
.assertEqual(~self
.empty
, self
.universe
)
117 def test_aspolyhedron(self
):
118 self
.assertEqual(self
.square1
.aspolyhedron(), self
.hull
)
119 self
.assertEqual(self
.universe
.aspolyhedron(), self
.universe
)
120 self
.assertEqual(self
.empty
.aspolyhedron(), self
.empty
)
122 def test_project(self
):
123 self
.assertEqual(self
.square1
.project(symbols('x')), self
.dropped
)
124 self
.assertEqual(self
.square1
.project(symbols('x y')), self
.universe
)
125 self
.assertEqual(self
.universe
.project([]), self
.universe
)
126 self
.assertEqual(self
.empty
.project([]), Empty
)
128 def test_sample(self
):
129 self
.assertEqual(self
.square6
.sample(),
130 {Symbol('x'): 1, Symbol('y'): 3})
131 with self
.assertRaises(ValueError):
133 self
.assertEqual(self
.universe
.sample(), {})
135 def test_intersection(self
):
136 self
.assertEqual(self
.square1
.intersection(self
.square2
),
140 self
.assertEqual(self
.square2
& self
.square1
, self
.intersection
)
141 self
.assertEqual(self
.square1
& self
.universe
, self
.square1
)
142 self
.assertEqual(self
.empty
& self
.square1
, Empty
)
143 self
.assertEqual(self
.universe
& self
.universe
, self
.universe
)
144 self
.assertEqual(self
.universe
& self
.empty
, Empty
)
145 self
.assertEqual(self
.empty
& self
.empty
, Empty
)
147 def test_union(self
):
148 self
.assertEqual(self
.square1
.union(self
.square2
), self
.union
)
149 self
.assertEqual(self
.square1
.union(self
.empty
), self
.square1
)
150 self
.assertEqual(self
.square1
.union(self
.universe
), self
.universe
)
151 self
.assertEqual(self
.universe
.union(self
.universe
), self
.universe
)
152 self
.assertEqual(self
.empty
.union(self
.empty
), self
.empty
)
155 self
.assertEqual(self
.square1 | self
.square2
, self
.union
)
158 self
.assertEqual(self
.square2
+ self
.square1
, self
.sum1
)
159 self
.assertEqual(Polyhedron(self
.square1
+ self
.square2
), self
.sum2
)
160 self
.assertEqual(self
.universe
+ self
.square1
, self
.universe
)
161 self
.assertEqual(self
.empty
+ self
.square1
, self
.square1
)
162 self
.assertEqual(self
.universe
+ self
.universe
, self
.universe
)
164 def test_difference(self
):
165 self
.assertEqual(self
.square2
- self
.square1
, self
.difference1
)
166 self
.assertEqual(Polyhedron(self
.square2
- self
.square1
),
168 self
.assertEqual(self
.square2
- self
.square2
, Empty
)
169 self
.assertEqual(self
.universe
- self
.universe
, Empty
)
171 def test_lexmin(self
):
172 self
.assertEqual(self
.square1
.lexmin(), self
.lexmin
)
173 self
.assertEqual(self
.universe
.lexmin(), self
.universe
)
174 self
.assertEqual(self
.empty
.lexmin(), Empty
)
176 def test_lexmax(self
):
177 self
.assertEqual(self
.square1
.lexmax(), self
.lexmax
)
178 self
.assertEqual(self
.universe
.lexmax(), self
.universe
)
179 self
.assertEqual(self
.empty
.lexmax(), Empty
)