comparison src/reduce_local.sml @ 1272:56bd4a4f6e66

Some serious bug-fix work to get HTML example to compile; this includes fixing a bug with 'val' patterns in Unnest and the need for more local reduction in Especialize
author Adam Chlipala <adamc@hcoop.net>
date Thu, 03 Jun 2010 13:04:37 -0400
parents c316ca3c9ec6
children 5b5c0b552f59
comparison
equal deleted inserted replaced
1271:503d4ec93494 1272:56bd4a4f6e66
1 (* Copyright (c) 2008, Adam Chlipala 1 (* Copyright (c) 2008-2010, Adam Chlipala
2 * All rights reserved. 2 * All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met: 5 * modification, are permitted provided that the following conditions are met:
6 * 6 *
41 41
42 datatype env_item = 42 datatype env_item =
43 Unknown 43 Unknown
44 | Known of exp 44 | Known of exp
45 45
46 | Lift of int 46 | UnknownC
47 | KnownC of con
48
49 | Lift of int * int
47 50
48 type env = env_item list 51 type env = env_item list
49 52
50 val deKnown = List.filter (fn Known _ => false 53 val deKnown = List.filter (fn Known _ => false
54 | KnownC _ => false
51 | _ => true) 55 | _ => true)
52 56
53 datatype result = Yes of env | No | Maybe 57 datatype result = Yes of env | No | Maybe
54 58
55 fun match (env, p : pat, e : exp) = 59 fun match (env, p : pat, e : exp) =
118 | _ => Maybe 122 | _ => Maybe
119 in 123 in
120 match (env, p, e) 124 match (env, p, e)
121 end 125 end
122 126
127 fun con env (all as (c, loc)) =
128 ((*Print.prefaces "con" [("c", CorePrint.p_con CoreEnv.empty all)];*)
129 case c of
130 TFun (c1, c2) => (TFun (con env c1, con env c2), loc)
131 | TCFun (x, k, c2) => (TCFun (x, k, con (UnknownC :: env) c2), loc)
132 | TKFun (x, c2) => (TKFun (x, con env c2), loc)
133 | TRecord c => (TRecord (con env c), loc)
134
135 | CRel n =>
136 let
137 fun find (n', env, nudge, liftC) =
138 case env of
139 [] => raise Fail "Reduce.con: CRel"
140 | Unknown :: rest => find (n', rest, nudge, liftC)
141 | Known _ :: rest => find (n', rest, nudge, liftC)
142 | Lift (liftC', _) :: rest => find (n', rest, nudge + liftC',
143 liftC + liftC')
144 | UnknownC :: rest =>
145 if n' = 0 then
146 (CRel (n + nudge), loc)
147 else
148 find (n' - 1, rest, nudge, liftC + 1)
149 | KnownC c :: rest =>
150 if n' = 0 then
151 con (Lift (liftC, 0) :: rest) c
152 else
153 find (n' - 1, rest, nudge - 1, liftC)
154 in
155 (*print (Int.toString n ^ ": " ^ e2s env ^ "\n");*)
156 find (n, env, 0, 0)
157 end
158 | CNamed _ => all
159 | CFfi _ => all
160 | CApp (c1, c2) =>
161 let
162 val c1 = con env c1
163 val c2 = con env c2
164 in
165 case #1 c1 of
166 CAbs (_, _, b) =>
167 con (KnownC c2 :: deKnown env) b
168
169 | CApp ((CMap (dom, ran), _), f) =>
170 (case #1 c2 of
171 CRecord (_, []) => (CRecord (ran, []), loc)
172 | CRecord (_, (x, c) :: rest) =>
173 con (deKnown env)
174 (CConcat ((CRecord (ran, [(x, (CApp (f, c), loc))]), loc),
175 (CApp (c1, (CRecord (dom, rest), loc)), loc)), loc)
176 | _ => (CApp (c1, c2), loc))
177
178 | _ => (CApp (c1, c2), loc)
179 end
180 | CAbs (x, k, b) => (CAbs (x, k, con (UnknownC :: env) b), loc)
181
182 | CKApp (c1, k) =>
183 let
184 val c1 = con env c1
185 in
186 case #1 c1 of
187 CKAbs (_, b) =>
188 con (deKnown env) b
189
190 | _ => (CKApp (c1, k), loc)
191 end
192 | CKAbs (x, b) => (CKAbs (x, con env b), loc)
193
194 | CName _ => all
195
196 | CRecord (k, xcs) => (CRecord (k, map (fn (x, c) => (con env x, con env c)) xcs), loc)
197 | CConcat (c1, c2) =>
198 let
199 val c1 = con env c1
200 val c2 = con env c2
201 in
202 case (#1 c1, #1 c2) of
203 (CRecord (k, xcs1), CRecord (_, xcs2)) =>
204 (CRecord (k, xcs1 @ xcs2), loc)
205 | (CRecord (_, []), _) => c2
206 | (_, CRecord (_, [])) => c1
207 | _ => (CConcat (c1, c2), loc)
208 end
209 | CMap _ => all
210
211 | CUnit => all
212
213 | CTuple cs => (CTuple (map (con env) cs), loc)
214 | CProj (c, n) =>
215 let
216 val c = con env c
217 in
218 case #1 c of
219 CTuple cs => List.nth (cs, n - 1)
220 | _ => (CProj (c, n), loc)
221 end)
222
223 fun patCon pc =
224 case pc of
225 PConVar _ => pc
226 | PConFfi {mod = m, datatyp, params, con = c, arg, kind} =>
227 PConFfi {mod = m, datatyp = datatyp, params = params, con = c,
228 arg = Option.map (con (map (fn _ => UnknownC) params)) arg,
229 kind = kind}
230
123 fun exp env (all as (e, loc)) = 231 fun exp env (all as (e, loc)) =
124 case e of 232 case e of
125 EPrim _ => all 233 EPrim _ => all
126 | ERel n => 234 | ERel n =>
127 let 235 let
128 fun find (n', env, nudge, lift) = 236 fun find (n', env, nudge, liftC, liftE) =
129 case env of 237 case env of
130 [] => (ERel (n + nudge), loc) 238 [] => (ERel (n + nudge), loc)
131 | Lift lift' :: rest => find (n', rest, nudge + lift', lift + lift') 239 | Lift (liftC', liftE') :: rest => find (n', rest, nudge + liftE', liftC + liftC', liftE + liftE')
240 | UnknownC :: rest => find (n', rest, nudge, liftC + 1, liftE)
241 | KnownC _ :: rest => find (n', rest, nudge, liftC, liftE)
132 | Unknown :: rest => 242 | Unknown :: rest =>
133 if n' = 0 then 243 if n' = 0 then
134 (ERel (n + nudge), loc) 244 (ERel (n + nudge), loc)
135 else 245 else
136 find (n' - 1, rest, nudge, lift + 1) 246 find (n' - 1, rest, nudge, liftC, liftE + 1)
137 | Known e :: rest => 247 | Known e :: rest =>
138 if n' = 0 then 248 if n' = 0 then
139 ((*print "SUBSTITUTING\n";*) 249 ((*print "SUBSTITUTING\n";*)
140 exp (Lift lift :: rest) e) 250 exp (Lift (liftC, liftE) :: rest) e)
141 else 251 else
142 find (n' - 1, rest, nudge - 1, lift) 252 find (n' - 1, rest, nudge - 1, liftC, liftE)
143 in 253 in
144 find (n, env, 0, 0) 254 find (n, env, 0, 0, 0)
145 end 255 end
146 | ENamed _ => all 256 | ENamed _ => all
147 | ECon (dk, pc, cs, eo) => (ECon (dk, pc, cs, Option.map (exp env) eo), loc) 257 | ECon (dk, pc, cs, eo) => (ECon (dk, patCon pc, map (con env) cs, Option.map (exp env) eo), loc)
148 | EFfi _ => all 258 | EFfi _ => all
149 | EFfiApp (m, f, es) => (EFfiApp (m, f, map (exp env) es), loc) 259 | EFfiApp (m, f, es) => (EFfiApp (m, f, map (exp env) es), loc)
150
151 | EApp ((ECApp ((ECAbs (_, _, (EAbs (_, (CRel 0, _), _,
152 (ECon (dk, pc, [(CRel 0, loc)], SOME (ERel 0, _)), _)), _)), _),
153 t), _), e) =>
154 (ECon (dk, pc, [t], SOME (exp env e)), loc)
155 260
156 | EApp (e1, e2) => 261 | EApp (e1, e2) =>
157 let 262 let
158 val e1 = exp env e1 263 val e1 = exp env e1
159 val e2 = exp env e2 264 val e2 = exp env e2
161 case #1 e1 of 266 case #1 e1 of
162 EAbs (_, _, _, b) => exp (Known e2 :: deKnown env) b 267 EAbs (_, _, _, b) => exp (Known e2 :: deKnown env) b
163 | _ => (EApp (e1, e2), loc) 268 | _ => (EApp (e1, e2), loc)
164 end 269 end
165 270
166 | EAbs (x, dom, ran, e) => (EAbs (x, dom, ran, exp (Unknown :: env) e), loc) 271 | EAbs (x, dom, ran, e) => (EAbs (x, con env dom, con env ran, exp (Unknown :: env) e), loc)
167 272
168 | ECApp ((ECAbs (_, _, (ECon (dk, pc, [(CRel 0, loc)], NONE), _)), _), t) => 273 | ECApp (e, c) =>
169 (ECon (dk, pc, [t], NONE), loc) 274 let
170 275 val e = exp env e
171 | ECApp (e, c) => (ECApp (exp env e, c), loc) 276 val c = con env c
172 | ECAbs (x, k, e) => (ECAbs (x, k, exp env e), loc) 277 in
278 case #1 e of
279 ECAbs (_, _, b) => exp (KnownC c :: deKnown env) b
280 | _ => (ECApp (e, c), loc)
281 end
282
283 | ECAbs (x, k, e) => (ECAbs (x, k, exp (UnknownC :: env) e), loc)
173 284
174 | EKApp (e, k) => (EKApp (exp env e, k), loc) 285 | EKApp (e, k) => (EKApp (exp env e, k), loc)
175 | EKAbs (x, e) => (EKAbs (x, exp env e), loc) 286 | EKAbs (x, e) => (EKAbs (x, exp env e), loc)
176 287
177 | ERecord xcs => (ERecord (map (fn (x, e, t) => (x, exp env e, t)) xcs), loc) 288 | ERecord xcs => (ERecord (map (fn (x, e, t) => (con env x, exp env e, con env t)) xcs), loc)
178 | EField (e, c, others) => 289 | EField (e, c, others) =>
179 let 290 let
180 val e = exp env e 291 val e = exp env e
292 val c = con env c
181 293
182 fun default () = (EField (e, c, others), loc) 294 fun default () = (EField (e, c, others), loc)
183 in 295 in
184 case (#1 e, #1 c) of 296 case (#1 e, #1 c) of
185 (ERecord xcs, CName x) => 297 (ERecord xcs, CName x) =>
187 NONE => default () 299 NONE => default ()
188 | SOME (_, e, _) => e) 300 | SOME (_, e, _) => e)
189 | _ => default () 301 | _ => default ()
190 end 302 end
191 303
192 | EConcat (e1, c1, e2, c2) => (EConcat (exp env e1, c1, exp env e2, c2), loc) 304 | EConcat (e1, c1, e2, c2) => (EConcat (exp env e1, con env c1, exp env e2, con env c2), loc)
193 | ECut (e, c, others) => (ECut (exp env e, c, others), loc) 305 | ECut (e, c, {field = f, rest = r}) => (ECut (exp env e,
194 | ECutMulti (e, c, others) => (ECutMulti (exp env e, c, others), loc) 306 con env c,
195 307 {field = con env f, rest = con env r}), loc)
196 | ECase (e, pes, others) => 308 | ECutMulti (e, c, {rest = r}) => (ECutMulti (exp env e, con env c, {rest = con env r}), loc)
197 let 309
310 | ECase (e, pes, {disc = d, result = r}) =>
311 let
312 val others = {disc = con env d, result = con env r}
313
198 fun patBinds (p, _) = 314 fun patBinds (p, _) =
199 case p of 315 case p of
200 PWild => 0 316 PWild => 0
201 | PVar _ => 1 317 | PVar _ => 1
202 | PPrim _ => 0 318 | PPrim _ => 0
203 | PCon (_, _, _, NONE) => 0 319 | PCon (_, _, _, NONE) => 0
204 | PCon (_, _, _, SOME p) => patBinds p 320 | PCon (_, _, _, SOME p) => patBinds p
205 | PRecord xpts => foldl (fn ((_, p, _), n) => n + patBinds p) 0 xpts 321 | PRecord xpts => foldl (fn ((_, p, _), n) => n + patBinds p) 0 xpts
206 322
323 fun pat (all as (p, loc)) =
324 case p of
325 PWild => all
326 | PVar (x, t) => (PVar (x, con env t), loc)
327 | PPrim _ => all
328 | PCon (dk, pc, cs, po) =>
329 (PCon (dk, patCon pc, map (con env) cs, Option.map pat po), loc)
330 | PRecord xpts => (PRecord (map (fn (x, p, t) => (x, pat p, con env t)) xpts), loc)
331
207 fun push () = 332 fun push () =
208 (ECase (exp env e, 333 (ECase (exp env e,
209 map (fn (p, e) => (p, 334 map (fn (p, e) => (pat p,
210 exp (List.tabulate (patBinds p, 335 exp (List.tabulate (patBinds p,
211 fn _ => Unknown) @ env) e)) 336 fn _ => Unknown) @ env) e))
212 pes, others), loc) 337 pes, others), loc)
213 338
214 fun search pes = 339 fun search pes =
224 end 349 end
225 350
226 | EWrite e => (EWrite (exp env e), loc) 351 | EWrite e => (EWrite (exp env e), loc)
227 | EClosure (n, es) => (EClosure (n, map (exp env) es), loc) 352 | EClosure (n, es) => (EClosure (n, map (exp env) es), loc)
228 353
229 | ELet (x, t, e1, e2) => (ELet (x, t, exp env e1, exp (Unknown :: env) e2), loc) 354 | ELet (x, t, e1, e2) => (ELet (x, con env t, exp env e1, exp (Unknown :: env) e2), loc)
230 355
231 | EServerCall (n, es, t) => (EServerCall (n, map (exp env) es, t), loc) 356 | EServerCall (n, es, t) => (EServerCall (n, map (exp env) es, con env t), loc)
232 357
233 fun reduce file = 358 fun reduce file =
234 let 359 let
235 fun doDecl (d as (_, loc)) = 360 fun doDecl (d as (_, loc)) =
236 case #1 d of 361 case #1 d of