Add the given relation as one or more constraints.

        Return a list of the names of the constraints added.

def _add_constraints(self, relation):
        """Add the given relation as one or more constraints.

        Return a list of the names of the constraints added.
        """

        expression = relation.expression
        constr_count = sum(True for _ in expression.value_sets())
        if constr_count == 0:
            return []

        row_indices = count(swiglpk.glp_add_rows(self._p, constr_count))

        names = []
        for i, value_set in zip(row_indices, expression.value_sets()):
            value_set = list(value_set)
            var_indices = swiglpk.intArray(1 + len(value_set))
            var_values = swiglpk.doubleArray(1 + len(value_set))
            for j, (variable, coeff) in enumerate(value_set):
                var_indices[1 + j] = self._variables[variable]
                var_values[1 + j] = float(coeff)

            swiglpk.glp_set_mat_row(
                self._p, i, len(value_set), var_indices, var_values)

            if relation.sense == RelationSense.Greater:
                swiglpk.glp_set_row_bnds(
                    self._p, i, swiglpk.GLP_LO, -float(expression.offset), 0)
            elif relation.sense == RelationSense.Less:
                swiglpk.glp_set_row_bnds(
                    self._p, i, swiglpk.GLP_UP, 0, -float(expression.offset))
            else:
                swiglpk.glp_set_row_bnds(
                    self._p, i, swiglpk.GLP_FX, -float(expression.offset), 0)

            names.append(i)

        self._do_presolve = True

        return names