159 fun stripC (i, f $ x) = stripC (i + 1, f) |
159 fun stripC (i, f $ x) = stripC (i + 1, f) |
160 | stripC p = p; |
160 | stripC p = p; |
161 |
161 |
162 val distinctN = "constr_distinct"; |
162 val distinctN = "constr_distinct"; |
163 |
163 |
164 fun distinct_rule thy ss tname eq_t = case #distinct (the_info thy tname) of |
164 fun distinct_rule thy ss tname eq_t = Goal.prove (Simplifier.the_context ss) [] [] eq_t |
165 FewConstrs thms => Goal.prove (Simplifier.the_context ss) [] [] eq_t (K |
165 (K (EVERY [rtac eq_reflection 1, rtac iffI 1, rtac notE 1, |
166 (EVERY [rtac eq_reflection 1, rtac iffI 1, rtac notE 1, |
166 atac 2, resolve_tac (#distinct (the_info thy tname)) 1, etac FalseE 1])); |
167 atac 2, resolve_tac thms 1, etac FalseE 1])) |
|
168 | ManyConstrs (thm, simpset) => |
|
169 let |
|
170 val [In0_inject, In1_inject, In0_not_In1, In1_not_In0] = |
|
171 map (PureThy.get_thm (ThyInfo.the_theory "Datatype" thy)) |
|
172 ["In0_inject", "In1_inject", "In0_not_In1", "In1_not_In0"]; |
|
173 in |
|
174 Goal.prove (Simplifier.the_context ss) [] [] eq_t (K |
|
175 (EVERY [rtac eq_reflection 1, rtac iffI 1, dtac thm 1, |
|
176 full_simp_tac (Simplifier.inherit_context ss simpset) 1, |
|
177 REPEAT (dresolve_tac [In0_inject, In1_inject] 1), |
|
178 eresolve_tac [In0_not_In1 RS notE, In1_not_In0 RS notE] 1, |
|
179 etac FalseE 1])) |
|
180 end; |
|
181 |
167 |
182 fun get_constr thy dtco = |
168 fun get_constr thy dtco = |
183 get_info thy dtco |
169 get_info thy dtco |
184 |> Option.map (fn { descr, index, ... } => (#3 o the o AList.lookup (op =) descr) index); |
170 |> Option.map (fn { descr, index, ... } => (#3 o the o AList.lookup (op =) descr) index); |
185 |
171 |
406 ||>> PureThy.add_thms [((Binding.name "induct", raw_induct), [mk_case_names_induct descr])] |
392 ||>> PureThy.add_thms [((Binding.name "induct", raw_induct), [mk_case_names_induct descr])] |
407 ||> Sign.restore_naming thy1; |
393 ||> Sign.restore_naming thy1; |
408 in |
394 in |
409 thy2 |
395 thy2 |
410 |> derive_datatype_props config dt_names alt_names [descr] sorts |
396 |> derive_datatype_props config dt_names alt_names [descr] sorts |
411 induct inject (distinct, distinct, map FewConstrs distinct) |
397 induct inject (distinct, distinct, distinct) |
412 end; |
398 end; |
413 |
399 |
414 fun gen_rep_datatype prep_term config after_qed alt_names raw_ts thy = |
400 fun gen_rep_datatype prep_term config after_qed alt_names raw_ts thy = |
415 let |
401 let |
416 fun constr_of_term (Const (c, T)) = (c, T) |
402 fun constr_of_term (Const (c, T)) = (c, T) |
543 val _ = check_nonempty descr handle (exn as Datatype_Empty s) => |
529 val _ = check_nonempty descr handle (exn as Datatype_Empty s) => |
544 if #strict config then error ("Nonemptiness check failed for datatype " ^ s) |
530 if #strict config then error ("Nonemptiness check failed for datatype " ^ s) |
545 else raise exn; |
531 else raise exn; |
546 |
532 |
547 val _ = message config ("Constructing datatype(s) " ^ commas_quote new_type_names); |
533 val _ = message config ("Constructing datatype(s) " ^ commas_quote new_type_names); |
548 val ((inject, distinct_rules, distinct_rewrites, distinct_entry, induct), thy') = thy |> |
534 val ((inject, (distinct_rules, distinct_rewrites, distinct_entry), induct), thy') = thy |> |
549 DatatypeRepProofs.representation_proofs config dt_info new_type_names descr sorts |
535 DatatypeRepProofs.representation_proofs config dt_info new_type_names descr sorts |
550 types_syntax constr_syntax (mk_case_names_induct (flat descr)); |
536 types_syntax constr_syntax (mk_case_names_induct (flat descr)); |
551 in |
537 in |
552 derive_datatype_props config dt_names (SOME new_type_names) descr sorts |
538 derive_datatype_props config dt_names (SOME new_type_names) descr sorts |
553 induct inject (distinct_rules, distinct_rewrites, distinct_entry) thy' |
539 induct inject (distinct_rules, distinct_rewrites, distinct_entry) thy' |