| author | wenzelm | 
| Wed, 05 Dec 2012 19:08:23 +0100 | |
| changeset 50374 | 1a7cae0711d2 | 
| parent 48902 | 44a6967240b7 | 
| child 52732 | b4da1f2ec73f | 
| permissions | -rw-r--r-- | 
| 41883 | 1 | (* Title: Tools/case_product.ML | 
| 2 | Author: Lars Noschinski, TU Muenchen | |
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 3 | |
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 4 | Combine two case rules into a single one. | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 5 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 6 | Assumes that the theorems are of the form | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 7 | "[| C1; ...; Cm; A1 ==> P; ...; An ==> P |] ==> P" | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 8 | where m is given by the "consumes" attribute of the theorem. | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 9 | *) | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 10 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 11 | signature CASE_PRODUCT = | 
| 41883 | 12 | sig | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 13 | val combine: Proof.context -> thm -> thm -> thm | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 14 | val combine_annotated: Proof.context -> thm -> thm -> thm | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 15 | val setup: theory -> theory | 
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 16 | end | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 17 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 18 | structure Case_Product: CASE_PRODUCT = | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 19 | struct | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 20 | |
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 21 | (*instantiate the conclusion of thm2 to the one of thm1*) | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 22 | fun inst_concl thm1 thm2 = | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 23 | let | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 24 | val cconcl_of = Drule.strip_imp_concl o Thm.cprop_of | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 25 | in Thm.instantiate (Thm.match (cconcl_of thm2, cconcl_of thm1)) thm2 end | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 26 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 27 | fun inst_thms thm1 thm2 ctxt = | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 28 | let | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 29 | val import = yield_singleton (apfst snd oo Variable.import true) | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 30 | val (i_thm1, ctxt') = import thm1 ctxt | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 31 | val (i_thm2, ctxt'') = import (inst_concl i_thm1 thm2) ctxt' | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 32 | in ((i_thm1, i_thm2), ctxt'') end | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 33 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 34 | (* | 
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 35 | Return list of prems, where loose bounds have been replaced by frees. | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 36 | FIXME: Focus | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 37 | *) | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 38 | fun free_prems t ctxt = | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 39 | let | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 40 | val bs = Term.strip_all_vars t | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 41 | val (names, ctxt') = Variable.variant_fixes (map fst bs) ctxt | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 42 | val subst = map Free (names ~~ map snd bs) | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 43 | val t' = map (Term.subst_bounds o pair (rev subst)) (Logic.strip_assums_hyp t) | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 44 | in ((t', subst), ctxt') end | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 45 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 46 | fun build_concl_prems thm1 thm2 ctxt = | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 47 | let | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 48 | val concl = Thm.concl_of thm1 | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 49 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 50 | fun is_consumes t = not (Logic.strip_assums_concl t aconv concl) | 
| 48902 
44a6967240b7
prefer classic take_prefix/take_suffix over chop_while (cf. 0659e84bdc5f);
 wenzelm parents: 
45375diff
changeset | 51 | val (p_cons1, p_cases1) = take_prefix is_consumes (Thm.prems_of thm1) | 
| 
44a6967240b7
prefer classic take_prefix/take_suffix over chop_while (cf. 0659e84bdc5f);
 wenzelm parents: 
45375diff
changeset | 52 | val (p_cons2, p_cases2) = take_prefix is_consumes (Thm.prems_of thm2) | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 53 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 54 | val p_cases_prod = map (fn p1 => map (fn p2 => | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 55 | let | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 56 | val (((t1, subst1), (t2, subst2)), _) = ctxt | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 57 | |> free_prems p1 ||>> free_prems p2 | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 58 | in | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 59 | Logic.list_implies (t1 @ t2, concl) | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 60 | |> fold_rev Logic.all (subst1 @ subst2) | 
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 61 | end) p_cases2) p_cases1 | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 62 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 63 | val prems = p_cons1 :: p_cons2 :: p_cases_prod | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 64 | in | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 65 | (concl, prems) | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 66 | end | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 67 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 68 | fun case_product_tac prems struc thm1 thm2 = | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 69 | let | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 70 | val (p_cons1 :: p_cons2 :: premss) = unflat struc prems | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 71 | val thm2' = thm2 OF p_cons2 | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 72 | in | 
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 73 | Tactic.rtac (thm1 OF p_cons1) | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 74 | THEN' EVERY' (map (fn p => | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 75 | Tactic.rtac thm2' | 
| 42361 | 76 | THEN' EVERY' (map (Proof_Context.fact_tac o single) p)) premss) | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 77 | end | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 78 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 79 | fun combine ctxt thm1 thm2 = | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 80 | let | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 81 | val ((i_thm1, i_thm2), ctxt') = inst_thms thm1 thm2 ctxt | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 82 | val (concl, prems_rich) = build_concl_prems i_thm1 i_thm2 ctxt' | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 83 | in | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 84 |     Goal.prove ctxt' [] (flat prems_rich) concl (fn {prems, ...} =>
 | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 85 | case_product_tac prems prems_rich i_thm1 i_thm2 1) | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 86 | |> singleton (Variable.export ctxt' ctxt) | 
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 87 | end | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 88 | |
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 89 | fun annotation_rule thm1 thm2 = | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 90 | let | 
| 44045 
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
 nipkow parents: 
42361diff
changeset | 91 | val (cases1, cons1) = apfst (map fst) (Rule_Cases.get thm1) | 
| 
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
 nipkow parents: 
42361diff
changeset | 92 | val (cases2, cons2) = apfst (map fst) (Rule_Cases.get thm2) | 
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 93 | val names = map_product (fn (x, _) => fn (y, _) => x ^ "_" ^ y) cases1 cases2 | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 94 | in | 
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 95 | Rule_Cases.name names o Rule_Cases.put_consumes (SOME (cons1 + cons2)) | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 96 | end | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 97 | |
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 98 | fun annotation thm1 thm2 = Thm.rule_attribute (K (annotation_rule thm1 thm2)) | 
| 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 99 | |
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 100 | fun combine_annotated ctxt thm1 thm2 = | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 101 | combine ctxt thm1 thm2 | 
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 102 | |> annotation_rule thm1 thm2 | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 103 | |
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 104 | |
| 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 105 | (* attribute setup *) | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 106 | |
| 41883 | 107 | val case_prod_attr = | 
| 108 | let | |
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 109 | fun combine_list ctxt = fold (fn x => fn y => combine_annotated ctxt y x) | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 110 | in | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 111 | Attrib.thms >> (fn thms => Thm.rule_attribute (fn ctxt => fn thm => | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 112 | combine_list (Context.proof_of ctxt) thms thm)) | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 113 | end | 
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 114 | |
| 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 115 | val setup = | 
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 116 |   Attrib.setup @{binding case_product} case_prod_attr "product with other case rules"
 | 
| 41826 
18d4d2b60016
introduce attribute case_prod for combining case rules
 noschinl parents: diff
changeset | 117 | |
| 45375 
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
 wenzelm parents: 
44045diff
changeset | 118 | end |