49 val fold_rev_let_if_case: Proof.context -> (term list -> term -> 'a -> 'a) -> typ list -> |
49 val fold_rev_let_if_case: Proof.context -> (term list -> term -> 'a -> 'a) -> typ list -> |
50 term -> 'a -> 'a |
50 term -> 'a -> 'a |
51 val massage_let_if_case: Proof.context -> (term -> bool) -> (typ list -> term -> term) -> |
51 val massage_let_if_case: Proof.context -> (term -> bool) -> (typ list -> term -> term) -> |
52 typ list -> term -> term |
52 typ list -> term -> term |
53 val massage_nested_corec_call: Proof.context -> (term -> bool) -> |
53 val massage_nested_corec_call: Proof.context -> (term -> bool) -> |
54 (typ list -> typ -> typ -> term -> term) -> (typ -> typ -> term -> term) -> typ list -> typ -> |
54 (typ list -> typ -> typ -> term -> term) -> (typ list -> typ -> typ -> term -> term) -> |
55 term -> term |
55 typ list -> typ -> typ -> term -> term |
56 val expand_to_ctr_term: Proof.context -> string -> typ list -> term -> term |
56 val expand_to_ctr_term: Proof.context -> string -> typ list -> term -> term |
57 val massage_corec_code_rhs: Proof.context -> (typ list -> term -> term list -> term) -> |
57 val massage_corec_code_rhs: Proof.context -> (typ list -> term -> term list -> term) -> |
58 typ list -> term -> term |
58 typ list -> term -> term |
59 val fold_rev_corec_code_rhs: Proof.context -> (term list -> term -> term list -> 'a -> 'a) -> |
59 val fold_rev_corec_code_rhs: Proof.context -> (term list -> term -> term list -> 'a -> 'a) -> |
60 typ list -> term -> 'a -> 'a |
60 typ list -> term -> 'a -> 'a |
304 if Term.is_dummy_pattern t then Const (@{const_name undefined}, fastype_of t) else t) |
304 if Term.is_dummy_pattern t then Const (@{const_name undefined}, fastype_of t) else t) |
305 end; |
305 end; |
306 |
306 |
307 fun curried_type (Type (@{type_name fun}, [Type (@{type_name prod}, Ts), T])) = Ts ---> T; |
307 fun curried_type (Type (@{type_name fun}, [Type (@{type_name prod}, Ts), T])) = Ts ---> T; |
308 |
308 |
309 fun massage_nested_corec_call ctxt has_call massage_call wrap_noncall bound_Ts U t0 = |
309 fun massage_nested_corec_call ctxt has_call massage_call massage_noncall bound_Ts U T t0 = |
310 let |
310 let |
311 fun check_no_call t = if has_call t then unexpected_corec_call ctxt [t0] t else (); |
311 fun check_no_call t = if has_call t then unexpected_corec_call ctxt [t0] t else (); |
312 |
312 |
313 fun massage_mutual_call bound_Ts (Type (@{type_name fun}, [_, U2])) |
313 fun massage_mutual_call bound_Ts (Type (@{type_name fun}, [_, U2])) |
314 (Type (@{type_name fun}, [T1, T2])) t = |
314 (Type (@{type_name fun}, [T1, T2])) t = |
315 Abs (Name.uu, T1, massage_mutual_call bound_Ts U2 T2 (incr_boundvars 1 t $ Bound 0)) |
315 Abs (Name.uu, T1, massage_mutual_call bound_Ts U2 T2 (incr_boundvars 1 t $ Bound 0)) |
316 | massage_mutual_call bound_Ts U T t = |
316 | massage_mutual_call bound_Ts U T t = |
317 if has_call t then massage_call bound_Ts T U t else wrap_noncall T U t; |
317 (if has_call t then massage_call else massage_noncall) bound_Ts U T t; |
318 |
318 |
319 fun massage_map bound_Ts (Type (_, Us)) (Type (s, Ts)) t = |
319 fun massage_map bound_Ts (Type (_, Us)) (Type (s, Ts)) t = |
320 (case try (dest_map ctxt s) t of |
320 (case try (dest_map ctxt s) t of |
321 SOME (map0, fs) => |
321 SOME (map0, fs) => |
322 let |
322 let |
372 in |
372 in |
373 Const (@{const_name case_prod}, U' --> U) $ massage_any_call bound_Ts U' T' t' |
373 Const (@{const_name case_prod}, U' --> U) $ massage_any_call bound_Ts U' T' t' |
374 end |
374 end |
375 | t1 $ t2 => |
375 | t1 $ t2 => |
376 (if has_call t2 then |
376 (if has_call t2 then |
377 massage_mutual_call bound_Ts U T t |
377 massage_mutual_call bound_Ts U T t |
378 else |
378 else |
379 massage_map bound_Ts U T t1 $ t2 |
379 massage_map bound_Ts U T t1 $ t2 |
380 handle NO_MAP _ => massage_mutual_call bound_Ts U T t) |
380 handle NO_MAP _ => massage_mutual_call bound_Ts U T t) |
381 | Abs (s, T', t') => |
381 | Abs (s, T', t') => |
382 Abs (s, T', massage_any_call (T' :: bound_Ts) (range_type U) (range_type T) t') |
382 Abs (s, T', massage_any_call (T' :: bound_Ts) (range_type U) (range_type T) t') |
383 | _ => massage_mutual_call bound_Ts U T t)) |
383 | _ => massage_mutual_call bound_Ts U T t)) |
384 | _ => ill_formed_corec_call ctxt t) |
384 | _ => ill_formed_corec_call ctxt t) |
385 else |
385 else |
386 wrap_noncall T U t) bound_Ts; |
386 massage_noncall bound_Ts U T t) bound_Ts; |
387 |
387 |
388 val T = fastype_of1 (bound_Ts, t0); |
388 val T = fastype_of1 (bound_Ts, t0); |
389 in |
389 in |
390 if has_call t0 then massage_any_call bound_Ts U T t0 else wrap_noncall T U t0 |
390 (if has_call t0 then massage_any_call else massage_noncall) bound_Ts U T t0 |
391 end; |
391 end; |
392 |
392 |
393 fun expand_to_ctr_term ctxt s Ts t = |
393 fun expand_to_ctr_term ctxt s Ts t = |
394 (case ctr_sugar_of ctxt s of |
394 (case ctr_sugar_of ctxt s of |
395 SOME {ctrs, casex, ...} => |
395 SOME {ctrs, casex, ...} => |
892 fun build_corec_arg_nested_call ctxt has_call (sel_eqns : coeqn_data_sel list) sel = |
892 fun build_corec_arg_nested_call ctxt has_call (sel_eqns : coeqn_data_sel list) sel = |
893 (case find_first (curry (op =) sel o #sel) sel_eqns of |
893 (case find_first (curry (op =) sel o #sel) sel_eqns of |
894 NONE => I |
894 NONE => I |
895 | SOME {fun_args, rhs_term, ...} => |
895 | SOME {fun_args, rhs_term, ...} => |
896 let |
896 let |
897 fun massage_call bound_Ts T U t0 = |
897 fun massage_call bound_Ts U T t0 = |
898 let |
898 let |
899 val U2 = |
899 val U2 = |
900 (case try dest_sumT U of |
900 (case try dest_sumT U of |
901 SOME (U1, U2) => if U1 = T then U2 else invalid_map ctxt t0 |
901 SOME (U1, U2) => if U1 = T then U2 else invalid_map ctxt t0 |
902 | NONE => invalid_map ctxt t0); |
902 | NONE => invalid_map ctxt t0); |
917 if is_Free t andalso has_call t then Inr_const T U2 $ HOLogic.unit else t; |
917 if is_Free t andalso has_call t then Inr_const T U2 $ HOLogic.unit else t; |
918 in |
918 in |
919 rewrite bound_Ts t0 |
919 rewrite bound_Ts t0 |
920 end; |
920 end; |
921 |
921 |
922 fun wrap_noncall T U t = build_map ctxt [] (uncurry Inl_const o dest_sumT o snd) (T, U) $ t; |
922 fun massage_noncall bound_Ts U T t = |
|
923 build_map ctxt [] (uncurry Inl_const o dest_sumT o snd) (T, U) $ t; |
923 |
924 |
924 val bound_Ts = List.rev (map fastype_of fun_args); |
925 val bound_Ts = List.rev (map fastype_of fun_args); |
925 |
|
926 fun build t = |
|
927 rhs_term |
|
928 |> massage_nested_corec_call ctxt has_call massage_call wrap_noncall bound_Ts |
|
929 (range_type (fastype_of t)) |
|
930 |> abs_tuple_balanced fun_args; |
|
931 in |
926 in |
932 build |
927 fn t => |
|
928 rhs_term |
|
929 |> massage_nested_corec_call ctxt has_call massage_call massage_noncall bound_Ts |
|
930 (range_type (fastype_of t)) (fastype_of1 (bound_Ts, rhs_term)) |
|
931 |> abs_tuple_balanced fun_args |
933 end); |
932 end); |
934 |
933 |
935 fun build_corec_args_sel ctxt has_call (all_sel_eqns : coeqn_data_sel list) |
934 fun build_corec_args_sel ctxt has_call (all_sel_eqns : coeqn_data_sel list) |
936 (ctr_spec : corec_ctr_spec) = |
935 (ctr_spec : corec_ctr_spec) = |
937 (case filter (curry (op =) (#ctr ctr_spec) o #ctr) all_sel_eqns of |
936 (case filter (curry (op =) (#ctr ctr_spec) o #ctr) all_sel_eqns of |