Import Upstream version 20180207
[hcoop/debian/mlton.git] / lib / mlton / set / unordered-universe.fun
CommitLineData
7f918cf1
CE
1(* Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 *
4 * MLton is released under a BSD-style license.
5 * See the file MLton-LICENSE for details.
6 *)
7(*-------------------------------------------------------------------*)
8(* SetEqual *)
9(*-------------------------------------------------------------------*)
10
11functor UnorderedUniverse(B: T): UNIVERSE =
12struct
13
14structure B = B
15structure O = Outstream
16structure L = ListSet.L
17
18structure Rep =
19 struct
20 datatype elt =
21 Base of B.t
22 | Pair of elt * elt
23 | Set of elt ListSet.t
24
25 type t = elt
26
27 fun makeEqual equalSet =
28 let fun equalElt(Base b, Base b') = B.equals(b, b')
29 | equalElt(Pair(x, y), Pair(x', y')) =
30 equalElt(x, x') andalso equalElt(y, y')
31 | equalElt(Set s, Set s') = equalSet(s, s')
32 | equalElt _ = false
33 in equalElt
34 end
35
36 fun makeOutput outputSet =
37 let fun outputElt(Base b, out) = B.output(b, out)
38 | outputElt(Pair(x, y), out) =
39 let val print = O.outputc out
40 in (print "(" ;
41 outputElt(x, out) ;
42 print ", " ;
43 outputElt(y, out) ;
44 print ")")
45 end
46 | outputElt(Set s, out) = outputSet(s, out)
47 in outputElt
48 end
49 end
50
51structure S = UnorderedSetMain(Rep)
52
53open Rep S
54
55fun toBase(Base b) = b
56 | toBase _ = Error.error "UnorderedUniverse.toBase"
57fun toPair(Pair p) = p
58 | toPair _ = Error.error "UnorderedUniverse.toPair"
59fun toSet(Set s) = s
60 | toSet _ = Error.error "UnorderedUniverse.toSet"
61
62fun cross(sx, sy) =
63 let val ys = toList sy
64 in fromList(L.foldl
65 (toList sx, [],
66 fn (ps, x) => L.mapAppend(ys, fn y => Pair(x, y), ps)))
67 end
68
69fun project1 s = replace(s,
70 fn Pair(x, _) => SOME x
71 | _ => Error.error "UnorderedUniverse.project1")
72fun project2 s = replace(s,
73 fn Pair(_, y) => SOME y
74 | _ => Error.error "UnorderedUniverse.project2")
75
76fun update (c, x, y) =
77 let fun update[] = [Pair(x, y)]
78 | update((Pair(x', y')) :: ps) =
79 if E.equals(x, x') then (Pair(x, y)) :: ps
80 else (Pair(x', y')) :: (update ps)
81 | update _ = Error.error "UnorderedUniverse.update"
82 in fromList(update(toList c))
83 end
84
85fun updateSet(c, c') =
86 L.foldl(toList c', c,
87 fn (c, Pair(x, y)) => update(c, x, y)
88 | _ => Error.error "UnorderedUniverse.updateSet")
89
90fun lookup (c, x) =
91 let fun lookup [] = NONE
92 | lookup (Pair(x', y) :: ps) =
93 if E.equals(x, x') then SOME y else lookup ps
94 | lookup _ = Error.error "UnorderedUniverse.lookup"
95 in lookup(toList c)
96 end
97
98fun Union s = L.foldl(toList s, empty,
99 fn (s', Set s) => s + s'
100 | _ => Error.error "UnorderedUniverse.Union")
101val Union = Trace.trace("UnorderedUniverse.Union", output, output) Union
102(*
103fun Cross s = listTo(L.map(L.cross(L.map(toList s,
104 toList o Elt.toSet)),
105 Set o listTo))
106*)
107end