The function ifact presented in the section on specifying with enhanced precision is a verified implementation of the factorial function as its type guarantees that ifact implements the specification of factorial encoded by the dataprop FACT. Clearly, the implementation of ifact closely follows the declaration of FACT. If we think of the latter as a logic program, then the former is essentially a functional version extracted from the logic program. However, the implementation of a specification in practice can often digress far from the specification algorithmically. For instance, we may want to have a verified implementation of factorial that is also tail-recursive. This can be done as follows:
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]
Please find on-line the entirety of the above presented code plus some testing code.