import time


def wait_for_computation(predicate, timeout, retry_after):
    """Return wrapped function retrying computation until result satisfies given predicate or timeout is reached."""
    def wrapper(func):
        def compute(*args, time_left=timeout, **kwargs):
            if time_left <= 0:
                raise TimeoutError('Timeout reached!')

            try:
                result = func(*args, **kwargs)
                if predicate(result):
                    return result
                else:
                    time.sleep(retry_after)
                    return compute(*args, time_left=time_left - retry_after, **kwargs)
            except Exception:
                time.sleep(retry_after)
                return compute(*args, time_left=time_left - retry_after, **kwargs)
        return compute
    return wrapper