def define(self, *names, **kwargs):
        """Define a variable in the problem.

        Variables must be defined before they can be accessed by var() or
        set(). This function takes keyword arguments lower and upper to define
        the bounds of the variable (default: -inf to inf). The keyword argument
        types can be used to select the type of the variable (only Continuous
        is supported). Raises ValueError if a name is already defined.
        """
        names = tuple(names)
        for name in names:
            if name in self._variables:
                raise ValueError('Variable already defined: {!r}'.format(name))

        lower = kwargs.get('lower', None)
        upper = kwargs.get('upper', None)
        vartype = kwargs.get('types', None)

        # Repeat values if a scalar is given
        if lower is None or isinstance(lower, numbers.Number):
            lower = repeat(lower, len(names))
        if upper is None or isinstance(upper, numbers.Number):
            upper = repeat(upper, len(names))
        if vartype is None or vartype in (
                VariableType.Continuous, VariableType.Binary,
                VariableType.Integer):
            vartype = repeat(vartype, len(names))

        lp_names = tuple(next(self._var_names) for name in names)

        # Assign default values
        vartype = (VariableType.Continuous if value is None else value
                   for value in vartype)

        self._variables.update(zip(names, lp_names))
        for name, lower, upper, t in zip(lp_names, lower, upper, vartype):
            if t != VariableType.Continuous:
                raise ValueError(
                    'Solver does not support non-continuous types')
            self._p.add_variable(0, lower, upper, name)