223 | mk_partial_compN n gT fT g = |
223 | mk_partial_compN n gT fT g = |
224 let val g' = mk_partial_compN (n - 1) gT (range_type fT) g in |
224 let val g' = mk_partial_compN (n - 1) gT (range_type fT) g in |
225 mk_partial_comp (fastype_of g') fT g' |
225 mk_partial_comp (fastype_of g') fT g' |
226 end; |
226 end; |
227 |
227 |
228 fun mk_compN bound_Ts n (g, f) = |
228 fun mk_compN n bound_Ts (g, f) = |
229 let val typof = curry fastype_of1 bound_Ts in |
229 let val typof = curry fastype_of1 bound_Ts in |
230 mk_partial_compN n (typof g) (typof f) g $ f |
230 mk_partial_compN n (typof g) (typof f) g $ f |
231 end; |
231 end; |
|
232 |
|
233 val mk_comp = mk_compN 1; |
232 |
234 |
233 fun factor_out_types ctxt massage destU U T = |
235 fun factor_out_types ctxt massage destU U T = |
234 (case try destU U of |
236 (case try destU U of |
235 SOME (U1, U2) => if U1 = T then massage T U2 else invalid_map ctxt |
237 SOME (U1, U2) => if U1 = T then massage T U2 else invalid_map ctxt |
236 | NONE => invalid_map ctxt); |
238 | NONE => invalid_map ctxt); |
243 permute_like (op aconv) flat_fs fs flat_fs' |
245 permute_like (op aconv) flat_fs fs flat_fs' |
244 end; |
246 end; |
245 |
247 |
246 fun massage_nested_rec_call ctxt has_call raw_massage_fun bound_Ts y y' = |
248 fun massage_nested_rec_call ctxt has_call raw_massage_fun bound_Ts y y' = |
247 let |
249 let |
|
250 fun check_no_call t = if has_call t then unexpected_rec_call ctxt t else (); |
|
251 |
248 val typof = curry fastype_of1 bound_Ts; |
252 val typof = curry fastype_of1 bound_Ts; |
249 val build_map_fst = build_map ctxt (fst_const o fst); |
253 val build_map_fst = build_map ctxt (fst_const o fst); |
250 |
254 |
251 val yT = typof y; |
255 val yT = typof y; |
252 val yU = typof y'; |
256 val yU = typof y'; |
253 |
257 |
254 fun y_of_y' () = build_map_fst (yU, yT) $ y'; |
258 fun y_of_y' () = build_map_fst (yU, yT) $ y'; |
255 val elim_y = Term.map_aterms (fn t => if t = y then y_of_y' () else t); |
259 val elim_y = Term.map_aterms (fn t => if t = y then y_of_y' () else t); |
256 |
260 |
257 fun massage_mutual_fun U T t = |
261 fun massage_mutual_fun U T t = |
258 if has_call t then factor_out_types ctxt raw_massage_fun HOLogic.dest_prodT U T t |
262 (case t of |
259 else HOLogic.mk_comp (t, build_map_fst (U, T)); |
263 Const (@{const_name comp}, comp_T) $ t1 $ t2 => |
|
264 mk_comp bound_Ts (tap check_no_call t1, massage_mutual_fun U T t2) |
|
265 | _ => |
|
266 if has_call t then factor_out_types ctxt raw_massage_fun HOLogic.dest_prodT U T t |
|
267 else mk_comp bound_Ts (t, build_map_fst (U, T))); |
260 |
268 |
261 fun massage_map (Type (_, Us)) (Type (s, Ts)) t = |
269 fun massage_map (Type (_, Us)) (Type (s, Ts)) t = |
262 (case try (dest_map ctxt s) t of |
270 (case try (dest_map ctxt s) t of |
263 SOME (map0, fs) => |
271 SOME (map0, fs) => |
264 let |
272 let |
270 end |
278 end |
271 | NONE => raise AINT_NO_MAP t) |
279 | NONE => raise AINT_NO_MAP t) |
272 | massage_map _ _ t = raise AINT_NO_MAP t |
280 | massage_map _ _ t = raise AINT_NO_MAP t |
273 and massage_map_or_map_arg U T t = |
281 and massage_map_or_map_arg U T t = |
274 if T = U then |
282 if T = U then |
275 if has_call t then unexpected_rec_call ctxt t else t |
283 tap check_no_call t |
276 else |
284 else |
277 massage_map U T t |
285 massage_map U T t |
278 handle AINT_NO_MAP _ => massage_mutual_fun U T t; |
286 handle AINT_NO_MAP _ => massage_mutual_fun U T t; |
279 |
287 |
280 fun massage_call (t as t1 $ t2) = |
288 fun massage_call (t as t1 $ t2) = |
284 handle AINT_NO_MAP t' => invalid_map ctxt t' |
292 handle AINT_NO_MAP t' => invalid_map ctxt t' |
285 else |
293 else |
286 let val (g, xs) = Term.strip_comb t2 in |
294 let val (g, xs) = Term.strip_comb t2 in |
287 if g = y then |
295 if g = y then |
288 if exists has_call xs then unexpected_rec_call ctxt t2 |
296 if exists has_call xs then unexpected_rec_call ctxt t2 |
289 else Term.list_comb (massage_call (mk_compN bound_Ts (length xs) (t1, y)), xs) |
297 else Term.list_comb (massage_call (mk_compN (length xs) bound_Ts (t1, y)), xs) |
290 else |
298 else |
291 ill_formed_rec_call ctxt t |
299 ill_formed_rec_call ctxt t |
292 end |
300 end |
293 else |
301 else |
294 elim_y t |
302 elim_y t |
409 else build_map_Inl (T, U) $ t; |
417 else build_map_Inl (T, U) $ t; |
410 |
418 |
411 fun massage_mutual_fun bound_Ts U T t = |
419 fun massage_mutual_fun bound_Ts U T t = |
412 (case t of |
420 (case t of |
413 Const (@{const_name comp}, comp_T) $ t1 $ t2 => |
421 Const (@{const_name comp}, comp_T) $ t1 $ t2 => |
414 mk_compN bound_Ts 1 (massage_mutual_fun bound_Ts U T t1, tap check_no_call t2) |
422 mk_comp bound_Ts (massage_mutual_fun bound_Ts U T t1, tap check_no_call t2) |
415 | _ => |
423 | _ => |
416 let |
424 let |
417 val var = Var ((Name.uu, Term.maxidx_of_term t + 1), |
425 val var = Var ((Name.uu, Term.maxidx_of_term t + 1), |
418 domain_type (fastype_of1 (bound_Ts, t))); |
426 domain_type (fastype_of1 (bound_Ts, t))); |
419 in |
427 in |