Case 923

The same returns in a different order left less

the_same_returns_in_a_different_order_left_less.eml - Two retirees hold the same fund, earn the same two yearly returns - up twenty and down twenty - and withdraw the same ten at the end of each year. Every return and every withdrawal is real and exactly applied. Why they end with different balances is computed below.

ok: true — round-trip fixpoint reached (python1 == python2)updated 2026-09-19

EML

eml
# Self-authored for the EML case corpus (no external origin). Two retirees hold
# the same fund, earn the same two yearly returns - up twenty and down twenty -
# and withdraw the same ten at the end of each year. Every return and every
# withdrawal is real and exactly applied. Why they end with different balances is
# computed below.
#
# The accounting is careful. Both start with the same balance; both receive
# exactly the same two returns, in different years; both withdraw exactly the
# same amounts; and the intent is exactly 'the same returns give the same
# result'.
#
# Without withdrawals the order does not matter and both end at 96, but a
# withdrawal is taken from whatever the balance is at the time, so whoever meets
# the loss first withdraws from a smaller pot and ends with less.

100 => starting_balance
20 => up_year_percent
20 => down_year_percent
10 => withdrawal_each_year

int(starting_balance * (100 + up_year_percent) / 100) - withdrawal_each_year => a_after_year_one
int(a_after_year_one * (100 - down_year_percent) / 100) - withdrawal_each_year => a_after_year_two
int(starting_balance * (100 - down_year_percent) / 100) - withdrawal_each_year => b_after_year_one
int(b_after_year_one * (100 + up_year_percent) / 100) - withdrawal_each_year => b_after_year_two
a_after_year_two - b_after_year_two => difference_from_order_alone
int(starting_balance * (100 + up_year_percent) / 100) => no_withdrawal_a_year_one
int(no_withdrawal_a_year_one * (100 - down_year_percent) / 100) => no_withdrawal_a_year_two
int(starting_balance * (100 - down_year_percent) / 100) => no_withdrawal_b_year_one
int(no_withdrawal_b_year_one * (100 + up_year_percent) / 100) => no_withdrawal_b_year_two
no_withdrawal_a_year_two - no_withdrawal_b_year_two => difference_without_withdrawals

"starting balance, both          : " + str(starting_balance) ^0
"returns, both                   : up " + str(up_year_percent) + " percent, down " + str(down_year_percent) + " percent" ^0
"withdrawal each year, both      : " + str(withdrawal_each_year) ^0
"" ^0
"A, up first                     : " + str(a_after_year_one) + " then " + str(a_after_year_two) ^0
"B, down first                   : " + str(b_after_year_one) + " then " + str(b_after_year_two) ^0
"difference from order alone     : " + str(difference_from_order_alone) ^0
"" ^0
"without withdrawals, A          : " + str(no_withdrawal_a_year_one) + " then " + str(no_withdrawal_a_year_two) ^0
"without withdrawals, B          : " + str(no_withdrawal_b_year_one) + " then " + str(no_withdrawal_b_year_two) ^0
"difference without withdrawals  : " + str(difference_without_withdrawals) ^0
"" ^0

# ---- what the accounting verified ----

"the two accounts" ^0
"  start : the same " + str(starting_balance) ^0
"  returns : the same two, exactly applied" ^0
"  withdrawals : the same " + str(withdrawal_each_year) + " each year" ^0
"  intent : the same returns give the same result" ^0
"  entries misapplied : 0" ^0
"  verdict : IDENTICAL INPUTS, EXACTLY APPLIED" ^0
"" ^0
"  applying the same returns and withdrawals exactly is the" ^0
"  part done right here, and it is why nothing about either" ^0
"  account is an error" ^0
"" ^0

# ---- why the order matters ----

"withdrawals and sequence" ^0
"  a return multiplies : and multiplication commutes, so" ^0
"    without withdrawals both reach " + str(no_withdrawal_a_year_two) ^0
"  a withdrawal subtracts : from the balance at that moment" ^0
"  B meets the loss first : withdraws " + str(withdrawal_each_year) + " from a pot already" ^0
"    down to " + str(b_after_year_one) + ", and the recovery works on less" ^0
"  A meets the gain first : withdraws from a pot up at " + str(a_after_year_one) ^0
"  so the same returns : leave A " + str(a_after_year_two) + " and B " + str(b_after_year_two) ^0
"" ^0

# ---- what the retirees got ----

"the outcome" ^0
"  A ends with : " + str(a_after_year_two) ^0
"  B ends with : " + str(b_after_year_two) ^0
"  average return, both : zero" ^0
"  is either account misapplied : no" ^0
"  do the same returns give the same result : only with no" ^0
"    cash flows in between, and there were" ^0
"" ^0

# ---- null control ----

# The same two accounts with no withdrawals during the sequence (withdrawals
# from a separate cash reserve), so only the commuting multiplications remain.
4 => nc_difference_with_withdrawals_in_the_sequence
0 => nc_difference_with_withdrawals_from_a_reserve
1 => nc_order_stops_mattering

"null control - take withdrawals from a reserve, not the fund" ^0
"  difference from order, withdrawals in the sequence : " + str(nc_difference_with_withdrawals_in_the_sequence) ^0
"  difference from order, withdrawals from a reserve : " + str(nc_difference_with_withdrawals_from_a_reserve) ^0
"  order stops mattering : " + str(nc_order_stops_mattering) ^0
"  no return and no withdrawal amount changed; the" ^0
"  subtractions stopped landing between the multiplications" ^0
"" ^0

# ---- the rule ----

"what identical returns exactly applied guarantee" ^0
"  both accounts saw the same growth factors : exactly, the" ^0
"    same two returns" ^0
"  both accounts end the same : not addressed; a withdrawal" ^0
"    is taken from the balance at that moment, so meeting the" ^0
"    loss first leaves " + str(b_after_year_two) + " and meeting it second leaves " + str(a_after_year_two) + "," ^0
"    with " + str(difference_without_withdrawals) + " difference when nothing is withdrawn" ^0
"" ^0

"multiplications can be taken in any order and subtractions in between cannot;" ^0
"the average return is the same for both and the path is not, and a pot that" ^0
"is drawn on at its low point never sees the recovery on the full amount" ^0
"" ^0

"Same start, same two returns, same withdrawals, exactly applied - nothing is an" ^0
"error. But each withdrawal comes out of the balance at that moment, so up-then-" ^0
"down leaves " + str(a_after_year_two) + " and down-then-up leaves " + str(b_after_year_two) + ", " + str(difference_from_order_alone) + " apart on an average return" ^0
"of zero, where without withdrawals both end at " + str(no_withdrawal_a_year_two) + ", until the withdrawals leave the sequence." ^0

Python (deterministic transpilation)

python
starting_balance = 100
up_year_percent = 20
down_year_percent = 20
withdrawal_each_year = 10
a_after_year_one = int(starting_balance * (100 + up_year_percent) / 100) - withdrawal_each_year
a_after_year_two = int(a_after_year_one * (100 - down_year_percent) / 100) - withdrawal_each_year
b_after_year_one = int(starting_balance * (100 - down_year_percent) / 100) - withdrawal_each_year
b_after_year_two = int(b_after_year_one * (100 + up_year_percent) / 100) - withdrawal_each_year
difference_from_order_alone = a_after_year_two - b_after_year_two
no_withdrawal_a_year_one = int(starting_balance * (100 + up_year_percent) / 100)
no_withdrawal_a_year_two = int(no_withdrawal_a_year_one * (100 - down_year_percent) / 100)
no_withdrawal_b_year_one = int(starting_balance * (100 - down_year_percent) / 100)
no_withdrawal_b_year_two = int(no_withdrawal_b_year_one * (100 + up_year_percent) / 100)
difference_without_withdrawals = no_withdrawal_a_year_two - no_withdrawal_b_year_two
print("starting balance, both          : " + str(starting_balance))
print("returns, both                   : up " + str(up_year_percent) + " percent, down " + str(down_year_percent) + " percent")
print("withdrawal each year, both      : " + str(withdrawal_each_year))
print("")
print("A, up first                     : " + str(a_after_year_one) + " then " + str(a_after_year_two))
print("B, down first                   : " + str(b_after_year_one) + " then " + str(b_after_year_two))
print("difference from order alone     : " + str(difference_from_order_alone))
print("")
print("without withdrawals, A          : " + str(no_withdrawal_a_year_one) + " then " + str(no_withdrawal_a_year_two))
print("without withdrawals, B          : " + str(no_withdrawal_b_year_one) + " then " + str(no_withdrawal_b_year_two))
print("difference without withdrawals  : " + str(difference_without_withdrawals))
print("")
print("the two accounts")
print("  start : the same " + str(starting_balance))
print("  returns : the same two, exactly applied")
print("  withdrawals : the same " + str(withdrawal_each_year) + " each year")
print("  intent : the same returns give the same result")
print("  entries misapplied : 0")
print("  verdict : IDENTICAL INPUTS, EXACTLY APPLIED")
print("")
print("  applying the same returns and withdrawals exactly is the")
print("  part done right here, and it is why nothing about either")
print("  account is an error")
print("")
print("withdrawals and sequence")
print("  a return multiplies : and multiplication commutes, so")
print("    without withdrawals both reach " + str(no_withdrawal_a_year_two))
print("  a withdrawal subtracts : from the balance at that moment")
print("  B meets the loss first : withdraws " + str(withdrawal_each_year) + " from a pot already")
print("    down to " + str(b_after_year_one) + ", and the recovery works on less")
print("  A meets the gain first : withdraws from a pot up at " + str(a_after_year_one))
print("  so the same returns : leave A " + str(a_after_year_two) + " and B " + str(b_after_year_two))
print("")
print("the outcome")
print("  A ends with : " + str(a_after_year_two))
print("  B ends with : " + str(b_after_year_two))
print("  average return, both : zero")
print("  is either account misapplied : no")
print("  do the same returns give the same result : only with no")
print("    cash flows in between, and there were")
print("")
nc_difference_with_withdrawals_in_the_sequence = 4
nc_difference_with_withdrawals_from_a_reserve = 0
nc_order_stops_mattering = 1
print("null control - take withdrawals from a reserve, not the fund")
print("  difference from order, withdrawals in the sequence : " + str(nc_difference_with_withdrawals_in_the_sequence))
print("  difference from order, withdrawals from a reserve : " + str(nc_difference_with_withdrawals_from_a_reserve))
print("  order stops mattering : " + str(nc_order_stops_mattering))
print("  no return and no withdrawal amount changed; the")
print("  subtractions stopped landing between the multiplications")
print("")
print("what identical returns exactly applied guarantee")
print("  both accounts saw the same growth factors : exactly, the")
print("    same two returns")
print("  both accounts end the same : not addressed; a withdrawal")
print("    is taken from the balance at that moment, so meeting the")
print("    loss first leaves " + str(b_after_year_two) + " and meeting it second leaves " + str(a_after_year_two) + ",")
print("    with " + str(difference_without_withdrawals) + " difference when nothing is withdrawn")
print("")
print("multiplications can be taken in any order and subtractions in between cannot;")
print("the average return is the same for both and the path is not, and a pot that")
print("is drawn on at its low point never sees the recovery on the full amount")
print("")
print("Same start, same two returns, same withdrawals, exactly applied - nothing is an")
print("error. But each withdrawal comes out of the balance at that moment, so up-then-")
print("down leaves " + str(a_after_year_two) + " and down-then-up leaves " + str(b_after_year_two) + ", " + str(difference_from_order_alone) + " apart on an average return")
print("of zero, where without withdrawals both end at " + str(no_withdrawal_a_year_two) + ", until the withdrawals leave the sequence.")

stdout (executed)

text
starting balance, both          : 100
returns, both                   : up 20 percent, down 20 percent
withdrawal each year, both      : 10

A, up first                     : 110 then 78
B, down first                   : 70 then 74
difference from order alone     : 4

without withdrawals, A          : 120 then 96
without withdrawals, B          : 80 then 96
difference without withdrawals  : 0

the two accounts
  start : the same 100
  returns : the same two, exactly applied
  withdrawals : the same 10 each year
  intent : the same returns give the same result
  entries misapplied : 0
  verdict : IDENTICAL INPUTS, EXACTLY APPLIED

  applying the same returns and withdrawals exactly is the
  part done right here, and it is why nothing about either
  account is an error

withdrawals and sequence
  a return multiplies : and multiplication commutes, so
    without withdrawals both reach 96
  a withdrawal subtracts : from the balance at that moment
  B meets the loss first : withdraws 10 from a pot already
    down to 70, and the recovery works on less
  A meets the gain first : withdraws from a pot up at 110
  so the same returns : leave A 78 and B 74

the outcome
  A ends with : 78
  B ends with : 74
  average return, both : zero
  is either account misapplied : no
  do the same returns give the same result : only with no
    cash flows in between, and there were

null control - take withdrawals from a reserve, not the fund
  difference from order, withdrawals in the sequence : 4
  difference from order, withdrawals from a reserve : 0
  order stops mattering : 1
  no return and no withdrawal amount changed; the
  subtractions stopped landing between the multiplications

what identical returns exactly applied guarantee
  both accounts saw the same growth factors : exactly, the
    same two returns
  both accounts end the same : not addressed; a withdrawal
    is taken from the balance at that moment, so meeting the
    loss first leaves 74 and meeting it second leaves 78,
    with 0 difference when nothing is withdrawn

multiplications can be taken in any order and subtractions in between cannot;
the average return is the same for both and the path is not, and a pot that
is drawn on at its low point never sees the recovery on the full amount

Same start, same two returns, same withdrawals, exactly applied - nothing is an
error. But each withdrawal comes out of the balance at that moment, so up-then-
down leaves 78 and down-then-up leaves 74, 4 apart on an average return
of zero, where without withdrawals both end at 96, until the withdrawals leave the sequence.

Trace event types

eml:run:starteml:assigneml:outputeml:run:done