import copy


def random_reset_mutation(random, candidate, args):
    """Return the mutants produced by randomly choosing new values.

    This function performs random-reset mutation. It assumes that 
    candidate solutions are composed of discrete values. This function
    makes use of the bounder function as specified in the EC's 
    ``evolve`` method, and it assumes that the bounder contains
    an attribute called *values* (which is true for instances of
    ``DiscreteBounder``).
    
    The mutation moves through a candidate solution and, with rate
    equal to the *mutation_rate*, randomly chooses a value from the 
    set of allowed values to be used in that location. Note that this
    value may be the same as the original value.

    .. Arguments:
       random -- the random number generator object
       candidate -- the candidate solution
       args -- a dictionary of keyword arguments

    Optional keyword arguments in args:
    
    - *mutation_rate* -- the rate at which mutation is performed (default 0.1)
    
    The mutation rate is applied on an element by element basis.
    
    """
    bounder = args['_ec'].bounder
    try:
        values = bounder.values
    except AttributeError:
        values = None
    if values is not None:
        rate = args.setdefault('mutation_rate', 0.1)
        mutant = copy.copy(candidate)
        for i, m in enumerate(mutant):
            if random.random() < rate:
                mutant[i] = random.choice(values)
        return mutant
    else:
        return candidate