20 signature RULE_CASES = |
20 signature RULE_CASES = |
21 sig |
21 sig |
22 include BASIC_RULE_CASES |
22 include BASIC_RULE_CASES |
23 datatype T = Case of |
23 datatype T = Case of |
24 {fixes: (binding * typ) list, |
24 {fixes: (binding * typ) list, |
25 assumes: (binding * term list) list, |
25 assumes: (string * term list) list, |
26 binds: (indexname * term option) list, |
26 binds: (indexname * term option) list, |
27 cases: (string * T) list} |
27 cases: (string * T) list} |
28 val case_hypsN: string |
28 val case_hypsN: string |
29 val strip_params: term -> (string * typ) list |
29 val strip_params: term -> (string * typ) list |
30 val make_common: Proof.context -> term -> |
30 val make_common: Proof.context -> term -> |
63 |
63 |
64 (** cases **) |
64 (** cases **) |
65 |
65 |
66 datatype T = Case of |
66 datatype T = Case of |
67 {fixes: (binding * typ) list, |
67 {fixes: (binding * typ) list, |
68 assumes: (binding * term list) list, |
68 assumes: (string * term list) list, |
69 binds: (indexname * term option) list, |
69 binds: (indexname * term option) list, |
70 cases: (string * T) list}; |
70 cases: (string * T) list}; |
71 |
71 |
72 type cases = (string * T option) list; |
72 type cases = (string * T option) list; |
73 |
73 |
92 |
92 |
93 fun extract_fixes NONE prop = (strip_params prop, []) |
93 fun extract_fixes NONE prop = (strip_params prop, []) |
94 | extract_fixes (SOME outline) prop = |
94 | extract_fixes (SOME outline) prop = |
95 chop (length (Logic.strip_params outline)) (strip_params prop); |
95 chop (length (Logic.strip_params outline)) (strip_params prop); |
96 |
96 |
97 fun extract_assumes _ _ NONE prop = ([(Binding.empty, Logic.strip_assums_hyp prop)], []) |
97 fun extract_assumes _ NONE prop = ([("", Logic.strip_assums_hyp prop)], []) |
98 | extract_assumes qualifier hyp_names (SOME outline) prop = |
98 | extract_assumes hyp_names (SOME outline) prop = |
99 let |
99 let |
100 val qual = Binding.qualify true qualifier o Binding.name; |
|
101 val (hyps, prems) = |
100 val (hyps, prems) = |
102 chop (length (Logic.strip_assums_hyp outline)) (Logic.strip_assums_hyp prop) |
101 chop (length (Logic.strip_assums_hyp outline)) (Logic.strip_assums_hyp prop) |
103 fun extract ((hyp_name, hyp) :: rest) = (qual hyp_name, hyp :: map snd rest); |
102 fun extract ((hyp_name, hyp) :: rest) = (hyp_name, hyp :: map snd rest); |
104 val (hyps1, hyps2) = chop (length hyp_names) hyps; |
103 val (hyps1, hyps2) = chop (length hyp_names) hyps; |
105 val pairs1 = if null hyps1 then [] else hyp_names ~~ hyps1; |
104 val pairs1 = if null hyps1 then [] else hyp_names ~~ hyps1; |
106 val pairs = pairs1 @ map (pair case_hypsN) hyps2; |
105 val pairs = pairs1 @ map (pair case_hypsN) hyps2; |
107 val named_hyps = map extract (partition_eq (eq_fst op =) pairs); |
106 val named_hyps = map extract (partition_eq (eq_fst op =) pairs); |
108 in (named_hyps, [(qual case_premsN, prems)]) end; |
107 in (named_hyps, [(case_premsN, prems)]) end; |
109 |
108 |
110 fun bindings args = map (apfst Binding.name) args; |
109 fun bindings args = map (apfst Binding.name) args; |
111 |
110 |
112 fun extract_case ctxt (case_outline, raw_prop) name hyp_names concls = |
111 fun extract_case ctxt (case_outline, raw_prop) hyp_names concls = |
113 let |
112 let |
114 val props = Logic.dest_conjunctions (Drule.norm_hhf (Proof_Context.theory_of ctxt) raw_prop); |
113 val props = Logic.dest_conjunctions (Drule.norm_hhf (Proof_Context.theory_of ctxt) raw_prop); |
115 val len = length props; |
114 val len = length props; |
116 val nested = is_some case_outline andalso len > 1; |
115 val nested = is_some case_outline andalso len > 1; |
117 |
116 |
123 if not nested then abs_fixes t |
122 if not nested then abs_fixes t |
124 else |
123 else |
125 fold_rev Term.abs fixes1 |
124 fold_rev Term.abs fixes1 |
126 (app (map (Term.dummy_pattern o #2) fixes2) (fold_rev Term.abs fixes2 t)); |
125 (app (map (Term.dummy_pattern o #2) fixes2) (fold_rev Term.abs fixes2 t)); |
127 val (assumes1, assumes2) = |
126 val (assumes1, assumes2) = |
128 extract_assumes name hyp_names case_outline prop |
127 extract_assumes hyp_names case_outline prop |
129 |> apply2 (map (apsnd (maps Logic.dest_conjunctions))); |
128 |> apply2 (map (apsnd (maps Logic.dest_conjunctions))); |
130 |
129 |
131 val concl = Object_Logic.drop_judgment ctxt (Logic.strip_assums_concl prop); |
130 val concl = Object_Logic.drop_judgment ctxt (Logic.strip_assums_concl prop); |
132 val binds = |
131 val binds = |
133 (case_conclN, concl) :: dest_binops concls concl |
132 (case_conclN, concl) :: dest_binops concls concl |
160 val nprems = Logic.count_prems prop; |
159 val nprems = Logic.count_prems prop; |
161 fun add_case ((name, hyp_names), concls) (cs, i) = |
160 fun add_case ((name, hyp_names), concls) (cs, i) = |
162 ((case try (fn () => |
161 ((case try (fn () => |
163 (Option.map (curry Logic.nth_prem i) rule_struct, Logic.nth_prem (i, prop))) () of |
162 (Option.map (curry Logic.nth_prem i) rule_struct, Logic.nth_prem (i, prop))) () of |
164 NONE => (name, NONE) |
163 NONE => (name, NONE) |
165 | SOME p => (name, extract_case ctxt p name hyp_names concls)) :: cs, i - 1); |
164 | SOME p => (name, extract_case ctxt p hyp_names concls)) :: cs, i - 1); |
166 in fold_rev add_case (drop (Int.max (n - nprems, 0)) cases) ([], n) |> #1 end; |
165 in fold_rev add_case (drop (Int.max (n - nprems, 0)) cases) ([], n) |> #1 end; |
167 |
166 |
168 in |
167 in |
169 |
168 |
170 fun make_common ctxt = make ctxt NONE; |
169 fun make_common ctxt = make ctxt NONE; |