def new_stage(protocol, stage, valuation, mem):
    new_valuation = new_stage_valuation(protocol, valuation, stage.disabled)

    if is_stable_or_dead(protocol, new_valuation, stage.disabled):
        return Stage(Formula(new_valuation),
                     new_valuation,
                     stage.disabled,
                     speed=Speed.ZERO,
                     parent=stage)

    F, J = eventually_disabled(protocol, new_valuation, stage.disabled, mem)

    # Compute new_formula (Φ) and new_disabled (T)
    if len(F) > 0:
        if len(J) > 0:
            new_disabled = set(stage.disabled) | set(J)
            new_formula = Formula(new_valuation, new_disabled)

            if v_disabled(J, valuation):
                new_formula.assert_valuation(valuation)
            elif v_enabled(J, valuation):
                K = posts_from_pres(protocol, new_valuation, J)
                new_formula.assert_some_pair_present(K)

            # Compute speed
            if is_very_fast(protocol, new_valuation, stage.disabled):
                new_speed = Speed.QUADRATIC
            elif is_fast(protocol, new_valuation, stage.disabled):
                new_speed = Speed.QUADRATIC_LOG
            else:
                new_speed = Speed.CUBIC
        else:
            new_disabled = set(stage.disabled) | set(F)
            new_formula = Formula(new_valuation, new_disabled)
            new_speed = Speed.POLYNOMIAL
    else:
        new_disabled = set(stage.disabled)
        new_formula = Formula(new_valuation, new_disabled)
        new_speed = Speed.EXPONENTIAL

        I = compute_I(protocol, new_valuation, stage.disabled)

        if any(valuation[Var(q)] is True for q in I):
            L = compute_L(protocol, new_valuation, stage.disabled, I)

            new_formula.assert_all_states_absent(I)
            new_formula.assert_some_pair_present(L)
        elif all(valuation[Var(q)] is False for q in I):
            new_formula.assert_valuation(valuation)
        else:
            new_formula.assert_all_states_absent(I)

    return Stage(new_formula,
                 new_valuation,
                 new_disabled,
                 speed=new_speed,
                 parent=stage)