Skip to content

Instantly share code, notes, and snippets.

@bbarker
Last active January 3, 2016 07:19
Show Gist options
  • Save bbarker/d068e38107e4b801b7c5 to your computer and use it in GitHub Desktop.
Save bbarker/d068e38107e4b801b7c5 to your computer and use it in GitHub Desktop.
There are a lot of nice library functions and succinct algorithms in ATS1's ATSLIB, while at the same time, many of these seem to be implemented in ATS2 using templates where possible. It can be helpful to check one's understanding of the ATS1 code by inspection and modification before attempting to port to ATS2. One alternative is to use versio…
//
staload _(*anon*) = "libc/SATS/stdio.sats"
//
staload _(*anon*) = "prelude/DATS/array.dats"
staload _(*anon*) = "prelude/DATS/array0.dats"
//
staload _(*anon*) = "prelude/DATS/list.dats"
staload _(*anon*) = "prelude/DATS/list0.dats"
staload _(*anon*) = "prelude/DATS/list_vt.dats"
//
staload _(*anon*) = "prelude/DATS/matrix.dats"
staload _(*anon*) = "prelude/DATS/matrix0.dats"
//
staload _(*anon*) = "prelude/DATS/option.dats"
staload _(*anon*) = "prelude/DATS/option0.dats"
//
staload _(*anon*) = "prelude/DATS/pointer.dats"
//
staload _(*anon*) = "prelude/DATS/reference.dats"
//
(* ****** ****** *)
#include "libats/DATS/linset_listord.dats"
staload LS = "libats/SATS/linset_listord.sats"
staload LVT = "prelude/SATS/list_vt.sats"
// defined in linset_listord.sats:
//absviewtype
//set_t0ype_viewtype (elt: t@ype+)
//stadef set = set_t0ype_viewtype
//assume
//set_t0ype_viewtype (elt: t@ype) = List_vt (elt)
(**** Print Functions *****)
extern
fun{a:t0p} print_val(x: a):<!ref> void
implement
print_val<int> (x) = print(x)
fn{a:t0p} print_lvt0(xsl: !List_vt (a)):<!ref> void =
begin (
list_vt_foreach_fun<a> (xsl, lam x =<!ref> (print_val<a> (x); print ' '));
print_newline();
) end
fn{a:t0p} print_lvt{n:nat}(xsl: !list_vt (a, n)):<!ref> void =
begin (
list_vt_foreach_fun<a> (xsl, lam x =<!ref> (print_val<a> (x); print ' '));
print_newline();
) end
fun{a:t0p} print_linset(xs: !set (a)): void =
let
// Not ideal to make a copy just to print
// (just for testing purposes)
val xsl = linset_listize(xs)
//
in (
print_lvt(xsl);
list_vt_free (xsl);
) end
(**** End Print Functions *****)
fn cmp (x1: int, x2: int):<cloref> Sgn = compare (x1, x2)
extern
fun{a:t@ype} my_linset_union
(xs1: set a, xs2: set a, cmp: cmp a):<> (* normally <> *) set (a)
implement{a}
my_linset_union
(xs1, xs2, cmp) = let
//
viewtypedef res = List_vt (a)
fun loop
{n1,n2:nat} .<n1+n2>. (
xs1: list_vt (a, n1), xs2: list_vt (a, n2), res: &res? >> res
) :<cloref> (* normally <cloref> *) void = // how to combine <!ref> and <cloref>?
case+ xs1 of
| list_vt_cons (x1, !p_xs1) => ( (*
In this example, x1 is always less than x2. When xs1 is initially
folded (last call to loop before xs1 => list_vt_nil), it includes
x1 = 3 (last member of xs1) and !p_xs1 = {4, 5, 6} (the entire
second list, since res := xs2 according to the list_nil case --
Remember, !p_xs1 is the res argument in loop in this case).
Nothing ever needs to be freed in this case; the two input lists
are disjoint, so the view is altered to include all the data in both
lists.
In ATS2, since we do not need (and can't be default) fold this dataviewtype,
we instead assign res with a list_vt_cons. *)
case+ xs2 of
| list_vt_cons (x2, !p_xs2) => let
val sgn = compare_elt_elt<a> (x1, x2, cmp)
in
if sgn < 0 then let
val xs11 = !p_xs1
val () = $effmask_all(print "xs11: ") //Test
val () = $effmask_all(print_lvt<a> (xs11)) //Test
prval () = fold@ {a} (xs2)
val () = loop (xs11, xs2, !p_xs1)
prval () = fold@ {a} (xs1)
in (
res := xs1;
$effmask_all(print "res: "); //Test
$effmask_all(print_lvt0<a> (res)) //Test
) end else if sgn > 0 then let
prval () = fold@ {a} (xs1)
val xs21 = !p_xs2
val () = $effmask_all(print "xs21: ") //Test
val () = $effmask_all(print_lvt<a> (xs21)) //Test
val () = loop (xs1, xs21, !p_xs2)
prval () = fold@ (xs2)
in
res := xs2
end else let // x1 = x2
val xs11 = !p_xs1
val xs21 = !p_xs2
val () = $effmask_all(print "xs11 ==: ") //Test
val () = $effmask_all(print_lvt<a> (xs11)) //Test
val () = $effmask_all(print "xs21 ==: ") //Test
val () = $effmask_all(print_lvt<a> (xs21)) //Test
val () = free@ {a}{0} (xs2)
val () = loop (xs11, xs21, !p_xs1)
prval () = fold@ (xs1)
in
res := xs1
end // end of [if]
end // end of [list_vt_cons]
| ~list_vt_nil () => (fold@ (xs1); res := xs1)
) // end of [list_vt_cons]
| ~list_vt_nil () => (res := xs2)
// end of [loop]
var res: res // uninitialized
val () = loop (xs1, xs2, res)
in
res
end // end of [linset_union]
implement
$LS.compare_elt_elt<int> (x1, x2, _(*cmp*)) =
if x1 < x2 then ~1 else if x1 > x2 then 1 else 0
implement main () =
let
val xmin = 1
val xmax = 3
val ymin = 4
val ymax = 6
var ints1: $LS.set (int) = $LS.linset_make_nil ()
var ints2: $LS.set (int) = $LS.linset_make_nil ()
var i: int
val () = for (i := xmin; i <= xmax; i := i+1) {
val _ = $LS.linset_insert<int> (ints1, i, cmp)
} (* end of [for] *)
val () = for (i := ymin; i <= ymax; i := i+1) {
val _ = $LS.linset_insert<int> (ints2, i, cmp)
} (* end of [for] *)
val ints_union = my_linset_union (ints1, ints2, cmp)
val () = print_linset<int>(ints_union)
val () = $LS.linset_free (ints_union)
in
print ("On to figuring out the algorithm!"); print_newline ()
end // end of [main]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment