60 val contains_dict_var: iterm -> bool |
60 val contains_dict_var: iterm -> bool |
61 val unambiguous_dictss: dict list list -> bool |
61 val unambiguous_dictss: dict list list -> bool |
62 val add_constsyms: iterm -> Code_Symbol.T list -> Code_Symbol.T list |
62 val add_constsyms: iterm -> Code_Symbol.T list -> Code_Symbol.T list |
63 val add_tyconames: iterm -> string list -> string list |
63 val add_tyconames: iterm -> string list -> string list |
64 val fold_varnames: (string -> 'a -> 'a) -> iterm -> 'a -> 'a |
64 val fold_varnames: (string -> 'a -> 'a) -> iterm -> 'a -> 'a |
|
65 val add_varnames: iterm -> string list -> string list |
65 |
66 |
66 datatype stmt = |
67 datatype stmt = |
67 NoStmt |
68 NoStmt |
68 | Fun of (typscheme * ((iterm list * iterm) * (thm option * bool)) list) * thm option |
69 | Fun of (typscheme * ((iterm list * iterm) * (thm option * bool)) list) * thm option |
69 | Datatype of vname list * |
70 | Datatype of vname list * |
231 and fold_clause vs (p, t) = fold_term (add_vars p vs) t; |
232 and fold_clause vs (p, t) = fold_term (add_vars p vs) t; |
232 in fold_term [] end |
233 in fold_term [] end |
233 fun add_vars t = fold_aux add_vars (insert (op =)) t; |
234 fun add_vars t = fold_aux add_vars (insert (op =)) t; |
234 in fold_aux add_vars f end; |
235 in fold_aux add_vars f end; |
235 |
236 |
|
237 val add_varnames = fold_varnames (insert (op =)); |
|
238 |
|
239 val declare_varnames = fold_varnames Name.declare; |
|
240 |
236 fun exists_var t v = fold_varnames (fn w => fn b => v = w orelse b) t false; |
241 fun exists_var t v = fold_varnames (fn w => fn b => v = w orelse b) t false; |
237 |
242 |
238 fun split_pat_abs ((NONE, ty) `|=> t) = SOME ((IVar NONE, ty), t) |
243 fun split_pat_abs ((NONE, ty) `|=> t) = SOME ((IVar NONE, ty), t) |
239 | split_pat_abs ((SOME v, ty) `|=> t) = SOME (case t |
244 | split_pat_abs ((SOME v, ty) `|=> t) = SOME (case t |
240 of ICase { term = IVar (SOME w), clauses = [(p, body)], ... } => |
245 of ICase { term = IVar (SOME w), clauses = [(p, body)], ... } => |
251 let |
256 let |
252 val (vs_tys, t') = unfold_abs_eta tys t; |
257 val (vs_tys, t') = unfold_abs_eta tys t; |
253 in (v_ty :: vs_tys, t') end |
258 in (v_ty :: vs_tys, t') end |
254 | unfold_abs_eta tys t = |
259 | unfold_abs_eta tys t = |
255 let |
260 let |
256 val ctxt = fold_varnames Name.declare t Name.context; |
261 val ctxt = Name.build_context (declare_varnames t); |
257 val vs_tys = (map o apfst) SOME (Name.invent_names ctxt "a" tys); |
262 val vs_tys = (map o apfst) SOME (Name.invent_names ctxt "a" tys); |
258 in (vs_tys, t `$$ map (IVar o fst) vs_tys) end; |
263 in (vs_tys, t `$$ map (IVar o fst) vs_tys) end; |
259 |
264 |
260 fun eta_expand k (const as { dom = tys, ... }, ts) = |
265 fun eta_expand k (const as { dom = tys, ... }, ts) = |
261 let |
266 let |
262 val j = length ts; |
267 val j = length ts; |
263 val l = k - j; |
268 val l = k - j; |
264 val _ = if l > length tys |
269 val _ = if l > length tys |
265 then error "Impossible eta-expansion" else (); |
270 then error "Impossible eta-expansion" else (); |
266 val vars = (fold o fold_varnames) Name.declare ts Name.context; |
271 val vars = Name.build_context (fold declare_varnames ts); |
267 val vs_tys = (map o apfst) SOME |
272 val vs_tys = (map o apfst) SOME |
268 (Name.invent_names vars "a" ((take l o drop j) tys)); |
273 (Name.invent_names vars "a" ((take l o drop j) tys)); |
269 in vs_tys `|==> IConst const `$$ ts @ map (IVar o fst) vs_tys end; |
274 in vs_tys `|==> IConst const `$$ ts @ map (IVar o fst) vs_tys end; |
270 |
275 |
271 fun map_terms_bottom_up f (t as IConst _) = f t |
276 fun map_terms_bottom_up f (t as IConst _) = f t |
287 then [] |
292 then [] |
288 else [(pat_args, body)] |
293 else [(pat_args, body)] |
289 | distill vs_map pat_args |
294 | distill vs_map pat_args |
290 (body as ICase { term = IVar (SOME v), clauses = clauses, ... }) = |
295 (body as ICase { term = IVar (SOME v), clauses = clauses, ... }) = |
291 let |
296 let |
292 val vs = build ((fold o fold_varnames) (insert (op =)) pat_args); |
297 val vs = build (fold add_varnames pat_args); |
293 fun varnames_disjunctive pat = |
298 fun varnames_disjunctive pat = |
294 null (inter (op =) vs (build (fold_varnames (insert (op =)) pat))); |
299 null (inter (op =) vs (build (add_varnames pat))); |
295 fun purge_unused_vars_in t = |
300 fun purge_unused_vars_in t = |
296 let |
301 let |
297 val vs = build (fold_varnames (insert (op =)) t); |
302 val vs = build (add_varnames t); |
298 in |
303 in |
299 map_terms_bottom_up (fn IVar (SOME v) => |
304 map_terms_bottom_up (fn IVar (SOME v) => |
300 IVar (if member (op =) vs v then SOME v else NONE) | t => t) |
305 IVar (if member (op =) vs v then SOME v else NONE) | t => t) |
301 end; |
306 end; |
302 in |
307 in |