148 val flat_fs' = map_args flat_fs; |
148 val flat_fs' = map_args flat_fs; |
149 in |
149 in |
150 permute_like (op aconv) flat_fs fs flat_fs' |
150 permute_like (op aconv) flat_fs fs flat_fs' |
151 end; |
151 end; |
152 |
152 |
153 fun massage_indirect_rec_call ctxt has_call massage_unapplied_direct_call bound_Ts y y' = |
153 fun massage_indirect_rec_call ctxt has_call raw_massage_fun bound_Ts y y' = |
154 let |
154 let |
155 val typof = curry fastype_of1 bound_Ts; |
155 val typof = curry fastype_of1 bound_Ts; |
156 val build_map_fst = build_map ctxt (fst_const o fst); |
156 val build_map_fst = build_map ctxt (fst_const o fst); |
157 |
157 |
158 val yT = typof y; |
158 val yT = typof y; |
159 val yU = typof y'; |
159 val yU = typof y'; |
160 |
160 |
161 fun y_of_y' () = build_map_fst (yU, yT) $ y'; |
161 fun y_of_y' () = build_map_fst (yU, yT) $ y'; |
162 val elim_y = Term.map_aterms (fn t => if t = y then y_of_y' () else t); |
162 val elim_y = Term.map_aterms (fn t => if t = y then y_of_y' () else t); |
163 |
163 |
164 fun check_and_massage_unapplied_direct_call U T t = |
164 fun massage_direct_fun U T t = |
165 if has_call t then |
165 if has_call t then factor_out_types ctxt raw_massage_fun HOLogic.dest_prodT U T t |
166 factor_out_types ctxt massage_unapplied_direct_call HOLogic.dest_prodT U T t |
166 else HOLogic.mk_comp (t, build_map_fst (U, T)); |
167 else |
|
168 HOLogic.mk_comp (t, build_map_fst (U, T)); |
|
169 |
167 |
170 fun massage_map (Type (_, Us)) (Type (s, Ts)) t = |
168 fun massage_map (Type (_, Us)) (Type (s, Ts)) t = |
171 (case try (dest_map ctxt s) t of |
169 (case try (dest_map ctxt s) t of |
172 SOME (map0, fs) => |
170 SOME (map0, fs) => |
173 let |
171 let |
182 and massage_map_or_map_arg U T t = |
180 and massage_map_or_map_arg U T t = |
183 if T = U then |
181 if T = U then |
184 if has_call t then unexpected_rec_call ctxt t else t |
182 if has_call t then unexpected_rec_call ctxt t else t |
185 else |
183 else |
186 massage_map U T t |
184 massage_map U T t |
187 handle AINT_NO_MAP _ => check_and_massage_unapplied_direct_call U T t; |
185 handle AINT_NO_MAP _ => massage_direct_fun U T t; |
188 |
186 |
189 fun massage_call (t as t1 $ t2) = |
187 fun massage_call (t as t1 $ t2) = |
190 if t2 = y then |
188 if t2 = y then |
191 massage_map yU yT (elim_y t1) $ y' |
189 massage_map yU yT (elim_y t1) $ y' |
192 handle AINT_NO_MAP t' => invalid_map ctxt t' |
190 handle AINT_NO_MAP t' => invalid_map ctxt t' |
219 | _ => f t) |
217 | _ => f t) |
220 in |
218 in |
221 fld |
219 fld |
222 end; |
220 end; |
223 |
221 |
224 fun massage_direct_corec_call ctxt has_call massage_direct_call U t = |
222 fun massage_direct_corec_call ctxt has_call raw_massage_call U t = |
225 massage_let_and_if ctxt has_call massage_direct_call U t; |
223 massage_let_and_if ctxt has_call raw_massage_call U t; |
226 |
224 |
227 fun massage_indirect_corec_call ctxt has_call massage_direct_call bound_Ts U t = |
225 fun massage_indirect_corec_call ctxt has_call raw_massage_call bound_Ts U t = |
228 let |
226 let |
229 val typof = curry fastype_of1 bound_Ts; |
227 val typof = curry fastype_of1 bound_Ts; |
230 val build_map_Inl = build_map ctxt (uncurry Inl_const o dest_sumT o snd) |
228 val build_map_Inl = build_map ctxt (uncurry Inl_const o dest_sumT o snd) |
231 |
229 |
232 fun check_and_massage_direct_call U T t = |
230 fun massage_direct_call U T t = |
233 if has_call t then factor_out_types ctxt massage_direct_call dest_sumT U T t |
231 if has_call t then factor_out_types ctxt raw_massage_call dest_sumT U T t |
234 else build_map_Inl (T, U) $ t; |
232 else build_map_Inl (T, U) $ t; |
235 |
233 |
236 fun check_and_massage_unapplied_direct_call U T t = |
234 fun massage_direct_fun U T t = |
237 let val var = Var ((Name.uu, Term.maxidx_of_term t + 1), domain_type (typof t)) in |
235 let val var = Var ((Name.uu, Term.maxidx_of_term t + 1), domain_type (typof t)) in |
238 Term.lambda var (check_and_massage_direct_call U T (t $ var)) |
236 Term.lambda var (massage_direct_call U T (t $ var)) |
239 end; |
237 end; |
240 |
238 |
241 fun massage_map (Type (_, Us)) (Type (s, Ts)) t = |
239 fun massage_map (Type (_, Us)) (Type (s, Ts)) t = |
242 (case try (dest_map ctxt s) t of |
240 (case try (dest_map ctxt s) t of |
243 SOME (map0, fs) => |
241 SOME (map0, fs) => |
253 and massage_map_or_map_arg U T t = |
251 and massage_map_or_map_arg U T t = |
254 if T = U then |
252 if T = U then |
255 if has_call t then unexpected_corec_call ctxt t else t |
253 if has_call t then unexpected_corec_call ctxt t else t |
256 else |
254 else |
257 massage_map U T t |
255 massage_map U T t |
258 handle AINT_NO_MAP _ => check_and_massage_unapplied_direct_call U T t; |
256 handle AINT_NO_MAP _ => massage_direct_fun U T t; |
259 |
257 |
260 fun massage_call U T = |
258 fun massage_call U T = |
261 massage_let_and_if ctxt has_call (fn t => |
259 massage_let_and_if ctxt has_call (fn t => |
262 if has_call t then |
260 if has_call t then |
263 (case U of |
261 (case U of |
269 end |
267 end |
270 | NONE => |
268 | NONE => |
271 (case t of |
269 (case t of |
272 t1 $ t2 => |
270 t1 $ t2 => |
273 (if has_call t2 then |
271 (if has_call t2 then |
274 check_and_massage_direct_call U T t |
272 massage_direct_call U T t |
275 else |
273 else |
276 massage_map U T t1 $ t2 |
274 massage_map U T t1 $ t2 |
277 handle AINT_NO_MAP _ => check_and_massage_direct_call U T t) |
275 handle AINT_NO_MAP _ => massage_direct_call U T t) |
278 | Abs (s, T', t') => Abs (s, T', massage_call (range_type U) (range_type T) t') |
276 | Abs (s, T', t') => Abs (s, T', massage_call (range_type U) (range_type T) t') |
279 | _ => check_and_massage_direct_call U T t)) |
277 | _ => massage_direct_call U T t)) |
280 | _ => ill_formed_corec_call ctxt t) |
278 | _ => ill_formed_corec_call ctxt t) |
281 else |
279 else |
282 build_map_Inl (T, U) $ t) U |
280 build_map_Inl (T, U) $ t) U |
283 in |
281 in |
284 massage_call U (typof t) t |
282 massage_call U (typof t) t |