51 fun ap_split' (T::Ts) U u = Abs ("v", T, ap_split' Ts U |
51 fun ap_split' (T::Ts) U u = Abs ("v", T, ap_split' Ts U |
52 (ap_split T (maps HOLogic.flatten_tupleT Ts ---> U) |
52 (ap_split T (maps HOLogic.flatten_tupleT Ts ---> U) |
53 (incr_boundvars 1 u) $ Bound 0)) |
53 (incr_boundvars 1 u) $ Bound 0)) |
54 | ap_split' _ _ u = u; |
54 | ap_split' _ _ u = u; |
55 |
55 |
56 fun complete_split_rule_var (t as Var (v, T), ts) (rl, vs) = |
56 fun complete_split_rule_var ctxt (t as Var (v, T), ts) (rl, vs) = |
57 let |
57 let |
58 val cterm = Thm.global_cterm_of (Thm.theory_of_thm rl) |
|
59 val (Us', U') = strip_type T; |
58 val (Us', U') = strip_type T; |
60 val Us = take (length ts) Us'; |
59 val Us = take (length ts) Us'; |
61 val U = drop (length ts) Us' ---> U'; |
60 val U = drop (length ts) Us' ---> U'; |
62 val T' = maps HOLogic.flatten_tupleT Us ---> U; |
61 val T' = maps HOLogic.flatten_tupleT Us ---> U; |
63 fun mk_tuple (v as Var ((a, _), T)) (xs, insts) = |
62 fun mk_tuple (v as Var ((a, _), T)) (xs, insts) = |
64 let |
63 let |
65 val Ts = HOLogic.flatten_tupleT T; |
64 val Ts = HOLogic.flatten_tupleT T; |
66 val ys = Name.variant_list xs (replicate (length Ts) a); |
65 val ys = Name.variant_list xs (replicate (length Ts) a); |
67 in (xs @ ys, (cterm v, cterm (HOLogic.mk_ptuple (HOLogic.flat_tupleT_paths T) T |
66 in |
68 (map (Var o apfst (rpair 0)) (ys ~~ Ts))))::insts) |
67 (xs @ ys, |
|
68 apply2 (Thm.cterm_of ctxt) |
|
69 (v, HOLogic.mk_ptuple (HOLogic.flat_tupleT_paths T) T |
|
70 (map (Var o apfst (rpair 0)) (ys ~~ Ts))) :: insts) |
69 end |
71 end |
70 | mk_tuple _ x = x; |
72 | mk_tuple _ x = x; |
71 val newt = ap_split' Us U (Var (v, T')); |
73 val newt = ap_split' Us U (Var (v, T')); |
72 val cterm = Thm.global_cterm_of (Thm.theory_of_thm rl); |
|
73 val (vs', insts) = fold mk_tuple ts (vs, []); |
74 val (vs', insts) = fold mk_tuple ts (vs, []); |
74 in |
75 in |
75 (Drule.instantiate_normalize ([], [(cterm t, cterm newt)] @ insts) rl, vs') |
76 (Drule.instantiate_normalize ([], [apply2 (Thm.cterm_of ctxt) (t, newt)] @ insts) rl, vs') |
76 end |
77 end |
77 | complete_split_rule_var _ x = x; |
78 | complete_split_rule_var _ _ x = x; |
78 |
79 |
79 fun collect_vars (Abs (_, _, t)) = collect_vars t |
80 fun collect_vars (Abs (_, _, t)) = collect_vars t |
80 | collect_vars t = |
81 | collect_vars t = |
81 (case strip_comb t of |
82 (case strip_comb t of |
82 (v as Var _, ts) => cons (v, ts) |
83 (v as Var _, ts) => cons (v, ts) |
97 let |
98 let |
98 val prop = Thm.prop_of rl; |
99 val prop = Thm.prop_of rl; |
99 val xs = Term.fold_aterms (fn Var ((x, _), _) => insert (op =) x | _ => I) prop []; |
100 val xs = Term.fold_aterms (fn Var ((x, _), _) => insert (op =) x | _ => I) prop []; |
100 val vars = collect_vars prop []; |
101 val vars = collect_vars prop []; |
101 in |
102 in |
102 fst (fold_rev complete_split_rule_var vars (rl, xs)) |
103 fst (fold_rev (complete_split_rule_var ctxt) vars (rl, xs)) |
103 |> remove_internal_split ctxt |
104 |> remove_internal_split ctxt |
104 |> Drule.export_without_context |
105 |> Drule.export_without_context |
105 |> Rule_Cases.save rl |
106 |> Rule_Cases.save rl |
106 end; |
107 end; |
107 |
108 |