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_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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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_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_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)
Esempio n. 7
0
    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)
Esempio n. 8
0
 def __init__(self, game):
     self.game = game
     self.solver = SimplexSolver()
     self.current_adjacent_fields = []
     self.newly_opened = []
     self.vars = [[
         Variable("a[{}][{}]".format(j, i))
         for i in range(self.game.board_dim)
     ] for j in range(self.game.board_dim)]
    def test_stay(self):
        x = Variable('x', 5)
        y = Variable('y', 10)

        solver = SimplexSolver()
        solver.add_stay(x)
        solver.add_stay(y)

        self.assertAlmostEqual(x.value, 5)
        self.assertAlmostEqual(y.value, 10)
Esempio n. 10
0
    def test_stay(self):
        x = Variable('x', 5)
        y = Variable('y', 10)

        solver = SimplexSolver()
        solver.add_stay(x)
        solver.add_stay(y)

        self.assertAlmostEqual(x.value, 5)
        self.assertAlmostEqual(y.value, 10)
Esempio n. 11
0
    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)
Esempio n. 12
0
    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)
Esempio n. 13
0
 def initialSetup(self, layer):
   self.solver = SimplexSolver()
   self.nodehash = {}
   for p in layer.paths:
     for n in p.nodes:
       nid = n.hash()
       self.nodehash[nid] = {
         "node": n,
         "xvar": Variable("x"+str(nid), n.position.x),
         "yvar": Variable("y"+str(nid), n.position.y),
         "affected": set()
       }
   self.setConstraintsFromHints(layer)
Esempio n. 14
0
    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))
Esempio n. 15
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)
Esempio n. 16
0
    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))
Esempio n. 17
0
    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)
Esempio n. 18
0
    def test_constructor(self):
        "A solver can be constructed"
        solver = SimplexSolver()

        self.assertEqual(len(solver.columns), 0)
        self.assertEqual(len(solver.rows), 1)
        self.assertEqual(len(solver.infeasible_rows), 0)
        self.assertEqual(len(solver.external_rows), 0)
        self.assertEqual(len(solver.external_parametric_vars), 0)
Esempio n. 19
0
 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))
Esempio n. 20
0
    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)))
Esempio n. 21
0
    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))
Esempio n. 22
0
 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))
Esempio n. 23
0
    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)
Esempio n. 24
0
    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))
        )
Esempio n. 25
0
    def test_leq_with_variable(self):
        # stay width
        # right >= rightMin
        solver = SimplexSolver()

        x = Variable('x', 10)
        width = Variable('width', 10)
        rightMin = Variable('rightMin', 100)

        right = x + width

        ieq = Constraint(rightMin, Constraint.LEQ, right)

        solver.add_stay(width)
        solver.add_stay(rightMin)
        solver.add_constraint(ieq)

        self.assertAlmostEqual(x.value, 90)
        self.assertAlmostEqual(width.value, 10)
Esempio n. 26
0
    def test_equality_with_stay(self):
        # stay width, rightMin
        # right >= rightMin
        solver = SimplexSolver()

        x = Variable('x', 10)
        width = Variable('width', 10)
        rightMin = Variable('rightMin', 100)

        right = x + width

        eq = Constraint(right, Constraint.EQ, rightMin)

        solver.add_stay(width)
        solver.add_stay(rightMin)
        solver.add_constraint(eq)

        self.assertAlmostEqual(x.value, 90)
        self.assertAlmostEqual(width.value, 10)
Esempio n. 27
0
    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)
Esempio n. 28
0
    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)
Esempio n. 29
0
    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)
Esempio n. 30
0
    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)
Esempio n. 31
0
    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)
Esempio n. 32
0
    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)
Esempio n. 33
0
class CSP(Strategy):
    def __init__(self, game):
        self.game = game
        self.solver = SimplexSolver()
        self.current_adjacent_fields = []
        self.newly_opened = []
        self.vars = [[
            Variable("a[{}][{}]".format(j, i))
            for i in range(self.game.board_dim)
        ] for j in range(self.game.board_dim)]

    def get_random_field(self):
        while True:
            i = randint(0, self.game.board_dim - 1)
            j = randint(0, self.game.board_dim - 1)
            if self.vars[i][j].value == 0 and self.game.board[i][j].covered:
                break

        return self.game.board[i][j]

    def open(self, field):
        boundary_list = []
        for field in self.game.open_field(field):

            # this case is really interesting, we are opening a field that is safe but solver
            # thinks that it is mined. We need to edit and enforce as stay constraint
            if self.vars[field.row][field.column] != 0:
                self.vars[field.row][field.column].value = 0
            self.solver.add_stay(self.vars[field.row][field.column])

            # if adjacent_mines is set we are looking at boundary field and we need to add it
            # to the boundary_list
            if field.adjacent_mines:
                boundary_list.append(field)

            if field in self.current_adjacent_fields:
                self.current_adjacent_fields.remove(field)
        return boundary_list

    def make_constraint(self, row_index, col_index):
        """
        Compute equations for field (row_index, col_index)
        """

        adjacent_fields = self.game.get_adjacent_fields(row_index, col_index)
        adjacent_mines = self.game.get_adjacent_mines(row_index, col_index)

        assert adjacent_mines
        for field in adjacent_fields:
            if field not in self.current_adjacent_fields and self.game.board[
                    field.row][field.column].covered:
                self.current_adjacent_fields.append(field)

        return adjacent_mines == sum(self.vars[f.row][f.column]
                                     for f in adjacent_fields if f.covered)

    def first_step(self, first_field=None):
        self.solver.add_constraint(self.game.num_mines == sum(
            self.vars[i][j] for i in range(0, self.game.board_dim)
            for j in range(0, self.game.board_dim)))

        for (row_index, row) in enumerate(self.game.board):
            for (col_index, var) in enumerate(row):
                self.solver.add_constraint(
                    self.vars[row_index][col_index] >= 0)
                self.solver.add_constraint(
                    self.vars[row_index][col_index] <= 1)

        if first_field:
            row, column = first_field
            self.newly_opened = self.open(self.game.board[row][column])
        else:
            self.newly_opened = self.open(self.get_random_field())

    def step(self):
        for new in self.newly_opened:
            self.solver.add_constraint(
                self.make_constraint(new.row, new.column))

        possible_fields = []
        for field in self.current_adjacent_fields:
            if self.vars[field.row][field.column].value == 1:
                self.game.mark_field_dangerous(field)
            else:
                if field.is_mine:
                    print(
                        "[CST-PSST] Pushing mined field {} in possible fields".
                        format(field))
                else:
                    print("[CST]Pushing field {} in possible fields".format(
                        field))
                possible_fields.append(field)

                if field in self.game.marked:
                    self.game.mark_field_safe(field)

        if possible_fields:
            print("[CST] Randomly choosing from possible fields: {}".format(
                possible_fields))
            new_field = choice(possible_fields)
        else:
            print(
                "[CST] I have no idea what to choose next, randomly generating..."
            )
            new_field = self.get_random_field()

        self.newly_opened = self.open(new_field)
def resolve(parent, dimensions, children, constraint_list):
    """
    Resolve a coordinates problem. The coordinates of the children entered in parameter will be computed.

    :param parent: the main box that contains the children entered in parameter
    :param dimensions: the dict of children's dimensions
    :param children: the children to dispose in the parent's box
    :param constraint_list: the list of constraints
    :return: the dict that contains the coordinates of the children in parameter
    """

    if parent.orthogonal_state:
        if parent.axis == 'horizontal':
            height = max(map(lambda child: dimensions[child][1], parent.children))
            for child in parent.children:
                w, h = dimensions[child]
                dimensions[child] = (w, height)
        else:
            width = max(map(lambda child: dimensions[child][0], parent.children))
            for child in parent.children:
                w, h = dimensions[child]
                dimensions[child] = (width, h)

    boxes = list(map(lambda child: BoxWithConstraints(child, dimensions), children))
    constraints = list(map(lambda constraint: Constraint(next(filter(lambda x: x.box == constraint.box1, boxes),
                                                              BoxWithConstraints(constraint.box1, dimensions)),
                                                         constraint.direction,
                                                         next(filter(lambda x: x.box == constraint.box2, boxes),
                                                              BoxWithConstraints(constraint.box2, dimensions))),
                           constraint_list))

    def add_constraint(solver, constraint):
        box1 = constraint.box1
        box2 = constraint.box2
        x1, y1, x2, y2 = box1.space
        x3, y3, x4, y4 = box2.space
        {
            'north': lambda: solver.add_constraint(box1.y + box1.height + y2 + space + y3 < box2.y),
            'east': lambda: solver.add_constraint(box1.x > box2.x + box2.width + x4 + space + x1),
            'south': lambda: solver.add_constraint(box1.y > box2.y + box2.height + y4 + space + y1),
            'west': lambda: solver.add_constraint(box1.x + box1.width + x2 + space + x3 < box2.x)
        }[constraint.direction]()

    solver = SimplexSolver()

    # dimension of the frame
    left_limit = Variable('left', 0)
    top_limit = Variable('top', parent.header)
    right_limit = Variable('right', 0)
    bot_limit = Variable('bottom', 0)

    # define the base constraints (stay)
    solver.add_stay(left_limit)
    solver.add_stay(top_limit)

    for i in range(len(boxes)):
        b1 = boxes[i]
        x1, y1, x2, y2 = b1.space
        solver.add_constraint(b1.x > left_limit + space + x1)
        solver.add_constraint(b1.y > top_limit + space + y1)
        solver.add_constraint(b1.x + b1.width + x2 + space < right_limit)
        solver.add_constraint(b1.y + b1.height + y2 + space < bot_limit)
        if parent.axis == 'horizontal':
            solver.add_constraint(b1.y + y1 - top_limit == bot_limit - b1.y - b1.height - y2, strength=WEAK)
        else:
            solver.add_constraint(b1.x + x1 - left_limit == right_limit - b1.x - b1.width - x2, strength=WEAK)
        for b2 in boxes[i + 1:]:
            if not (any(filter(lambda constraint: b1 in [constraint.box1, constraint.box2] \
                    and b2 in [constraint.box1, constraint.box2], constraints))):
                x3, y3, x4, y4 = b2.space
                if parent.axis == 'horizontal':
                    solver.add_constraint(b2.x > b1.x + b1.width + space + x2 + x3, strength=WEAK)
                else:
                    solver.add_constraint(b2.y > b1.y + b1.height + space + y2 + y3, strength=WEAK)

    for constraint in constraints:
        add_constraint(solver, constraint)

    width, height = max(map(lambda box: box.x.value + box.width + box.space[2] + space, boxes)), \
                    max(map(lambda box: box.y.value + box.height + box.space[3] + space, boxes))
    new_coordinates = OrderedDict({parent: (0, 0, width, height)})
    for box in boxes:
        new_coordinates[box.box] = (box.x.value, box.y.value, box.x.value + box.width, box.y.value + box.height)
    return new_coordinates
Esempio n. 35
0
    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)
Esempio n. 36
0
class TTSolver:

  def initialSetup(self, layer):
    self.solver = SimplexSolver()
    self.nodehash = {}
    for p in layer.paths:
      for n in p.nodes:
        nid = n.hash()
        self.nodehash[nid] = {
          "node": n,
          "xvar": Variable("x"+str(nid), n.position.x),
          "yvar": Variable("y"+str(nid), n.position.y),
          "affected": set()
        }
    self.setConstraintsFromHints(layer)

  def yvar(self,n):
    if not n:
      raise ValueError
    if not (n.hash() in self.nodehash):
      raise KeyError(n)
    return self.nodehash[n.hash()]["yvar"]

  def xvar(self,n):
    if not n:
      raise ValueError
    if not (n.hash() in self.nodehash):
      raise KeyError(n)
    return self.nodehash[n.hash()]["xvar"]

  def setConstraintsFromHints(self, layer):
    c = []
    for h in layer.hints:
      if h.type == TAG:
        try:
          if h.options() == DIAGONAL or (h.options() < 8 and not h.horizontal):
            v1 = self.yvar(h.originNode)
            v2 = self.yvar(h.targetNode)
            yValue = v1.value - v2.value
            ystem = v1 - v2
            c.append(ystem == yValue)

          if h.options() == DIAGONAL or (h.options() < 8 and h.horizontal):
            v1 = self.xvar(h.originNode)
            v2 = self.xvar(h.targetNode)
            xValue = v1.value - v2.value
            xstem = v1 - v2
            c.append(xstem == xValue)

          if h.options() == PROPORTIONAL_TRIPLE:
            if h.horizontal:
              v1 = self.xvar(h.originNode)
              v2 = self.xvar(h.targetNode)
              v3 = self.xvar(h.otherNode1)
              proportion = safediv(h.targetNode.position.x - h.originNode.position.x , h.otherNode1.position.x - h.targetNode.position.x)
            else:
              v1 = self.yvar(h.originNode)
              v2 = self.yvar(h.targetNode)
              v3 = self.yvar(h.otherNode1)
              proportion = safediv(h.targetNode.position.y - h.originNode.position.y, h.otherNode1.position.y - h.targetNode.position.y)
            d1 = v2 - v1
            d2 = v3 - v2
            c.append(d2 * proportion == d1)

          if h.options() == PROPORTIONAL_QUAD:
            on2 = h.valueForKey_("otherNode2") # Glyphs bug
            if h.horizontal:
              v1 = self.xvar(h.originNode)
              v2 = self.xvar(h.targetNode)
              v3 = self.xvar(h.otherNode1)
              v4 = self.xvar(on2)
              proportion = safediv(h.targetNode.position.x - h.originNode.position.x, on2.position.x - h.otherNode1.position.x)
            else:
              v1 = self.yvar(h.originNode)
              v2 = self.yvar(h.targetNode)
              v3 = self.yvar(h.otherNode1)
              v4 = self.yvar(on2)
              proportion = safediv(h.targetNode.position.y - h.originNode.position.y, on2.position.y - h.otherNode1.position.y)
            d1 = v2 - v1
            d2 = v4 - v3
            # print(d1,d2,proportion)
            c.append(d2 * proportion == d1)
        except ValueError:
          print("I found a busted constraint. It'll get cleaned up soon.")
    for cs in c:
      self.solver.add_constraint(cs)

  def _diagonalConstraints(self, c, n1,n2):
    v1 = self.xvar(n1)
    v2 = self.xvar(n2)
    xValue = v1.value - v2.value
    xstem = v1 - v2
    v1 = self.yvar(n1)
    v2 = self.yvar(n2)
    yValue = v1.value - v2.value
    ystem = v1 - v2
    c.append(xstem == xValue)
    c.append(ystem == yValue)

  def _makeEditable(self,node):
    n = self.nodehash[node.hash()]
    self.solver.add_edit_var(n["xvar"])
    self.solver.add_edit_var(n["yvar"])

  def _suggest(self,node):
    n = self.nodehash[node.hash()]
    # print("Suggesting ",n["node"].position.x,n["node"].position.y)
    self.solver.suggest_value(n["xvar"], n["node"].position.x)
    self.solver.suggest_value(n["yvar"], n["node"].position.y)

  def setStayFromNodes(self, layer):
    nodes = filter(lambda x:x.hash() in self.nodehash, layer.selection)
    if len(nodes) < 1:
      return

    temporaryConstraints = []
    c = []
    for p in layer.paths:
      for n in p.nodes:
        if n.type != GSOFFCURVE:
          # Constrain left handle and this node
          if n.prevNode.type == GSOFFCURVE and not n.prevNode.selected:
              self._diagonalConstraints(c, n, n.prevNode)
          if n.nextNode.type == GSOFFCURVE and not n.nextNode.selected:
            self._diagonalConstraints(c, n, n.nextNode)

    for cs in c:
      temporaryConstraints.append(self.solver.add_constraint(cs, strength=WEAK))

    # print("Putting stuff into solver")
    for n in nodes:
      self._makeEditable(n)
      if n.type != GSOFFCURVE:
        if n.nextNode.type == GSOFFCURVE:
          self._makeEditable(n.nextNode)
        if n.prevNode.type == GSOFFCURVE:
          self._makeEditable(n.prevNode)
      else:
        if n.nextNode.type == CURVE and n.nextNode.smooth:
          self._makeEditable(n.nextNode)
          self._makeEditable(n.nextNode.nextNode)
        elif n.prevNode.type == CURVE and n.prevNode.smooth:
          self._makeEditable(n.prevNode)
          self._makeEditable(n.prevNode.prevNode)

    with self.solver.edit():
      for n in nodes:
        self._suggest(n)
        if n.type != GSOFFCURVE:
          if n.nextNode.type == GSOFFCURVE:
            self._suggest(n.nextNode)
          if n.prevNode.type == GSOFFCURVE:
            self._suggest(n.prevNode)
        else:
          if n.nextNode.type == CURVE and n.nextNode.smooth:
            self._suggest(n.nextNode)
            self._suggest(n.nextNode.nextNode)
          elif n.prevNode.type == CURVE and n.prevNode.smooth:
            self._suggest(n.prevNode)
            self._suggest(n.prevNode.prevNode)

    for j in nodes:
      n = self.nodehash[j.hash()]
      # print("Got: ",n["xvar"],n["yvar"])

    for c in temporaryConstraints:
      self.solver.remove_constraint(c)

  def updateGlyphWithSolution(self):
    for i in self.nodehash:
      n = self.nodehash[i]
      # print(n["node"], "->", n["xvar"].value, n["yvar"].value)
      n["node"].position = (n["xvar"].value, n["yvar"].value)

  def updateSolverFromGlyph(self):
    for i in self.nodehash:
      n = self.nodehash[i]
      n["xvar"].value = n["node"].position.x
      n["yvar"].value = n["node"].position.y
      n["xstay"] = self.solver.add_stay(n["xvar"], strength=WEAK)
      n["ystay"] = self.solver.add_stay(n["yvar"], strength=WEAK)
      self.solver.add_edit_var(n["xvar"])
      self.solver.add_edit_var(n["yvar"])

    if len(self.nodehash) > 0:
      with self.solver.edit():
        for i in self.nodehash:
          n = self.nodehash[i]
          self.solver.suggest_value(n["xvar"], n["node"].position.x)
          self.solver.suggest_value(n["yvar"], n["node"].position.y)
Esempio n. 37
0
    def test_multiedit1(self):
        # This test stresses the edit session stack. begin_edit() starts a new
        # "edit variable group" and "end_edit" closes it, leaving only the
        # previously opened edit variables still active.
        x = Variable('x')
        y = Variable('y')
        w = Variable('w')
        h = Variable('h')
        solver = SimplexSolver()

        # Add some stays
        solver.add_stay(x)
        solver.add_stay(y)
        solver.add_stay(w)
        solver.add_stay(h)

        # start an editing session
        solver.add_edit_var(x)
        solver.add_edit_var(y)

        with solver.edit():
            solver.suggest_value(x, 10)
            solver.suggest_value(y, 20)

            # Force the system to resolve.
            solver.resolve()

            self.assertAlmostEqual(x.value, 10)
            self.assertAlmostEqual(y.value, 20)
            self.assertAlmostEqual(w.value, 0)
            self.assertAlmostEqual(h.value, 0)

            # Open a second set of variables for editing
            solver.add_edit_var(w)
            solver.add_edit_var(h)

            with solver.edit():
                solver.suggest_value(w, 30)
                solver.suggest_value(h, 40)

            # Close the second set...
            self.assertAlmostEqual(x.value, 10)
            self.assertAlmostEqual(y.value, 20)
            self.assertAlmostEqual(w.value, 30)
            self.assertAlmostEqual(h.value, 40)

            # Now make sure the first set can still be edited
            solver.suggest_value(x, 50)
            solver.suggest_value(y, 60)

        self.assertAlmostEqual(x.value, 50)
        self.assertAlmostEqual(y.value, 60)
        self.assertAlmostEqual(w.value, 30)
        self.assertAlmostEqual(h.value, 40)
Esempio n. 38
0
    def test_quadrilateral(self):
        "A simple version of the quadrilateral test"

        solver = SimplexSolver()

        class Point(object):
            def __init__(self, identifier, x, y):
                self.x = Variable('x' + identifier, x)
                self.y = Variable('y' + identifier, y)

            def __repr__(self):
                return u'(%s, %s)' % (self.x.value, self.y.value)

            __hash__ = object.__hash__

            def __eq__(self, other):
                return self.x.value == other[0] and self.y.value == other[1]

        points = [
            Point('0', 10, 10),
            Point('1', 10, 200),
            Point('2', 200, 200),
            Point('3', 200, 10),
            Point('m0', 0, 0),
            Point('m1', 0, 0),
            Point('m2', 0, 0),
            Point('m3', 0, 0),
        ]
        midpoints = points[4:]

        # Add point stays
        weight = 1.0
        multiplier = 2.0
        for point in points[:4]:
            solver.add_stay(point.x, WEAK, weight)
            solver.add_stay(point.y, WEAK, weight)
            weight = weight * multiplier

        for start, end in [(0, 1), (1, 2), (2, 3), (3, 0)]:
            cle = (points[start].x + points[end].x) / 2
            cleq = midpoints[start].x == cle
            solver.add_constraint(cleq)
            cle = (points[start].y + points[end].y) / 2
            cleq = midpoints[start].y == cle
            solver.add_constraint(cleq)

        cle = points[0].x + 20
        solver.add_constraint(cle <= points[2].x)
        solver.add_constraint(cle <= points[3].x)

        cle = points[1].x + 20
        solver.add_constraint(cle <= points[2].x)
        solver.add_constraint(cle <= points[3].x)

        cle = points[0].y + 20
        solver.add_constraint(cle <= points[1].y)
        solver.add_constraint(cle <= points[2].y)

        cle = points[3].y + 20
        solver.add_constraint(cle <= points[1].y)
        solver.add_constraint(cle <= points[2].y)

        for point in points:
            solver.add_constraint(point.x >= 0)
            solver.add_constraint(point.y >= 0)

            solver.add_constraint(point.x <= 500)
            solver.add_constraint(point.y <= 500)

        # Check the initial answers

        self.assertEqual(points[0], (10.0, 10.0))
        self.assertEqual(points[1], (10.0, 200.0))
        self.assertEqual(points[2], (200.0, 200.0))
        self.assertEqual(points[3], (200.0, 10.0))
        self.assertEqual(points[4], (10.0, 105.0))
        self.assertEqual(points[5], (105.0, 200.0))
        self.assertEqual(points[6], (200.0, 105.0))
        self.assertEqual(points[7], (105.0, 10.0))

        # Now move point 2 to a new location

        solver.add_edit_var(points[2].x)
        solver.add_edit_var(points[2].y)

        solver.begin_edit()

        solver.suggest_value(points[2].x, 300)
        solver.suggest_value(points[2].y, 400)

        solver.end_edit()

        # Check that the other points have been moved.
        self.assertEqual(points[0], (10.0, 10.0))
        self.assertEqual(points[1], (10.0, 200.0))
        self.assertEqual(points[2], (300.0, 400.0))
        self.assertEqual(points[3], (200.0, 10.0))
        self.assertEqual(points[4], (10.0, 105.0))
        self.assertEqual(points[5], (155.0, 300.0))
        self.assertEqual(points[6], (250.0, 205.0))
        self.assertEqual(points[7], (105.0, 10.0))
Esempio n. 39
0
    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)
Esempio n. 40
0
    def test_paper_example(self):

        solver = SimplexSolver()

        left = Variable('left')
        middle = Variable('middle')
        right = Variable('right')

        solver.add_constraint(middle == (left + right) / 2)
        solver.add_constraint(right == left + 10)
        solver.add_constraint(right <= 100)
        solver.add_constraint(left >= 0)

        # Check that all the required constraints are true:
        self.assertAlmostEqual((left.value + right.value) / 2, middle.value)
        self.assertAlmostEqual(right.value, left.value + 10)
        self.assertGreaterEqual(left.value, 0)
        self.assertLessEqual(right.value, 100)

        # Set the middle value to a stay
        middle.value = 45.0
        solver.add_stay(middle)

        # Check that all the required constraints are true:
        self.assertAlmostEqual((left.value + right.value) / 2, middle.value)
        self.assertAlmostEqual(right.value, left.value + 10)
        self.assertGreaterEqual(left.value, 0)
        self.assertLessEqual(right.value, 100)

        # But more than that - since we gave a position for middle, we know
        # where all the points should be.

        self.assertAlmostEqual(left.value, 40)
        self.assertAlmostEqual(middle.value, 45)
        self.assertAlmostEqual(right.value, 50)
Esempio n. 41
0
    def test_buttons(self):
        "A test of a horizontal layout of two buttons on a screen."

        class Button(object):
            def __init__(self, identifier):
                self.left = Variable('left' + identifier, 0)
                self.width = Variable('width' + identifier, 0)

            def __repr__(self):
                return u'(%s:%s)' % (self.left.value, self.width.value)

        solver = SimplexSolver()

        b1 = Button('b1')
        b2 = Button('b2')
        left_limit = Variable('left', 0)
        right_limit = Variable('width', 0)

        left_limit.value = 0
        solver.add_stay(left_limit, REQUIRED)
        stay = solver.add_stay(right_limit, WEAK)

        # The two buttons are the same width
        solver.add_constraint(b1.width == b2.width)

        # b1 starts 50 from the left margin.
        solver.add_constraint(b1.left == left_limit + 50)

        # b2 ends 50 from the right margin
        solver.add_constraint(left_limit + right_limit == b2.left + b2.width + 50)

        # b2 starts at least 100 from the end of b1
        solver.add_constraint(b2.left >= (b1.left + b1.width + 100))

        # b1 has a minimum width of 87
        solver.add_constraint(b1.width >= 87)

        # b1's preferred width is 87
        solver.add_constraint(b1.width == 87, STRONG)

        # b2's minimum width is 113
        solver.add_constraint(b2.width >= 113)

        # b2's preferred width is 113
        solver.add_constraint(b2.width == 113, STRONG)

        # Without imposign a stay on the right, right_limit will be the minimum width for the layout
        self.assertAlmostEqual(b1.left.value, 50.0)
        self.assertAlmostEqual(b1.width.value, 113.0)
        self.assertAlmostEqual(b2.left.value, 263.0)
        self.assertAlmostEqual(b2.width.value, 113.0)
        self.assertAlmostEqual(right_limit.value, 426.0)

        # The window is 500 pixels wide.
        right_limit.value = 500
        stay = solver.add_stay(right_limit, REQUIRED)
        self.assertAlmostEqual(b1.left.value, 50.0)
        self.assertAlmostEqual(b1.width.value, 113.0)
        self.assertAlmostEqual(b2.left.value, 337.0)
        self.assertAlmostEqual(b2.width.value, 113.0)
        self.assertAlmostEqual(right_limit.value, 500.0)
        solver.remove_constraint(stay)

        # Expand to 700 pixels
        right_limit.value = 700
        stay = solver.add_stay(right_limit, REQUIRED)
        self.assertAlmostEqual(b1.left.value, 50.0)
        self.assertAlmostEqual(b1.width.value, 113.0)
        self.assertAlmostEqual(b2.left.value, 537.0)
        self.assertAlmostEqual(b2.width.value, 113.0)
        self.assertAlmostEqual(right_limit.value, 700.0)
        solver.remove_constraint(stay)

        # Contract to 600
        right_limit.value = 600
        stay = solver.add_stay(right_limit, REQUIRED)
        self.assertAlmostEqual(b1.left.value, 50.0)
        self.assertAlmostEqual(b1.width.value, 113.0)
        self.assertAlmostEqual(b2.left.value, 437.0)
        self.assertAlmostEqual(b2.width.value, 113.0)
        self.assertAlmostEqual(right_limit.value, 600.0)
        solver.remove_constraint(stay)
Esempio n. 42
0
    def test_quadrilateral(self):
        "A simple version of the quadrilateral test"

        solver = SimplexSolver()

        class Point(object):
            def __init__(self, identifier, x, y):
                self.x = Variable('x' + identifier, x)
                self.y = Variable('y' + identifier, y)

            def __repr__(self):
                return u'(%s, %s)' % (self.x.value, self.y.value)

            __hash__ = object.__hash__

            def __eq__(self, other):
                return self.x.value == other[0] and self.y.value == other[1]

        points = [
            Point('0', 10, 10),
            Point('1', 10, 200),
            Point('2', 200, 200),
            Point('3', 200, 10),

            Point('m0', 0, 0),
            Point('m1', 0, 0),
            Point('m2', 0, 0),
            Point('m3', 0, 0),
        ]
        midpoints = points[4:]

        # Add point stays
        weight = 1.0
        multiplier = 2.0
        for point in points[:4]:
            solver.add_stay(point.x, WEAK, weight)
            solver.add_stay(point.y, WEAK, weight)
            weight = weight * multiplier

        for start, end in [(0, 1), (1, 2), (2, 3), (3, 0)]:
            cle = (points[start].x + points[end].x) / 2
            cleq = midpoints[start].x == cle
            solver.add_constraint(cleq)
            cle = (points[start].y + points[end].y) / 2
            cleq = midpoints[start].y == cle
            solver.add_constraint(cleq)

        cle = points[0].x + 20
        solver.add_constraint(cle <= points[2].x)
        solver.add_constraint(cle <= points[3].x)

        cle = points[1].x + 20
        solver.add_constraint(cle <= points[2].x)
        solver.add_constraint(cle <= points[3].x)

        cle = points[0].y + 20
        solver.add_constraint(cle <= points[1].y)
        solver.add_constraint(cle <= points[2].y)

        cle = points[3].y + 20
        solver.add_constraint(cle <= points[1].y)
        solver.add_constraint(cle <= points[2].y)

        for point in points:
            solver.add_constraint(point.x >= 0)
            solver.add_constraint(point.y >= 0)

            solver.add_constraint(point.x <= 500)
            solver.add_constraint(point.y <= 500)

        # Check the initial answers

        self.assertEqual(points[0], (10.0, 10.0))
        self.assertEqual(points[1], (10.0, 200.0))
        self.assertEqual(points[2], (200.0, 200.0))
        self.assertEqual(points[3], (200.0, 10.0))
        self.assertEqual(points[4], (10.0, 105.0))
        self.assertEqual(points[5], (105.0, 200.0))
        self.assertEqual(points[6], (200.0, 105.0))
        self.assertEqual(points[7], (105.0, 10.0))

        # Now move point 2 to a new location

        solver.add_edit_var(points[2].x)
        solver.add_edit_var(points[2].y)

        solver.begin_edit()

        solver.suggest_value(points[2].x, 300)
        solver.suggest_value(points[2].y, 400)

        solver.end_edit()

        # Check that the other points have been moved.
        self.assertEqual(points[0], (10.0, 10.0))
        self.assertEqual(points[1], (10.0, 200.0))
        self.assertEqual(points[2], (300.0, 400.0))
        self.assertEqual(points[3], (200.0, 10.0))
        self.assertEqual(points[4], (10.0, 105.0))
        self.assertEqual(points[5], (155.0, 300.0))
        self.assertEqual(points[6], (250.0, 205.0))
        self.assertEqual(points[7], (105.0, 10.0))
Esempio n. 43
0
    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)
Esempio n. 44
0
    def test_multiedit2(self):

        x = Variable('x')
        y = Variable('y')
        w = Variable('w')
        h = Variable('h')

        solver = SimplexSolver()
        solver.add_stay(x)
        solver.add_stay(y)
        solver.add_stay(w)
        solver.add_stay(h)
        solver.add_edit_var(x)
        solver.add_edit_var(y)

        solver.begin_edit()
        solver.suggest_value(x, 10)
        solver.suggest_value(y, 20)
        solver.resolve()
        solver.end_edit()

        self.assertAlmostEqual(x.value, 10)
        self.assertAlmostEqual(y.value, 20)
        self.assertAlmostEqual(w.value, 0)
        self.assertAlmostEqual(h.value, 0)

        solver.add_edit_var(w)
        solver.add_edit_var(h)

        solver.begin_edit()
        solver.suggest_value(w, 30)
        solver.suggest_value(h, 40)
        solver.end_edit()

        self.assertAlmostEqual(x.value, 10)
        self.assertAlmostEqual(y.value, 20)
        self.assertAlmostEqual(w.value, 30)
        self.assertAlmostEqual(h.value, 40)

        solver.add_edit_var(x)
        solver.add_edit_var(y)

        solver.begin_edit()
        solver.suggest_value(x, 50)
        solver.suggest_value(y, 60)
        solver.end_edit()

        self.assertAlmostEqual(x.value, 50)
        self.assertAlmostEqual(y.value, 60)
        self.assertAlmostEqual(w.value, 30)
        self.assertAlmostEqual(h.value, 40)
Esempio n. 45
0
    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)
Esempio n. 46
0
    def test_buttons(self):
        "A test of a horizontal layout of two buttons on a screen."

        class Button(object):
            def __init__(self, identifier):
                self.left = Variable('left' + identifier, 0)
                self.width = Variable('width' + identifier, 0)

            def __repr__(self):
                return u'(%s:%s)' % (self.left.value, self.width.value)

        solver = SimplexSolver()

        b1 = Button('b1')
        b2 = Button('b2')
        left_limit = Variable('left', 0)
        right_limit = Variable('width', 0)

        left_limit.value = 0
        solver.add_stay(left_limit, REQUIRED)
        stay = solver.add_stay(right_limit, WEAK)

        # The two buttons are the same width
        solver.add_constraint(b1.width == b2.width)

        # b1 starts 50 from the left margin.
        solver.add_constraint(b1.left == left_limit + 50)

        # b2 ends 50 from the right margin
        solver.add_constraint(left_limit + right_limit == b2.left + b2.width +
                              50)

        # b2 starts at least 100 from the end of b1
        solver.add_constraint(b2.left >= (b1.left + b1.width + 100))

        # b1 has a minimum width of 87
        solver.add_constraint(b1.width >= 87)

        # b1's preferred width is 87
        solver.add_constraint(b1.width == 87, STRONG)

        # b2's minimum width is 113
        solver.add_constraint(b2.width >= 113)

        # b2's preferred width is 113
        solver.add_constraint(b2.width == 113, STRONG)

        # Without imposign a stay on the right, right_limit will be the minimum width for the layout
        self.assertAlmostEqual(b1.left.value, 50.0)
        self.assertAlmostEqual(b1.width.value, 113.0)
        self.assertAlmostEqual(b2.left.value, 263.0)
        self.assertAlmostEqual(b2.width.value, 113.0)
        self.assertAlmostEqual(right_limit.value, 426.0)

        # The window is 500 pixels wide.
        right_limit.value = 500
        stay = solver.add_stay(right_limit, REQUIRED)
        self.assertAlmostEqual(b1.left.value, 50.0)
        self.assertAlmostEqual(b1.width.value, 113.0)
        self.assertAlmostEqual(b2.left.value, 337.0)
        self.assertAlmostEqual(b2.width.value, 113.0)
        self.assertAlmostEqual(right_limit.value, 500.0)
        solver.remove_constraint(stay)

        # Expand to 700 pixels
        right_limit.value = 700
        stay = solver.add_stay(right_limit, REQUIRED)
        self.assertAlmostEqual(b1.left.value, 50.0)
        self.assertAlmostEqual(b1.width.value, 113.0)
        self.assertAlmostEqual(b2.left.value, 537.0)
        self.assertAlmostEqual(b2.width.value, 113.0)
        self.assertAlmostEqual(right_limit.value, 700.0)
        solver.remove_constraint(stay)

        # Contract to 600
        right_limit.value = 600
        stay = solver.add_stay(right_limit, REQUIRED)
        self.assertAlmostEqual(b1.left.value, 50.0)
        self.assertAlmostEqual(b1.width.value, 113.0)
        self.assertAlmostEqual(b2.left.value, 437.0)
        self.assertAlmostEqual(b2.width.value, 113.0)
        self.assertAlmostEqual(right_limit.value, 600.0)
        solver.remove_constraint(stay)
Esempio n. 47
0
    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)
Esempio n. 48
0
    def test_paper_example(self):

        solver = SimplexSolver()

        left = Variable('left')
        middle = Variable('middle')
        right = Variable('right')

        solver.add_constraint(middle == (left + right) / 2)
        solver.add_constraint(right == left + 10)
        solver.add_constraint(right <= 100)
        solver.add_constraint(left >= 0)

        # Check that all the required constraints are true:
        self.assertAlmostEqual((left.value + right.value) / 2, middle.value)
        self.assertAlmostEqual(right.value, left.value + 10)
        self.assertGreaterEqual(left.value, 0)
        self.assertLessEqual(right.value, 100)

        # Set the middle value to a stay
        middle.value = 45.0
        solver.add_stay(middle)

        # Check that all the required constraints are true:
        self.assertAlmostEqual((left.value + right.value) / 2, middle.value)
        self.assertAlmostEqual(right.value, left.value + 10)
        self.assertGreaterEqual(left.value, 0)
        self.assertLessEqual(right.value, 100)

        # But more than that - since we gave a position for middle, we know
        # where all the points should be.

        self.assertAlmostEqual(left.value, 40)
        self.assertAlmostEqual(middle.value, 45)
        self.assertAlmostEqual(right.value, 50)
Esempio n. 49
0
    def test_multiedit1(self):
        # This test stresses the edit session stack. begin_edit() starts a new
        # "edit variable group" and "end_edit" closes it, leaving only the
        # previously opened edit variables still active.
        x = Variable('x')
        y = Variable('y')
        w = Variable('w')
        h = Variable('h')
        solver = SimplexSolver()

        # Add some stays
        solver.add_stay(x)
        solver.add_stay(y)
        solver.add_stay(w)
        solver.add_stay(h)

        # start an editing session
        solver.add_edit_var(x)
        solver.add_edit_var(y)

        with solver.edit():
            solver.suggest_value(x, 10)
            solver.suggest_value(y, 20)

            # Force the system to resolve.
            solver.resolve()

            self.assertAlmostEqual(x.value, 10)
            self.assertAlmostEqual(y.value, 20)
            self.assertAlmostEqual(w.value, 0)
            self.assertAlmostEqual(h.value, 0)

            # Open a second set of variables for editing
            solver.add_edit_var(w)
            solver.add_edit_var(h)

            with solver.edit():
                solver.suggest_value(w, 30)
                solver.suggest_value(h, 40)

            # Close the second set...
            self.assertAlmostEqual(x.value, 10)
            self.assertAlmostEqual(y.value, 20)
            self.assertAlmostEqual(w.value, 30)
            self.assertAlmostEqual(h.value, 40)

            # Now make sure the first set can still be edited
            solver.suggest_value(x, 50)
            solver.suggest_value(y, 60)

        self.assertAlmostEqual(x.value, 50)
        self.assertAlmostEqual(y.value, 60)
        self.assertAlmostEqual(w.value, 30)
        self.assertAlmostEqual(h.value, 40)
Esempio n. 50
0
    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)
Esempio n. 51
0
    def test_add_edit_var_required(self):
        "Solver works with REQUIRED strength"
        solver = SimplexSolver()

        a = Variable(name='a')

        solver.add_stay(a, STRONG, 0)
        solver.resolve()

        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)
Esempio n. 52
0
    def test_multiedit2(self):

        x = Variable('x')
        y = Variable('y')
        w = Variable('w')
        h = Variable('h')

        solver = SimplexSolver()
        solver.add_stay(x)
        solver.add_stay(y)
        solver.add_stay(w)
        solver.add_stay(h)
        solver.add_edit_var(x)
        solver.add_edit_var(y)

        solver.begin_edit()
        solver.suggest_value(x, 10)
        solver.suggest_value(y, 20)
        solver.resolve()
        solver.end_edit()

        self.assertAlmostEqual(x.value, 10)
        self.assertAlmostEqual(y.value, 20)
        self.assertAlmostEqual(w.value, 0)
        self.assertAlmostEqual(h.value, 0)

        solver.add_edit_var(w)
        solver.add_edit_var(h)

        solver.begin_edit()
        solver.suggest_value(w, 30)
        solver.suggest_value(h, 40)
        solver.end_edit()

        self.assertAlmostEqual(x.value, 10)
        self.assertAlmostEqual(y.value, 20)
        self.assertAlmostEqual(w.value, 30)
        self.assertAlmostEqual(h.value, 40)

        solver.add_edit_var(x)
        solver.add_edit_var(y)

        solver.begin_edit()
        solver.suggest_value(x, 50)
        solver.suggest_value(y, 60)
        solver.end_edit()

        self.assertAlmostEqual(x.value, 50)
        self.assertAlmostEqual(y.value, 60)
        self.assertAlmostEqual(w.value, 30)
        self.assertAlmostEqual(h.value, 40)
Esempio n. 53
0
from cassowary import SimplexSolver, Variable
import numpy as np

solver = SimplexSolver()

#create variables with default value
x1 = Variable('x1')
x2 = Variable('x2')
z1 = Variable('z1')
z2 = Variable('z2')
z = Variable('z')

#known variables
num = 2
c = np.array([9, 1])
m = np.array([1, 2])
ub = np.array([10, 3])
max_profit = sum(ub - c)
max_total_residues = max_profit + sum(c - m)
profit = 0
total_residues = profit + sum(c - m)
avg = total_residues*1.0/num

solver.add_constraint(z1 <= avg + x1)
solver.add_constraint(x1 + z1 >= avg)
solver.add_constraint(z2 <= avg + x2)
solver.add_constraint(x2 + z2 >= avg)
solver.add_constraint(x1 + x2 == total_residues)
solver.add_constraint(x1 + m[0] <= ub[0])
solver.add_constraint(x2 + m[1] <= ub[1])
solver.add_constraint(x1 >= 0)
Esempio n. 54
0
    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)