fun grexp_to_string(e0: GREXP): string = case+ e0 of | GRconj (e1, e2) => let val epar = @(e1,e2) in case+ epar of | @(GRgenes (s1), GRgenes (s2)) => stringInOpIze(s1,"and") + " and " + stringInOpIze(s2,"and")
Question 1: What is the right way to pass by reference in this situation (it seems a waste to be passing around entire sets by value)?:stringInOpIze (gset: &genes, inop: string): string
Question 2: What might this error mean in the following code? I presume it has something to do with me not handling the consumption of s1 and s2.error(3): the linear dynamic variable [_.view] needs to be consumed but it is preserved with the type [S2Eapp(S2Ecst(at_viewt0ype_addr_view); S2Etop(1; S2Eapp(S2Ecst(set_t0ype_type); S2Ecst(string_type))), S2Evar(_(11041)))] instead.
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"//
(* ********************************* Begin CODE ******************************** *)
staload "prelude/SATS/string.sats"staload "prelude/SATS/filebas.sats"staload "prelude/SATS/printf.sats"staload "libc/SATS/stdio.sats"staload "prelude/SATS/integer.sats"staload "prelude/SATS/list.sats"
staload "libats/SATS/linset_avltree.sats" staload _ = "libats/DATS/linset_avltree.dats"
staload "sstream.sats"dynload "sstream.dats"
#define NUL '\000'
viewdef genes = set(string)
dataviewtype GREXP = | GRgenes of genes | GRconj of (GREXP, GREXP) | GRdisj of (GREXP, GREXP)
//extern//fun stringInOpIze (gset: genes, inop:string): string
//implement fun stringInOpIze (gset: !genes, inop: string): string = let val glist:List(string) = list_of_list_vt(linset_listize (gset)) fun loop(astr:string, alist:List(string)): string = case+ alist of | list_nil () => "" | list_cons(x,xs) => loop(astr + " " + inop + " " + x, xs ) in loop("",glist) end
//implement
fun print_pretty_grexp (grexp: !GREXP): void = () where {(* Idea is to put parentheses around a sequence of disjunctions, to improve the ease of identifying conjunctions and disjunctions, and improve readability in general. *) fun grexp_to_string(e0: !GREXP): string = case+ e0 of
| GRconj (!e1, !e2) => (case+ (!e1, !e2) of | (GRgenes (!s1), GRgenes (!s2)) => let
val _ = $showtype e0
val x = stringInOpIze(!s1,"and") + " and " + stringInOpIze(!s2,"and") prval () = fold@ !e1 and () = fold@ !e2 and () = fold@ e0 in x end | (GRgenes (!s1), GRconj(_,_)) => let val x = stringInOpIze(!s1,"and") + " and " val y = grexp_to_string(!e2) prval () = fold@ !e1 prval () = fold@ e0 in x + y end
val y = grexp_to_string(!e2)
(*
Hello,
inspired by the above question, I've cooked up an annotated example for dataviewtypes to illustrate the states of bindings (how/when certain bindings are usable/accessible) inside patterns. If I understand correctly, the general rule is, that whenever some binding x has been unfolded/deconstructed/matched by a pattern, it has to be fold@ed, to be accessible as x again. In case an "as" clause is used, e.g.
case+ d0 of
| dvt_1 ( !d1 as dvt_2(!d11,!d12) )
as below, !d1 is unfolded/deconstructed directly, and only accessible/usable as !d1 after fold@ing it again. As you see I'm having difficulty with the correct terminology for these state transitions, it might be helpful to come up with some kind of glossary for these things, to ease communication.
regards, Johann
*)
dataviewtype dvt = | dvt_0 of () | dvt_1 of (dvt) | dvt_2 of (dvt,dvt)
// (a)ccessible/usable// (u)nfolded// (f)olded// (n)o view available// (-) not in scope// d0 d1 d11 d12 d121// -----------------------fun use_dvt(d0: !dvt):void = case+ d0 of // a - - - - | dvt_1 ( !d1 as dvt_2(!d11,!d12) ) => let // u u a a - val () = case+ (!d11,!d12) of // | (dvt_0(), dvt_1(!d121)) => let // u u u u a prval () = fold@ !d11 and () = fold@ !d12 // u u af af n in end // | (_,_) => () // prval () = fold@ !d1 // u af n n - prval () = fold@ d0 // af n n n - in end// d0 d1 d2 d11 d12// ----------------------- | dvt_2 ( !d1, !d2 ) => // u a a (case+ !d1 of | dvt_2(!d11,!d12) => let // u u a a a prval () = fold@ !d1 // u af a n n prval () = fold@ d0 // af n n n n in end | _ => fold@ d0 ) | _ => ()
// HX: choose an element in an unspecified manner//fun{a:t@ype}linset_choose ( xs: !set a, x: &a? >> opt (a, b)) : #[b:bool] bool (b) // end of [linset_choose]
val (pfg, pf | gene) = ptr_alloc<string> () val _ = $showtype !gene val found = if ssize <> 1 then ($raise InvalidCase; linset_choose(!s,!gene )) else linset_choose(!s,gene)
prval () = fold@ e0
in gene end
(*
First, opt (a, b)? and a? are really just the same
*)
(*
Here is a typical sequence of using linset_choose:
*)
var gene: string // uninitialized
val ans = linset_choose(!s, gene)
val () = assertloc (ans) // [linset_choose] succeeded
prval () = opt_unsome {string} (gene)
// now [gene] contains a value of the type [string]
(*
Note that the [linset] package should primarily be used to implement abstract types.
*)
dataviewtype GREXP = | GRgenes of genes
| GRconj of genes | GRconj of (GREXP,GREXP) | GRdisj of genes | GRdisj of (GREXP,GREXP)
fun toCNF (bexp: !GREXP): GREXP = let val LR = case+ bexp of | GRconj(!ex1,!ex2) => let val retv = (toCNF(!ex1),toCNF(!ex2)) val _ = $showtype retv prval () = fold@ bexp in retv end | GRdisj(ex1,ex2) => (toCNF(ex1),toCNF(ex2)) | GRgenes(g) => (bexp, bexp) // ? in case+ bexp of | GRgenes(!g) => (fold@ bexp; bexp) //Start here | GRconj(!ex1,!ex2) => (case+ (LR.0,LR.1) of | (GRgenes(g1), GRgenes(g2)) => let var setu = linset_union(!g1,!g2) val _ = linset_free(g1) val _ = linset_free(g2) in (fold@ bexp; GRconj setu) end | (_,_) => (fold@ bexp; GRconj(!ex1,!ex2)) ) | GRdisj(!ex1,!ex2) => (case+ (LR.0,LR.1) of // Handle disjunctive cases: | (GRdisj(lx1,lx2), GRdisj(rx1,rx2)) => let //GRdisj(LR.0,LR.1) val setu = linset_union(!lx1,!lx2) val setu = linset_union(setu,!rx1) //Any memory lost here? val setu = linset_union(setu,!rx2) val _ = linset_free(lx1) val _ = linset_free(lx2) val _ = linset_free(rx1) //shouldn't be able to free ? val _ = linset_free(rx2) in GRdisj setu end | (GRdisj(lx1,lx2), GRgenes(g)) => let //GRdisj(LR.0,!ex2) val setu = linset_union(!lx1, !lx2) val setu = linset_union(setu, g) val _ = linset_free(lx1) val _ = linset_free(lx2) val _ = linset_free(g) in GRdisj setu end | (GRgenes(g), GRdisj(rx1,rx2)) => let // GRdisj(!ex1,LR.1) val setu = linset_union(!rx1, !rx2) val setu = linset_union(setu, g) val _ = linset_free(rx1) val _ = linset_free(rx2) val _ = linset_free(g) in GRdisj setu end | (GRgenes(g1), GRgenes(g2)) => let var setu = linset_union(!g1,!g2) val _ = linset_free(g1) val _ = linset_free(g2) in GRdisj setu end // Distribute OR over ANDs: | (GRconj(lx1,lx2),GRconj(rx1,rx2)) => GRconj(GRconj(GRconj(toCNF(GRdisj(lx1,rx1)),toCNF(GRdisj(lx2,rx1))), toCNF(GRdisj(lx1,rx2))),toCNF(GRdisj(lx2,rx2))) // Handle e.g.: (.. OR ..) OR (.. AND ...) | (GRconj(lx1,lx2), _) => GRconj(toCNF(GRdisj(lx1,LR.1)),toCNF(GRdisj(lx2,LR.1))) | (_ ,GRconj(rx1,rx2)) => GRconj(toCNF(GRdisj(LR.0,rx1)),toCNF(GRdisj(LR.0,rx2))) ) end
staload "libats/SATS/linset_listord.sats" staload _ = "libats/DATS/linset_listord.dats" dynload "libats/DATS/linset_listord.dats"
implement{a}linset_choose (xs, x0) = case+ xs of | list_vt_cons (x, !p_xs) => let prval () = fold@ xs val () = x0 := x prval () = opt_some {a} (x0) in true end // end of [list_vt_cons] | list_vt_nil () => let prval () = fold@ xs prval () = opt_none {a} (x0) in false end // end of [list_vt_nil]// end of [linset_choose]
dataviewtype dvt =
| dvt_0 of ()
| dvt_1 of (dvt)
| dvt_2 of (dvt,dvt)
// (a)ccessible/usable
// (u)nfolded
// (f)olded
// (n)o view available
// (-) not in scope
// d0 d1 d11 d12 d121
// -----------------------
fun use_dvt(d0: !dvt):void = case+ d0 of // a - - - -
| @dvt_1 (d1 as dvt_2(d11,d12) ) => let // u a a a -
val () = case+ (d11,d12) of //
| (@dvt_0 (), @dvt_1 (d121) ) => let // u a u u a
prval () = fold@ d11 and () = fold@ d12 // u a af af n
in () end //
| (_,_) => () //
prval () = fold@ d0 // af n n n -
in () end // d0 d1 d2 d11 d12
//------------------------
| @dvt_2 (d1,d2) => // u a a
(case+ d1 of //
| @dvt_2 (d11,d12) => let // u u a a a
prval () = fold@ d1 // u af a n n
prval () = fold@ d0 // af n n n n
in () end
| _ => fold@ d0
)
| _ => ()
datavtype dvt =
| dvt0 of ()
| dvt2 of (dvt,dvt)
fun foo (x: !dvt): void =
case+ x of
| dvt0 () => ()
| dvt2 (x1, x2) => () // x1 and x2 are values
| @dvt2 (x1, x2) => fold@(x) // x1 and x2 are l-values
To view this discussion on the web visit https://groups.google.com/d/msgid/ats-lang-users/3a97996d-313c-40bb-ac08-40e262e201d7%40googlegroups.com.--
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-user...@googlegroups.com.
To post to this group, send email to ats-lan...@googlegroups.com.
Visit this group at http://groups.google.com/group/ats-lang-users.