def test_inconsistent2(self): solver = SimplexSolver() x = Variable('x') solver.add_constraint(Constraint(x, Constraint.GEQ, 10)) with self.assertRaises(RequiredFailure): solver.add_constraint(Constraint(x, Constraint.LEQ, 5))
def test_expression_with_variable_and_operators(self): v = Variable(name='v', value=10) ieq = Constraint(v, Constraint.GEQ, 5) self.assertExpressionEqual(ieq.expression, v - 5) ieq = Constraint(v, Constraint.LEQ, 5) self.assertExpressionEqual(ieq.expression, 5 - v)
def test_delete2(self): solver = SimplexSolver() x = Variable('x') y = Variable('y') solver.add_constraint(Constraint(x, Constraint.EQ, 100, WEAK)) solver.add_constraint(Constraint(y, Constraint.EQ, 120, STRONG)) c10 = Constraint(x, Constraint.LEQ, 10) c20 = Constraint(x, Constraint.LEQ, 20) solver.add_constraint(c10) solver.add_constraint(c20) self.assertAlmostEqual(x.value, 10) self.assertAlmostEqual(y.value, 120) solver.remove_constraint(c10) self.assertAlmostEqual(x.value, 20) self.assertAlmostEqual(y.value, 120) cxy = Constraint(x * 2, Constraint.EQ, y) solver.add_constraint(cxy) self.assertAlmostEqual(x.value, 20) self.assertAlmostEqual(y.value, 40) solver.remove_constraint(c20) self.assertAlmostEqual(x.value, 60) self.assertAlmostEqual(y.value, 120) solver.remove_constraint(cxy) self.assertAlmostEqual(x.value, 100) self.assertAlmostEqual(y.value, 120)
def test_delete1(self): solver = SimplexSolver() x = Variable('x') cbl = Constraint(x, Constraint.EQ, 100, WEAK) solver.add_constraint(cbl) c10 = Constraint(x, Constraint.LEQ, 10) c20 = Constraint(x, Constraint.LEQ, 20) solver.add_constraint(c10) solver.add_constraint(c20) self.assertAlmostEqual(x.value, 10) solver.remove_constraint(c10) self.assertAlmostEqual(x.value, 20) solver.remove_constraint(c20) self.assertAlmostEqual(x.value, 100) c10again = Constraint(x, Constraint.LEQ, 10) solver.add_constraint(c10) solver.add_constraint(c10again) self.assertAlmostEqual(x.value, 10) solver.remove_constraint(c10) self.assertAlmostEqual(x.value, 10) solver.remove_constraint(c10again) self.assertAlmostEqual(x.value, 100)
def test_strength(self): "Solvers should handle strengths correctly" solver = SimplexSolver() x = Variable(name='x', value=10) y = Variable(name='y', value=20) z = Variable(name='z', value=1) w = Variable(name='w', value=1) # Default weights. e0 = Constraint(x, Constraint.EQ, y) solver.add_stay(y) solver.add_constraint(e0) self.assertAlmostEqual(x.value, 20.0) self.assertAlmostEqual(y.value, 20.0) # Add a weak constraint. e1 = Constraint(x, Constraint.EQ, z, strength=WEAK) solver.add_stay(x) solver.add_constraint(e1) self.assertAlmostEqual(x.value, 20.0) self.assertAlmostEqual(z.value, 20.0) # Add a strong constraint. e2 = Constraint(z, Constraint.EQ, w, strength=STRONG) solver.add_stay(w) solver.add_constraint(e2) self.assertAlmostEqual(w.value, 1.0) self.assertAlmostEqual(z.value, 1.0)
def test_constructor_with_variable_operator_expression_args2(self): v = Variable(name='v', value=10) e = Expression(Variable(name='x', value=5), 2, 4) ieq = Constraint(e, Constraint.GEQ, v) self.assertExpressionEqual(ieq.expression, e - v) ieq = Constraint(e, Constraint.LEQ, v) self.assertExpressionEqual(ieq.expression, v - e)
def test_operator_arguments_to_inequality(self): v1 = Variable(name='v1', value=10) v2 = Variable(name='v2', value=5) ieq = Constraint(v1, Constraint.GEQ, v2) self.assertExpressionEqual(ieq.expression, v1 - v2) ieq = Constraint(v1, Constraint.LEQ, v2) self.assertExpressionEqual(ieq.expression, v2 - v1)
def test_expression_with_reused_variables(self): e1 = Expression(constant=10) e2 = Expression(Variable(name='c', value=10), 2, 4) ieq = Constraint(e1, Constraint.GEQ, e2) self.assertExpressionEqual(ieq.expression, e1 - e2) ieq = Constraint(e1, Constraint.LEQ, e2) self.assertExpressionEqual(ieq.expression, e2 - e1)
def test_inconsistent4(self): solver = SimplexSolver() x = Variable('x') y = Variable('y') # x = 10 solver.add_constraint(Constraint(x, Constraint.EQ, 10)) # x = y solver.add_constraint(Constraint(x, Constraint.EQ, y)) # y = 5. Should fail. with self.assertRaises(RequiredFailure): solver.add_constraint(Constraint(y, Constraint.EQ, 5))
def test_casso1(self): solver = SimplexSolver() x = Variable('x') y = Variable('y') solver.add_constraint(Constraint(x, Constraint.LEQ, y)) solver.add_constraint(Constraint(y, Constraint.EQ, x + 3)) solver.add_constraint(Constraint(x, Constraint.EQ, 10, WEAK)) solver.add_constraint(Constraint(y, Constraint.EQ, 10, WEAK)) self.assertTrue( (approx_equal(x.value, 10) and approx_equal(y.value, 13)) or (approx_equal(x.value, 7) and approx_equal(y.value, 10)))
def test_add_edit_var_required_after_suggestions(self): "Solver works with REQUIRED strength after many suggestions" solver = SimplexSolver() a = Variable(name='a') b = Variable(name='b') solver.add_stay(a, STRONG, 0) solver.add_constraint(Constraint(a, Constraint.EQ, b, REQUIRED)) solver.resolve() self.assertEqual(b.value, 0) self.assertEqual(a.value, 0) solver.add_edit_var(a, REQUIRED) solver.begin_edit() solver.suggest_value(a, 2) solver.resolve() self.assertEqual(a.value, 2) self.assertEqual(b.value, 2) solver.suggest_value(a, 10) solver.resolve() self.assertEqual(a.value, 10) self.assertEqual(b.value, 10)
def test_variable_leq_constant(self): solver = SimplexSolver() x = Variable('x', 100) ieq = Constraint(x, Constraint.LEQ, 10) solver.add_constraint(ieq) self.assertAlmostEqual(x.value, 10)
def test_variable_equal_constant(self): solver = SimplexSolver() x = Variable('x', 10) eq = Constraint(100, Constraint.EQ, x) solver.add_constraint(eq) self.assertAlmostEqual(x.value, 100)
def test_constant_leq_variable(self): # 100 <= x solver = SimplexSolver() x = Variable('x', 10) ieq = Constraint(100, Constraint.LEQ, x) solver.add_constraint(ieq) self.assertAlmostEqual(x.value, 100)
def test_from_constant(self): "Constraint can be constructed from a constant expression" ex = Expression(constant=10) # Constant value is ported to a float. self.assertIsInstance(ex.constant, float) self.assertAlmostEqual(ex.constant, 10.0) c1 = Constraint(ex) self.assertExpressionEqual(c1.expression, ex) self.assertFalse(c1.is_inequality) c2 = Constraint(10) self.assertAlmostEqual(c2.expression.constant, 10) self.assertTrue(c2.expression.is_constant) self.assertFalse(c2.is_inequality)
def test_simple(self): solver = SimplexSolver() x = Variable('x', 167) y = Variable('y', 2) eq = Constraint(x, Constraint.EQ, y) solver.add_constraint(eq) self.assertAlmostEqual(x.value, y.value) self.assertAlmostEqual(x.value, 0) self.assertAlmostEqual(y.value, 0)
def test_leq_with_stay(self): # stay width # 100 <= right solver = SimplexSolver() x = Variable('x', 10) width = Variable('width', 10) right = x + width ieq = Constraint(100, Constraint.LEQ, right) solver.add_stay(width) solver.add_constraint(ieq) self.assertAlmostEqual(x.value, 90) self.assertAlmostEqual(width.value, 10)
def test_error_weights(self): solver = SimplexSolver() x = Variable('x', 100) y = Variable('y', 200) z = Variable('z', 50) self.assertAlmostEqual(x.value, 100) self.assertAlmostEqual(y.value, 200) self.assertAlmostEqual(z.value, 50) solver.add_constraint(Constraint(z, Constraint.EQ, x, WEAK)) solver.add_constraint(Constraint(x, Constraint.EQ, 20, WEAK)) solver.add_constraint(Constraint(y, Constraint.EQ, 200, STRONG)) self.assertAlmostEqual(x.value, 20) self.assertAlmostEqual(y.value, 200) self.assertAlmostEqual(z.value, 20) solver.add_constraint(Constraint(z + 150, Constraint.LEQ, y, MEDIUM)) self.assertAlmostEqual(x.value, 20) self.assertAlmostEqual(y.value, 200) self.assertAlmostEqual(z.value, 20)
def test_geq_with_stay(self): # stay width # right >= 100 solver = SimplexSolver() # x = 10 x = Variable('x', 10) # width = 10 width = Variable('width', 10) # right = x + width right = x + width # right >= 100 ieq = Constraint(right, Constraint.GEQ, 100) solver.add_stay(width) solver.add_constraint(ieq) self.assertAlmostEqual(x.value, 90) self.assertAlmostEqual(width.value, 10)
def test_geq_with_variable(self): # stay width, rightMin # right >= rightMin solver = SimplexSolver() x = Variable('x', 10) width = Variable('width', 10) rightMin = Variable('rightMin', 100) right = x + width ieq = Constraint(right, Constraint.GEQ, rightMin) solver.add_stay(width) solver.add_stay(rightMin) solver.add_constraint(ieq) self.assertAlmostEqual(x.value, 90) self.assertAlmostEqual(width.value, 10)
def test_inconsistent3(self): solver = SimplexSolver() w = Variable('w') x = Variable('x') y = Variable('y') z = Variable('z') solver.add_constraint(Constraint(w, Constraint.GEQ, 10)) solver.add_constraint(Constraint(x, Constraint.GEQ, w)) solver.add_constraint(Constraint(y, Constraint.GEQ, x)) solver.add_constraint(Constraint(z, Constraint.GEQ, y)) solver.add_constraint(Constraint(z, Constraint.GEQ, 8)) with self.assertRaises(RequiredFailure): solver.add_constraint(Constraint(z, Constraint.LEQ, 4))
def test_leq_with_expression(self): # stay width, rightMin # right >= rightMin solver = SimplexSolver() x1 = Variable('x1', 10) width1 = Variable('width1', 10) right1 = x1 + width1 x2 = Variable('x2', 100) width2 = Variable('width2', 10) right2 = x2 + width2 ieq = Constraint(right2, Constraint.LEQ, right1) solver.add_stay(width1) solver.add_stay(width2) solver.add_stay(x2) solver.add_constraint(ieq) self.assertAlmostEqual(x1.value, 100)
def test_numbers_in_place_of_variables(self): v = Variable(name='v', value=22) eq = Constraint(v, Constraint.EQ, 5) self.assertExpressionEqual(eq.expression, 5 - v)
def test_multiedit3(self): MIN = 100 MAX = 500 width = Variable('width') height = Variable('height') top = Variable('top') bottom = Variable('bottom') left = Variable('left') right = Variable('right') solver = SimplexSolver() iw = Variable('window_innerWidth', random.randrange(MIN, MAX)) ih = Variable('window_innerHeight', random.randrange(MIN, MAX)) solver.add_constraint( Constraint(width, Constraint.EQ, iw, strength=STRONG, weight=0.0)) solver.add_constraint( Constraint(height, Constraint.EQ, ih, strength=STRONG, weight=0.0)) solver.add_constraint( Constraint(top, Constraint.EQ, 0, strength=WEAK, weight=0.0)) solver.add_constraint( Constraint(left, Constraint.EQ, 0, strength=WEAK, weight=0.0)) solver.add_constraint( Constraint(bottom, Constraint.EQ, top + height, strength=MEDIUM, weight=0.0)) # Right is at least left + width solver.add_constraint( Constraint(right, Constraint.EQ, left + width, strength=MEDIUM, weight=0.0)) solver.add_stay(iw) solver.add_stay(ih) # Propegate viewport size changes. for i in range(0, 30): # Measurement should be cheap here. iwv = random.randrange(MIN, MAX) ihv = random.randrange(MIN, MAX) solver.add_edit_var(iw) solver.add_edit_var(ih) with solver.edit(): solver.suggest_value(iw, iwv) solver.suggest_value(ih, ihv) # solver.resolve() self.assertAlmostEqual(top.value, 0) self.assertAlmostEqual(left.value, 0) self.assertLessEqual(bottom.value, MAX) self.assertGreaterEqual(bottom.value, MIN) self.assertLessEqual(right.value, MAX) self.assertGreaterEqual(right.value, MIN)
def test_inequality_expression_instantiation(self): e = Expression(constant=10) ieq = Constraint(e) self.assertExpressionEqual(ieq.expression, e)
def test_works_with_nested_expressions(self): e1 = Expression(constant=10) e2 = Expression(Variable(name='z', value=10), 2, 4) eq = Constraint(e1, Constraint.EQ, e2) self.assertExpressionEqual(eq.expression, e1 - e2)
def test_equations_in_place_of_variables(self): e = Expression(constant=10) v = Variable(name='v', value=22) eq = Constraint(e, Constraint.EQ, v) self.assertExpressionEqual(eq.expression, 10 - v)