'Unconstrains an exit to the loop header by looping one more time
and replacing all modified variables with unconstrained versions.'

def unconstrain_loop(self, constrained_entry):

    constrained_state = constrained_entry.state.copy()
    constrained_results = self._tick_loop(start=constrained_entry)
    l.debug('%d    paths    to    header    found', len(constrained_results.found))
    unconstrained_states = []
    for p in constrained_results.found:
        new_state = p.state.copy()
        if self._unconstrain_registers:
            new_state.registers.unconstrain_differences(constrained_state.registers)
        if self._unconstrain_memory:
            new_state.memory.unconstrain_differences(constrained_state.memory)
        unconstrained_states.append(new_state)
    l.debug('%d    unconstrained    states', len(unconstrained_states))
    unconstrained_exits = []
    unconstrained_entry = constrained_entry
    for s in unconstrained_states:
        unconstrained_entry.state = s
        unconstrained_results = self._tick_loop(start=unconstrained_entry)
        unconstrained_exits += unconstrained_results.deviating
    return unconstrained_exits
