dataview sllst_v
(a:t@ype, int, addr) =
| {l:addr} sllst_v_nil (a, 0, null)
| {n:nat} {l:addr | l <> null} {l_nxt:addr}
sllst_v_cons (a, n+1, l) of ((a, ptr l_nxt) @ l, sllst_v (a, n, l_nxt))
fun{a:t@ype}
sllst_length {n:nat} {l:addr}
(pf: !sllst_v (a, n, l) | p: ptr l): int n =
if p <> null then let
prval sllst_v_cons (pf_at, pf1) = pf
val n = sllst_length (pf1 | p->1)
prval () = pf := sllst_v_cons (pf_at, pf1)
in
n + 1
end else let
prval sllst_v_nil () = pf
prval () = pf := sllst_v_nil ()
in
0
end
fun{a:t@ype} sllst_append_main
{n1,n2:nat} {l1,l2:addr | l1 <> null} (
pf1: sllst_v (a, n1, l1)
, pf2: sllst_v (a, n2, l2)
| p1: ptr l1, p2: ptr l2
) : (sllst_v (a, n1+n2, l1) | void) = let
prval sllst_v_cons (pf_at, pf1) = pf1
val p1_nxt = p1->1
in
if p1_nxt <> null then let
val (pf | ()) = sllst_append_main (pf1, pf2 | p1_nxt, p2)
in
(sllst_v_cons (pf_at, pf) | ())
end else let
val () = p1->1 := p2
prval sllst_v_nil () = pf1
in
(sllst_v_cons (pf_at, pf2) | ())
end end
fun{a:t@ype} sllst_append
{n1,n2:nat} {l1,l2:addr} (
pf1: sllst_v (a, n1, l1)
, pf2: sllst_v (a, n2, l2)
| p1: ptr l1, p2: ptr l2
) : [l:addr] (sllst_v (a, n1+n2, l) | ptr l) =
if p1 <> null then let
val (pf | ()) = sllst_append_main (pf1, pf2 | p1, p2)
in
(pf | p1)
end else let
prval sllst_v_nil () = pf1
in
(pf2 | p2)
end