64 |
64 |
65 |
65 |
66 (* complete splitting of partially splitted rules *) |
66 (* complete splitting of partially splitted rules *) |
67 |
67 |
68 fun ap_split' (T::Ts) U u = Abs ("v", T, ap_split' Ts U |
68 fun ap_split' (T::Ts) U u = Abs ("v", T, ap_split' Ts U |
69 (ap_split T (flat (map HOLogic.prodT_factors Ts) ---> U) |
69 (ap_split T (List.concat (map HOLogic.prodT_factors Ts) ---> U) |
70 (incr_boundvars 1 u) $ Bound 0)) |
70 (incr_boundvars 1 u) $ Bound 0)) |
71 | ap_split' _ _ u = u; |
71 | ap_split' _ _ u = u; |
72 |
72 |
73 fun complete_split_rule_var ((t as Var (v, T), ts), (rl, vs)) = |
73 fun complete_split_rule_var ((t as Var (v, T), ts), (rl, vs)) = |
74 let |
74 let |
75 val cterm = Thm.cterm_of (#sign (Thm.rep_thm rl)) |
75 val cterm = Thm.cterm_of (#sign (Thm.rep_thm rl)) |
76 val (Us', U') = strip_type T; |
76 val (Us', U') = strip_type T; |
77 val Us = take (length ts, Us'); |
77 val Us = Library.take (length ts, Us'); |
78 val U = drop (length ts, Us') ---> U'; |
78 val U = Library.drop (length ts, Us') ---> U'; |
79 val T' = flat (map HOLogic.prodT_factors Us) ---> U; |
79 val T' = List.concat (map HOLogic.prodT_factors Us) ---> U; |
80 fun mk_tuple ((xs, insts), v as Var ((a, _), T)) = |
80 fun mk_tuple ((xs, insts), v as Var ((a, _), T)) = |
81 let |
81 let |
82 val Ts = HOLogic.prodT_factors T; |
82 val Ts = HOLogic.prodT_factors T; |
83 val ys = Term.variantlist (replicate (length Ts) a, xs); |
83 val ys = Term.variantlist (replicate (length Ts) a, xs); |
84 in (xs @ ys, (cterm v, cterm (HOLogic.mk_tuple T |
84 in (xs @ ys, (cterm v, cterm (HOLogic.mk_tuple T |
85 (map (Var o apfst (rpair 0)) (ys ~~ Ts))))::insts) |
85 (map (Var o apfst (rpair 0)) (ys ~~ Ts))))::insts) |
86 end |
86 end |
87 | mk_tuple (x, _) = x; |
87 | mk_tuple (x, _) = x; |
88 val newt = ap_split' Us U (Var (v, T')); |
88 val newt = ap_split' Us U (Var (v, T')); |
89 val cterm = Thm.cterm_of (#sign (Thm.rep_thm rl)); |
89 val cterm = Thm.cterm_of (#sign (Thm.rep_thm rl)); |
90 val (vs', insts) = foldl mk_tuple ((vs, []), ts); |
90 val (vs', insts) = Library.foldl mk_tuple ((vs, []), ts); |
91 in |
91 in |
92 (instantiate ([], [(cterm t, cterm newt)] @ insts) rl, vs') |
92 (instantiate ([], [(cterm t, cterm newt)] @ insts) rl, vs') |
93 end |
93 end |
94 | complete_split_rule_var (_, x) = x; |
94 | complete_split_rule_var (_, x) = x; |
95 |
95 |
96 fun collect_vars (vs, Abs (_, _, t)) = collect_vars (vs, t) |
96 fun collect_vars (vs, Abs (_, _, t)) = collect_vars (vs, t) |
97 | collect_vars (vs, t) = (case strip_comb t of |
97 | collect_vars (vs, t) = (case strip_comb t of |
98 (v as Var _, ts) => (v, ts)::vs |
98 (v as Var _, ts) => (v, ts)::vs |
99 | (t, ts) => foldl collect_vars (vs, ts)); |
99 | (t, ts) => Library.foldl collect_vars (vs, ts)); |
100 |
100 |
101 |
101 |
102 val split_rule_var = Drule.standard o remove_internal_split o split_rule_var'; |
102 val split_rule_var = Drule.standard o remove_internal_split o split_rule_var'; |
103 |
103 |
104 (*curries ALL function variables occurring in a rule's conclusion*) |
104 (*curries ALL function variables occurring in a rule's conclusion*) |
105 fun split_rule rl = |
105 fun split_rule rl = |
106 foldr split_rule_var' (Term.term_vars (concl_of rl), rl) |
106 Library.foldr split_rule_var' (Term.term_vars (concl_of rl), rl) |
107 |> remove_internal_split |
107 |> remove_internal_split |
108 |> Drule.standard; |
108 |> Drule.standard; |
109 |
109 |
110 fun complete_split_rule rl = |
110 fun complete_split_rule rl = |
111 fst (foldr complete_split_rule_var |
111 fst (Library.foldr complete_split_rule_var |
112 (collect_vars ([], concl_of rl), |
112 (collect_vars ([], concl_of rl), |
113 (rl, map (fst o fst o dest_Var) (Term.term_vars (#prop (Thm.rep_thm rl)))))) |
113 (rl, map (fst o fst o dest_Var) (Term.term_vars (#prop (Thm.rep_thm rl)))))) |
114 |> remove_internal_split |
114 |> remove_internal_split |
115 |> Drule.standard |
115 |> Drule.standard |
116 |> RuleCases.save rl; |
116 |> RuleCases.save rl; |