```//
// Course: BU CAS CS 520, Fall 2010
// Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
// Lecture on Tuesday, Nov 4, 2010
//

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

dataview
charr_v_cons (n+1, l) of (char @ l, charr_v (n, l+1))
// end of [charr_v]

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

prfun
charr_v_split
{n,i:nat | i <= n} {l:addr} .<n>.
(pf: charr_v (n, l)): (charr_v (i, l), charr_v (n-i,l+i)) =
sif i == 0 then
(charr_v_nil (), pf)
else let
prval charr_v_cons (pf1, pf2) = pf
prval (pf21, pf22) = charr_v_split {n-1,i-1} (pf2)
in
(charr_v_cons (pf1, pf21), pf22)
end // end of [sif]
// end of [charr_v_split]

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

prfun
charr_v_unsplit
pf1: charr_v (n1, l), pf2: charr_v (n2, l+n1)
) : charr_v (n1+n2, l) =
sif n1 == 0 then let
prval charr_v_nil () = pf1 in pf2
end else let
prval charr_v_cons (pf11, pf12) = pf1
in
charr_v_cons (pf11, charr_v_unsplit (pf12, pf2))
end // end of [sif]

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

extern
prfun
charr_v_takeout1
{n,i:nat | i < n} {l:addr}
(pf: charr_v (n, l))
: (char @ (l+i), char @ (l+i) -<lin> charr_v (n, l))

prfun
charr_v_takeout
{n,i:nat | i < n} {l:addr} .<i>.
(pf: charr_v (n, l))
: (char @ (l+i), char @ (l+i) -<lin> charr_v (n, l)) =
sif i == 0 then let
prval charr_v_cons (pf1, pf2) = pf
in
(pf1, llam pf1 => charr_v_cons (pf1, pf2))
end else let
prval charr_v_cons (pf1, pf2) = pf
prval (pfat, fpf) = charr_v_takeout {n-1,i-1} (pf2)
in
(pfat, llam pfat => charr_v_cons (pf1, fpf (pfat)))
end // end of [sif]

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

(*
fun charr_get
{n,i:nat | i < n} {l:addr} .<n>. (
pf: !charr_v (n, l) | p: ptr l, i: int i
) : char = let
prval (pf1, pf2) = charr_v_split {n,i} (pf)
prval charr_v_cons (pf21, pf22) = pf2
val c = !(p+i)
prval () = pf := charr_v_unsplit (pf1, charr_v_cons (pf21, pf22))
in
c
end // end of [charr_get]
*)

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

fun charr_get
{n,i:nat | i < n} {l:addr} .<n>. (
pf: !charr_v (n, l) | p: ptr l, i: int i
) : char = let
prval (pfat, fpf) = charr_v_takeout {n,i} (pf)
val c = !(p+i)
prval () = pf := fpf (pfat)
in
c
end // end of [charr_get]

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

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