Mercurial > urweb
comparison src/disjoint.sml @ 90:94ef20a31550
Fancier head normalization pushed inside of Disjoint
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Thu, 03 Jul 2008 11:04:25 -0400 |
parents | 7bab29834cd6 |
children | cc68da3801bc |
comparison
equal
deleted
inserted
replaced
89:d3ee072fa609 | 90:94ef20a31550 |
---|---|
107 structure PS = BinarySetFn(PK) | 107 structure PS = BinarySetFn(PK) |
108 structure PM = BinaryMapFn(PK) | 108 structure PM = BinaryMapFn(PK) |
109 | 109 |
110 type env = PS.set PM.map | 110 type env = PS.set PM.map |
111 | 111 |
112 type goal = ErrorMsg.span * ElabEnv.env * env * Elab.con * Elab.con | |
113 | |
112 val empty = PM.empty | 114 val empty = PM.empty |
113 | 115 |
114 fun nameToRow (c, loc) = | 116 fun nameToRow (c, loc) = |
115 (CRecord ((KUnit, loc), [((c, loc), (CUnit, loc))]), loc) | 117 (CRecord ((KUnit, loc), [((c, loc), (CUnit, loc))]), loc) |
116 | 118 |
126 | 128 |
127 datatype piece' = | 129 datatype piece' = |
128 Piece of piece | 130 Piece of piece |
129 | Unknown of con | 131 | Unknown of con |
130 | 132 |
131 fun decomposeRow env c = | |
132 let | |
133 fun decomposeName (c, acc) = | |
134 case #1 (hnormCon env c) of | |
135 CName s => Piece (NameC s) :: acc | |
136 | CRel n => Piece (NameR n) :: acc | |
137 | CNamed n => Piece (NameN n) :: acc | |
138 | CModProj (m1, ms, x) => Piece (NameM (m1, ms, x)) :: acc | |
139 | _ => Unknown c :: acc | |
140 | |
141 fun decomposeRow (c, acc) = | |
142 case #1 (hnormCon env c) of | |
143 CRecord (_, xcs) => foldl (fn ((x, _), acc) => decomposeName (x, acc)) acc xcs | |
144 | CConcat (c1, c2) => decomposeRow (c1, decomposeRow (c2, acc)) | |
145 | CRel n => Piece (RowR n) :: acc | |
146 | CNamed n => Piece (RowN n) :: acc | |
147 | CModProj (m1, ms, x) => Piece (RowM (m1, ms, x)) :: acc | |
148 | _ => Unknown c :: acc | |
149 in | |
150 decomposeRow (c, []) | |
151 end | |
152 | |
153 fun assert env denv (c1, c2) = | |
154 let | |
155 val ps1 = decomposeRow env c1 | |
156 val ps2 = decomposeRow env c2 | |
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 | |
175 val denv = foldl (assertPiece ps2) denv ps1 | |
176 in | |
177 foldl (assertPiece ps1) denv ps2 | |
178 end | |
179 | |
180 fun pieceEnter p = | 133 fun pieceEnter p = |
181 case p of | 134 case p of |
182 NameR n => NameR (n + 1) | 135 NameR n => NameR (n + 1) |
183 | RowR n => RowR (n + 1) | 136 | RowR n => RowR (n + 1) |
184 | _ => p | 137 | _ => p |
194 | _ => | 147 | _ => |
195 case PM.find (denv, p1) of | 148 case PM.find (denv, p1) of |
196 NONE => false | 149 NONE => false |
197 | SOME pset => PS.member (pset, p2) | 150 | SOME pset => PS.member (pset, p2) |
198 | 151 |
199 fun prove env denv (c1, c2, loc) = | 152 fun decomposeRow (env, denv) c = |
200 let | 153 let |
201 val ps1 = decomposeRow env c1 | 154 fun decomposeName (c, (acc, gs)) = |
202 val ps2 = decomposeRow env c2 | 155 let |
156 val (cAll as (c, _), gs') = hnormCon (env, denv) c | |
157 | |
158 val acc = case c of | |
159 CName s => Piece (NameC s) :: acc | |
160 | CRel n => Piece (NameR n) :: acc | |
161 | CNamed n => Piece (NameN n) :: acc | |
162 | CModProj (m1, ms, x) => Piece (NameM (m1, ms, x)) :: acc | |
163 | _ => Unknown cAll :: acc | |
164 in | |
165 (acc, gs' @ gs) | |
166 end | |
167 | |
168 fun decomposeRow (c, (acc, gs)) = | |
169 let | |
170 val (cAll as (c, _), gs') = hnormCon (env, denv) c | |
171 val gs = gs' @ gs | |
172 in | |
173 case c of | |
174 CRecord (_, xcs) => foldl (fn ((x, _), acc_gs) => decomposeName (x, acc_gs)) (acc, gs) xcs | |
175 | CConcat (c1, c2) => decomposeRow (c1, decomposeRow (c2, (acc, gs))) | |
176 | CRel n => (Piece (RowR n) :: acc, gs) | |
177 | CNamed n => (Piece (RowN n) :: acc, gs) | |
178 | CModProj (m1, ms, x) => (Piece (RowM (m1, ms, x)) :: acc, gs) | |
179 | _ => (Unknown cAll :: acc, gs) | |
180 end | |
181 in | |
182 decomposeRow (c, ([], [])) | |
183 end | |
184 | |
185 and assert env denv (c1, c2) = | |
186 let | |
187 val (ps1, gs1) = decomposeRow (env, denv) c1 | |
188 val (ps2, gs2) = decomposeRow (env, denv) c2 | |
189 | |
190 val unUnknown = List.mapPartial (fn Unknown _ => NONE | Piece p => SOME p) | |
191 val ps1 = unUnknown ps1 | |
192 val ps2 = unUnknown ps2 | |
193 | |
194 (*val () = print "APieces1:\n" | |
195 val () = app pp ps1 | |
196 val () = print "APieces2:\n" | |
197 val () = app pp ps2*) | |
198 | |
199 fun assertPiece ps (p, denv) = | |
200 let | |
201 val pset = Option.getOpt (PM.find (denv, p), PS.empty) | |
202 val ps = case p of | |
203 NameC _ => List.filter (fn NameC _ => false | _ => true) ps | |
204 | _ => ps | |
205 val pset = PS.addList (pset, ps) | |
206 in | |
207 PM.insert (denv, p, pset) | |
208 end | |
209 | |
210 val denv = foldl (assertPiece ps2) denv ps1 | |
211 in | |
212 (foldl (assertPiece ps1) denv ps2, gs1 @ gs2) | |
213 end | |
214 | |
215 and prove env denv (c1, c2, loc) = | |
216 let | |
217 val (ps1, gs1) = decomposeRow (env, denv) c1 | |
218 val (ps2, gs2) = decomposeRow (env, denv) c2 | |
203 | 219 |
204 val hasUnknown = List.exists (fn Unknown _ => true | _ => false) | 220 val hasUnknown = List.exists (fn Unknown _ => true | _ => false) |
205 val unUnknown = List.mapPartial (fn Unknown _ => NONE | Piece p => SOME p) | 221 val unUnknown = List.mapPartial (fn Unknown _ => NONE | Piece p => SOME p) |
206 in | 222 in |
207 if hasUnknown ps1 orelse hasUnknown ps2 then | 223 if hasUnknown ps1 orelse hasUnknown ps2 then |
208 [(c1, c2)] | 224 [(loc, env, denv, c1, c2)] |
209 else | 225 else |
210 let | 226 let |
211 val ps1 = unUnknown ps1 | 227 val ps1 = unUnknown ps1 |
212 val ps2 = unUnknown ps2 | 228 val ps2 = unUnknown ps2 |
213 | 229 |
220 foldl (fn (p1, rem) => | 236 foldl (fn (p1, rem) => |
221 foldl (fn (p2, rem) => | 237 foldl (fn (p2, rem) => |
222 if prove1 denv (p1, p2) then | 238 if prove1 denv (p1, p2) then |
223 rem | 239 rem |
224 else | 240 else |
225 (pieceToRow (p1, loc), pieceToRow (p2, loc)) :: rem) rem ps2) | 241 (loc, env, denv, pieceToRow (p1, loc), pieceToRow (p2, loc)) :: rem) rem ps2) |
226 [] ps1 | 242 (gs1 @ gs2) ps1 |
227 end | 243 end |
244 end | |
245 | |
246 and hnormCon (env, denv) c = | |
247 let | |
248 val cAll as (c, loc) = ElabOps.hnormCon env c | |
249 | |
250 fun doDisj (c1, c2, c) = | |
251 let | |
252 val (c, gs) = hnormCon (env, denv) c | |
253 in | |
254 (c, prove env denv (c1, c2, loc) @ gs) | |
255 end | |
256 in | |
257 case c of | |
258 CDisjoint cs => doDisj cs | |
259 | TDisjoint cs => doDisj cs | |
260 | _ => (cAll, []) | |
228 end | 261 end |
229 | 262 |
230 end | 263 end |