aboutsummaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'frontend')
-rw-r--r--frontend/utilities.dcl5
-rw-r--r--frontend/utilities.icl30
2 files changed, 35 insertions, 0 deletions
diff --git a/frontend/utilities.dcl b/frontend/utilities.dcl
index 909f859..664375b 100644
--- a/frontend/utilities.dcl
+++ b/frontend/utilities.dcl
@@ -115,3 +115,8 @@ iterateSt op st :== iterate_st op st
revAppend :: ![a] ![a] -> [a] // Reverse the list using the second argument as accumulator.
revMap :: !(.a -> .b) ![.a] !u:[.b] -> u:[.b]
+:: Bag x = Empty | Single !x | Pair !(Bag x) !(Bag x)
+
+uniqueBagToList :: !*(Bag x) -> [x] // exploits reuse of unique nodes (if compiled with that option)
+bagToList :: !(Bag x) -> [x]
+isEmptyBag :: !(Bag x) -> Bool
diff --git a/frontend/utilities.icl b/frontend/utilities.icl
index c721d71..b7cb0d5 100644
--- a/frontend/utilities.icl
+++ b/frontend/utilities.icl
@@ -222,3 +222,33 @@ zip2Append [] [] tail
zip2Append [x : xs] [y : ys] tail
= [(x,y) : zip2Append xs ys tail]
*/
+
+:: Bag x = Empty | Single !x | Pair !(Bag x) !(Bag x)
+
+uniqueBagToList :: !*(Bag x) -> [x] // exploits reuse of unique nodes (if compiled with that option)
+uniqueBagToList bag
+ = accumulate_elements bag []
+ where
+ accumulate_elements :: !*(Bag x) [x] -> [x]
+ accumulate_elements Empty accu
+ = accu
+ accumulate_elements (Single element) accu
+ = [element : accu]
+ accumulate_elements (Pair bag1 bag2) accu
+ = accumulate_elements bag1 (accumulate_elements bag2 accu)
+
+bagToList :: !(Bag x) -> [x]
+bagToList bag
+ = accumulate_elements bag []
+ where
+ accumulate_elements :: !(Bag x) [x] -> [x]
+ accumulate_elements Empty accu
+ = accu
+ accumulate_elements (Single element) accu
+ = [element : accu]
+ accumulate_elements (Pair bag1 bag2) accu
+ = accumulate_elements bag1 (accumulate_elements bag2 accu)
+
+isEmptyBag :: !(Bag x) -> Bool
+isEmptyBag Empty = True
+isEmptyBag _ = False