comparison src/unpoly.sml @ 794:dc3fc3f3b834

Improving/reordering Unpoly and Especialize; pathmaps
author Adam Chlipala <adamc@hcoop.net>
date Thu, 14 May 2009 08:13:54 -0400
parents 2d64457eedb1
children 6271f0e3c272
comparison
equal deleted inserted replaced
793:3e5d1c6ae30c 794:dc3fc3f3b834
70 else 70 else
71 e 71 e
72 end 72 end
73 | _ => e} 73 | _ => e}
74 74
75 structure M = BinaryMapFn(struct
76 type ord_key = con list
77 val compare = Order.joinL U.Con.compare
78 end)
79
80 type func = {
81 kinds : kind list,
82 defs : (string * int * con * exp * string) list,
83 replacements : int M.map
84 }
85
75 type state = { 86 type state = {
76 funcs : (kind list * (string * int * con * exp * string) list) IM.map, 87 funcs : func IM.map,
77 decls : decl list, 88 decls : decl list,
78 nextName : int 89 nextName : int
79 } 90 }
80 91
81 fun kind (k, st) = (k, st) 92 fun kind (k, st) = (k, st)
84 95
85 fun exp (e, st : state) = 96 fun exp (e, st : state) =
86 case e of 97 case e of
87 ECApp _ => 98 ECApp _ =>
88 let 99 let
89 (*val () = Print.prefaces "exp" [("e", CorePrint.p_exp CoreEnv.empty (e, ErrorMsg.dummySpan))]*)
90
91 fun unravel (e, cargs) = 100 fun unravel (e, cargs) =
92 case e of 101 case e of
93 ECApp ((e, _), c) => unravel (e, c :: cargs) 102 ECApp ((e, _), c) => unravel (e, c :: cargs)
94 | ENamed n => SOME (n, rev cargs) 103 | ENamed n => SOME (n, rev cargs)
95 | _ => NONE 104 | _ => NONE
100 if List.exists isOpen cargs then 109 if List.exists isOpen cargs then
101 (e, st) 110 (e, st)
102 else 111 else
103 case IM.find (#funcs st, n) of 112 case IM.find (#funcs st, n) of
104 NONE => (e, st) 113 NONE => (e, st)
105 | SOME (ks, vis) => 114 | SOME {kinds = ks, defs = vis, replacements} =>
106 let 115 case M.find (replacements, cargs) of
107 val (vis, nextName) = ListUtil.foldlMap 116 SOME n => (ENamed n, st)
108 (fn ((x, n, t, e, s), nextName) => 117 | NONE =>
109 ((x, nextName, n, t, e, s), nextName + 1)) 118 let
110 (#nextName st) vis 119 val old_vis = vis
111 120 val (vis, (thisName, nextName)) =
112 fun specialize (x, n, n_old, t, e, s) = 121 ListUtil.foldlMap
113 let 122 (fn ((x, n', t, e, s), (thisName, nextName)) =>
114 fun trim (t, e, cargs) = 123 ((x, nextName, n', t, e, s),
115 case (t, e, cargs) of 124 (if n' = n then nextName else thisName,
116 ((TCFun (_, _, t), _), 125 nextName + 1)))
117 (ECAbs (_, _, e), _), 126 (0, #nextName st) vis
118 carg :: cargs) => 127
119 let 128 fun specialize (x, n, n_old, t, e, s) =
120 val t = subConInCon (length cargs, carg) t 129 let
121 val e = subConInExp (length cargs, carg) e 130 fun trim (t, e, cargs) =
122 in 131 case (t, e, cargs) of
123 trim (t, e, cargs) 132 ((TCFun (_, _, t), _),
124 end 133 (ECAbs (_, _, e), _),
125 | (_, _, []) => 134 carg :: cargs) =>
126 let 135 let
127 val e = foldl (fn ((_, n, n_old, _, _, _), e) => 136 val t = subConInCon (length cargs, carg) t
128 unpolyNamed (n_old, ENamed n) e) 137 val e = subConInExp (length cargs, carg) e
129 e vis 138 in
130 in 139 trim (t, e, cargs)
131 SOME (t, e) 140 end
132 end 141 | (_, _, []) =>
133 | _ => NONE 142 (*let
134 in 143 val e = foldl (fn ((_, n, n_old, _, _, _), e) =>
135 (*Print.prefaces "specialize" 144 unpolyNamed (n_old, ENamed n) e)
136 [("t", CorePrint.p_con CoreEnv.empty t), 145 e vis
137 ("e", CorePrint.p_exp CoreEnv.empty e), 146 in*)
138 ("|cargs|", Print.PD.string (Int.toString (length cargs)))];*) 147 SOME (t, e)
139 Option.map (fn (t, e) => (x, n, n_old, t, e, s)) 148 (*end*)
140 (trim (t, e, cargs)) 149 | _ => NONE
141 end 150 in
142 151 (*Print.prefaces "specialize"
143 val vis = List.map specialize vis 152 [("t", CorePrint.p_con CoreEnv.empty t),
144 in 153 ("e", CorePrint.p_exp CoreEnv.empty e),
145 if List.exists (not o Option.isSome) vis orelse length cargs > length ks then 154 ("|cargs|", Print.PD.string (Int.toString (length cargs)))];*)
146 (e, st) 155 Option.map (fn (t, e) => (x, n, n_old, t, e, s))
147 else 156 (trim (t, e, cargs))
148 let 157 end
149 val vis = List.mapPartial (fn x => x) vis 158
150 val vis = map (fn (x, n, n_old, t, e, s) => 159 val vis = List.map specialize vis
151 (x ^ "_unpoly", n, n_old, t, e, s)) vis 160 in
152 val vis' = map (fn (x, n, _, t, e, s) => 161 if List.exists (not o Option.isSome) vis orelse length cargs > length ks then
153 (x, n, t, e, s)) vis 162 (e, st)
154 163 else
155 val ks' = List.drop (ks, length cargs) 164 let
156 in 165 val vis = List.mapPartial (fn x => x) vis
157 case List.find (fn (_, _, n_old, _, _, _) => n_old = n) vis of 166
158 NONE => raise Fail "Unpoly: Inconsistent 'val rec' record" 167 val vis = map (fn (x, n, n_old, t, e, s) =>
159 | SOME (_, n, _, _, _, _) => 168 (x ^ "_unpoly", n, n_old, t, e, s)) vis
160 (ENamed n, 169 val vis' = map (fn (x, n, _, t, e, s) =>
161 {funcs = foldl (fn (vi, funcs) => 170 (x, n, t, e, s)) vis
162 IM.insert (funcs, #2 vi, (ks', vis'))) 171
163 (#funcs st) vis', 172 val funcs = IM.insert (#funcs st, n,
173 {kinds = ks,
174 defs = old_vis,
175 replacements = M.insert (replacements,
176 cargs,
177 thisName)})
178
179 val ks' = List.drop (ks, length cargs)
180
181 val st = {funcs = foldl (fn (vi, funcs) =>
182 IM.insert (funcs, #2 vi,
183 {kinds = ks',
184 defs = vis',
185 replacements = M.empty}))
186 funcs vis',
187 decls = #decls st,
188 nextName = nextName}
189
190 val (vis', st) = ListUtil.foldlMap (fn ((x, n, t, e, s), st) =>
191 let
192 val (e, st) = polyExp (e, st)
193 in
194 ((x, n, t, e, s), st)
195 end)
196 st vis'
197 in
198 (ENamed thisName,
199 {funcs = #funcs st,
164 decls = (DValRec vis', ErrorMsg.dummySpan) :: #decls st, 200 decls = (DValRec vis', ErrorMsg.dummySpan) :: #decls st,
165 nextName = nextName}) 201 nextName = #nextName st})
166 end 202 end
167 end 203 end
168 end 204 end
169 | _ => (e, st) 205 | _ => (e, st)
206
207 and polyExp (x, st) = U.Exp.foldMap {kind = kind, con = con, exp = exp} st x
170 208
171 fun decl (d, st : state) = 209 fun decl (d, st : state) =
172 case d of 210 case d of
173 DValRec (vis as ((x, n, t, e, s) :: rest)) => 211 DValRec (vis as ((x, n, t, e, s) :: rest)) =>
174 let 212 let
230 in 268 in
231 if List.exists (fn x => irregular (deAbs (#4 x, cargs))) vis then 269 if List.exists (fn x => irregular (deAbs (#4 x, cargs))) vis then
232 (d, st) 270 (d, st)
233 else 271 else
234 (d, {funcs = foldl (fn (vi, funcs) => 272 (d, {funcs = foldl (fn (vi, funcs) =>
235 IM.insert (funcs, #2 vi, (cargs, vis))) 273 IM.insert (funcs, #2 vi, {kinds = cargs,
274 defs = vis,
275 replacements = M.empty}))
236 (#funcs st) vis, 276 (#funcs st) vis,
237 decls = #decls st, 277 decls = #decls st,
238 nextName = #nextName st}) 278 nextName = #nextName st})
239 end 279 end
240 end 280 end