%{#
#include "libats/CATS/qlist.cats"
%}
#define
ATS_PACKNAME "ATSLIB.libats.qlist"
absvtype
qlist_vtype(a:vt@ype+, n:int) = ptr
vtypedef
qlist(a:vt0p, n:int) = qlist_vtype(a, n)
vtypedef
qlist(a:vt0p) = [n:int] qlist_vtype(a, n)
vtypedef
qlist0(a:vt0p) = [n:int | n >= 0] qlist(a, n)
praxi
lemma_qlist_param
{a:vt0p}{n:int}
(q0: !qlist(INV(a), n)): [n >= 0] void
fun{}
qlist_make_nil{a:vt0p}():<!wrt> qlist(a, 0)
fun{}
qlist_free_nil{a:vt0p}(qlist(a, 0)):<!wrt> void
fun
{a:vt0p}
qlist_length
{n:int}(q0: !qlist(INV(a), n)):<> int(n)
fun{a:vt0p}
qlist_is_nil
{n:int}(q0: !qlist(a, n)):<> bool(n == 0)
fun{a:vt0p}
qlist_isnot_nil
{n:int}(q0: !qlist(INV(a), n)):<> bool(n > 0)
fun{}
fprint_qlist$sep
(out: FILEref): void
fun{a:vt0p}
fprint_qlist
(
out: FILEref, que: !qlist(INV(a))
) : void
fun{a:vt0p}
fprint_qlist_sep
(
out: FILEref, que: !qlist(INV(a)), sep: string
) : void
fun{a:vt0p}
qlist_insert{n:int}
(
que:
!qlist(INV(a), n) >> qlist(a, n+1)
, elt: a
) :<!wrt> void
fun{a:vt0p}
qlist_takeout{n:pos}
(
q0: !qlist(INV(a), n) >> qlist(a, n-1)
) :<!wrt> (a)
fun{a:vt0p}
qlist_takeout_opt
(q0: !qlist(INV(a)) >> _):<!wrt> Option_vt(a)
fun{}
qlist_takeout_list{a:vt0p}{n:int}
(q0: !qlist(INV(a), n) >> qlist(a, 0)):<!wrt> list_vt(a, n)
fun
{a:vt0p}
qlist_foreach(q0: !qlist(INV(a))): void
fun
{a:vt0p}
{env:vt0p}
qlist_foreach_env
(q0: !qlist(INV(a)), env: &(env) >> _): void
fun
{a:vt0p}
{env:vt0p}
qlist_foreach$cont(x0: &a, env: &env): bool
fun
{a:vt0p}
{env:vt0p}
qlist_foreach$fwork(x0: &a >> _, env: &(env) >> _): void
abst@ype
qstruct_tsize =
$extype"atslib_qlist_struct"
absvt@ype
qstruct_vt0ype
(a:vt@ype+, n:int) = qstruct_tsize
stadef
qstruct = qstruct_vt0ype
stadef
qstruct = qstruct_tsize
viewtypedef
qstruct(a:vt0p) = [n:int] qstruct(a, n)
viewtypedef
qstruct0(a:vt0p) = [n:nat] qstruct(a, n)
fun{}
qstruct_initize
{a:vt0p}
(q0: &qstruct? >> qstruct(a, 0)):<!wrt> void
praxi
qstruct_uninitize
{a:vt0p}
( q0: &qstruct(a, 0) >> qstruct? ):<prf> void
praxi
qstruct_objfize
{a:vt0p}
{l:addr}{n:int}
(
pf:
qstruct
(INV(a), n) @ l | p0: !ptrlin(l) >> qlist(a, n)
) :<prf> mfree_ngc_v(l)
praxi
qstruct_unobjfize
{a:vt0p}
{l:addr}{n:int}
(
pf: mfree_ngc_v(l) | p0: ptr(l), q0: !qlist(INV(a), n) >> ptrlin(l)
) :<prf> qstruct(a, n) @ l
fun{a:vt0p}
qstruct_insert{n:int}
(
q0: &qstruct(INV(a), n) >> qstruct(a, n+1), x0: a
) :<!wrt> void
fun{a:vt0p}
qstruct_takeout{n:pos}
(q0: &qstruct(INV(a), n) >> qstruct(a, n-1)):<!wrt> (a)
fun{}
qstruct_takeout_list{a:vt0p}{n:int}
(q0: &qstruct(INV(a), n) >> qstruct(a, 0)):<!wrt> list_vt(a, n)
absvtype
qlist_node_vtype(a:vt@ype+, l:addr) = ptr
stadef
mynode = qlist_node_vtype
vtypedef
mynode(a) = [l:addr] mynode(a, l)
vtypedef
mynode0(a) = [l:addr | l >= null] mynode(a, l)
vtypedef
mynode1(a) = [l:addr | l > null] mynode(a, l)
castfn
mynode2ptr
{a:vt0p}
{l:addr}
(nx: !mynode(INV(a), l)):<> ptr(l)
fun{}
mynode_null{a:vt0p}(): mynode(a, null)
praxi
mynode_free_null{a:vt0p}(nx: mynode(a, null)): void
fun{a:vt0p}
mynode_make_elt(x: a):<!wrt> mynode1(a)
fun{a:vt0p}
mynode_getref_elt(nx: !mynode1(INV(a))):<> cPtr1(a)
fun{a:vt0p}
mynode_free_elt
(nx: mynode1(INV(a)), res: &(a?) >> a):<!wrt> void
fun{a:vt0p}
mynode_getfree_elt(node: mynode1(INV(a))):<!wrt> (a)
fun{a:vt0p}
qlist_insert_ngc
{n:int}
(
q0: !qlist(INV(a), n) >> qlist(a, n+1), nx: mynode1(a)
) :<!wrt> void
fun{a:vt0p}
qlist_takeout_ngc
{n:int | n > 0}
(q0: !qlist(INV(a), n) >> qlist(a, n-1)):<!wrt> mynode1(a)
overload iseqz with qlist_is_nil
overload isneqz with qlist_isnot_nil
overload length with qlist_length
overload fprint with fprint_qlist
overload fprint with fprint_qlist_sep
#define ATS_PACKNAME "ATSLIB.libats.sllist"
typedef SHR(a:type) = a
typedef NSH(a:type) = a
absvtype
sllist_vtype (a:viewt@ype+, n:int) = ptr
stadef sllist = sllist_vtype
vtypedef Sllist (a:vt0p) = [n:int] sllist (a, n)
vtypedef Sllist0 (a:vt0p) = [n:int | n >= 0] sllist (a, n)
vtypedef Sllist1 (a:vt0p) = [n:int | n >= 1] sllist (a, n)
castfn
sllist2ptr {a:vt0p} (xs: !Sllist (INV(a))):<> Ptr0
castfn
sllist2ptr1 {a:vt0p} (xs: !Sllist1 (INV(a))):<> Ptr1
praxi
lemma_sllist_param {a:vt0p}
{n:int} (xs: !sllist (INV(a), n)): [n >= 0] void
fun{}
sllist_nil {a:vt0p} ():<> sllist (a, 0)
praxi
sllist_free_nil
{a:vt0p} (xs: sllist (INV(a), 0)): void
fun{a:vt0p}
sllist_sing (x: a):<!wrt> sllist (a, 1)
fun{a:vt0p}
sllist_cons{n:int}
(x: a, xs: sllist (INV(a), n)):<!wrt> sllist (a, n+1)
fun{a:vt0p}
sllist_uncons{n:int | n > 0}
(xs: &sllist (INV(a), n) >> sllist (a, n-1)):<!wrt> (a)
fun{a:vt0p}
sllist_snoc{n:int}
(xs: sllist (INV(a), n), x: a):<!wrt> sllist (a, n+1)
fun{a:vt0p}
sllist_unsnoc{n:int | n > 0}
(xs: &sllist (INV(a), n) >> sllist (a, n-1)):<!wrt> (a)
fun{a:t0p}
sllist_make_list
{n:int} (xs: list (INV(a), n)):<!wrt> sllist (a, n)
fun{a:t0p}
sllist_make_list_vt
{n:int} (xs: list_vt (INV(a), n)):<!wrt> sllist (a, n)
fun{
} sllist_is_nil
{a:vt0p}{n:int} (xs: !sllist (INV(a), n)):<> bool (n==0)
fun{
} sllist_is_cons
{a:vt0p}{n:int} (xs: !sllist (INV(a), n)):<> bool (n > 0)
overload iseqz with sllist_is_nil
overload isneqz with sllist_is_cons
fun{a:vt0p}
sllist_length
{n:int} (xs: !sllist (INV(a), n)):<> int (n)
overload length with sllist_length
fun{a:t0p}
sllist_get_elt (xs: !Sllist1 (INV(a))): (a)
fun{a:t0p}
sllist_set_elt (xs: !Sllist1 (INV(a)), x0: a): void
fun{a:vt0p}
sllist_getref_elt (xs: !Sllist1 (INV(a))):<> cPtr1 (a)
fun{a:vt0p}
sllist_getref_next (xs: !Sllist1 (INV(a))):<> Ptr1
fun{a:vt0p}
sllist_getref_elt_at {n:int}
(xs: !sllist (INV(a), n), i: natLt(n)):<> cPtr1 (a)
fun{a:t0p}
sllist_get_elt_at {n:int}
(xs: !sllist (INV(a), n), i: natLt(n)):<> (a)
overload [] with sllist_get_elt_at
fun{a:t0p}
sllist_set_elt_at {n:int}
(xs: !sllist (INV(a), n), i: natLt(n), x0: a):<!wrt> void
overload [] with sllist_set_elt_at
fun{a:vt0p}
sllist_getref_at{n:int}
(xs: &sllist (INV(a), n), i: natLte(n)):<> Ptr1
fun{a:vt0p}
sllist_insert_at {n:int}
(xs: sllist (INV(a), n), i: natLte(n), x0: a):<!wrt> sllist (a, n+1)
fun{a:vt0p}
sllist_takeout_at {n:int}
(xs: &sllist (INV(a), n) >> sllist (a, n-1), i: natLt(n)):<!wrt> (a)
fun{a:vt0p}
sllist_append
{n1,n2:int} (
xs1: sllist (INV(a), n1), xs2: sllist (a, n2)
) :<!wrt> sllist (a, n1+n2)
fun{a:vt0p}
sllist_reverse
{n:int} (xs: sllist (INV(a), n)):<!wrt> sllist (a, n)
fun{a:vt0p}
sllist_reverse_append
{n1,n2:int} (
xs1: sllist (INV(a), n1), xs2: sllist (a, n2)
) :<!wrt> sllist (a, n1+n2)
fun{a:t0p}
sllist_free (xs: Sllist (INV(a))):<!wrt> void
fun{a:vt0p}
sllist_freelin$clear (x: &a >> a?):<!wrt> void
fun{a:vt0p}
sllist_freelin (xs: Sllist (INV(a))):<!wrt> void
fun{
a:vt0p}{b:vt0p
} sllist_map$fopr (x: &a): b
fun{
a:vt0p}{b:vt0p
} sllist_map {n:int} (xs: !sllist (a, n)): sllist (b, n)
fun{
a:vt0p}{env:vt0p
} sllist_foreach$cont (x: &a, env: &env): bool
fun{
a:vt0p}{env:vt0p
} sllist_foreach$fwork (x: &a, env: &env >> _): void
fun{a:vt0p}
sllist_foreach (xs: !Sllist (INV(a))): void
fun{
a:vt0p}{env:vt0p
} sllist_foreach_env
(xs: !Sllist (INV(a)), env: &env >> _): void
fun{}
fprint_sllist$sep (out: FILEref): void
fun{a:vt0p}
fprint_sllist
(out: FILEref, xs: !Sllist (INV(a))): void
overload fprint with fprint_sllist
staload "libats/SATS/gnode.sats"
stadef mytkind = $extkind"libats_sllist"
typedef g2node0 (a:vt0p) = gnode0 (mytkind, a)
typedef g2node1 (a:vt0p) = gnode1 (mytkind, a)
fun{a:vt0p}
sllist_cons_ngc{n:int}
(nx: g2node1(a), xs: sllist(INV(a), n)):<!wrt> sllist (a, n+1)
fun{a:vt0p}
sllist_uncons_ngc{n:pos}
(xs: &sllist (INV(a), n) >> sllist (a, n-1)):<!wrt> g2node1 (a)
fun{a:vt0p}
sllist_snoc_ngc{n:int}
(xs: sllist(INV(a), n), nx: g2node1(a)):<!wrt> sllist (a, n+1)
fun{a:vt0p}
sllist_unsnoc_ngc{n:pos}
(xs: &sllist (INV(a), n) >> sllist (a, n-1)):<!wrt> g2node1 (a)
#define
ATS_PACKNAME
"ATSLIB.libats.stklist"
#define
ATS_EXTERN_PREFIX "atslib_"
absvtype
stklist_vtype
(a: vt@ype+, n: int) = ptr
stadef
stklist = stklist_vtype
vtypedef
stklist
(
a:vt0p
) = [n:int] stklist_vtype(a, n)
praxi
lemma_stklist_param
{a:vt0p}{n:int}
(stk: !stklist(INV(a), n)): [n >= 0] void
fun{}
stklist_make_nil
{a:vt0p}():<!wrt> stklist(a, 0)
fun{}
stklist_getfree
{a:vt0p}{n:int}
(stk: stklist(INV(a), n)):<!wrt> list_vt(a, n)
fun{}
stklist_is_nil
{a:vt0p}{n:int}
(stk: !stklist(INV(a), n)):<> bool(n==0)
fun{}
stklist_isnot_nil
{a:vt0p}{n:int}
(stk: !stklist(INV(a), n)):<> bool(n > 0)
fun
{a:vt0p}
stklist_insert
{n:int}
(
stk: !stklist(INV(a), n) >> stklist(a, n+1), x0: a
) :<!wrt> void
fun
{a:vt0p}
stklist_takeout
{n:int | n > 0}
(
stk: !stklist(INV(a), n) >> stklist(a, n-1)
) :<!wrt> (a)
fun
{a:vt0p}
stklist_takeout_opt
(stk: !stklist(INV(a)) >> _):<!wrt> Option_vt(a)
#define
ATS_PACKNAME
"ATSLIB.libats.stkarray"
#define
ATS_EXTERN_PREFIX "atslib_"
%{#
//
#include "libats/CATS/stkarray.cats"
//
%}
absvtype
stkarray_vtype
(a: vt@ype+, m: int, n: int) = ptr
stadef
stkarray = stkarray_vtype
vtypedef
stkarray
(
a:vt0p
) = [m,n:int] stkarray_vtype (a, m, n)
abst@ype
stkarray_tsize = $extype"atslib_stkarray_struct"
praxi
lemma_stkarray_param
{a:vt0p}{m,n:int}
(!stkarray(INV(a), m, n)): [m >= n; n >= 0] void
fun{a:vt0p}
stkarray_make_cap
{m:int} (cap: size_t(m)):<!wrt> stkarray(a, m, 0)
fun
stkarray_make_ngc_tsz
{a:vt0p}
{l:addr}{m:int}
(
stkarray_tsize? @ l
| ptr(l), arrayptr(a?, m), size_t(m), sizeof_t(a)
) :<!wrt> (mfree_ngc_v (l) | stkarray(a, m, 0)) = "mac#%"
fun
stkarray_free_nil
{a:vt0p}{m:int}
(stk: stkarray(a, m, 0)):<!wrt> void = "mac#%"
fun
stkarray_getfree_arrayptr
{a:vt0p}{m,n:int}
(stkarray(INV(a), m, n)):<!wrt> arrayptr(a, n) = "mac#%"
fun{a:vt0p}
stkarray_get_size
{m,n:int} (stk: !stkarray(INV(a), m, n)):<> size_t(n)
fun{a:vt0p}
stkarray_get_capacity
{m,n:int} (stk: !stkarray(INV(a), m, n)):<> size_t(m)
fun
stkarray_get_ptrbeg{a:vt0p}
{m,n:int} (stk: !stkarray(INV(a), m, n)):<> Ptr1 = "mac#%"
fun
stkarray_is_nil
{a:vt0p}{m,n:int}
(stk: !stkarray(INV(a), m, n)):<> bool(n==0) = "mac#%"
fun
stkarray_isnot_nil
{a:vt0p}{m,n:int}
(stk: !stkarray(INV(a), m, n)):<> bool(n > 0) = "mac#%"
fun
stkarray_is_full
{a:vt0p}{m,n:int}
(stk: !stkarray(INV(a), m, n)):<> bool(m==n) = "mac#%"
fun
stkarray_isnot_full
{a:vt0p}{m,n:int}
(stk: !stkarray(INV(a), m, n)):<> bool(m > n) = "mac#%"
fun{}
fprint_stkarray$sep(out: FILEref): void
fun{a:vt0p}
fprint_stkarray
(out: FILEref, stk: !stkarray(INV(a))): void
fun{a:vt0p}
fprint_stkarray_sep
(out: FILEref, stk: !stkarray(INV(a)), sep: string): void
overload fprint with fprint_stkarray
overload fprint with fprint_stkarray_sep
fun{a:vt0p}
stkarray_insert
{m,n:int | m > n}
(
stk:
!stkarray(INV(a), m, n) >> stkarray(a, m, n+1)
, elt: a
) :<!wrt> void
fun{a:vt0p}
stkarray_insert_opt
(stk: !stkarray(INV(a)) >> _, x0: a):<!wrt> Option_vt(a)
fun{a:vt0p}
stkarray_takeout
{m,n:int | n > 0}
(
stk:
!stkarray(INV(a), m, n) >> stkarray(a, m, n-1)
) :<!wrt> (a)
fun{a:vt0p}
stkarray_takeout_opt
(stk: !stkarray(INV(a)) >> _):<!wrt> Option_vt(a)
fun{a:vt0p}
stkarray_getref_top
{m,n:int | n > 0}
(stk: !stkarray(INV(a), m, n)):<> cPtr1(a)
symintr stkarray_getref_at
fun{a:vt0p}
stkarray_getref_at_int
{m,n:int}{i:nat | i < n}
(stk: !stkarray(INV(a), m, n), i: int(i)):<> cPtr1(a)
fun{a:vt0p}
stkarray_getref_at_size
{m,n:int}{i:nat | i < n}
(stk: !stkarray(INV(a), m, n), i: size_t(i)):<> cPtr1(a)
overload stkarray_getref_at with stkarray_getref_at_int
overload stkarray_getref_at with stkarray_getref_at_size
fun{
a:vt0p}{env:vt0p
} stkarray_foreach$cont(x: &a, env: &env): bool
fun{
a:vt0p}{env:vt0p
} stkarray_foreach$fwork(x: &a >> _, env: &(env) >> _): void
fun{
a:vt0p
} stkarray_foreach{m,n:int}
(stk: !stkarray(INV(a), m, n)): sizeLte(n)
fun{
a:vt0p}{env:vt0p
} stkarray_foreach_env{m,n:int}
(stk: !stkarray(INV(a), m, n), env: &(env) >> _): sizeLte(n)
staload
UN = "prelude/SATS/unsafe.sats"
staload "libats/SATS/qlist.sats"
implement
{}
qlist_make_nil
() = pq where {
val (
pf, pfgc | p
) = ptr_alloc<qstruct> ()
val pq = ptr2ptrlin (p)
val () = qstruct_initize (!p)
prval pfngc = qstruct_objfize (pf | pq)
prval () = mfree_gcngc_v_nullify (pfgc, pfngc)
}
implement
{}
qlist_free_nil
{a}(pq) = () where
{
val () = __mfree(pq) where
{
extern fun __mfree
: qlist (a, 0) -<0,!wrt> void = "mac#atspre_mfree_gc"
}
}
implement
{a}
qlist_insert
(pq, x) = let
val nx =
mynode_make_elt<a>(x) in qlist_insert_ngc<a>(pq, nx)
end
implement
{a}
qstruct_insert
(que, x) = let
val pq = addr@(que)
val pq2 = ptr2ptrlin(pq)
prval
pfngc =
qstruct_objfize(view@(que)|pq2)
val () = qlist_insert<a>(pq2, x)
prval pfat = qstruct_unobjfize(pfngc | pq, pq2)
prval () =
(view@(que) := pfat)
prval () = ptrlin_free(pq2)
in
end
implement
{a}
qlist_takeout(pq) = let
val nx0 =
qlist_takeout_ngc(pq) in mynode_getfree_elt<a>(nx0)
end
implement
{a}
qlist_takeout_opt(pq) =
(
if qlist_isnot_nil(pq)
then Some_vt{a}(qlist_takeout(pq)) else None_vt{a}()
)
implement
{a}
qstruct_takeout
(que) = res where
{
val pq = addr@(que)
val pq2 = ptr2ptrlin(pq)
prval
pfngc =
qstruct_objfize(view@(que)|pq2)
val res = qlist_takeout<a>(pq2)
prval pfat = qstruct_unobjfize(pfngc | pq, pq2)
prval () =
(view@(que) := pfat)
prval () = ptrlin_free(pq2)
}
stadef mykind = $extkind"atslib_qlist"
datavtype
qlist_data(a:vt@ype+) = QLIST of (ptr, ptr)
assume
qlist_vtype(a: vt0p, n: int) = qlist_data(a)
implement
{a}
qlist_is_nil
{n} (pq) = let
val+@QLIST (nxf, p_nxr) = pq
val isnil = (addr@(nxf) = p_nxr)
prval () = fold@ (pq)
in
$UN.cast{bool(n==0)}(isnil)
end
implement
{a}
qlist_isnot_nil
{n} (pq) = let
val+@QLIST (nxf, p_nxr) = pq
val isnot = (addr@(nxf) != p_nxr)
prval () = fold@ (pq)
in
$UN.cast{bool(n > 0)}(isnot)
end
implement
{a}
qlist_length
{n} (pq) = let
implement
{a}{ env }
qlist_foreach$cont(x, env) = true
implement
qlist_foreach$fwork<a><int>(x, env) = env := env+1
var env: int = (0)
val () =
$effmask_all(qlist_foreach_env<a><int>(pq, env))
in
$UN.cast{int(n)}(env)
end
implement
{}
fprint_qlist$sep
(out) = fprint_string (out, "->")
implement
{a}
fprint_qlist
(out, pq) = let
implement
{a}{ env }
qlist_foreach$cont
(x, env) = true
implement
qlist_foreach$fwork<a><int>
(x0, env) = let
val () =
if env > 0
then fprint_qlist$sep<>(out)
val () = (env := env + 1)
val () = fprint_ref<a>(out, x0)
in
end
var env: int = 0
in
qlist_foreach_env<a><int>(pq, env)
end
implement
{a}
fprint_qlist_sep
(out, pq, sep) = let
implement
{}
fprint_qlist$sep (out) = fprint_string (out, sep)
in
fprint_qlist<a> (out, pq)
end
implement
{a}{ env }
qlist_foreach$cont(_x_, env) = true
implement
{a}
qlist_foreach(pq) = let
var
env: void = () in qlist_foreach_env<a><void>(pq, env)
end
implement
{a}{ env }
qlist_foreach_env
(pq, env) = let
fun loop
(
p_nxf: ptr, p_nxr: ptr, env: &env
) : void = let
in
if p_nxf != p_nxr then let
val xs =
$UN.ptr0_get<List1_vt(a)>(p_nxf)
val+@list_vt_cons(x1, xs2) = xs
val test =
qlist_foreach$cont<a><env>(x1, env)
val () =
(
if
test
then let
val () =
qlist_foreach$fwork<a><env>(x1, env)
in
loop(addr@(xs2), p_nxr, env)
end
) : void
prval () = fold@ (xs)
prval () = $UN.cast2void(xs)
in
end else ()
end
val+@QLIST(nxf, p_nxr) = pq
val () = loop(addr@(nxf), p_nxr, env)
prval () = fold@(pq)
in
end
implement
{}
qstruct_initize
{a}(que) = let
val pq =
$UN.castvwtp0
{qlist(a,0)}(addr@(que))
val+@QLIST(nxf, p_nxr) = pq
val () = (p_nxr := addr@ (nxf))
prval () = fold@(pq)
prval () =
__assert(que, pq) where
{
extern praxi
__assert (que: &qstruct? >> qstruct(a, 0), pq: qlist(a, 0)): void
}
in
end
extern
castfn
mynode1_encode
{a:vt0p}
(xs: List1_vt(INV(a))):<> mynode1(a)
extern
castfn
mynode1_decode
{a:vt0p}
(nx: mynode1(INV(a))):<> List1_vt(a)
implement
{}
mynode_null{a}() =
$UN.castvwtp0{mynode(a,null)}(list_vt_nil)
implement
{a}
mynode_make_elt (x) =
$UN.castvwtp0{mynode1(a)}(list_vt_cons{a}{0}(x, _))
implement
{a}
mynode_free_elt
(nx, res) = () where
{
val xs =
mynode1_decode(nx)
val+~list_vt_cons(x1, xs2) = xs
val () = (res := x1)
prval () =
__assert (xs2) where {
extern praxi __assert : {vt:vtype} (vt) -<prf> void
}
}
implement
{a}
mynode_getfree_elt
(nx) = (x1) where
{
val xs =
mynode1_decode(nx)
val+~list_vt_cons(x1, xs2) = xs
prval () =
__assert(xs2) where {
extern praxi __assert : {vt:vtype} (vt) -<prf> void
}
}
implement
{a}
qlist_insert_ngc
(pq, nx0) = let
val+@QLIST(nxf, p_nxr) = pq
val xs = mynode1_decode(nx0)
val+@list_vt_cons(_, xs2) = xs
val p2_nxr = addr@(xs2)
prval () = fold@(xs)
val nx0 = mynode1_encode(xs)
val () = $UN.ptr0_set<mynode1(a)>(p_nxr, nx0)
val () = (p_nxr := p2_nxr)
prval () = fold@ (pq)
in
end
implement
{a}
qlist_takeout_ngc
(q0) = nx0 where
{
val+@QLIST(nxf, p_nxr) = q0
val nx0 =
$UN.castvwtp0{mynode1(a)}(nxf)
val xs = mynode1_decode(nx0)
val+@list_vt_cons (_, xs2) = xs
val p2_nxr = addr@(xs2)
prval () = fold@(xs)
val nx0 = mynode1_encode(xs)
val () =
(
if
(p_nxr != p2_nxr)
then
(
nxf := $UN.ptr0_get<ptr>(p2_nxr)
)
else p_nxr := addr@(nxf)
) : void
prval () = fold@ (q0)
}
implement
{}
qlist_takeout_list
{a}{n}(pq) = xs where
{
val+@QLIST(nxf, p_nxr) = pq
val () =
$UN.ptr0_set<ptr>(p_nxr, the_null_ptr)
val xs = $UN.castvwtp0{list_vt(a,n)}(nxf)
val () = p_nxr := addr@(nxf)
prval () = fold@(pq)
}
implement
{}
qstruct_takeout_list
{a}{n}(que) = xs where
{
val pq = addr@(que)
val pq2 = ptr2ptrlin (pq)
prval
pfngc =
qstruct_objfize(view@(que)|pq2)
val xs = qlist_takeout_list(pq2)
prval pfat = qstruct_unobjfize(pfngc | pq, pq2)
prval () =
(view@(que) := pfat)
prval () = ptrlin_free (pq2)
}
staload
UN = "prelude/SATS/unsafe.sats"
staload "libats/SATS/gnode.sats"
staload "libats/SATS/sllist.sats"
#define nullp the_null_ptr
extern
fun{a:vt0p}
g2node_make_elt
(x: a):<!wrt> g2node1(a)
extern
fun{a:t0p}
g2node_free
(nx: g2node1(INV(a))):<!wrt> void
extern
fun{a:vt0p}
g2node_freelin
(nx: g2node1(INV(a))):<!wrt> void
extern
fun{a:vt0p}
g2node_free_elt
(
nx: g2node1(INV(a)), res: &(a?) >> a
) :<!wrt> void
extern
fun{a:vt0p}
g2node_getfree_elt(nx: g2node1(INV(a))):<!wrt>(a)
extern
castfn
sllist0_encode
{a:vt0p}{n:int}
(nx: g2node0(INV(a))) :<> sllist(a, n)
extern
castfn
sllist0_decode
{a:vt0p}{n:int}
(xs: sllist(INV(a), n)) :<> g2node0(a)
extern
castfn
sllist1_encode
{a:vt0p}{n:int | n > 0}
(nx: g2node1(INV(a))) :<> sllist(a, n)
extern
castfn
sllist1_decode
{a:vt0p}{n:int | n > 0}
(xs: sllist(INV(a), n)) :<> g2node1(a)
implement
{}
sllist_nil() = sllist0_encode(gnode_null())
implement
{a}
sllist_sing(x) = sllist_cons<a>(x, sllist_nil())
implement
{a}
sllist_cons
(x, xs) = let
val nx =
g2node_make_elt<a>(x) in sllist_cons_ngc<a>(nx, xs)
end
implement{a}
sllist_uncons
(xs) = let
val nx0 =
sllist_uncons_ngc<a>(xs) in g2node_getfree_elt<a>(nx0)
end
implement
{a}
sllist_snoc
(xs, x) = let
val nx = g2node_make_elt<a> (x) in sllist_snoc_ngc (xs, nx)
end
implement{a}
sllist_unsnoc
(xs) = let
val nx0 = sllist_unsnoc_ngc (xs) in g2node_getfree_elt<a> (nx0)
end
implement
{a}
sllist_make_list
{n}(xs) = let
fun loop (
nx0: g2node1 (a), xs: List (a)
) : void = let
in
case+ xs of
| list_cons
(x, xs) => let
val nx1 = g2node_make_elt<a> (x)
val () = gnode_link11 (nx0, nx1)
in
loop (nx1, xs)
end
| list_nil () => let
val () = gnode_set_next_null (nx0)
in
end
end
in
case+ xs of
| list_cons
(x, xs) => let
val nx0 = g2node_make_elt<a> (x)
val () = $effmask_all (loop (nx0, xs))
in
sllist0_encode (nx0)
end
| list_nil () => sllist_nil ()
end
implement
{a}
sllist_make_list_vt
{n}(xs) = $UN.castvwtp0{sllist(a,n)}(xs)
implement
{}
sllist_is_nil
{a}{n} (xs) = let
val nxs = $UN.castvwtp1{g2node0(a)}(xs)
in
$UN.cast{bool(n==0)}(gnodelst_is_nil (nxs))
end
implement
{}
sllist_is_cons
{a}{n} (xs) = let
val nxs = $UN.castvwtp1{g2node0(a)}(xs)
in
$UN.cast{bool(n > 0)}(gnodelst_is_cons (nxs))
end
implement
{a}
sllist_length
{n} (xs) = let
val nxs = $UN.castvwtp1{g2node0(a)}(xs)
in
$UN.cast{int(n)}(gnodelst_length (nxs))
end
implement
{a}
sllist_get_elt
(xs) = let
val p_elt =
sllist_getref_elt (xs) in $UN.cptr_get<a> (p_elt)
end
implement
{a}
sllist_set_elt
(xs, x0) = let
val p_elt =
sllist_getref_elt (xs) in $UN.cptr_set<a> (p_elt, x0)
end
implement
{a}
sllist_getref_elt (xs) = let
val nxs =
$UN.castvwtp1{g2node1(a)}(xs) in gnode_getref_elt (nxs)
end
implement
{a}
sllist_getref_next (xs) = let
val nxs =
$UN.castvwtp1{g2node1(a)}(xs) in cptr2ptr (gnode_getref_next (nxs))
end
implement
{a}
sllist_get_elt_at
(xs, i) = let
val p_elt =
sllist_getref_elt_at (xs, i) in $UN.cptr_get<a> (p_elt)
end
implement
{a}
sllist_set_elt_at
(xs, i, x0) = let
val p_elt =
sllist_getref_elt_at (xs, i) in $UN.cptr_set<a> (p_elt, x0)
end
implement
{a}
sllist_getref_elt_at
(xs, i) = let
fun loop
(
nxs: g2node1 (a), i: int
) : g2node1 (a) =
if i > 0 then let
val nxs = gnode_get_next (nxs)
in
loop ($UN.cast{g2node1(a)}(nxs), i-1)
end else nxs
val nxs0 = $UN.castvwtp1{g2node1(a)}(xs)
val nxs_i = $effmask_all (loop (nxs0, i))
in
gnode_getref_elt (nxs_i)
end
implement
{a}
sllist_getref_at (xs, i) = let
fun loop (
p: Ptr1, i: int
) : Ptr1 = let
in
if i > 0 then let
val nx =
$UN.ptr1_get<g2node1(a)> (p)
val p2 = gnode_getref_next (nx)
in
loop (cptr2ptr (p2), i-1)
end else (p)
end
val p0 = $UN.cast{Ptr1}(addr@(xs))
in
$effmask_all (loop (p0, i))
end
implement
{a}
sllist_insert_at
{n} (xs, i, x0) = let
var xs = xs
val p_i = sllist_getref_at (xs, i)
val nx0 = g2node_make_elt<a> (x0)
val nxs = $UN.ptr1_get<g2node0(a)> (p_i)
val () = gnode_link10 (nx0, nxs)
val () = $UN.ptr1_set<g2node1(a)> (p_i, nx0)
in
$UN.castvwtp0{sllist(a, n+1)}(xs)
end
implement
{a}
sllist_takeout_at
{n} (xs, i) = let
val p_i = sllist_getref_at (xs, i)
val nxs = $UN.ptr1_get<g2node1(a)> (p_i)
val nx0 = nxs
val nxs = gnode_get_next (nx0)
val () = $UN.ptr1_set<g2node0(a)> (p_i, nxs)
prval (
) = __assert (xs) where {
extern praxi __assert (xs: &sllist (a, n) >> sllist (a, n-1)): void
}
in
g2node_getfree_elt (nx0)
end
implement
{a}
sllist_append
{n1,n2} (xs1, xs2) = let
prval() = lemma_sllist_param(xs1)
prval() = lemma_sllist_param(xs2)
val iscons1 = sllist_is_cons(xs1)
in
if
iscons1
then let
val iscons2 = sllist_is_cons(xs2)
in
if iscons2 then let
val nxs1 = sllist1_decode (xs1)
val nxs2 = sllist0_decode (xs2)
val nxs1_end = gnodelst_next_all (nxs1)
val _void_ = gnode_link10 (nxs1_end, nxs2)
in
sllist0_encode (nxs1)
end else let
prval () = sllist_free_nil (xs2) in xs1
end
end else let
prval () = sllist_free_nil (xs1) in xs2
end
end
implement
{a}
sllist_reverse (xs) = let
in
sllist_reverse_append (xs, sllist_nil ())
end
implement
{a}
sllist_reverse_append
(xs1, xs2) = let
fun loop
(
nxs: g2node0 (a), res: g2node1 (a)
) : g2node1 (a) = let
val iscons = gnodelst_is_cons (nxs)
in
if
iscons
then let
val nx0 = nxs
val nxs = gnode_get_next (nx0)
val () = gnode_link11 (nx0, res)
in
loop (nxs, nx0)
end else res
end
prval (
) = lemma_sllist_param (xs1)
val iscons = sllist_is_cons (xs1)
in
if
iscons
then let
val nxs1 = sllist1_decode (xs1)
val nx0 = nxs1
val nxs1 = gnode_get_next (nx0)
val () = gnode_link10 (nx0, sllist0_decode (xs2))
in
sllist0_encode ($effmask_all (loop (nxs1, nx0)))
end else let
prval () = sllist_free_nil (xs1)
in
xs2
end
end
implement
{a}
sllist_free
(xs) = let
fun
loop
(
nxs: g2node0(a)
) : void = let
val
iscons =
gnodelst_is_cons(nxs)
in
if
iscons
then let
val nxs2 =
gnode_get_next(nxs)
val () = g2node_free<a>(nxs)
in
loop(nxs2)
end else ()
end
val nxs = sllist0_decode(xs)
in
$effmask_all (loop(nxs))
end
implement
{a}
sllist_freelin
(xs) = let
implement
(a2)
gclear_ref<a2>(x0) =
{
prval () = $UN.castview2void_at(view@x0)
val () = sllist_freelin$clear<a>(x0)
prval () = $UN.castview2void_at(view@x0)
}
fun
loop
(
nxs: g2node0(a)
) : void = let
val
iscons =
gnodelst_is_cons(nxs)
in
if
iscons
then let
val nxs2 =
gnode_get_next(nxs)
val () = g2node_freelin<a>(nxs)
in
loop(nxs2)
end else ()
end
val nxs = sllist0_decode(xs)
in
$effmask_all(loop(nxs))
end
implement
{a}{b}
sllist_map{n}(xs) = let
fun
loop
(
nxs: g2node0(a), p_res: ptr
) : void = let
val
iscons = gnodelst_is_cons(nxs)
in
if
iscons
then let
val nx = nxs
val nxs = gnode_get_next(nx)
val p_x = gnode_getref_elt(nx)
val (pf, fpf | p_x) = $UN.cptr_vtake{a}(p_x)
val y = sllist_map$fopr<a><b>(!p_x)
prval () = fpf(pf)
val ny = g2node_make_elt<b>(y)
val () = $UN.ptr0_set<g2node1(b)>(p_res, ny)
val p_res = gnode_getref_next(ny)
in
loop (nxs, cptr2ptr(p_res))
end else ()
end
var res: ptr
val () = loop ($UN.castvwtp1{g2node0(a)}(xs), addr@(res))
in
$UN.castvwtp0{sllist(b,n)}(res)
end
implement
{a}{env}
sllist_foreach_env
(xs, env) = let
fun loop (
nxs: g2node0 (a), env: &env
) : void = let
val iscons = gnodelst_is_cons (nxs)
in
if iscons then let
val nx0 = nxs
val nxs = gnode_get_next (nxs)
val p_elt = gnode_getref_elt (nx0)
val (pf, fpf | p_elt) = $UN.cptr_vtake {a} (p_elt)
val test = sllist_foreach$cont (!p_elt, env)
in
if test then let
val () = sllist_foreach$fwork (!p_elt, env)
prval () = fpf (pf)
in
loop (nxs, env)
end else let
prval () = fpf (pf)
in
end
end else ()
end
val nxs = $UN.castvwtp1{g2node0(a)}(xs)
in
loop (nxs, env)
end
implement
{}
fprint_sllist$sep
(out) = fprint_string (out, "->")
implement
{a}
fprint_sllist (out, xs) = let
fun loop (
out: FILEref, nxs: g2node0 (a), i: int
) : void = let
val iscons = gnodelst_is_cons (nxs)
in
if iscons then let
val nx0 = nxs
val nxs = gnode_get_next (nx0)
val () =
if i > 0 then fprint_sllist$sep (out)
val p_elt = gnode_getref_elt (nx0)
val (pf, fpf | p_elt) = $UN.cptr_vtake {a} (p_elt)
val () = fprint_ref (out, !p_elt)
prval () = fpf (pf)
in
loop (out, nxs, i+1)
end
end
val nxs = $UN.castvwtp1{g2node0(a)}(xs)
in
loop (out, nxs, 0)
end
datavtype
slnode_vtype
(a:vt@ype+) = SLNODE of (a, ptr)
vtypedef slnode (a:vt0p) = slnode_vtype (a)
extern
praxi slnode_vfree {a:vt0p} (nx: slnode (a)): void
extern
castfn
g2node_decode {a:vt0p} (nx: g2node1 (INV(a))):<> slnode (a)
extern
castfn
g2node_encode {a:vt0p} (nx: slnode (INV(a))):<> g2node1 (a)
implement
{a}
g2node_make_elt
(x) = let
in
$UN.castvwtp0{g2node1(a)}(SLNODE{a}(x, _))
end
implement
{a}
g2node_free(nx) = let
val nx =
g2node_decode (nx)
val+~SLNODE (_, _) = (nx) in
end
implement
{a}
g2node_freelin(nx) = let
val nx =
g2node_decode (nx)
val+@SLNODE(x0, _) = (nx)
val () = gclear_ref<a>(x0) in free@{a}(nx)
end
implement
{a}
g2node_free_elt
(nx, res) = let
val nx = g2node_decode (nx)
val~SLNODE (x, _) = (nx); val () = res := x in
end
implement
{a}
g2node_getfree_elt
(nx) = let
val nx = g2node_decode (nx)
val~SLNODE (x, _) = (nx) in x
end
implement(a)
gnode_getref_elt<mytkind><a>
(nx) = let
val nx = g2node_decode (nx)
val+@SLNODE (elt, _) = nx
val p_elt = addr@ (elt)
prval () = fold@ (nx)
prval () = slnode_vfree (nx)
in
$UN.cast{cPtr1(a)}(p_elt)
end
implement(a)
gnode_getref_next<mytkind><a>
(nx) = let
val nx = g2node_decode (nx)
val+@SLNODE (_, next) = nx
val p_next = addr@ (next)
prval () = fold@ (nx)
prval () = slnode_vfree (nx)
in
$UN.cast{cPtr1(g2node0(a))}(p_next)
end
implement(a)
gnode_link10<mytkind><a>
(nx1, nx2) = gnode_set_next (nx1, nx2)
implement(a)
gnode_link11<mytkind><a>
(nx1, nx2) = gnode_set_next (nx1, nx2)
implement
{a}
sllist_cons_ngc
(nx0, xs) = let
val nxs = sllist0_decode (xs)
val _void_ = gnode_link10 (nx0, nxs)
in
sllist0_encode (nx0)
end
implement
{a}
sllist_uncons_ngc
(xs) = let
val nxs = sllist1_decode (xs)
val nxs2 = gnode_get_next (nxs)
val _void_ = xs := sllist0_encode (nxs2)
in
nxs
end
implement
{a}
sllist_snoc_ngc
{n} (xs, nx0) = let
vtypedef res = sllist(a,n+1)
val () = gnode_set_next_null (nx0)
val nxs = sllist0_decode (xs)
val iscons = gnodelst_is_cons (nxs)
in
if iscons then let
val nx_end = gnodelst_next_all (nxs)
val _void_ = gnode_link11 (nx_end, nx0)
in
$UN.castvwtp0{res}(nxs)
end else
$UN.castvwtp0{res}(nx0)
end
implement
{a}
sllist_unsnoc_ngc
{n} (xs) = let
fun loop
(
xs: &Sllist1 (a) >> Sllist0(a)
) : g2node1(a) = let
val p = sllist_getref_next (xs)
val (pf, fpf | p) = $UN.ptr_vtake{Sllist0(a)}(p)
val iscons = sllist_is_cons (!p)
in
if iscons
then let
val res = loop (!p)
prval () = fpf (pf) in res
end
else let
prval () = fpf (pf)
val nx = $UN.castvwtp0{g2node1(a)}(xs)
val () = xs := sllist_nil{a}() in nx
end
end
val res = $effmask_all (loop (xs))
prval [l:addr] EQADDR () = eqaddr_make_ptr (addr@xs)
prval () = view@xs := $UN.castview0{sllist(a,n-1)@l}(view@xs)
in
res
end
#define
ATS_PACKNAME
"ATSLIB.libats.stklist"
#define
ATS_DYNLOADFLAG 0
#define
ATS_EXTERN_PREFIX "atslib_"
staload
UN = "prelude/SATS/unsafe.sats"
staload "libats/SATS/stklist.sats"
assume
stklist_vtype
(a:vt0p, n:int) = aPtr1(list_vt(a, n))
implement
{}
stklist_make_nil
{a}() =
(
aptr_make_elt<
list_vt(a,0)>(list_vt_nil)
)
implement
{}
stklist_getfree
{a}{n}(stk) =
aptr_getfree_elt<list_vt(a,n)>(stk)
implement
{}
stklist_is_nil
{a}{n}(stk) = isnil where
{
val p0 = $UN.castvwtp1{ptr}(stk)
val xs = $UN.ptr0_get<list_vt(a,n)>(p0)
val isnil = list_vt_is_nil(xs)
prval () = $UN.cast2void(xs)
}
implement
{}
stklist_isnot_nil
{a}{n}(stk) = iscons where
{
val p0 = $UN.castvwtp1{ptr}(stk)
val xs = $UN.ptr0_get<list_vt(a,n)>(p0)
val iscons = list_vt_is_cons(xs)
prval () = $UN.cast2void(xs)
}
implement
{a}
stklist_insert
{n}(stk, x0) = let
prval
() =
lemma_stklist_param(stk)
val xs =
aptr_get_elt<list_vt(a,n)>(stk)
val xs = list_vt_cons(x0, xs)
in
aptr_set_elt<list_vt(a,n+1)>(stk, xs)
end
implement
{a}
stklist_takeout
{n}(stk) = x0 where
{
val xs =
aptr_get_elt<list_vt(a,n)>(stk)
val+~list_vt_cons(x0, xs) = xs
val () = aptr_set_elt<list_vt(a,n-1)>(stk, xs)
}
implement
{a}
stklist_takeout_opt
(stk) = let
prval
() =
lemma_stklist_param(stk)
val xs =
aptr_get_elt<List0_vt(a)>(stk)
in
case+ xs of
| list_vt_nil
(
) => None_vt() where
{
val () = aptr_set_elt(stk, xs)
}
| ~list_vt_cons
(
x0, xs
) => Some_vt(x0) where
{
val () = aptr_set_elt(stk, xs)
}
end
#define
ATS_PACKNAME
"ATSLIB.libats.stkarray"
#define
ATS_DYNLOADFLAG 0
#define
ATS_EXTERN_PREFIX "atslib_"
staload
UN = "prelude/SATS/unsafe.sats"
staload "libats/SATS/stkarray.sats"
implement
{a}
stkarray_make_cap
(cap) = stk where
{
val A = arrayptr_make_uninitized<a>(cap)
val
(pfat, pfgc | p) = ptr_alloc<stkarray_tsize>()
val (pfngc | stk) =
stkarray_make_ngc_tsz{a}(pfat | p, A, cap, sizeof<a>)
prval () = mfree_gcngc_v_nullify(pfgc, pfngc)
}
local
extern
fun
stkarray_get_size_tsz
{a:vt0p}{m,n:int}
(
stk: !stkarray (a, m, n), sizeof_t(a)
) :<> size_t(n) = "mac#%"
extern
fun
stkarray_get_capacity_tsz
{a:vt0p}{m,n:int}
(
stk: !stkarray (a, m, n), sizeof_t(a)
) :<> size_t(m) = "mac#%"
in
implement
{a}
stkarray_get_size
(stk) =
stkarray_get_size_tsz{a}(stk, sizeof<a>)
implement
{a}
stkarray_get_capacity
(stk) =
stkarray_get_capacity_tsz{a}(stk, sizeof<a>)
end
implement
{}
fprint_stkarray$sep
(out) = fprint (out, "<-")
implement
{a}
fprint_stkarray
(out, stk) = let
val n =
stkarray_get_size<a>(stk)
prval
[n:int]
EQINT() = eqint_make_guint(n)
implement
fprint_array$sep<>
(out) = fprint_stkarray$sep<>(out)
val
p_beg =
stkarray_get_ptrbeg{a}(stk)
val
(pf,fpf|p_beg) =
$UN.ptr_vtake{array(a,n)}(p_beg)
val () = fprint_array<a>(out, !p_beg, n)
prval () = fpf(pf)
in
end
implement
{a}
fprint_stkarray_sep
(out, stk, sep) = let
implement
{}
fprint_stkarray$sep
(out) = fprint_string(out, sep)
in
fprint_stkarray<a> (out, stk)
end
extern fun
stkarray_get_ptrcur{a:vt0p}
{m,n:int} (stk: !stkarray (INV(a), m, n)):<> ptr = "mac#%"
extern fun
stkarray_set_ptrcur{a:vt0p}
{m,n:int} (stk: !stkarray (INV(a), m, n), ptr):<!wrt> void = "mac#%"
implement
{a}
stkarray_insert
{m,n}(stk, x0) = let
val p_cur =
stkarray_get_ptrcur{a}(stk)
val () =
$UN.ptr0_set<a>(p_cur, x0)
val () =
stkarray_set_ptrcur{a}(stk, ptr_succ<a>(p_cur))
prval () = __assert (stk) where
{
extern
praxi
__assert
(!stkarray(a, m, n) >> stkarray(a, m, n+1)): void
}
in
end
implement
{a}
stkarray_insert_opt
(stk, x0) = let
val
isnot = stkarray_isnot_full{a}(stk)
in
if
isnot
then let
val () = stkarray_insert<a>(stk, x0) in None_vt()
end else Some_vt{a}(x0)
end
implement
{a}
stkarray_takeout
{m,n} (stk) = x0 where
{
val p_cur =
stkarray_get_ptrcur{a}(stk)
val p1_cur = ptr_pred<a>(p_cur)
val x0 = $UN.ptr0_get<a>(p1_cur)
val () = stkarray_set_ptrcur{a}(stk, p1_cur)
prval () = __assert (stk) where
{
extern
praxi
__assert
(!stkarray(a, m, n) >> stkarray(a, m, n-1)): void
}
}
implement
{a}
stkarray_takeout_opt
(stk) = let
val
isnot = stkarray_isnot_nil{a}(stk)
in
if
isnot
then let
val x0 =
stkarray_takeout<a>(stk) in Some_vt{a}(x0)
end else None_vt()
end
implement
{a}{env}
stkarray_foreach$cont(x, env) = true
implement
{a}
stkarray_foreach
(stk) = let
var env: void = () in
stkarray_foreach_env<a><void>(stk, env)
end
implement
{a}{env}
stkarray_foreach_env
(stk, env) = let
implement
array_rforeach$cont<a><env>
(x, env) =
stkarray_foreach$cont<a><env>(x, env)
implement
array_rforeach$fwork<a><env>
(x, env) =
stkarray_foreach$fwork<a><env>(x, env)
val n =
stkarray_get_size<a>(stk)
prval
[
n:int
] EQINT() = eqint_make_guint(n)
val p0 = stkarray_get_ptrbeg{a}(stk)
val (pf,fpf|p0) = $UN.ptr0_vtake{array(a,n)}(p0)
val res = array_rforeach_env<a><env>(!p0, n, env)
in
let prval () = fpf(pf) in res end
end