-
-
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…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
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