--
--
-- Assoc-Collection
--
--
toAssoc xs :=
match xs as list something with
| [] -> []
| $x :: (loop $i (2, $n)
(#x :: ...)
(!(#x :: _) & $rs)) -> (x, n) :: toAssoc rs
fromAssoc xs :=
match xs as list (something, integer) with
| [] -> []
| ($x, $n) :: $rs -> take n (repeat1 x) ++ fromAssoc rs
--
-- Assoc List
--
assocList a :=
matcher
| [] as () with
| [] -> [()]
| _ -> []
| $ :: $ as (a, assocList a) with
| $tgt ->
match tgt as list (something, integer) with
| ($x, #1) :: $rs -> [(x, rs)]
| ($x, $n) :: $rs -> [(x, (x, n - 1) :: rs)]
| _ -> []
| ncons $ #$k $ as (a, assocList a) with
| $tgt ->
match tgt as list (something, integer) with
| ($x, #k) :: $rs -> [(x, rs)]
| ($x, ?(> k) & $n) :: $rs -> [(x, (x, n - k) :: rs)]
| _ -> []
| ncons $ $ $ as (a, integer, assocList a) with
| $tgt ->
match tgt as list (something, integer) with
| ($x, $k) :: $rs -> [(x, k, rs)]
| _ -> []
| #$val as () with
| $tgt -> if val = tgt then [()] else []
| $ as (something) with
| $tgt -> [tgt]
--
-- Assoc Multiset
--
assocMultiset a :=
matcher
| [] as () with
| [] -> [()]
| _ -> []
| #$x :: $ as (assocMultiset a) with
| $tgt ->
matchAll tgt as list (a, integer) with
| $hs ++ (#x, $n) :: $ts ->
if n = 1 then hs ++ ts else hs ++ (x, n - 1) :: ts
| $ :: $ as (a, assocMultiset a) with
| $tgt ->
matchAll tgt as list (a, integer) with
| $hs ++ ($x, $n) :: $ts ->
if n = 1 then (x, hs ++ ts) else (x, hs ++ (x, n - 1) :: ts)
| ncons #$x #$n $ as (assocMultiset a) with
| $tgt ->
matchAll tgt as list (a, integer) with
| $hs ++ (#x, ?(>= n) & $k) :: $ts ->
if k - n = 0 then hs ++ ts else hs ++ (x, k - n) :: ts
| ncons $ #$n $ as (a, assocMultiset a) with
| $tgt ->
matchAll tgt as list (a, integer) with
| $hs ++ ($x, ?(>= n) & $k) :: $ts ->
if k - n = 0 then (x, hs ++ ts) else (x, hs ++ (x, k - n) :: ts)
| ncons #$x $ $ as (integer, assocMultiset a) with
| $tgt ->
matchAll tgt as list (a, integer) with
| $hs ++ (#x, $n) :: $ts -> (n, hs ++ ts)
| ncons $ $ $ as (a, integer, assocMultiset a) with
| $tgt ->
matchAll tgt as list (a, integer) with
| $hs ++ ($x, $n) :: $ts -> (x, n, hs ++ ts)
| $ as (something) with
| $tgt -> [tgt]
AC.intersect xs ys :=
matchAll (xs, ys) as (assocMultiset something, assocMultiset something) with
| (ncons $x $m _, ncons #x $n _) -> (x, min m n)
AC.intersectAs a xs ys :=
matchAll (xs, ys) as (assocMultiset a, assocMultiset a) with
| (ncons $x $m _, ncons #x $n _) -> (x, min m n)