//
// Proving f91 (i) = 91 for every integer i <= 100,
// where [f91] is the famous MacCarthy's 91-function.
//
// Hongwei Xi (hwxi AT cs DOT bu DOT edu)
//

(*
** f91 (i) = f91 (f91 (i+11)) if i <= 100
** f91 (i) = i - 10           otherwise
*)

dataprop F91 (int, int) =
  | {i:int | i <= 100} {r1,r2:int}
      F91def1 (i, r2) of (F91 (i+11, r1), F91 (r1, r2))
  | {i:int | i >= 101} F91def2 (i, i-10) of ()

prfun f91_lemma1
  {i:nat | i <= 10} .<i>. (i: int i): F91 (100-i, 91) =
  if i = 0 then begin
    F91def1 (F91def2 {111} (), F91def2 {101} ())
  end else begin
    F91def1 (F91def2 {100-i+11} (), f91_lemma1 (i-1))
  end
// end of [f91_lemma1]
    
prfun f91_lemma2
  {i:int | i <= 100} .<100-i>. (i: int i): F91 (i, 91) =
  if i >= 90 then f91_lemma1 (100-i)
  else begin
    F91def1 (f91_lemma2 (i+11), f91_lemma1 (9))
  end
// end of [f91_lemma2]

extern fun f91 {i:int} (i: int i): [r:int] (F91 (i, r) | int r)

implement f91 (i) = begin
  if i <= 100 then (f91_lemma2 i | 91) else (F91def2 () | i - 10)
end // end of [f91]

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

(* end of [f91-2008-09-30.dats] *)