| author | wenzelm | 
| Mon, 16 Mar 2015 16:59:59 +0100 | |
| changeset 59720 | f893472fff31 | 
| parent 59627 | bb1e4a35d506 | 
| child 59970 | e9f73d87d904 | 
| permissions | -rw-r--r-- | 
| 33471 | 1 | (* Title: HOL/Tools/Function/induction_schema.ML | 
| 2 | Author: Alexander Krauss, TU Muenchen | |
| 3 | ||
| 4 | A method to prove induction schemas. | |
| 5 | *) | |
| 6 | ||
| 7 | signature INDUCTION_SCHEMA = | |
| 8 | sig | |
| 9 | val mk_ind_tac : (int -> tactic) -> (int -> tactic) -> (int -> tactic) | |
| 10 | -> Proof.context -> thm list -> tactic | |
| 11 | val induction_schema_tac : Proof.context -> thm list -> tactic | |
| 12 | end | |
| 13 | ||
| 14 | structure Induction_Schema : INDUCTION_SCHEMA = | |
| 15 | struct | |
| 16 | ||
| 17 | open Function_Lib | |
| 18 | ||
| 19 | type rec_call_info = int * (string * typ) list * term list * term list | |
| 20 | ||
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 21 | datatype scheme_case = SchemeCase of | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 22 |  {bidx : int,
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 23 | qs: (string * typ) list, | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 24 | oqnames: string list, | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 25 | gs: term list, | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 26 | lhs: term list, | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 27 | rs: rec_call_info list} | 
| 33471 | 28 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 29 | datatype scheme_branch = SchemeBranch of | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 30 |  {P : term,
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 31 | xs: (string * typ) list, | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 32 | ws: (string * typ) list, | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 33 | Cs: term list} | 
| 33471 | 34 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 35 | datatype ind_scheme = IndScheme of | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 36 |  {T: typ, (* sum of products *)
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 37 | branches: scheme_branch list, | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 38 | cases: scheme_case list} | 
| 33471 | 39 | |
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 40 | fun ind_atomize ctxt = Raw_Simplifier.rewrite ctxt true @{thms induct_atomize}
 | 
| 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 41 | fun ind_rulify ctxt = Raw_Simplifier.rewrite ctxt true @{thms induct_rulify}
 | 
| 33471 | 42 | |
| 43 | fun meta thm = thm RS eq_reflection | |
| 44 | ||
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 45 | fun sum_prod_conv ctxt = Raw_Simplifier.rewrite ctxt true | 
| 55642 
63beb38e9258
adapted to renaming of datatype 'cases' and 'recs' to 'case' and 'rec'
 blanchet parents: 
54742diff
changeset | 46 |   (map meta (@{thm split_conv} :: @{thms sum.case}))
 | 
| 33471 | 47 | |
| 59627 | 48 | fun term_conv ctxt cv t = | 
| 49 | cv (Thm.cterm_of ctxt t) | |
| 59582 | 50 | |> Thm.prop_of |> Logic.dest_equals |> snd | 
| 33471 | 51 | |
| 52 | fun mk_relT T = HOLogic.mk_setT (HOLogic.mk_prodT (T, T)) | |
| 53 | ||
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 54 | fun dest_hhf ctxt t = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 55 | let | 
| 42495 
1af81b70cf09
clarified Variable.focus vs. Variable.focus_cterm -- eliminated clone;
 wenzelm parents: 
42361diff
changeset | 56 | val ((params, imp), ctxt') = Variable.focus t ctxt | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 57 | in | 
| 42495 
1af81b70cf09
clarified Variable.focus vs. Variable.focus_cterm -- eliminated clone;
 wenzelm parents: 
42361diff
changeset | 58 | (ctxt', map #2 params, Logic.strip_imp_prems imp, Logic.strip_imp_concl imp) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 59 | end | 
| 33471 | 60 | |
| 61 | fun mk_scheme' ctxt cases concl = | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 62 | let | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 63 | fun mk_branch concl = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 64 | let | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 65 | val (_, ws, Cs, _ $ Pxs) = dest_hhf ctxt concl | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 66 | val (P, xs) = strip_comb Pxs | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 67 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 68 |         SchemeBranch { P=P, xs=map dest_Free xs, ws=ws, Cs=Cs }
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 69 | end | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 70 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 71 | val (branches, cases') = (* correction *) | 
| 41418 | 72 | case Logic.dest_conjunctions concl of | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 73 | [conc] => | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 74 | let | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 75 | val _ $ Pxs = Logic.strip_assums_concl conc | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 76 | val (P, _) = strip_comb Pxs | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 77 | val (cases', conds) = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 78 | take_prefix (Term.exists_subterm (curry op aconv P)) cases | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 79 | val concl' = fold_rev (curry Logic.mk_implies) conds conc | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 80 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 81 | ([mk_branch concl'], cases') | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 82 | end | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 83 | | concls => (map mk_branch concls, cases) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 84 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 85 | fun mk_case premise = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 86 | let | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 87 | val (ctxt', qs, prems, _ $ Plhs) = dest_hhf ctxt premise | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 88 | val (P, lhs) = strip_comb Plhs | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 89 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 90 | fun bidx Q = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 91 |           find_index (fn SchemeBranch {P=P',...} => Q aconv P') branches
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 92 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 93 | fun mk_rcinfo pr = | 
| 33471 | 94 | let | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 95 | val (_, Gvs, Gas, _ $ Phyp) = dest_hhf ctxt' pr | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 96 | val (P', rcs) = strip_comb Phyp | 
| 33471 | 97 | in | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 98 | (bidx P', Gvs, Gas, rcs) | 
| 33471 | 99 | end | 
| 100 | ||
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 101 |         fun is_pred v = exists (fn SchemeBranch {P,...} => v aconv P) branches
 | 
| 33471 | 102 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 103 | val (gs, rcprs) = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 104 | take_prefix (not o Term.exists_subterm is_pred) prems | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 105 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 106 |         SchemeCase {bidx=bidx P, qs=qs, oqnames=map fst qs(*FIXME*),
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 107 | gs=gs, lhs=lhs, rs=map mk_rcinfo rcprs} | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 108 | end | 
| 33471 | 109 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 110 |     fun PT_of (SchemeBranch { xs, ...}) =
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 111 | foldr1 HOLogic.mk_prodT (map snd xs) | 
| 33471 | 112 | |
| 55968 | 113 | val ST = Balanced_Tree.make (uncurry Sum_Tree.mk_sumT) (map PT_of branches) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 114 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 115 |     IndScheme {T=ST, cases=map mk_case cases', branches=branches }
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 116 | end | 
| 33471 | 117 | |
| 118 | fun mk_completeness ctxt (IndScheme {cases, branches, ...}) bidx =
 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 119 | let | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 120 |     val SchemeBranch { xs, ws, Cs, ... } = nth branches bidx
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 121 |     val relevant_cases = filter (fn SchemeCase {bidx=bidx', ...} => bidx' = bidx) cases
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 122 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 123 |     val allqnames = fold (fn SchemeCase {qs, ...} => fold (insert (op =) o Free) qs) relevant_cases []
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 124 |     val (Pbool :: xs') = map Free (Variable.variant_frees ctxt allqnames (("P", HOLogic.boolT) :: xs))
 | 
| 42361 | 125 | val Cs' = map (Pattern.rewrite_term (Proof_Context.theory_of ctxt) (filter_out (op aconv) (map Free xs ~~ xs')) []) Cs | 
| 33471 | 126 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 127 |     fun mk_case (SchemeCase {qs, oqnames, gs, lhs, ...}) =
 | 
| 33471 | 128 | HOLogic.mk_Trueprop Pbool | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 129 | |> fold_rev (fn x_l => curry Logic.mk_implies (HOLogic.mk_Trueprop(HOLogic.mk_eq x_l))) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 130 | (xs' ~~ lhs) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 131 | |> fold_rev (curry Logic.mk_implies) gs | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 132 | |> fold_rev mk_forall_rename (oqnames ~~ map Free qs) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 133 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 134 | HOLogic.mk_Trueprop Pbool | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 135 | |> fold_rev (curry Logic.mk_implies o mk_case) relevant_cases | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 136 | |> fold_rev (curry Logic.mk_implies) Cs' | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 137 | |> fold_rev (Logic.all o Free) ws | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 138 | |> fold_rev mk_forall_rename (map fst xs ~~ xs') | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 139 |     |> mk_forall_rename ("P", Pbool)
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 140 | end | 
| 33471 | 141 | |
| 33855 
cd8acf137c9c
eliminated dead code and some unused bindings, reported by polyml
 krauss parents: 
33697diff
changeset | 142 | fun mk_wf R (IndScheme {T, ...}) =
 | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 143 |   HOLogic.Trueprop $ (Const (@{const_name wf}, mk_relT T --> HOLogic.boolT) $ R)
 | 
| 33471 | 144 | |
| 145 | fun mk_ineqs R (IndScheme {T, cases, branches}) =
 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 146 | let | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 147 | fun inject i ts = | 
| 55968 | 148 | Sum_Tree.mk_inj T (length branches) (i + 1) (foldr1 HOLogic.mk_prod ts) | 
| 33471 | 149 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 150 |     val thesis = Free ("thesis", HOLogic.boolT) (* FIXME *)
 | 
| 33471 | 151 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 152 | fun mk_pres bdx args = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 153 | let | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 154 |         val SchemeBranch { xs, ws, Cs, ... } = nth branches bdx
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 155 | fun replace (x, v) t = betapply (lambda (Free x) t, v) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 156 | val Cs' = map (fold replace (xs ~~ args)) Cs | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 157 | val cse = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 158 | HOLogic.mk_Trueprop thesis | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 159 | |> fold_rev (curry Logic.mk_implies) Cs' | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 160 | |> fold_rev (Logic.all o Free) ws | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 161 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 162 | Logic.mk_implies (cse, HOLogic.mk_Trueprop thesis) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 163 | end | 
| 33471 | 164 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 165 |     fun f (SchemeCase {bidx, qs, oqnames, gs, lhs, rs, ...}) =
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 166 | let | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 167 | fun g (bidx', Gvs, Gas, rcarg) = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 168 | let val export = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 169 | fold_rev (curry Logic.mk_implies) Gas | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 170 | #> fold_rev (curry Logic.mk_implies) gs | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 171 | #> fold_rev (Logic.all o Free) Gvs | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 172 | #> fold_rev mk_forall_rename (oqnames ~~ map Free qs) | 
| 33471 | 173 | in | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 174 | (HOLogic.mk_mem (HOLogic.mk_prod (inject bidx' rcarg, inject bidx lhs), R) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 175 | |> HOLogic.mk_Trueprop | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 176 | |> export, | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 177 | mk_pres bidx' rcarg | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 178 | |> export | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 179 | |> Logic.all thesis) | 
| 33471 | 180 | end | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 181 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 182 | map g rs | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 183 | end | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 184 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 185 | map f cases | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 186 | end | 
| 33471 | 187 | |
| 188 | ||
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 189 | fun mk_ind_goal ctxt branches = | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 190 | let | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 191 | val thy = Proof_Context.theory_of ctxt | 
| 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 192 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 193 |     fun brnch (SchemeBranch { P, xs, ws, Cs, ... }) =
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 194 | HOLogic.mk_Trueprop (list_comb (P, map Free xs)) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 195 | |> fold_rev (curry Logic.mk_implies) Cs | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 196 | |> fold_rev (Logic.all o Free) ws | 
| 59627 | 197 | |> term_conv ctxt (ind_atomize ctxt) | 
| 35625 | 198 | |> Object_Logic.drop_judgment thy | 
| 39756 
6c8e83d94536
consolidated tupled_lambda; moved to structure HOLogic
 krauss parents: 
37677diff
changeset | 199 | |> HOLogic.tupled_lambda (foldr1 HOLogic.mk_prod (map Free xs)) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 200 | in | 
| 55968 | 201 | Sum_Tree.mk_sumcases HOLogic.boolT (map brnch branches) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 202 | end | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 203 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 204 | fun mk_induct_rule ctxt R x complete_thms wf_thm ineqss | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 205 |   (IndScheme {T, cases=scases, branches}) =
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 206 | let | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 207 | val n = length branches | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 208 | val scases_idx = map_index I scases | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 209 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 210 | fun inject i ts = | 
| 55968 | 211 | Sum_Tree.mk_inj T n (i + 1) (foldr1 HOLogic.mk_prod ts) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 212 |     val P_of = nth (map (fn (SchemeBranch { P, ... }) => P) branches)
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 213 | |
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 214 | val P_comp = mk_ind_goal ctxt branches | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 215 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 216 | (* Inductive Hypothesis: !!z. (z,x):R ==> P z *) | 
| 46217 
7b19666f0e3d
renamed Term.all to Logic.all_const, in accordance to HOLogic.all_const;
 wenzelm parents: 
42495diff
changeset | 217 |     val ihyp = Logic.all_const T $ Abs ("z", T,
 | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 218 | Logic.mk_implies | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 219 | (HOLogic.mk_Trueprop ( | 
| 37677 | 220 |           Const (@{const_name Set.member}, HOLogic.mk_prodT (T, T) --> mk_relT T --> HOLogic.boolT) 
 | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 221 | $ (HOLogic.pair_const T T $ Bound 0 $ x) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 222 | $ R), | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 223 | HOLogic.mk_Trueprop (P_comp $ Bound 0))) | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 224 | |> Thm.cterm_of ctxt | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 225 | |
| 36945 | 226 | val aihyp = Thm.assume ihyp | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 227 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 228 | (* Rule for case splitting along the sum types *) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 229 |     val xss = map (fn (SchemeBranch { xs, ... }) => map Free xs) branches
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 230 | val pats = map_index (uncurry inject) xss | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 231 | val sum_split_rule = | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
47432diff
changeset | 232 | Pat_Completeness.prove_completeness ctxt [x] (P_comp $ x) xss (map single pats) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 233 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 234 |     fun prove_branch (bidx, (SchemeBranch { P, xs, ws, Cs, ... }, (complete_thm, pat))) =
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 235 | let | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 236 | val fxs = map Free xs | 
| 59618 | 237 | val branch_hyp = | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 238 | Thm.assume (Thm.cterm_of ctxt (HOLogic.mk_Trueprop (HOLogic.mk_eq (x, pat)))) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 239 | |
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 240 | val C_hyps = map (Thm.cterm_of ctxt #> Thm.assume) Cs | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 241 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 242 | val (relevant_cases, ineqss') = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 243 | (scases_idx ~~ ineqss) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 244 |           |> filter (fn ((_, SchemeCase {bidx=bidx', ...}), _) => bidx' = bidx)
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 245 | |> split_list | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 246 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 247 |         fun prove_case (cidx, SchemeCase {qs, gs, lhs, rs, ...}) ineq_press =
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 248 | let | 
| 36945 | 249 | val case_hyps = | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 250 | map (Thm.assume o Thm.cterm_of ctxt o HOLogic.mk_Trueprop o HOLogic.mk_eq) | 
| 59618 | 251 | (fxs ~~ lhs) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 252 | |
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 253 | val cqs = map (Thm.cterm_of ctxt o Free) qs | 
| 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 254 | val ags = map (Thm.assume o Thm.cterm_of ctxt) gs | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 255 | |
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
47432diff
changeset | 256 | val replace_x_simpset = | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
47432diff
changeset | 257 | put_simpset HOL_basic_ss ctxt addsimps (branch_hyp :: case_hyps) | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
47432diff
changeset | 258 | val sih = full_simplify replace_x_simpset aihyp | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 259 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 260 | fun mk_Prec (idx, Gvs, Gas, rcargs) (ineq, pres) = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 261 | let | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 262 | val cGas = map (Thm.assume o Thm.cterm_of ctxt) Gas | 
| 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 263 | val cGvs = map (Thm.cterm_of ctxt o Free) Gvs | 
| 36945 | 264 | val import = fold Thm.forall_elim (cqs @ cGvs) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 265 | #> fold Thm.elim_implies (ags @ cGas) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 266 | val ipres = pres | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 267 | |> Thm.forall_elim (Thm.cterm_of ctxt (list_comb (P_of idx, rcargs))) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 268 | |> import | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 269 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 270 | sih | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 271 | |> Thm.forall_elim (Thm.cterm_of ctxt (inject idx rcargs)) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 272 | |> Thm.elim_implies (import ineq) (* Psum rcargs *) | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 273 | |> Conv.fconv_rule (sum_prod_conv ctxt) | 
| 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 274 | |> Conv.fconv_rule (ind_rulify ctxt) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 275 | |> (fn th => th COMP ipres) (* P rs *) | 
| 59582 | 276 | |> fold_rev (Thm.implies_intr o Thm.cprop_of) cGas | 
| 36945 | 277 | |> fold_rev Thm.forall_intr cGvs | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 278 | end | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 279 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 280 | val P_recs = map2 mk_Prec rs ineq_press (* [P rec1, P rec2, ... ] *) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 281 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 282 | val step = HOLogic.mk_Trueprop (list_comb (P, lhs)) | 
| 59582 | 283 | |> fold_rev (curry Logic.mk_implies o Thm.prop_of) P_recs | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 284 | |> fold_rev (curry Logic.mk_implies) gs | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 285 | |> fold_rev (Logic.all o Free) qs | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 286 | |> Thm.cterm_of ctxt | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 287 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 288 | val Plhs_to_Pxs_conv = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 289 | foldl1 (uncurry Conv.combination_conv) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 290 | (Conv.all_conv :: map (fn ch => K (Thm.symmetric (ch RS eq_reflection))) case_hyps) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 291 | |
| 36945 | 292 | val res = Thm.assume step | 
| 293 | |> fold Thm.forall_elim cqs | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 294 | |> fold Thm.elim_implies ags | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 295 | |> fold Thm.elim_implies P_recs (* P lhs *) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 296 | |> Conv.fconv_rule (Conv.arg_conv Plhs_to_Pxs_conv) (* P xs *) | 
| 59582 | 297 | |> fold_rev (Thm.implies_intr o Thm.cprop_of) (ags @ case_hyps) | 
| 36945 | 298 | |> fold_rev Thm.forall_intr cqs (* !!qs. Gas ==> xs = lhss ==> P xs *) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 299 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 300 | (res, (cidx, step)) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 301 | end | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 302 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 303 | val (cases, steps) = split_list (map2 prove_case relevant_cases ineqss') | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 304 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 305 | val bstep = complete_thm | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 306 | |> Thm.forall_elim (Thm.cterm_of ctxt (list_comb (P, fxs))) | 
| 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 307 | |> fold (Thm.forall_elim o Thm.cterm_of ctxt) (fxs @ map Free ws) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 308 | |> fold Thm.elim_implies C_hyps | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 309 | |> fold Thm.elim_implies cases (* P xs *) | 
| 59582 | 310 | |> fold_rev (Thm.implies_intr o Thm.cprop_of) C_hyps | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 311 | |> fold_rev (Thm.forall_intr o Thm.cterm_of ctxt o Free) ws | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 312 | |
| 59618 | 313 | val Pxs = | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 314 | Thm.cterm_of ctxt (HOLogic.mk_Trueprop (P_comp $ x)) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 315 | |> Goal.init | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 316 | |> (Simplifier.rewrite_goals_tac ctxt | 
| 55642 
63beb38e9258
adapted to renaming of datatype 'cases' and 'recs' to 'case' and 'rec'
 blanchet parents: 
54742diff
changeset | 317 |                 (map meta (branch_hyp :: @{thm split_conv} :: @{thms sum.case}))
 | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 318 | THEN CONVERSION (ind_rulify ctxt) 1) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 319 | |> Seq.hd | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 320 | |> Thm.elim_implies (Conv.fconv_rule Drule.beta_eta_conversion bstep) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 321 | |> Goal.finish ctxt | 
| 59582 | 322 | |> Thm.implies_intr (Thm.cprop_of branch_hyp) | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 323 | |> fold_rev (Thm.forall_intr o Thm.cterm_of ctxt) fxs | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 324 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 325 | (Pxs, steps) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 326 | end | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 327 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 328 | val (branches, steps) = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 329 | map_index prove_branch (branches ~~ (complete_thms ~~ pats)) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 330 | |> split_list |> apsnd flat | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 331 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 332 | val istep = sum_split_rule | 
| 52467 | 333 | |> fold (fn b => fn th => Drule.compose (b, 1, th)) branches | 
| 36945 | 334 | |> Thm.implies_intr ihyp | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 335 | |> Thm.forall_intr (Thm.cterm_of ctxt x) (* "!!x. (!!y<x. P y) ==> P x" *) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 336 | |
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 337 | val induct_rule = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 338 |       @{thm "wf_induct_rule"}
 | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 339 | |> (curry op COMP) wf_thm | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 340 | |> (curry op COMP) istep | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 341 | |
| 59058 
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
 wenzelm parents: 
58963diff
changeset | 342 | val steps_sorted = map snd (sort (int_ord o apply2 fst) steps) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 343 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 344 | (steps_sorted, induct_rule) | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 345 | end | 
| 33471 | 346 | |
| 347 | ||
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 348 | fun mk_ind_tac comp_tac pres_tac term_tac ctxt facts = | 
| 46467 | 349 | (* FIXME proper use of facts!? *) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 350 | (ALLGOALS (Method.insert_tac facts)) THEN HEADGOAL (SUBGOAL (fn (t, i) => | 
| 33471 | 351 | let | 
| 352 | val (ctxt', _, cases, concl) = dest_hhf ctxt t | |
| 353 |     val scheme as IndScheme {T=ST, branches, ...} = mk_scheme' ctxt' cases concl
 | |
| 59618 | 354 | val ([Rn, xn], ctxt'') = Variable.variant_fixes ["R", "x"] ctxt' | 
| 33471 | 355 | val R = Free (Rn, mk_relT ST) | 
| 356 | val x = Free (xn, ST) | |
| 357 | ||
| 59618 | 358 | val ineqss = | 
| 359 | mk_ineqs R scheme | |
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 360 | |> map (map (apply2 (Thm.assume o Thm.cterm_of ctxt''))) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 361 | val complete = | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 362 | map_range (mk_completeness ctxt'' scheme #> Thm.cterm_of ctxt'' #> Thm.assume) | 
| 59618 | 363 | (length branches) | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 364 | val wf_thm = mk_wf R scheme |> Thm.cterm_of ctxt'' |> Thm.assume | 
| 33471 | 365 | |
| 366 | val (descent, pres) = split_list (flat ineqss) | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 367 | val newgoals = complete @ pres @ wf_thm :: descent | 
| 33471 | 368 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 369 | val (steps, indthm) = | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 370 | mk_induct_rule ctxt'' R x complete wf_thm ineqss scheme | 
| 33471 | 371 | |
| 372 |     fun project (i, SchemeBranch {xs, ...}) =
 | |
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 373 | let | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 374 | val inst = (foldr1 HOLogic.mk_prod (map Free xs)) | 
| 55968 | 375 | |> Sum_Tree.mk_inj ST (length branches) (i + 1) | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59618diff
changeset | 376 | |> Thm.cterm_of ctxt'' | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 377 | in | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 378 | indthm | 
| 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 379 | |> Drule.instantiate' [] [SOME inst] | 
| 55968 | 380 | |> simplify (put_simpset Sum_Tree.sumcase_split_ss ctxt'') | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52467diff
changeset | 381 | |> Conv.fconv_rule (ind_rulify ctxt'') | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 382 | end | 
| 33471 | 383 | |
| 384 | val res = Conjunction.intr_balanced (map_index project branches) | |
| 59582 | 385 | |> fold_rev Thm.implies_intr (map Thm.cprop_of newgoals @ steps) | 
| 34232 
36a2a3029fd3
new year's resolution: reindented code in function package
 krauss parents: 
33855diff
changeset | 386 | |> Drule.generalize ([], [Rn]) | 
| 33471 | 387 | |
| 388 | val nbranches = length branches | |
| 389 | val npres = length pres | |
| 390 | in | |
| 59618 | 391 |     Thm.bicompose (SOME ctxt'') {flatten = false, match = false, incremented = false}
 | 
| 52223 
5bb6ae8acb87
tuned signature -- more explicit flags for low-level Thm.bicompose;
 wenzelm parents: 
51717diff
changeset | 392 | (false, res, length newgoals) i | 
| 33471 | 393 | THEN term_tac (i + nbranches + npres) | 
| 394 | THEN (EVERY (map (TRY o pres_tac) ((i + nbranches + npres - 1) downto (i + nbranches)))) | |
| 395 | THEN (EVERY (map (TRY o comp_tac) ((i + nbranches - 1) downto i))) | |
| 396 | end)) | |
| 397 | ||
| 398 | ||
| 399 | fun induction_schema_tac ctxt = | |
| 58963 
26bf09b95dda
proper context for assume_tac (atac remains as fall-back without context);
 wenzelm parents: 
58950diff
changeset | 400 | mk_ind_tac (K all_tac) (assume_tac ctxt APPEND' Goal.assume_rule_tac ctxt) (K all_tac) ctxt; | 
| 33471 | 401 | |
| 402 | end |