253 let |
253 let |
254 val thy = Proof_Context.theory_of ctxt; |
254 val thy = Proof_Context.theory_of ctxt; |
255 |
255 |
256 fun check_no_call t = if has_call t then unexpected_corec_call ctxt t else (); |
256 fun check_no_call t = if has_call t then unexpected_corec_call ctxt t else (); |
257 |
257 |
258 fun massage_rec bound_Ts t = |
258 fun massage_abs bound_Ts (Abs (s, T, t)) = massage_abs (T :: bound_Ts) t |
|
259 | massage_abs bound_Ts t = massage_rec bound_Ts t |
|
260 and massage_rec bound_Ts t = |
259 let val typof = curry fastype_of1 bound_Ts in |
261 let val typof = curry fastype_of1 bound_Ts in |
260 (case Term.strip_comb t of |
262 (case Term.strip_comb t of |
261 (Const (@{const_name Let}, _), [arg1, arg2]) => |
263 (Const (@{const_name Let}, _), [arg1, arg2]) => |
262 massage_rec bound_Ts (betapply (arg2, arg1)) |
264 massage_rec bound_Ts (betapply (arg2, arg1)) |
263 | (Const (@{const_name If}, _), obj :: (branches as [then_branch, _])) => |
265 | (Const (@{const_name If}, _), obj :: (branches as [_, _])) => |
264 let val branches' = map (massage_rec bound_Ts) branches in |
266 let val branches' = map (massage_rec bound_Ts) branches in |
265 Term.list_comb (If_const (typof (hd branches')) $ tap check_no_call obj, branches') |
267 Term.list_comb (If_const (typof (hd branches')) $ tap check_no_call obj, branches') |
266 end |
268 end |
267 | (Const (c, _), args as _ :: _) => |
269 | (Const (c, _), args as _ :: _) => |
268 let val n = num_binder_types (Sign.the_const_type thy c) in |
270 let val n = num_binder_types (Sign.the_const_type thy c) in |
270 (case fastype_of1 (bound_Ts, nth args (n - 1)) of |
272 (case fastype_of1 (bound_Ts, nth args (n - 1)) of |
271 Type (s, Ts) => |
273 Type (s, Ts) => |
272 if case_of ctxt s = SOME c then |
274 if case_of ctxt s = SOME c then |
273 let |
275 let |
274 val (branches, obj_leftovers) = chop n args; |
276 val (branches, obj_leftovers) = chop n args; |
275 val branches' = map (massage_rec bound_Ts) branches; |
277 val branches' = map (massage_abs bound_Ts o Envir.eta_long bound_Ts) branches; |
276 val casex' = Const (c, map typof branches' ---> map typof obj_leftovers ---> |
278 val casex' = Const (c, map typof branches' ---> map typof obj_leftovers ---> |
277 typof t); |
279 typof t); |
278 in |
280 in |
279 betapplys (casex', branches' @ tap (List.app check_no_call) obj_leftovers) |
281 betapplys (casex', branches' @ tap (List.app check_no_call) obj_leftovers) |
280 end |
282 end |
368 | NONE => raise Fail "expand_ctr_term"); |
370 | NONE => raise Fail "expand_ctr_term"); |
369 |
371 |
370 fun expand_corec_code_rhs ctxt has_call bound_Ts t = |
372 fun expand_corec_code_rhs ctxt has_call bound_Ts t = |
371 (case fastype_of1 (bound_Ts, t) of |
373 (case fastype_of1 (bound_Ts, t) of |
372 Type (s, Ts) => |
374 Type (s, Ts) => |
373 massage_let_if_case ctxt has_call (fn bound_Ts => fn t => |
375 massage_let_if_case ctxt has_call (fn _ => fn t => |
374 if can (dest_ctr ctxt s) t then t else expand_ctr_term ctxt s Ts t) bound_Ts t |
376 if can (dest_ctr ctxt s) t then t else expand_ctr_term ctxt s Ts t) bound_Ts t |
375 | _ => raise Fail "expand_corec_code_rhs"); |
377 | _ => raise Fail "expand_corec_code_rhs"); |
376 |
378 |
377 fun massage_corec_code_rhs ctxt massage_ctr = |
379 fun massage_corec_code_rhs ctxt massage_ctr = |
378 massage_let_if_case ctxt (K false) |
380 massage_let_if_case ctxt (K false) |