author | kuncar |
Mon, 24 Feb 2014 18:12:39 +0100 | |
changeset 55721 | 1c2cfc06c96a |
parent 55141 | 863b4f9f6bd7 |
child 56334 | 6b3739fee456 |
permissions | -rw-r--r-- |
6778 | 1 |
(* Title: Pure/Isar/calculation.ML |
2 |
Author: Markus Wenzel, TU Muenchen |
|
3 |
||
17350
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
wenzelm
parents:
16571
diff
changeset
|
4 |
Generic calculational proofs. |
6778 | 5 |
*) |
6 |
||
7 |
signature CALCULATION = |
|
8 |
sig |
|
21506 | 9 |
val print_rules: Proof.context -> unit |
16571 | 10 |
val get_calculation: Proof.state -> thm list option |
18728 | 11 |
val trans_add: attribute |
12 |
val trans_del: attribute |
|
13 |
val sym_add: attribute |
|
14 |
val sym_del: attribute |
|
15 |
val symmetric: attribute |
|
49868
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
16 |
val also: thm list option -> bool -> Proof.state -> Proof.state Seq.result Seq.seq |
37047
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
17 |
val also_cmd: (Facts.ref * Attrib.src list) list option -> |
49868
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
18 |
bool -> Proof.state -> Proof.state Seq.result Seq.seq |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
19 |
val finally: thm list option -> bool -> Proof.state -> Proof.state Seq.result Seq.seq |
36323
655e2d74de3a
modernized naming conventions of main Isar proof elements;
wenzelm
parents:
33519
diff
changeset
|
20 |
val finally_cmd: (Facts.ref * Attrib.src list) list option -> bool -> |
49868
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
21 |
Proof.state -> Proof.state Seq.result Seq.seq |
17350
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
wenzelm
parents:
16571
diff
changeset
|
22 |
val moreover: bool -> Proof.state -> Proof.state |
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
wenzelm
parents:
16571
diff
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 |
|
37047
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
31 |
structure Data = Generic_Data |
18637 | 32 |
( |
30560 | 33 |
type T = (thm Item_Net.T * thm list) * (thm list * int) option; |
34 |
val empty = ((Thm.elim_rules, []), NONE); |
|
18637 | 35 |
val extend = I; |
33519 | 36 |
fun merge (((trans1, sym1), _), ((trans2, sym2), _)) = |
30560 | 37 |
((Item_Net.merge (trans1, trans2), Thm.merge_thms (sym1, sym2)), NONE); |
18637 | 38 |
); |
39 |
||
38332
6551e310e7cb
prefer plain Attrib.eval_thmss -- also means the assert_forward of Proof.get_thmss_cmd is skipped, leading to uniform (albeit odd) behaviour concerning forward chaining;
wenzelm
parents:
37047
diff
changeset
|
40 |
val get_rules = #1 o Data.get o Context.Proof; |
6551e310e7cb
prefer plain Attrib.eval_thmss -- also means the assert_forward of Proof.get_thmss_cmd is skipped, leading to uniform (albeit odd) behaviour concerning forward chaining;
wenzelm
parents:
37047
diff
changeset
|
41 |
|
22846 | 42 |
fun print_rules ctxt = |
51584 | 43 |
let |
44 |
val pretty_thm = Display.pretty_thm_item ctxt; |
|
45 |
val (trans, sym) = get_rules ctxt; |
|
46 |
in |
|
47 |
[Pretty.big_list "transitivity rules:" (map pretty_thm (Item_Net.content trans)), |
|
48 |
Pretty.big_list "symmetry rules:" (map pretty_thm sym)] |
|
51580
64ef8260dc60
Pretty.item markup for improved readability of lists of items;
wenzelm
parents:
49868
diff
changeset
|
49 |
end |> Pretty.chunks |> Pretty.writeln; |
6778 | 50 |
|
51 |
||
52 |
(* access calculation *) |
|
53 |
||
54 |
fun get_calculation state = |
|
37047
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
55 |
(case #2 (Data.get (Context.Proof (Proof.context_of state))) of |
15531 | 56 |
NONE => NONE |
57 |
| SOME (thms, lev) => if lev = Proof.level state then SOME thms else NONE); |
|
6778 | 58 |
|
17350
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
wenzelm
parents:
16571
diff
changeset
|
59 |
val calculationN = "calculation"; |
6778 | 60 |
|
17350
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
wenzelm
parents:
16571
diff
changeset
|
61 |
fun put_calculation calc = |
18728 | 62 |
`Proof.level #-> (fn lev => Proof.map_context (Context.proof_map |
37047
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
63 |
(Data.map (apsnd (K (Option.map (rpair lev) calc)))))) |
26252 | 64 |
#> Proof.put_thms false (calculationN, calc); |
6778 | 65 |
|
66 |
||
18637 | 67 |
|
6778 | 68 |
(** attributes **) |
69 |
||
12379 | 70 |
(* add/del rules *) |
71 |
||
37047
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
72 |
val trans_add = Thm.declaration_attribute (Data.map o apfst o apfst o Item_Net.update); |
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
73 |
val trans_del = Thm.declaration_attribute (Data.map o apfst o apfst o Item_Net.remove); |
6778 | 74 |
|
18637 | 75 |
val sym_add = |
45375
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
42360
diff
changeset
|
76 |
Thm.declaration_attribute (fn th => |
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
42360
diff
changeset
|
77 |
(Data.map o apfst o apsnd) (Thm.add_thm th) #> |
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
42360
diff
changeset
|
78 |
Thm.attribute_declaration (Context_Rules.elim_query NONE) th); |
33369 | 79 |
|
18637 | 80 |
val sym_del = |
45375
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
42360
diff
changeset
|
81 |
Thm.declaration_attribute (fn th => |
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
42360
diff
changeset
|
82 |
(Data.map o apfst o apsnd) (Thm.del_thm th) #> |
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
42360
diff
changeset
|
83 |
Thm.attribute_declaration Context_Rules.rule_del th); |
12379 | 84 |
|
85 |
||
18637 | 86 |
(* symmetric *) |
12379 | 87 |
|
18728 | 88 |
val symmetric = Thm.rule_attribute (fn x => fn th => |
37047
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
89 |
(case Seq.chop 2 (Drule.multi_resolves [th] (#2 (#1 (Data.get x)))) of |
20898 | 90 |
([th'], _) => Drule.zero_var_indexes th' |
12379 | 91 |
| ([], _) => raise THM ("symmetric: no unifiers", 1, [th]) |
92 |
| _ => raise THM ("symmetric: multiple unifiers", 1, [th]))); |
|
93 |
||
6778 | 94 |
|
95 |
(* concrete syntax *) |
|
96 |
||
53171 | 97 |
val _ = Theory.setup |
55141 | 98 |
(Attrib.setup @{binding trans} (Attrib.add_del trans_add trans_del) |
30528 | 99 |
"declaration of transitivity rule" #> |
55141 | 100 |
Attrib.setup @{binding sym} (Attrib.add_del sym_add sym_del) |
30528 | 101 |
"declaration of symmetry rule" #> |
55141 | 102 |
Attrib.setup @{binding symmetric} (Scan.succeed symmetric) |
30528 | 103 |
"resolution with symmetry rule" #> |
39557
fe5722fce758
renamed structure PureThy to Pure_Thy and moved most content to Global_Theory, to emphasize that this is global-only;
wenzelm
parents:
38332
diff
changeset
|
104 |
Global_Theory.add_thms |
29579 | 105 |
[((Binding.empty, transitive_thm), [trans_add]), |
53171 | 106 |
((Binding.empty, symmetric_thm), [sym_add])] #> snd); |
15801 | 107 |
|
6778 | 108 |
|
6787 | 109 |
|
6778 | 110 |
(** proof commands **) |
111 |
||
14555
341908d6c792
'also'/'moreover': do not interfere with current facts, allow in chain mode;
wenzelm
parents:
14549
diff
changeset
|
112 |
fun assert_sane final = |
341908d6c792
'also'/'moreover': do not interfere with current facts, allow in chain mode;
wenzelm
parents:
14549
diff
changeset
|
113 |
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:
14549
diff
changeset
|
114 |
|
37047
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
115 |
fun maintain_calculation int final calc state = |
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
116 |
let |
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
117 |
val state' = put_calculation (SOME calc) state; |
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
118 |
val ctxt' = Proof.context_of state'; |
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
119 |
val _ = |
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
120 |
if int then |
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
121 |
Pretty.writeln |
42360 | 122 |
(Proof_Context.pretty_fact ctxt' |
123 |
(Proof_Context.full_name ctxt' (Binding.name calculationN), calc)) |
|
37047
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
124 |
else (); |
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
125 |
in state' |> final ? (put_calculation NONE #> Proof.chain_facts calc) end; |
8562 | 126 |
|
127 |
||
17350
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
wenzelm
parents:
16571
diff
changeset
|
128 |
(* also and finally *) |
8562 | 129 |
|
17350
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
wenzelm
parents:
16571
diff
changeset
|
130 |
fun calculate prep_rules final raw_rules int state = |
6778 | 131 |
let |
38332
6551e310e7cb
prefer plain Attrib.eval_thmss -- also means the assert_forward of Proof.get_thmss_cmd is skipped, leading to uniform (albeit odd) behaviour concerning forward chaining;
wenzelm
parents:
37047
diff
changeset
|
132 |
val ctxt = Proof.context_of state; |
49868
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
133 |
val pretty_thm = Display.pretty_thm ctxt; |
51584 | 134 |
val pretty_thm_item = Display.pretty_thm_item ctxt; |
38332
6551e310e7cb
prefer plain Attrib.eval_thmss -- also means the assert_forward of Proof.get_thmss_cmd is skipped, leading to uniform (albeit odd) behaviour concerning forward chaining;
wenzelm
parents:
37047
diff
changeset
|
135 |
|
12805 | 136 |
val strip_assums_concl = Logic.strip_assums_concl o Thm.prop_of; |
18947 | 137 |
val eq_prop = op aconv o pairself (Envir.beta_eta_contract o strip_assums_concl); |
49868
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
138 |
fun check_projection ths th = |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
139 |
(case find_index (curry eq_prop th) ths of |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
140 |
~1 => Seq.Result [th] |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
141 |
| i => |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
142 |
Seq.Error (fn () => |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
143 |
(Pretty.string_of o Pretty.chunks) |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
144 |
[Pretty.block [Pretty.str "Vacuous calculation result:", Pretty.brk 1, pretty_thm th], |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
145 |
(Pretty.block o Pretty.fbreaks) |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
146 |
(Pretty.str ("derived as projection (" ^ string_of_int (i + 1) ^ ") from:") :: |
51584 | 147 |
map pretty_thm_item ths)])); |
8300 | 148 |
|
38332
6551e310e7cb
prefer plain Attrib.eval_thmss -- also means the assert_forward of Proof.get_thmss_cmd is skipped, leading to uniform (albeit odd) behaviour concerning forward chaining;
wenzelm
parents:
37047
diff
changeset
|
149 |
val opt_rules = Option.map (prep_rules ctxt) raw_rules; |
11097 | 150 |
fun combine ths = |
49868
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
151 |
Seq.append |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
152 |
((case opt_rules of |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
153 |
SOME rules => rules |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
154 |
| NONE => |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
155 |
(case ths of |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
156 |
[] => Item_Net.content (#1 (get_rules ctxt)) |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
157 |
| th :: _ => Item_Net.retrieve (#1 (get_rules ctxt)) (strip_assums_concl th))) |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
158 |
|> Seq.of_list |> Seq.maps (Drule.multi_resolve ths) |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
159 |
|> Seq.map (check_projection ths)) |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
160 |
(Seq.single (Seq.Error (fn () => |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
161 |
(Pretty.string_of o Pretty.block o Pretty.fbreaks) |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
162 |
(Pretty.str "No matching trans rules for calculation:" :: |
51584 | 163 |
map pretty_thm_item ths)))); |
7414 | 164 |
|
14555
341908d6c792
'also'/'moreover': do not interfere with current facts, allow in chain mode;
wenzelm
parents:
14549
diff
changeset
|
165 |
val facts = Proof.the_facts (assert_sane final state); |
6903 | 166 |
val (initial, calculations) = |
6778 | 167 |
(case get_calculation state of |
49868
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
168 |
NONE => (true, Seq.single (Seq.Result facts)) |
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
169 |
| SOME calc => (false, combine (calc @ facts))); |
37047
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
170 |
|
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
171 |
val _ = initial andalso final andalso error "No calculation yet"; |
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
172 |
val _ = initial andalso is_some opt_rules andalso |
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
173 |
error "Initial calculation -- no rules to be given"; |
6778 | 174 |
in |
49868
3039922ffd8d
more informative errors for 'also' and 'finally';
wenzelm
parents:
45375
diff
changeset
|
175 |
calculations |> Seq.map_result (fn calc => maintain_calculation int final calc state) |
6778 | 176 |
end; |
177 |
||
36323
655e2d74de3a
modernized naming conventions of main Isar proof elements;
wenzelm
parents:
33519
diff
changeset
|
178 |
val also = calculate (K I) false; |
38332
6551e310e7cb
prefer plain Attrib.eval_thmss -- also means the assert_forward of Proof.get_thmss_cmd is skipped, leading to uniform (albeit odd) behaviour concerning forward chaining;
wenzelm
parents:
37047
diff
changeset
|
179 |
val also_cmd = calculate Attrib.eval_thms false; |
36323
655e2d74de3a
modernized naming conventions of main Isar proof elements;
wenzelm
parents:
33519
diff
changeset
|
180 |
val finally = calculate (K I) true; |
38332
6551e310e7cb
prefer plain Attrib.eval_thmss -- also means the assert_forward of Proof.get_thmss_cmd is skipped, leading to uniform (albeit odd) behaviour concerning forward chaining;
wenzelm
parents:
37047
diff
changeset
|
181 |
val finally_cmd = calculate Attrib.eval_thms true; |
6778 | 182 |
|
183 |
||
17350
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
wenzelm
parents:
16571
diff
changeset
|
184 |
(* moreover and ultimately *) |
8562 | 185 |
|
17350
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
wenzelm
parents:
16571
diff
changeset
|
186 |
fun collect final int state = |
8588 | 187 |
let |
14555
341908d6c792
'also'/'moreover': do not interfere with current facts, allow in chain mode;
wenzelm
parents:
14549
diff
changeset
|
188 |
val facts = Proof.the_facts (assert_sane final state); |
8588 | 189 |
val (initial, thms) = |
190 |
(case get_calculation state of |
|
15531 | 191 |
NONE => (true, []) |
192 |
| SOME thms => (false, thms)); |
|
8588 | 193 |
val calc = thms @ facts; |
37047
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
194 |
val _ = initial andalso final andalso error "No calculation yet"; |
4a95a50d0ec4
print calculation result in the context where the fact is actually defined -- proper externing;
wenzelm
parents:
36323
diff
changeset
|
195 |
in maintain_calculation int final calc state end; |
8588 | 196 |
|
17350
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
wenzelm
parents:
16571
diff
changeset
|
197 |
val moreover = collect false; |
26cd3756377a
more self-contained proof elements (material from isar_thy.ML);
wenzelm
parents:
16571
diff
changeset
|
198 |
val ultimately = collect true; |
8562 | 199 |
|
55141 | 200 |
|
201 |
(* outer syntax *) |
|
202 |
||
203 |
val calc_args = |
|
204 |
Scan.option (@{keyword "("} |-- Parse.!!! ((Parse_Spec.xthms1 --| @{keyword ")"}))); |
|
205 |
||
206 |
val _ = |
|
207 |
Outer_Syntax.command @{command_spec "also"} "combine calculation and current facts" |
|
208 |
(calc_args >> (Toplevel.proofs' o also_cmd)); |
|
209 |
||
210 |
val _ = |
|
211 |
Outer_Syntax.command @{command_spec "finally"} |
|
212 |
"combine calculation and current facts, exhibit result" |
|
213 |
(calc_args >> (Toplevel.proofs' o finally_cmd)); |
|
214 |
||
215 |
val _ = |
|
216 |
Outer_Syntax.command @{command_spec "moreover"} "augment calculation by current facts" |
|
217 |
(Scan.succeed (Toplevel.proof' moreover)); |
|
218 |
||
219 |
val _ = |
|
220 |
Outer_Syntax.command @{command_spec "ultimately"} |
|
221 |
"augment calculation by current facts, exhibit result" |
|
222 |
(Scan.succeed (Toplevel.proof' ultimately)); |
|
223 |
||
224 |
val _ = |
|
225 |
Outer_Syntax.improper_command @{command_spec "print_trans_rules"} "print transitivity rules" |
|
226 |
(Scan.succeed (Toplevel.unknown_context o Toplevel.keep (print_rules o Toplevel.context_of))); |
|
227 |
||
6778 | 228 |
end; |