(*
**
** BU CAS CS520, Fall 2009
**
** Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
**
** Exercise 1 in Assignment 1
**
*)

prfn verify {p:bool | p} (): void = ()

prfun exercise1
  {n:nat} {p:int} .<n>.
  (pf: MUL (2*n+1, 2*n+1, p)): [k:nat | p - 1 == 8*k] void =
  sif n == 0 then let
    prval () = mul_elim {1,1} (pf) in #[0 | ()]
  end else let // n > 0
    prval [p1:int] pf1 = mul_istot {2*n-1,2*n-1} () // pf1: MUL (2*n-1, 2*n-1, p1)
    prval [k1:int] () = exercise1 {n-1} {..} (pf1)  // induction hypothesis: p1-1=8*k1
    // prval () = verify {p1-1==8*k1} ()
    prval pf2 = mul_add_const {2} (pf1) // pf2: MUL (2*n+1, 2*n-1, p1+4*n-2)
    prval pf3 = mul_commute (pf2)       // pf3: MUL (2*n-1, 2*n+1, p1+4*n-2)
    prval pf4 = mul_add_const {2} (pf3) // pf4: MUL (2*n+1, 2*n+1, p1+4*n-2+4*n+2)
    prval () = mul_isfun (pf, pf4)      // p = p1+8*n
    // prval () = verify {p == p1+8*n} ()
  in
    #[k1+n | ()] // p = 8(k1+n)
  end // end of [sif]
// end of [exercise1]

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

(* end of [exercise1.dats] *)