comparison src/disjoint.sml @ 88:7bab29834cd6

Constraints in modules
author Adam Chlipala <adamc@hcoop.net>
date Tue, 01 Jul 2008 15:58:02 -0400
parents e86370850c30
children 94ef20a31550
comparison
equal deleted inserted replaced
87:275aaeb73f1f 88:7bab29834cd6
28 structure Disjoint :> DISJOINT = struct 28 structure Disjoint :> DISJOINT = struct
29 29
30 open Elab 30 open Elab
31 open ElabOps 31 open ElabOps
32 32
33 structure SS = BinarySetFn(struct
34 type ord_key = string
35 val compare = String.compare
36 end)
37
38 structure IS = IntBinarySet
39 structure IM = IntBinaryMap
40
41 type name_ineqs = {
42 namesC : SS.set,
43 namesR : IS.set,
44 namesN : IS.set
45 }
46
47 val name_default = {
48 namesC = SS.empty,
49 namesR = IS.empty,
50 namesN = IS.empty
51 }
52
53 type row_ineqs = {
54 namesC : SS.set,
55 namesR : IS.set,
56 namesN : IS.set,
57 rowsR : IS.set,
58 rowsN : IS.set
59 }
60
61 val row_default = {
62 namesC = SS.empty,
63 namesR = IS.empty,
64 namesN = IS.empty,
65 rowsR = IS.empty,
66 rowsN = IS.empty
67 }
68
69 fun nameToRow_ineqs {namesC, namesR, namesN} =
70 {namesC = namesC,
71 namesR = namesR,
72 namesN = namesN,
73 rowsR = IS.empty,
74 rowsN = IS.empty}
75
76 type env = {
77 namesR : name_ineqs IM.map,
78 namesN : name_ineqs IM.map,
79 rowsR : row_ineqs IM.map,
80 rowsN : row_ineqs IM.map
81 }
82
83 val empty = {
84 namesR = IM.empty,
85 namesN = IM.empty,
86 rowsR = IM.empty,
87 rowsN = IM.empty
88 }
89
90 datatype piece = 33 datatype piece =
91 NameC of string 34 NameC of string
92 | NameR of int 35 | NameR of int
93 | NameN of int 36 | NameN of int
37 | NameM of int * string list * string
94 | RowR of int 38 | RowR of int
95 | RowN of int 39 | RowN of int
96 | Unknown 40 | RowM of int * string list * string
41
42 fun p2s p =
43 case p of
44 NameC s => "NameC(" ^ s ^ ")"
45 | NameR n => "NameR(" ^ Int.toString n ^ ")"
46 | NameN n => "NameN(" ^ Int.toString n ^ ")"
47 | NameM (n, _, s) => "NameR(" ^ Int.toString n ^ ", " ^ s ^ ")"
48 | RowR n => "RowR(" ^ Int.toString n ^ ")"
49 | RowN n => "RowN(" ^ Int.toString n ^ ")"
50 | RowM (n, _, s) => "RowR(" ^ Int.toString n ^ ", " ^ s ^ ")"
51
52 fun pp p = print (p2s p ^ "\n")
53
54 structure PK = struct
55
56 type ord_key = piece
57
58 fun join (o1, o2) =
59 case o1 of
60 EQUAL => o2 ()
61 | v => v
62
63 fun joinL f (os1, os2) =
64 case (os1, os2) of
65 (nil, nil) => EQUAL
66 | (nil, _) => LESS
67 | (h1 :: t1, h2 :: t2) =>
68 join (f (h1, h2), fn () => joinL f (t1, t2))
69 | (_ :: _, nil) => GREATER
70
71 fun compare (p1, p2) =
72 case (p1, p2) of
73 (NameC s1, NameC s2) => String.compare (s1, s2)
74 | (NameR n1, NameR n2) => Int.compare (n1, n2)
75 | (NameN n1, NameN n2) => Int.compare (n1, n2)
76 | (NameM (n1, ss1, s1), NameM (n2, ss2, s2)) =>
77 join (Int.compare (n1, n2),
78 fn () => join (String.compare (s1, s2), fn () =>
79 joinL String.compare (ss1, ss2)))
80 | (RowR n1, RowR n2) => Int.compare (n1, n2)
81 | (RowN n1, RowN n2) => Int.compare (n1, n2)
82 | (RowM (n1, ss1, s1), RowM (n2, ss2, s2)) =>
83 join (Int.compare (n1, n2),
84 fn () => join (String.compare (s1, s2), fn () =>
85 joinL String.compare (ss1, ss2)))
86
87 | (NameC _, _) => LESS
88 | (_, NameC _) => GREATER
89
90 | (NameR _, _) => LESS
91 | (_, NameR _) => GREATER
92
93 | (NameN _, _) => LESS
94 | (_, NameN _) => GREATER
95
96 | (NameM _, _) => LESS
97 | (_, NameM _) => GREATER
98
99 | (RowR _, _) => LESS
100 | (_, RowR _) => GREATER
101
102 | (RowN _, _) => LESS
103 | (_, RowN _) => GREATER
104
105 end
106
107 structure PS = BinarySetFn(PK)
108 structure PM = BinaryMapFn(PK)
109
110 type env = PS.set PM.map
111
112 val empty = PM.empty
97 113
98 fun nameToRow (c, loc) = 114 fun nameToRow (c, loc) =
99 (CRecord ((KUnit, loc), [((c, loc), (CUnit, loc))]), loc) 115 (CRecord ((KUnit, loc), [((c, loc), (CUnit, loc))]), loc)
100 116
101 fun pieceToRow (p, loc) = 117 fun pieceToRow (p, loc) =
102 case p of 118 case p of
103 NameC s => nameToRow (CName s, loc) 119 NameC s => nameToRow (CName s, loc)
104 | NameR n => nameToRow (CRel n, loc) 120 | NameR n => nameToRow (CRel n, loc)
105 | NameN n => nameToRow (CNamed n, loc) 121 | NameN n => nameToRow (CNamed n, loc)
122 | NameM (n, xs, x) => nameToRow (CModProj (n, xs, x), loc)
106 | RowR n => (CRel n, loc) 123 | RowR n => (CRel n, loc)
107 | RowN n => (CRel n, loc) 124 | RowN n => (CNamed n, loc)
108 | Unknown => raise Fail "Unknown to row" 125 | RowM (n, xs, x) => (CModProj (n, xs, x), loc)
126
127 datatype piece' =
128 Piece of piece
129 | Unknown of con
109 130
110 fun decomposeRow env c = 131 fun decomposeRow env c =
111 let 132 let
112 fun decomposeName (c, acc) = 133 fun decomposeName (c, acc) =
113 case #1 (hnormCon env c) of 134 case #1 (hnormCon env c) of
114 CName s => NameC s :: acc 135 CName s => Piece (NameC s) :: acc
115 | CRel n => NameR n :: acc 136 | CRel n => Piece (NameR n) :: acc
116 | CNamed n => NameN n :: acc 137 | CNamed n => Piece (NameN n) :: acc
117 | _ => (print "Unknown name\n"; Unknown :: acc) 138 | CModProj (m1, ms, x) => Piece (NameM (m1, ms, x)) :: acc
118 139 | _ => Unknown c :: acc
140
119 fun decomposeRow (c, acc) = 141 fun decomposeRow (c, acc) =
120 case #1 (hnormCon env c) of 142 case #1 (hnormCon env c) of
121 CRecord (_, xcs) => foldl (fn ((x, _), acc) => decomposeName (x, acc)) acc xcs 143 CRecord (_, xcs) => foldl (fn ((x, _), acc) => decomposeName (x, acc)) acc xcs
122 | CConcat (c1, c2) => decomposeRow (c1, decomposeRow (c2, acc)) 144 | CConcat (c1, c2) => decomposeRow (c1, decomposeRow (c2, acc))
123 | CRel n => RowR n :: acc 145 | CRel n => Piece (RowR n) :: acc
124 | CNamed n => RowN n :: acc 146 | CNamed n => Piece (RowN n) :: acc
125 | _ => (print "Unknown row\n"; Unknown :: acc) 147 | CModProj (m1, ms, x) => Piece (RowM (m1, ms, x)) :: acc
148 | _ => Unknown c :: acc
126 in 149 in
127 decomposeRow (c, []) 150 decomposeRow (c, [])
128 end 151 end
129
130 fun assertPiece_name (ps, ineqs : name_ineqs) =
131 {namesC = foldl (fn (p', namesC) =>
132 case p' of
133 NameC s => SS.add (namesC, s)
134 | _ => namesC) (#namesC ineqs) ps,
135 namesR = foldl (fn (p', namesR) =>
136 case p' of
137 NameR n => IS.add (namesR, n)
138 | _ => namesR) (#namesR ineqs) ps,
139 namesN = foldl (fn (p', namesN) =>
140 case p' of
141 NameN n => IS.add (namesN, n)
142 | _ => namesN) (#namesN ineqs) ps}
143
144 fun assertPiece_row (ps, ineqs : row_ineqs) =
145 {namesC = foldl (fn (p', namesC) =>
146 case p' of
147 NameC s => SS.add (namesC, s)
148 | _ => namesC) (#namesC ineqs) ps,
149 namesR = foldl (fn (p', namesR) =>
150 case p' of
151 NameR n => IS.add (namesR, n)
152 | _ => namesR) (#namesR ineqs) ps,
153 namesN = foldl (fn (p', namesN) =>
154 case p' of
155 NameN n => IS.add (namesN, n)
156 | _ => namesN) (#namesN ineqs) ps,
157 rowsR = foldl (fn (p', rowsR) =>
158 case p' of
159 RowR n => IS.add (rowsR, n)
160 | _ => rowsR) (#rowsR ineqs) ps,
161 rowsN = foldl (fn (p', rowsN) =>
162 case p' of
163 RowN n => IS.add (rowsN, n)
164 | _ => rowsN) (#rowsN ineqs) ps}
165
166 fun assertPiece ps (p, denv) =
167 case p of
168 Unknown => denv
169 | NameC _ => denv
170
171 | NameR n =>
172 let
173 val ineqs = Option.getOpt (IM.find (#namesR denv, n), name_default)
174 val ineqs = assertPiece_name (ps, ineqs)
175 in
176 {namesR = IM.insert (#namesR denv, n, ineqs),
177 namesN = #namesN denv,
178 rowsR = #rowsR denv,
179 rowsN = #rowsN denv}
180 end
181
182 | NameN n =>
183 let
184 val ineqs = Option.getOpt (IM.find (#namesN denv, n), name_default)
185 val ineqs = assertPiece_name (ps, ineqs)
186 in
187 {namesR = #namesR denv,
188 namesN = IM.insert (#namesN denv, n, ineqs),
189 rowsR = #rowsR denv,
190 rowsN = #rowsN denv}
191 end
192
193 | RowR n =>
194 let
195 val ineqs = Option.getOpt (IM.find (#rowsR denv, n), row_default)
196 val ineqs = assertPiece_row (ps, ineqs)
197 in
198 {namesR = #namesR denv,
199 namesN = #namesN denv,
200 rowsR = IM.insert (#rowsR denv, n, ineqs),
201 rowsN = #rowsN denv}
202 end
203
204 | RowN n =>
205 let
206 val ineqs = Option.getOpt (IM.find (#rowsN denv, n), row_default)
207 val ineqs = assertPiece_row (ps, ineqs)
208 in
209 {namesR = #namesR denv,
210 namesN = #namesN denv,
211 rowsR = #rowsR denv,
212 rowsN = IM.insert (#rowsN denv, n, ineqs)}
213 end
214 152
215 fun assert env denv (c1, c2) = 153 fun assert env denv (c1, c2) =
216 let 154 let
217 val ps1 = decomposeRow env c1 155 val ps1 = decomposeRow env c1
218 val ps2 = decomposeRow env c2 156 val ps2 = decomposeRow env c2
219 157
158 val unUnknown = List.mapPartial (fn Unknown _ => NONE | Piece p => SOME p)
159 val ps1 = unUnknown ps1
160 val ps2 = unUnknown ps2
161
162 (*val () = print "APieces1:\n"
163 val () = app pp ps1
164 val () = print "APieces2:\n"
165 val () = app pp ps2*)
166
167 fun assertPiece ps (p, denv) =
168 let
169 val pset = Option.getOpt (PM.find (denv, p), PS.empty)
170 val pset = PS.addList (pset, ps)
171 in
172 PM.insert (denv, p, pset)
173 end
174
220 val denv = foldl (assertPiece ps2) denv ps1 175 val denv = foldl (assertPiece ps2) denv ps1
221 in 176 in
222 foldl (assertPiece ps1) denv ps2 177 foldl (assertPiece ps1) denv ps2
223 end 178 end
224 179
225 fun nameEnter {namesC, namesR, namesN} = 180 fun pieceEnter p =
226 {namesC = namesC,
227 namesR = IS.map (fn n => n + 1) namesR,
228 namesN = namesN}
229
230 fun rowEnter {namesC, namesR, namesN, rowsR, rowsN} =
231 {namesC = namesC,
232 namesR = IS.map (fn n => n + 1) namesR,
233 namesN = namesN,
234 rowsR = IS.map (fn n => n + 1) rowsR,
235 rowsN = rowsN}
236
237 fun enter {namesR, namesN, rowsR, rowsN} =
238 {namesR = IM.foldli (fn (n, ineqs, namesR) => IM.insert (namesR, n+1, nameEnter ineqs)) IM.empty namesR,
239 namesN = IM.map nameEnter namesN,
240 rowsR = IM.foldli (fn (n, ineqs, rowsR) => IM.insert (rowsR, n+1, rowEnter ineqs)) IM.empty rowsR,
241 rowsN = IM.map rowEnter rowsN}
242
243 fun getIneqs (denv : env) p =
244 case p of 181 case p of
245 Unknown => raise Fail "getIneqs: Unknown" 182 NameR n => NameR (n + 1)
246 | NameC _ => raise Fail "getIneqs: NameC" 183 | RowR n => RowR (n + 1)
247 | NameR n => nameToRow_ineqs (Option.getOpt (IM.find (#namesR denv, n), name_default)) 184 | _ => p
248 | NameN n => nameToRow_ineqs (Option.getOpt (IM.find (#namesN denv, n), name_default)) 185
249 | RowR n => Option.getOpt (IM.find (#rowsR denv, n), row_default) 186 fun enter denv =
250 | RowN n => Option.getOpt (IM.find (#rowsN denv, n), row_default) 187 PM.foldli (fn (p, pset, denv') =>
251 188 PM.insert (denv', pieceEnter p, PS.map pieceEnter pset))
252 fun prove1' denv (p1, p2) = 189 PM.empty denv
253 let
254 val {namesC, namesR, namesN, rowsR, rowsN} = getIneqs denv p1
255 in
256 case p2 of
257 Unknown => raise Fail "prove1': Unknown"
258 | NameC s => SS.member (namesC, s)
259 | NameR n => IS.member (namesR, n)
260 | NameN n => IS.member (namesN, n)
261 | RowR n => IS.member (rowsR, n)
262 | RowN n => IS.member (rowsN, n)
263 end
264 190
265 fun prove1 denv (p1, p2) = 191 fun prove1 denv (p1, p2) =
266 case (p1, p2) of 192 case (p1, p2) of
267 (NameC s1, NameC s2) => s1 <> s2 193 (NameC s1, NameC s2) => s1 <> s2
268 | (NameC _, _) => prove1' denv (p2, p1) 194 | _ =>
269 | (_, RowR _) => prove1' denv (p2, p1) 195 case PM.find (denv, p1) of
270 | (_, RowN _) => prove1' denv (p2, p1) 196 NONE => false
271 | _ => prove1' denv (p1, p2) 197 | SOME pset => PS.member (pset, p2)
272 198
273 fun prove env denv (c1, c2, loc) = 199 fun prove env denv (c1, c2, loc) =
274 let 200 let
275 val ps1 = decomposeRow env c1 201 val ps1 = decomposeRow env c1
276 val ps2 = decomposeRow env c2 202 val ps2 = decomposeRow env c2
277 203
278 val hasUnknown = List.exists (fn p => p = Unknown) 204 val hasUnknown = List.exists (fn Unknown _ => true | _ => false)
205 val unUnknown = List.mapPartial (fn Unknown _ => NONE | Piece p => SOME p)
279 in 206 in
280 if hasUnknown ps1 orelse hasUnknown ps2 then 207 if hasUnknown ps1 orelse hasUnknown ps2 then
281 [(c1, c2)] 208 [(c1, c2)]
282 else 209 else
283 foldl (fn (p1, rem) => 210 let
284 foldl (fn (p2, rem) => 211 val ps1 = unUnknown ps1
285 if prove1 denv (p1, p2) then 212 val ps2 = unUnknown ps2
286 rem 213
287 else 214 in
288 (pieceToRow (p1, loc), pieceToRow (p2, loc)) :: rem) rem ps2) 215 (*print "Pieces1:\n";
289 [] ps1 216 app pp ps1;
217 print "Pieces2:\n";
218 app pp ps2;*)
219
220 foldl (fn (p1, rem) =>
221 foldl (fn (p2, rem) =>
222 if prove1 denv (p1, p2) then
223 rem
224 else
225 (pieceToRow (p1, loc), pieceToRow (p2, loc)) :: rem) rem ps2)
226 [] ps1
227 end
290 end 228 end
291 229
292 end 230 end