```//
// Course: BU CAS CS 520, Fall 2010
// Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
// Lecture on Tuesday & Thursday, Oct 19 & 21, 2010
//

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

datatype ilist (int) =
| ilist_nil (0) of ()
// ilist_nil: () -> ilist(0)
| {n:nat} ilist_cons (n+1) of (int, ilist(n))
// ilist_cons: {n:nat} (int, ilist(n) -> ilist (n+1)
// end of [ilist]

extern
fun head {n:int | n > 0} (xs: ilist(n)): int

// val x = head (ilist_nil) // a type error

extern
fun tail {n:int | n > 0} (xs: ilist(n)): ilist(n-1)

(*
(tail (ilist_cons (1, ilist_nil))) // a type error
*)

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

extern
fun ilist_length {n:nat} (xs: ilist(n)): int(n)

implement
ilist_length (xs) = let
fun loop {i,j:nat} .<i>.
(xs: ilist (i), j: int(j)): int(i+j) =
case+ xs of
| ilist_cons (_, xs1) => loop (xs1, j+1)
| ilist_nil () => j
// end of [loop]
in
loop (xs, 0)
end // end of [ilist_length]

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

extern
fun ilist_append {m,n:nat}
(xs: ilist (m), ys: ilist (n)): ilist (m+n)
// end of [ilist_append]

implement
ilist_append (xs, ys) =
case+ xs of
| ilist_cons (x, xs1) => ilist_cons (x, ilist_append (xs1, ys))
| ilist_nil () => ys
// end of [ilist_append]

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

extern
fun ilist_reverse {n:nat}
(xs: ilist (n)): ilist (n) = "ilist_reverse"
// end of [ilist_reverse]

implement
ilist_reverse (xs) =
revapp (xs, ilist_nil) where {
fun revapp {i,j:nat}
(xs: ilist(i), ys: ilist(j)): ilist(i+j) =
case+ xs of
| ilist_cons (x, xs1) => revapp (xs1, ilist_cons (x, ys))
| ilist_nil () => ys
// end of [revapp]
} // end of [ilist_reverse]

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

(* end of [ilist.dats] *)
```