specifying with enhanced precision の章で示した関数 ifact は階乗関数の検証された実装の一つでした。 その型は ifact が dataprop FACT にエンコードされた階乗の仕様を実装していることを保証しています。 明確に、ifact の実装は FACT の宣言にきっちり従っています。 もし後者をロジックプログラムと考えれば、本質的に前者はロジックプログラムから展開された関数的なバージョンです。 けれども、仕様の実装の実際はアルゴリズム的な仕様からしばしば遠く外れたものになることがあります。 例えば、階乗の検証された実装を末尾再帰として得たいかもしれません。 これは次のようになるでしょう:
fun ifact2 {n:nat} .<>. ( n: int (n) ) :<> [r:int] (FACT(n, r) | int r) = let fun loop {i:nat|i <= n}{r:int} .<n-i>. ( pf: FACT(i, r) | n: int n, i: int i, r: int r ) :<> [r:int] (FACT(n, r) | int r) = if n - i > 0 then let val (pfmul | r1) = imul2 (i+1, r) in loop (FACTind(pf, pfmul) | n, i+1, r1) end else (pf | r) // end of [if] // end of [loop] in loop (FACTbas() | n, 0, 1) end // end of [ifact2]
fun ifact2 (n) = let fun loop (n, i, r) = if n - i > 0 then let val r1 = (i+1) * r in loop (n, i+1, r1) end else r // end of [if] // end of [loop] in loop (n, 0, 1) end // end of [ifact2]
この章のコード全体とテストコードは オンライン から入手できます。