| author | wenzelm | 
| Sun, 15 Apr 2007 14:31:47 +0200 | |
| changeset 22691 | 290454649b8c | 
| parent 22573 | 2ac646ab2f6c | 
| child 22846 | fb79144af9a3 | 
| permissions | -rw-r--r-- | 
| 6778 | 1 | (* Title: Pure/Isar/calculation.ML | 
| 2 | ID: $Id$ | |
| 3 | Author: Markus Wenzel, TU Muenchen | |
| 4 | ||
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 5 | Generic calculational proofs. | 
| 6778 | 6 | *) | 
| 7 | ||
| 8 | signature CALCULATION = | |
| 9 | sig | |
| 21506 | 10 | val print_rules: Proof.context -> unit | 
| 16571 | 11 | val get_calculation: Proof.state -> thm list option | 
| 18728 | 12 | val trans_add: attribute | 
| 13 | val trans_del: attribute | |
| 14 | val sym_add: attribute | |
| 15 | val sym_del: attribute | |
| 16 | val symmetric: attribute | |
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 17 | val also: (thmref * Attrib.src list) list option -> bool -> Proof.state -> Proof.state Seq.seq | 
| 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 18 | val also_i: thm list option -> bool -> Proof.state -> Proof.state Seq.seq | 
| 22573 | 19 | val finally_: (thmref * Attrib.src list) list option -> bool -> | 
| 20 | Proof.state -> Proof.state Seq.seq | |
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 21 | val finally_i: thm list option -> bool -> Proof.state -> Proof.state Seq.seq | 
| 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 22 | val moreover: bool -> Proof.state -> Proof.state | 
| 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 23 | val ultimately: bool -> Proof.state -> Proof.state | 
| 6778 | 24 | end; | 
| 25 | ||
| 26 | structure Calculation: CALCULATION = | |
| 27 | struct | |
| 28 | ||
| 18637 | 29 | (** calculation data **) | 
| 6778 | 30 | |
| 18637 | 31 | structure CalculationData = GenericDataFun | 
| 32 | ( | |
| 6778 | 33 | val name = "Isar/calculation"; | 
| 12379 | 34 | type T = (thm NetRules.T * thm list) * (thm list * int) option; | 
| 18637 | 35 | val empty = ((NetRules.elim, []), NONE); | 
| 36 | val extend = I; | |
| 6778 | 37 | |
| 18637 | 38 | fun merge _ (((trans1, sym1), _), ((trans2, sym2), _)) = | 
| 39 | ((NetRules.merge (trans1, trans2), Drule.merge_rules (sym1, sym2)), NONE); | |
| 6778 | 40 | |
| 18637 | 41 | fun print generic ((trans, sym), _) = | 
| 42 | let val ctxt = Context.proof_of generic in | |
| 43 | [Pretty.big_list "transitivity rules:" | |
| 44 | (map (ProofContext.pretty_thm ctxt) (NetRules.rules trans)), | |
| 45 | Pretty.big_list "symmetry rules:" (map (ProofContext.pretty_thm ctxt) sym)] | |
| 46 | |> Pretty.chunks |> Pretty.writeln | |
| 47 | end; | |
| 48 | ); | |
| 49 | ||
| 18708 | 50 | val _ = Context.add_setup CalculationData.init; | 
| 21506 | 51 | val print_rules = CalculationData.print o Context.Proof; | 
| 6778 | 52 | |
| 53 | ||
| 54 | (* access calculation *) | |
| 55 | ||
| 56 | fun get_calculation state = | |
| 18637 | 57 | (case #2 (CalculationData.get (Context.Proof (Proof.context_of state))) of | 
| 15531 | 58 | NONE => NONE | 
| 59 | | SOME (thms, lev) => if lev = Proof.level state then SOME thms else NONE); | |
| 6778 | 60 | |
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 61 | val calculationN = "calculation"; | 
| 6778 | 62 | |
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 63 | fun put_calculation calc = | 
| 18728 | 64 | `Proof.level #-> (fn lev => Proof.map_context (Context.proof_map | 
| 65 | (CalculationData.map (apsnd (K (Option.map (rpair lev) calc)))))) | |
| 21445 
0d562bf8ac3e
renamed Proof.put_thms_internal to Proof.put_thms;
 wenzelm parents: 
20898diff
changeset | 66 | #> Proof.put_thms (calculationN, calc); | 
| 6778 | 67 | |
| 68 | ||
| 18637 | 69 | |
| 6778 | 70 | (** attributes **) | 
| 71 | ||
| 12379 | 72 | (* add/del rules *) | 
| 73 | ||
| 18728 | 74 | val trans_add = Thm.declaration_attribute (CalculationData.map o apfst o apfst o NetRules.insert); | 
| 75 | val trans_del = Thm.declaration_attribute (CalculationData.map o apfst o apfst o NetRules.delete); | |
| 6778 | 76 | |
| 18637 | 77 | val sym_add = | 
| 18728 | 78 | Thm.declaration_attribute (CalculationData.map o apfst o apsnd o Drule.add_rule) | 
| 18637 | 79 | #> ContextRules.elim_query NONE; | 
| 80 | val sym_del = | |
| 18728 | 81 | Thm.declaration_attribute (CalculationData.map o apfst o apsnd o Drule.del_rule) | 
| 18637 | 82 | #> ContextRules.rule_del; | 
| 12379 | 83 | |
| 84 | ||
| 18637 | 85 | (* symmetric *) | 
| 12379 | 86 | |
| 18728 | 87 | val symmetric = Thm.rule_attribute (fn x => fn th => | 
| 19861 | 88 | (case Seq.chop 2 (Drule.multi_resolves [th] (#2 (#1 (CalculationData.get x)))) of | 
| 20898 | 89 | ([th'], _) => Drule.zero_var_indexes th' | 
| 12379 | 90 |   | ([], _) => raise THM ("symmetric: no unifiers", 1, [th])
 | 
| 91 |   | _ => raise THM ("symmetric: multiple unifiers", 1, [th])));
 | |
| 92 | ||
| 6778 | 93 | |
| 94 | (* concrete syntax *) | |
| 95 | ||
| 18637 | 96 | val trans_att = Attrib.add_del_args trans_add trans_del; | 
| 97 | val sym_att = Attrib.add_del_args sym_add sym_del; | |
| 12379 | 98 | |
| 15801 | 99 | val _ = Context.add_setup | 
| 18708 | 100 | (Attrib.add_attributes | 
| 18728 | 101 |    [("trans", trans_att, "declaration of transitivity rule"),
 | 
| 102 |     ("sym", sym_att, "declaration of symmetry rule"),
 | |
| 103 |     ("symmetric", Attrib.no_args symmetric, "resolution with symmetry rule")] #>
 | |
| 18708 | 104 | PureThy.add_thms | 
| 18728 | 105 |    [(("", transitive_thm), [trans_add]),
 | 
| 106 |     (("", symmetric_thm), [sym_add])] #> snd);
 | |
| 15801 | 107 | |
| 6778 | 108 | |
| 6787 | 109 | |
| 6778 | 110 | (** proof commands **) | 
| 111 | ||
| 18678 | 112 | fun err_if b msg = if b then error msg else (); | 
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 113 | |
| 14555 
341908d6c792
'also'/'moreover': do not interfere with current facts, allow in chain mode;
 wenzelm parents: 
14549diff
changeset | 114 | fun assert_sane final = | 
| 
341908d6c792
'also'/'moreover': do not interfere with current facts, allow in chain mode;
 wenzelm parents: 
14549diff
changeset | 115 | if final then Proof.assert_forward else Proof.assert_forward_or_chain; | 
| 
341908d6c792
'also'/'moreover': do not interfere with current facts, allow in chain mode;
 wenzelm parents: 
14549diff
changeset | 116 | |
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 117 | fun maintain_calculation false calc = put_calculation (SOME calc) | 
| 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 118 | | maintain_calculation true calc = put_calculation NONE #> Proof.chain_facts calc; | 
| 6778 | 119 | |
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 120 | fun print_calculation false _ _ = () | 
| 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 121 | | print_calculation true ctxt calc = | 
| 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 122 | Pretty.writeln (ProofContext.pretty_fact ctxt (calculationN, calc)); | 
| 8562 | 123 | |
| 124 | ||
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 125 | (* also and finally *) | 
| 8562 | 126 | |
| 18637 | 127 | val get_rules = #1 o CalculationData.get o Context.Proof o Proof.context_of; | 
| 128 | ||
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 129 | fun calculate prep_rules final raw_rules int state = | 
| 6778 | 130 | let | 
| 12805 | 131 | val strip_assums_concl = Logic.strip_assums_concl o Thm.prop_of; | 
| 18947 | 132 | val eq_prop = op aconv o pairself (Envir.beta_eta_contract o strip_assums_concl); | 
| 11097 | 133 | fun projection ths th = Library.exists (Library.curry eq_prop th) ths; | 
| 8300 | 134 | |
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 135 | val opt_rules = Option.map (prep_rules state) raw_rules; | 
| 11097 | 136 | fun combine ths = | 
| 15531 | 137 | (case opt_rules of SOME rules => rules | 
| 138 | | NONE => | |
| 18637 | 139 | (case ths of [] => NetRules.rules (#1 (get_rules state)) | 
| 140 | | th :: _ => NetRules.retrieve (#1 (get_rules state)) (strip_assums_concl th))) | |
| 18223 | 141 | |> Seq.of_list |> Seq.maps (Drule.multi_resolve ths) | 
| 11097 | 142 | |> Seq.filter (not o projection ths); | 
| 7414 | 143 | |
| 14555 
341908d6c792
'also'/'moreover': do not interfere with current facts, allow in chain mode;
 wenzelm parents: 
14549diff
changeset | 144 | val facts = Proof.the_facts (assert_sane final state); | 
| 6903 | 145 | val (initial, calculations) = | 
| 6778 | 146 | (case get_calculation state of | 
| 15531 | 147 | NONE => (true, Seq.single facts) | 
| 148 | | SOME calc => (false, Seq.map single (combine (calc @ facts)))); | |
| 6778 | 149 | in | 
| 18678 | 150 | err_if (initial andalso final) "No calculation yet"; | 
| 151 | err_if (initial andalso is_some opt_rules) "Initial calculation -- no rules to be given"; | |
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 152 | calculations |> Seq.map (fn calc => (print_calculation int (Proof.context_of state) calc; | 
| 12055 | 153 | state |> maintain_calculation final calc)) | 
| 6778 | 154 | end; | 
| 155 | ||
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 156 | val also = calculate Proof.get_thmss false; | 
| 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 157 | val also_i = calculate (K I) false; | 
| 22573 | 158 | val finally_ = calculate Proof.get_thmss true; | 
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 159 | val finally_i = calculate (K I) true; | 
| 6778 | 160 | |
| 161 | ||
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 162 | (* moreover and ultimately *) | 
| 8562 | 163 | |
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 164 | fun collect final int state = | 
| 8588 | 165 | let | 
| 14555 
341908d6c792
'also'/'moreover': do not interfere with current facts, allow in chain mode;
 wenzelm parents: 
14549diff
changeset | 166 | val facts = Proof.the_facts (assert_sane final state); | 
| 8588 | 167 | val (initial, thms) = | 
| 168 | (case get_calculation state of | |
| 15531 | 169 | NONE => (true, []) | 
| 170 | | SOME thms => (false, thms)); | |
| 8588 | 171 | val calc = thms @ facts; | 
| 172 | in | |
| 18678 | 173 | err_if (initial andalso final) "No calculation yet"; | 
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 174 | print_calculation int (Proof.context_of state) calc; | 
| 8588 | 175 | state |> maintain_calculation final calc | 
| 176 | end; | |
| 177 | ||
| 17350 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 178 | val moreover = collect false; | 
| 
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
 wenzelm parents: 
16571diff
changeset | 179 | val ultimately = collect true; | 
| 8562 | 180 | |
| 6778 | 181 | end; |