4 Copyright 1998 University of Cambridge |
4 Copyright 1998 University of Cambridge |
5 |
5 |
6 LeadsTo relation, restricted to the set of reachable states. |
6 LeadsTo relation, restricted to the set of reachable states. |
7 *) |
7 *) |
8 |
8 |
|
9 (*Map its type, ['a program, 'a set, 'a set] => bool, to just 'a*) |
|
10 Blast.overloaded ("SubstAx.LeadsTo", |
|
11 HOLogic.dest_setT o domain_type o range_type); |
9 |
12 |
10 |
13 |
11 (*** Specialized laws for handling invariants ***) |
14 (*** Specialized laws for handling invariants ***) |
12 |
15 |
13 Goal "[| Invariant prg INV; LeadsTo prg (INV Int A) A' |] \ |
16 Goal "[| Invariant prg INV; LeadsTo prg (INV Int A) A' |] \ |
40 val [prem] = Goalw [LeadsTo_def] |
43 val [prem] = Goalw [LeadsTo_def] |
41 "(!!A. A : S ==> LeadsTo prg A B) ==> LeadsTo prg (Union S) B"; |
44 "(!!A. A : S ==> LeadsTo prg A B) ==> LeadsTo prg (Union S) B"; |
42 by (Simp_tac 1); |
45 by (Simp_tac 1); |
43 by (stac Int_Union 1); |
46 by (stac Int_Union 1); |
44 by (blast_tac (claset() addIs [leadsTo_UN, |
47 by (blast_tac (claset() addIs [leadsTo_UN, |
45 simplify (simpset()) prem]) 1); |
48 simplify (simpset()) prem]) 1); |
46 qed "LeadsTo_Union"; |
49 qed "LeadsTo_Union"; |
47 |
50 |
48 |
51 |
49 (*** Derived rules ***) |
52 (*** Derived rules ***) |
50 |
53 |
86 Goal "[| LeadsTo prg A A'; A' <= B' |] ==> LeadsTo prg A B'"; |
89 Goal "[| LeadsTo prg A A'; A' <= B' |] ==> LeadsTo prg A B'"; |
87 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1); |
90 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1); |
88 by (blast_tac (claset() addIs [leadsTo_weaken_R]) 1); |
91 by (blast_tac (claset() addIs [leadsTo_weaken_R]) 1); |
89 qed_spec_mp "LeadsTo_weaken_R"; |
92 qed_spec_mp "LeadsTo_weaken_R"; |
90 |
93 |
91 |
|
92 Goal "[| LeadsTo prg A A'; B <= A; id: Acts prg |] \ |
94 Goal "[| LeadsTo prg A A'; B <= A; id: Acts prg |] \ |
93 \ ==> LeadsTo prg B A'"; |
95 \ ==> LeadsTo prg B A'"; |
94 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1); |
96 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1); |
95 by (blast_tac (claset() addIs [leadsTo_weaken_L]) 1); |
97 by (blast_tac (claset() addIs [leadsTo_weaken_L]) 1); |
96 qed_spec_mp "LeadsTo_weaken_L"; |
98 qed_spec_mp "LeadsTo_weaken_L"; |
97 |
99 |
98 |
100 Goal "[| LeadsTo prg A A'; id: Acts prg; \ |
99 (*Distributes over binary unions*) |
101 \ B <= A; A' <= B' |] \ |
|
102 \ ==> LeadsTo prg B B'"; |
|
103 (*PROOF FAILED unless the Trans rule is last*) |
|
104 by (blast_tac (claset() addIs [LeadsTo_weaken_R, LeadsTo_weaken_L, |
|
105 LeadsTo_Trans]) 1); |
|
106 qed "LeadsTo_weaken"; |
|
107 |
|
108 |
|
109 (** Two theorems for "proof lattices" **) |
|
110 |
|
111 Goal "[| id: Acts prg; LeadsTo prg A B |] ==> LeadsTo prg (A Un B) B"; |
|
112 by (blast_tac (claset() addIs [LeadsTo_Un, subset_imp_LeadsTo]) 1); |
|
113 qed "LeadsTo_Un_post"; |
|
114 |
|
115 Goal "[| id: Acts prg; LeadsTo prg A B; LeadsTo prg B C |] \ |
|
116 \ ==> LeadsTo prg (A Un B) C"; |
|
117 by (blast_tac (claset() addIs [LeadsTo_Un, subset_imp_LeadsTo, |
|
118 LeadsTo_weaken_L, LeadsTo_Trans]) 1); |
|
119 qed "LeadsTo_Trans_Un"; |
|
120 |
|
121 |
|
122 (** Distributive laws **) |
|
123 |
100 Goal "id: Acts prg ==> \ |
124 Goal "id: Acts prg ==> \ |
101 \ LeadsTo prg (A Un B) C = \ |
125 \ LeadsTo prg (A Un B) C = \ |
102 \ (LeadsTo prg A C & LeadsTo prg B C)"; |
126 \ (LeadsTo prg A C & LeadsTo prg B C)"; |
103 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken_L]) 1); |
127 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken_L]) 1); |
104 qed "LeadsTo_Un_distrib"; |
128 qed "LeadsTo_Un_distrib"; |
112 Goal "id: Acts prg ==> \ |
136 Goal "id: Acts prg ==> \ |
113 \ LeadsTo prg (Union S) B = \ |
137 \ LeadsTo prg (Union S) B = \ |
114 \ (ALL A : S. LeadsTo prg A B)"; |
138 \ (ALL A : S. LeadsTo prg A B)"; |
115 by (blast_tac (claset() addIs [LeadsTo_Union, LeadsTo_weaken_L]) 1); |
139 by (blast_tac (claset() addIs [LeadsTo_Union, LeadsTo_weaken_L]) 1); |
116 qed "LeadsTo_Union_distrib"; |
140 qed "LeadsTo_Union_distrib"; |
117 |
|
118 |
|
119 Goal "[| LeadsTo prg A A'; id: Acts prg; \ |
|
120 \ B <= A; A' <= B' |] \ |
|
121 \ ==> LeadsTo prg B B'"; |
|
122 (*PROOF FAILED*) |
|
123 by (blast_tac (claset() addIs [LeadsTo_Trans, LeadsTo_weaken_R, |
|
124 LeadsTo_weaken_L]) 1); |
|
125 qed "LeadsTo_weaken"; |
|
126 |
141 |
127 |
142 |
128 (** More rules using the premise "Invariant prg" **) |
143 (** More rules using the premise "Invariant prg" **) |
129 |
144 |
130 Goalw [LeadsTo_def, Constrains_def] |
145 Goalw [LeadsTo_def, Constrains_def] |
158 qed "Invariant_LeadsTo_weaken"; |
173 qed "Invariant_LeadsTo_weaken"; |
159 |
174 |
160 |
175 |
161 (*Set difference: maybe combine with leadsTo_weaken_L?? |
176 (*Set difference: maybe combine with leadsTo_weaken_L?? |
162 This is the most useful form of the "disjunction" rule*) |
177 This is the most useful form of the "disjunction" rule*) |
163 Goal "[| LeadsTo prg (A-B) C; LeadsTo prg B C; id: Acts prg |] \ |
178 Goal "[| LeadsTo prg (A-B) C; LeadsTo prg (A Int B) C; id: Acts prg |] \ |
164 \ ==> LeadsTo prg A C"; |
179 \ ==> LeadsTo prg A C"; |
165 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken]) 1); |
180 by (stac (Un_Diff_Int RS sym) 1 THEN rtac LeadsTo_Un 1); |
|
181 by (REPEAT (assume_tac 1)); |
|
182 (*One step, but PROOF FAILED... |
|
183 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken]) 1); |
|
184 *) |
166 qed "LeadsTo_Diff"; |
185 qed "LeadsTo_Diff"; |
|
186 |
|
187 |
167 |
188 |
168 |
189 |
169 val prems = |
190 val prems = |
170 Goal "(!! i. i:I ==> LeadsTo prg (A i) (A' i)) \ |
191 Goal "(!! i. i:I ==> LeadsTo prg (A i) (A' i)) \ |
171 \ ==> LeadsTo prg (UN i:I. A i) (UN i:I. A' i)"; |
192 \ ==> LeadsTo prg (UN i:I. A i) (UN i:I. A' i)"; |
403 (EVERY [REPEAT (Invariant_Int_tac 1), |
424 (EVERY [REPEAT (Invariant_Int_tac 1), |
404 etac Invariant_LeadsTo_Basis 1 |
425 etac Invariant_LeadsTo_Basis 1 |
405 ORELSE (*subgoal may involve LeadsTo, leadsTo or ensures*) |
426 ORELSE (*subgoal may involve LeadsTo, leadsTo or ensures*) |
406 REPEAT (ares_tac [LeadsTo_Basis, ensuresI] 1), |
427 REPEAT (ares_tac [LeadsTo_Basis, ensuresI] 1), |
407 res_inst_tac [("act", sact)] transient_mem 2, |
428 res_inst_tac [("act", sact)] transient_mem 2, |
|
429 (*simplify the command's domain*) |
408 simp_tac (simpset() addsimps (Domain_partial_func::cmd_defs)) 3, |
430 simp_tac (simpset() addsimps (Domain_partial_func::cmd_defs)) 3, |
409 simp_tac (simpset() addsimps [main_def]) 2, |
431 (*INSIST that the command belongs to the program*) |
|
432 force_tac (claset(), simpset() addsimps [main_def]) 2, |
410 constrains_tac (main_def::cmd_defs) 1, |
433 constrains_tac (main_def::cmd_defs) 1, |
411 rewrite_goals_tac cmd_defs, |
434 rewrite_goals_tac cmd_defs, |
412 ALLGOALS Clarify_tac, |
435 ALLGOALS Clarify_tac, |
413 Auto_tac]); |
436 Auto_tac]); |
414 |
437 |