//
// A simple example of programming with proofs
//
// Hongwei Xi (hwxi AT cs DOT BU DOT edu)
// October, 2008
//

dataprop TALLY (int, int) =
  | TALLYbas (0, 0)
  | {n:nat} {r:int} TALLYind (n+1, r+n+1) of TALLY (n, r)

// [tally1] is non-tail-recursive
fun tally1 {n:nat} .<n>.
  (x: int n):<> [r:int] (TALLY (n, r) | int r) =
  if x > 0 then let
    val (pf | res) = tally1 (x-1)
  in
    (TALLYind pf | res + x)
  end else begin
    (TALLYbas () | 0)
  end // end of [if]

// [tally2] is tail-recursive
fun tally2 {n:nat} .<n>.
  (x: int n):<> [r:int] (TALLY (n, r) | int r) = let
  fun loop {n:nat} {r0:int} .<n>. (x: int n, res: int r0)
    :<> [r:int] (TALLY (n, r) | int (r+r0))  =
    if x > 0 then
      let val (pf | res) = loop (x-1, res + x)
    in
      (TALLYind pf | res)
    end else begin
      (TALLYbas () | res)
    end // end of [if]
in
  loop (x, 0)
end // end of [tally2]

(* ****** ****** *)

(* end of [tally-2008-10-23.dats] *)