SICP問題3.44

Ben Bitdidddleが考えたお金を口座から口座へ移す手続き

(define (transfer from-account to-account amount)
  ((from-account 'withdraw) amount)
  ((to-account 'deposit) amount))

Louis Reasonerはここに問題があるとしているが、それは正しいか?正しくない場合、移動の問題と交換の問題の本質的な違いがあるか?
from-accountの残高は、少なくともamountであると仮定する
という問題。
前の問題と同様に残高の移動のプロセスを分解して考えると

1. 口座from-accountからの払い出し
1.1. 口座from-accountの残高-amountの金額を算出する
1.2. 口座from-accountの残高を1.1.の金額で更新する
2. 口座to-accountへの預け入れ
2.1. 口座to-accountの残高+amountの金額を算出する
2.2. 口座to-accountの残高を2.1.の金額で更新する

であり、1.と2.はそれぞれ直列化されている
ここで残高がそれぞれ20ドルである x, y, zという口座があると仮定する。
ここでx->yに20ドル, x->zへ10ドル移動するプロセスp1, p2がある場合を考える。
上記のとおり払い出し、預け入れは直列化されているので移動のパターンは以下のとおりとなる。

p1(xから20ドル払い出し) -> p1(yへ20ドル預け入れ) -> p2(xから10ドル払い出し) ->p2(zへ10ドル預け入れ)

p1(xから20ドル払い出し) -> p2(xから10ドル払い出し) -> p1(yへ20ドル預け入れ) ->p2(zへ10ドル預け入れ)

p1(xから20ドル払い出し) -> p2(xから10ドル払い出し) -> p2(zへ10ドル預け入れ)-> p1(yへ20ドル預け入れ) 

p2(xから10ドル払い出し) -> p2(zへ10ドル預け入れ) -> p1(xから20ドル払い出し) -> p1(yへ20ドル預け入れ)

p2(xから10ドル払い出し) -> p1(xから20ドル払い出し) -> p2(zへ10ドル預け入れ) -> p1(yへ20ドル預け入れ)

p2(xから10ドル払い出し) -> p1(xから20ドル払い出し) -> p1(yへ20ドル預け入れ) -> p2(zへ10ドル預け入れ)

この場合、

p1(xから20ドル払い出し) -> p1(yへ20ドル預け入れ) -> p2(xから10ドル払い出し) ->p2(zへ10ドル預け入れ)
=> p1はOK。p2はxの残高不足でNG

p1(xから20ドル払い出し) -> p2(xから10ドル払い出し) -> p1(yへ20ドル預け入れ) ->p2(zへ10ドル預け入れ)
=> p1はOK。p2はxの残高不足でNG

p1(xから20ドル払い出し) -> p2(xから10ドル払い出し) -> p2(zへ10ドル預け入れ)-> p1(yへ20ドル預け入れ) 
=> p1はOK。p2はxの残高不足でNG

p2(xから10ドル払い出し) -> p2(zへ10ドル預け入れ) -> p1(xから20ドル払い出し) -> p1(yへ20ドル預け入れ)
=> p2はOK。p1はxの残高不足でNG

p2(xから10ドル払い出し) -> p1(xから20ドル払い出し) -> p2(zへ10ドル預け入れ) -> p1(yへ20ドル預け入れ)
=> p2はOK。p1はxの残高不足でNG

p2(xから10ドル払い出し) -> p1(xから20ドル払い出し) -> p1(yへ20ドル預け入れ) -> p2(zへ10ドル預け入れ)
=> p2はOK。p1はxの残高不足でNG

となり、並列で動いても特に問題はない。
交換の場合は局所変数differenceを計算する必要があり、交換自体を直列化しないとdifferenceがさまざまな値をとる可能性があったため、問題が発生した。