comparison src/unpoly.sml @ 1122:85d194409b17

Reduce concatenations of the empty record; unpoly non-recursive functions
author Adam Chlipala <adamc@hcoop.net>
date Sun, 10 Jan 2010 13:44:22 -0500
parents 065ce3252090
children ac3dbbc85c6e
comparison
equal deleted inserted replaced
1121:0cee0c8d8c37 1122:85d194409b17
205 | _ => (e, st) 205 | _ => (e, st)
206 206
207 and polyExp (x, st) = U.Exp.foldMap {kind = kind, con = con, exp = exp} st x 207 and polyExp (x, st) = U.Exp.foldMap {kind = kind, con = con, exp = exp} st x
208 208
209 fun decl (d, st : state) = 209 fun decl (d, st : state) =
210 case d of 210 let
211 DValRec (vis as ((x, n, t, e, s) :: rest)) => 211 fun unravel (e, cargs) =
212 let 212 case e of
213 fun unravel (e, cargs) = 213 (ECAbs (_, k, e), _) =>
214 case e of 214 unravel (e, k :: cargs)
215 (ECAbs (_, k, e), _) => 215 | _ => rev cargs
216 unravel (e, k :: cargs) 216 in
217 | _ => rev cargs 217 case d of
218 218 DVal (vi as (x, n, t, e, s)) =>
219 val cargs = unravel (e, []) 219 let
220 220 val cargs = unravel (e, [])
221 fun unravel (e, cargs) = 221
222 case (e, cargs) of 222 val ns = IS.singleton n
223 ((ECAbs (_, k, e), _), k' :: cargs) => 223 in
224 U.Kind.compare (k, k') = EQUAL 224 (d, {funcs = IM.insert (#funcs st, n, {kinds = cargs,
225 andalso unravel (e, cargs) 225 defs = [vi],
226 | (_, []) => true 226 replacements = M.empty}),
227 | _ => false 227 decls = #decls st,
228 in 228 nextName = #nextName st})
229 if List.exists (fn vi => not (unravel (#4 vi, cargs))) rest then 229 end
230 (d, st) 230 | DValRec (vis as ((x, n, t, e, s) :: rest)) =>
231 else 231 let
232 let 232 val cargs = unravel (e, [])
233 val ns = IS.addList (IS.empty, map #2 vis) 233
234 val nargs = length cargs 234 fun unravel (e, cargs) =
235 235 case (e, cargs) of
236 fun deAbs (e, cargs) = 236 ((ECAbs (_, k, e), _), k' :: cargs) =>
237 case (e, cargs) of 237 U.Kind.compare (k, k') = EQUAL
238 ((ECAbs (_, _, e), _), _ :: cargs) => deAbs (e, cargs) 238 andalso unravel (e, cargs)
239 | (_, []) => e 239 | (_, []) => true
240 | _ => raise Fail "Unpoly: deAbs" 240 | _ => false
241 241
242 (** Verifying lack of polymorphic recursion *) 242 fun deAbs (e, cargs) =
243 243 case (e, cargs) of
244 fun kind _ = false 244 ((ECAbs (_, _, e), _), _ :: cargs) => deAbs (e, cargs)
245 fun con _ = false 245 | (_, []) => e
246 246 | _ => raise Fail "Unpoly: deAbs"
247 fun exp e = 247
248 case e of 248 in
249 ECApp (e, c) => 249 if List.exists (fn vi => not (unravel (#4 vi, cargs))) rest then
250 let 250 (d, st)
251 fun isIrregular (e, pos) = 251 else
252 case #1 e of 252 let
253 ENamed n => 253 val ns = IS.addList (IS.empty, map #2 vis)
254 IS.member (ns, n) 254 val nargs = length cargs
255 andalso 255
256 (case #1 c of 256 (** Verifying lack of polymorphic recursion *)
257 CRel i => i <> nargs - pos 257
258 | _ => true) 258 fun kind _ = false
259 | ECApp (e, _) => isIrregular (e, pos + 1) 259 fun con _ = false
260 | _ => false 260
261 in 261 fun exp e =
262 isIrregular (e, 1) 262 case e of
263 end 263 ECApp (e, c) =>
264 | ECAbs _ => true 264 let
265 | _ => false 265 fun isIrregular (e, pos) =
266 266 case #1 e of
267 val irregular = U.Exp.exists {kind = kind, con = con, exp = exp} 267 ENamed n =>
268 in 268 IS.member (ns, n)
269 if List.exists (fn x => irregular (deAbs (#4 x, cargs))) vis then 269 andalso
270 (d, st) 270 (case #1 c of
271 else 271 CRel i => i <> nargs - pos
272 (d, {funcs = foldl (fn (vi, funcs) => 272 | _ => true)
273 IM.insert (funcs, #2 vi, {kinds = cargs, 273 | ECApp (e, _) => isIrregular (e, pos + 1)
274 defs = vis, 274 | _ => false
275 replacements = M.empty})) 275 in
276 (#funcs st) vis, 276 isIrregular (e, 1)
277 decls = #decls st, 277 end
278 nextName = #nextName st}) 278 | ECAbs _ => true
279 end 279 | _ => false
280 end 280
281 281 val irregular = U.Exp.exists {kind = kind, con = con, exp = exp}
282 | _ => (d, st) 282 in
283 if List.exists (fn x => irregular (deAbs (#4 x, cargs))) vis then
284 (d, st)
285 else
286 (d, {funcs = foldl (fn (vi, funcs) =>
287 IM.insert (funcs, #2 vi, {kinds = cargs,
288 defs = vis,
289 replacements = M.empty}))
290 (#funcs st) vis,
291 decls = #decls st,
292 nextName = #nextName st})
293 end
294 end
295
296 | _ => (d, st)
297 end
283 298
284 val polyDecl = U.Decl.foldMap {kind = kind, con = con, exp = exp, decl = decl} 299 val polyDecl = U.Decl.foldMap {kind = kind, con = con, exp = exp, decl = decl}
285 300
286 fun unpoly file = 301 fun unpoly file =
287 let 302 let