191 | massage_call t = if t = y then y_of_y' () else ill_formed_rec_call ctxt t; |
191 | massage_call t = if t = y then y_of_y' () else ill_formed_rec_call ctxt t; |
192 in |
192 in |
193 massage_call o Envir.beta_eta_contract |
193 massage_call o Envir.beta_eta_contract |
194 end; |
194 end; |
195 |
195 |
196 fun massage_let_and_if ctxt has_call massage_rec massage_else U T t = |
196 fun massage_let_and_if ctxt check_cond massage_else = |
197 (case Term.strip_comb t of |
197 let |
198 (Const (@{const_name Let}, _), [arg1, arg2]) => massage_rec U T (betapply (arg2, arg1)) |
198 fun massage_rec U T t = |
199 | (Const (@{const_name If}, _), arg :: args) => |
199 (case Term.strip_comb t of |
200 if has_call arg then unexpected_corec_call ctxt arg |
200 (Const (@{const_name Let}, _), [arg1, arg2]) => massage_rec U T (betapply (arg2, arg1)) |
201 else list_comb (If_const U $ arg, map (massage_rec U T) args) |
201 | (Const (@{const_name If}, _), arg :: args) => |
202 | _ => massage_else U T t); |
202 list_comb (If_const U $ tap check_cond arg, map (massage_rec U T) args) |
|
203 | _ => massage_else U T t) |
|
204 in |
|
205 massage_rec |
|
206 end; |
203 |
207 |
204 fun massage_direct_corec_call ctxt has_call massage_direct_call bound_Ts res_U t = |
208 fun massage_direct_corec_call ctxt has_call massage_direct_call bound_Ts res_U t = |
205 let |
209 let val typof = curry fastype_of1 bound_Ts in |
206 val typof = curry fastype_of1 bound_Ts; |
210 massage_let_and_if ctxt ((not o has_call) orf unexpected_corec_call ctxt) massage_direct_call |
207 |
211 res_U (typof t) (Envir.beta_eta_contract t) |
208 fun massage_call U T = |
|
209 massage_let_and_if ctxt has_call massage_call massage_direct_call U T; |
|
210 in |
|
211 massage_call res_U (typof t) (Envir.beta_eta_contract t) |
|
212 end; |
212 end; |
213 |
213 |
214 fun massage_indirect_corec_call ctxt has_call massage_direct_call bound_Ts res_U t = |
214 fun massage_indirect_corec_call ctxt has_call massage_direct_call bound_Ts res_U t = |
215 let |
215 let |
216 val typof = curry fastype_of1 bound_Ts; |
216 val typof = curry fastype_of1 bound_Ts; |
243 else |
243 else |
244 massage_map U T t |
244 massage_map U T t |
245 handle AINT_NO_MAP _ => check_and_massage_unapplied_direct_call U T t; |
245 handle AINT_NO_MAP _ => check_and_massage_unapplied_direct_call U T t; |
246 |
246 |
247 fun massage_call U T = |
247 fun massage_call U T = |
248 massage_let_and_if ctxt has_call massage_call |
248 massage_let_and_if ctxt ((not o has_call) orf unexpected_corec_call ctxt) |
249 (fn U => fn T => fn t => |
249 (fn U => fn T => fn t => |
250 (case U of |
250 (case U of |
251 Type (s, Us) => |
251 Type (s, Us) => |
252 (case try (dest_ctr ctxt s) t of |
252 (case try (dest_ctr ctxt s) t of |
253 SOME (f, args) => |
253 SOME (f, args) => |