8 *) |
8 *) |
9 |
9 |
10 |
10 |
11 (*Resembles the previous definition of LeadsTo*) |
11 (*Resembles the previous definition of LeadsTo*) |
12 |
12 |
|
13 (* Equivalence with the HOL-like definition *) |
13 Goalw [LeadsTo_def] |
14 Goalw [LeadsTo_def] |
14 "A LeadsTo B = \ |
15 "st_set(B)==> A LeadsTo B = {F:program. F:(reachable(F) Int A) leadsTo B}"; |
15 \ {F:program. F : (reachable(F) Int A) leadsTo (reachable(F) Int B) & \ |
16 by (blast_tac (claset() addDs [psp_stable2, leadsToD2, constrainsD2] |
16 \ A:condition & B:condition}"; |
|
17 by (blast_tac (claset() addDs [psp_stable2, leadsToD, constrainsD2] |
|
18 addIs [leadsTo_weaken]) 1); |
17 addIs [leadsTo_weaken]) 1); |
19 qed "LeadsTo_eq_leadsTo"; |
18 qed "LeadsTo_eq"; |
20 |
19 |
21 Goalw [LeadsTo_def] |
20 Goalw [LeadsTo_def] "A LeadsTo B <=program"; |
22 "F: A LeadsTo B ==> F:program & A:condition & B:condition"; |
21 by Auto_tac; |
23 by (Blast_tac 1); |
22 qed "LeadsTo_type"; |
24 qed "LeadsToD"; |
|
25 |
23 |
26 (*** Specialized laws for handling invariants ***) |
24 (*** Specialized laws for handling invariants ***) |
27 |
25 |
28 (** Conjoining an Always property **) |
26 (** Conjoining an Always property **) |
29 Goal "[| F : Always(INV); A:condition |] ==> \ |
27 Goal "F : Always(I) ==> (F:(I Int A) LeadsTo A') <-> (F: A LeadsTo A')"; |
30 \ (F : (INV Int A) LeadsTo A') <-> (F : A LeadsTo A')"; |
|
31 by (asm_full_simp_tac |
28 by (asm_full_simp_tac |
32 (simpset() addsimps [LeadsTo_def, Always_eq_includes_reachable, |
29 (simpset() addsimps [LeadsTo_def, Always_eq_includes_reachable, |
33 Int_absorb2, Int_assoc RS sym, leadsToD]) 1); |
30 Int_absorb2, Int_assoc RS sym, leadsToD2]) 1); |
34 qed "Always_LeadsTo_pre"; |
31 qed "Always_LeadsTo_pre"; |
35 |
32 |
36 Goal "[| F : Always(INV); A':condition |] \ |
33 Goalw [LeadsTo_def] "F:Always(I) ==> (F : A LeadsTo (I Int A')) <-> (F : A LeadsTo A')"; |
37 \ ==> (F : A LeadsTo (INV Int A')) <-> (F : A LeadsTo A')"; |
34 by (asm_full_simp_tac (simpset() addsimps [Always_eq_includes_reachable, |
38 by (asm_full_simp_tac |
35 Int_absorb2, Int_assoc RS sym,leadsToD2]) 1); |
39 (simpset() addsimps [LeadsTo_eq_leadsTo, Always_eq_includes_reachable, |
|
40 Int_absorb2, Int_assoc RS sym,leadsToD]) 1); |
|
41 qed "Always_LeadsTo_post"; |
36 qed "Always_LeadsTo_post"; |
42 |
37 |
43 (* Like 'Always_LeadsTo_pre RS iffD1', but with premises in the good order *) |
38 (* Like 'Always_LeadsTo_pre RS iffD1', but with premises in the good order *) |
44 Goal "[| F:Always(C); F : (C Int A) LeadsTo A'; A:condition |] \ |
39 Goal "[| F:Always(C); F : (C Int A) LeadsTo A' |] ==> F: A LeadsTo A'"; |
45 \ ==> F: A LeadsTo A'"; |
|
46 by (blast_tac (claset() addIs [Always_LeadsTo_pre RS iffD1]) 1); |
40 by (blast_tac (claset() addIs [Always_LeadsTo_pre RS iffD1]) 1); |
47 qed "Always_LeadsToI"; |
41 qed "Always_LeadsToI"; |
48 |
42 |
49 (* Like 'Always_LeadsTo_post RS iffD2', but with premises in the good order *) |
43 (* Like 'Always_LeadsTo_post RS iffD2', but with premises in the good order *) |
50 Goal |
44 Goal "[| F:Always(C); F:A LeadsTo A' |] ==> F : A LeadsTo (C Int A')"; |
51 "[| F : Always(C); F : A LeadsTo A'; A':condition |] \ |
|
52 \ ==> F : A LeadsTo (C Int A')"; |
|
53 by (blast_tac (claset() addIs [Always_LeadsTo_post RS iffD2]) 1); |
45 by (blast_tac (claset() addIs [Always_LeadsTo_post RS iffD2]) 1); |
54 qed "Always_LeadsToD"; |
46 qed "Always_LeadsToD"; |
55 |
47 |
56 (*** Introduction rules: Basis, Trans, Union ***) |
48 (*** Introduction rules: Basis, Trans, Union ***) |
57 |
49 |
58 Goal "F : A leadsTo B ==> F : A LeadsTo B"; |
50 Goal "F : A Ensures B ==> F : A LeadsTo B"; |
59 by (simp_tac (simpset() addsimps [LeadsTo_def]) 1); |
51 by (auto_tac (claset(), simpset() addsimps |
60 by (blast_tac (claset() addIs [leadsTo_weaken_L] |
52 [Ensures_def, LeadsTo_def])); |
61 addDs [leadsToD]) 1); |
53 qed "LeadsTo_Basis"; |
62 qed "leadsTo_imp_LeadsTo"; |
|
63 |
54 |
64 Goal "[| F : A LeadsTo B; F : B LeadsTo C |] ==> F : A LeadsTo C"; |
55 Goal "[| F : A LeadsTo B; F : B LeadsTo C |] ==> F : A LeadsTo C"; |
65 by (full_simp_tac (simpset() addsimps [LeadsTo_eq_leadsTo]) 1); |
56 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1); |
66 by (blast_tac (claset() addIs [leadsTo_Trans]) 1); |
57 by (blast_tac (claset() addIs [leadsTo_Trans]) 1); |
67 qed "LeadsTo_Trans"; |
58 qed "LeadsTo_Trans"; |
68 |
59 |
69 Goalw [LeadsTo_def] |
60 val [major, program] = Goalw [LeadsTo_def] |
70 "[| ALL A:S. F : A LeadsTo B; F:program; B:condition |] \ |
61 "[|(!!A. A:S ==> F : A LeadsTo B); F:program|]==>F:Union(S) LeadsTo B"; |
71 \ ==> F : Union(S) LeadsTo B"; |
62 by (cut_facts_tac [program] 1); |
72 by Auto_tac; |
63 by Auto_tac; |
73 by (stac Int_Union_Union2 1); |
64 by (stac Int_Union_Union2 1); |
74 by (blast_tac (claset() addIs [leadsTo_UN]) 1); |
65 by (rtac leadsTo_UN 1); |
75 bind_thm("LeadsTo_Union", ballI RS result()); |
66 by (dtac major 1); |
76 |
67 by Auto_tac; |
|
68 qed "LeadsTo_Union"; |
77 |
69 |
78 (*** Derived rules ***) |
70 (*** Derived rules ***) |
79 |
71 |
80 Goalw [LeadsTo_def] |
72 Goal "F : A leadsTo B ==> F : A LeadsTo B"; |
81 "[| F:program; A:condition |] ==>F : A LeadsTo state"; |
73 by (forward_tac [leadsToD2] 1); |
82 by (blast_tac (claset() addIs [leadsTo_state]) 1); |
74 by (Clarify_tac 1); |
83 qed "LeadsTo_state"; |
75 by (asm_simp_tac (simpset() addsimps [LeadsTo_eq]) 1); |
84 Addsimps [LeadsTo_state]; |
76 by (blast_tac (claset() addIs [leadsTo_weaken_L]) 1); |
|
77 qed "leadsTo_imp_LeadsTo"; |
85 |
78 |
86 (*Useful with cancellation, disjunction*) |
79 (*Useful with cancellation, disjunction*) |
87 Goal "F : A LeadsTo (A' Un A') ==> F : A LeadsTo A'"; |
80 Goal "F : A LeadsTo (A' Un A') ==> F : A LeadsTo A'"; |
88 by (asm_full_simp_tac (simpset() addsimps Un_ac) 1); |
81 by (asm_full_simp_tac (simpset() addsimps Un_ac) 1); |
89 qed "LeadsTo_Un_duplicate"; |
82 qed "LeadsTo_Un_duplicate"; |
90 |
83 |
91 Goal "F : A LeadsTo (A' Un C Un C) ==> F : A LeadsTo (A' Un C)"; |
84 Goal "F : A LeadsTo (A' Un C Un C) ==> F : A LeadsTo (A' Un C)"; |
92 by (asm_full_simp_tac (simpset() addsimps Un_ac) 1); |
85 by (asm_full_simp_tac (simpset() addsimps Un_ac) 1); |
93 qed "LeadsTo_Un_duplicate2"; |
86 qed "LeadsTo_Un_duplicate2"; |
94 |
87 |
95 Goal "[| ALL i:I. F : A(i) LeadsTo B; F:program; B:condition |] \ |
88 val [major, program] = Goalw [LeadsTo_def] |
|
89 "[|(!!i. i:I ==> F : A(i) LeadsTo B); F:program|] \ |
96 \ ==> F : (UN i:I. A(i)) LeadsTo B"; |
90 \ ==> F : (UN i:I. A(i)) LeadsTo B"; |
97 by (simp_tac (simpset() addsimps [Int_Union_Union]) 1); |
91 by (cut_facts_tac [program] 1); |
98 by (blast_tac (claset() addIs [LeadsTo_Union]) 1); |
92 by (asm_simp_tac (simpset() addsimps [Int_Union_Union2]) 1); |
99 bind_thm("LeadsTo_UN", ballI RS result()); |
93 by (rtac leadsTo_UN 1); |
|
94 by (dtac major 1); |
|
95 by Auto_tac; |
|
96 qed "LeadsTo_UN"; |
100 |
97 |
101 (*Binary union introduction rule*) |
98 (*Binary union introduction rule*) |
102 Goal "[| F : A LeadsTo C; F : B LeadsTo C |] ==> F : (A Un B) LeadsTo C"; |
99 Goal "[| F : A LeadsTo C; F : B LeadsTo C |] ==> F : (A Un B) LeadsTo C"; |
103 by (stac Un_eq_Union 1); |
100 by (stac Un_eq_Union 1); |
104 by (blast_tac (claset() addIs [LeadsTo_Union] |
101 by (rtac LeadsTo_Union 1); |
105 addDs [LeadsToD]) 1); |
102 by (auto_tac (claset() addDs [LeadsTo_type RS subsetD], simpset())); |
106 qed "LeadsTo_Un"; |
103 qed "LeadsTo_Un"; |
107 |
104 |
108 (*Lets us look at the starting state*) |
105 (*Lets us look at the starting state*) |
109 Goal "[| ALL s:A. F : {s} LeadsTo B; F:program; B:condition |]\ |
106 val [major, program] = Goal |
110 \ ==> F : A LeadsTo B"; |
107 "[|(!!s. s:A ==> F:{s} LeadsTo B); F:program|]==>F:A LeadsTo B"; |
|
108 by (cut_facts_tac [program] 1); |
111 by (stac (UN_singleton RS sym) 1 THEN rtac LeadsTo_UN 1); |
109 by (stac (UN_singleton RS sym) 1 THEN rtac LeadsTo_UN 1); |
112 by (REPEAT(Blast_tac 1)); |
110 by (forward_tac [major] 1); |
113 bind_thm("single_LeadsTo_I", ballI RS result()); |
111 by Auto_tac; |
114 |
112 qed "single_LeadsTo_I"; |
115 Goal "[| A <= B; B:condition; F:program |] ==> F : A LeadsTo B"; |
113 |
116 by (subgoal_tac "A:condition" 1); |
114 Goal "[| A <= B; F:program |] ==> F : A LeadsTo B"; |
117 by (force_tac (claset(), |
115 by (asm_simp_tac (simpset() addsimps [LeadsTo_def]) 1); |
118 simpset() addsimps [condition_def]) 2); |
|
119 by (simp_tac (simpset() addsimps [LeadsTo_def]) 1); |
|
120 by (blast_tac (claset() addIs [subset_imp_leadsTo]) 1); |
116 by (blast_tac (claset() addIs [subset_imp_leadsTo]) 1); |
121 qed "subset_imp_LeadsTo"; |
117 qed "subset_imp_LeadsTo"; |
122 |
118 |
123 bind_thm ("empty_LeadsTo", empty_subsetI RS subset_imp_LeadsTo); |
119 Goal "F:0 LeadsTo A <-> F:program"; |
124 Addsimps [empty_LeadsTo]; |
120 by (auto_tac (claset() addDs [LeadsTo_type RS subsetD] |
125 |
121 addIs [empty_subsetI RS subset_imp_LeadsTo], simpset())); |
126 Goal "[| F : A LeadsTo A'; A' <= B'; B':condition |] ==> F : A LeadsTo B'"; |
122 qed "empty_LeadsTo"; |
127 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1); |
123 AddIffs [empty_LeadsTo]; |
128 by (blast_tac (claset() addIs [leadsTo_weaken_R]) 1); |
124 |
|
125 Goal "F : A LeadsTo state <-> F:program"; |
|
126 by (auto_tac (claset() addDs [LeadsTo_type RS subsetD], |
|
127 simpset() addsimps [LeadsTo_eq])); |
|
128 qed "LeadsTo_state"; |
|
129 AddIffs [LeadsTo_state]; |
|
130 |
|
131 Goalw [LeadsTo_def] |
|
132 "[| F:A LeadsTo A'; A'<=B'|] ==> F : A LeadsTo B'"; |
|
133 by (auto_tac (claset() addIs[leadsTo_weaken_R], simpset())); |
129 qed_spec_mp "LeadsTo_weaken_R"; |
134 qed_spec_mp "LeadsTo_weaken_R"; |
130 |
135 |
131 |
136 Goalw [LeadsTo_def] "[| F : A LeadsTo A'; B <= A |] ==> F : B LeadsTo A'"; |
132 Goal "[| F : A LeadsTo A'; B <= A |] \ |
137 by (auto_tac (claset() addIs[leadsTo_weaken_L], simpset())); |
133 \ ==> F : B LeadsTo A'"; |
|
134 by (subgoal_tac "B:condition" 1); |
|
135 by (force_tac (claset() addSDs [LeadsToD], |
|
136 simpset() addsimps [condition_def]) 2); |
|
137 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1); |
|
138 by (blast_tac (claset() addIs [leadsTo_weaken_L]) 1); |
|
139 qed_spec_mp "LeadsTo_weaken_L"; |
138 qed_spec_mp "LeadsTo_weaken_L"; |
140 |
139 |
141 Goal "[| F : A LeadsTo A'; \ |
140 Goal "[| F : A LeadsTo A'; B<=A; A'<=B' |] ==> F : B LeadsTo B'"; |
142 \ B <= A; A' <= B'; B':condition |] \ |
|
143 \ ==> F : B LeadsTo B'"; |
|
144 by (blast_tac (claset() addIs [LeadsTo_weaken_R, |
141 by (blast_tac (claset() addIs [LeadsTo_weaken_R, |
145 LeadsTo_weaken_L, LeadsTo_Trans]) 1); |
142 LeadsTo_weaken_L, LeadsTo_Trans]) 1); |
146 qed "LeadsTo_weaken"; |
143 qed "LeadsTo_weaken"; |
147 |
144 |
148 Goal "[| F : Always(C); F : A LeadsTo A'; \ |
145 Goal |
149 \ C Int B <= A; C Int A' <= B'; B:condition; B':condition |] \ |
146 "[| F:Always(C); F:A LeadsTo A'; C Int B <= A; C Int A' <= B' |] \ |
150 \ ==> F : B LeadsTo B'"; |
147 \ ==> F : B LeadsTo B'"; |
151 by (blast_tac (claset() |
148 by (blast_tac (claset() addDs [Always_LeadsToI] |
152 addDs [AlwaysD2, LeadsToD, Always_LeadsToI] |
149 addIs [LeadsTo_weaken, Always_LeadsToD]) 1); |
153 addIs [LeadsTo_weaken, Always_LeadsToD]) 1); |
|
154 qed "Always_LeadsTo_weaken"; |
150 qed "Always_LeadsTo_weaken"; |
155 |
151 |
156 (** Two theorems for "proof lattices" **) |
152 (** Two theorems for "proof lattices" **) |
157 |
153 |
158 Goal "F : A LeadsTo B ==> F:(A Un B) LeadsTo B"; |
154 Goal "F : A LeadsTo B ==> F:(A Un B) LeadsTo B"; |
159 by (blast_tac (claset() |
155 by (blast_tac (claset() addDs [LeadsTo_type RS subsetD] |
160 addIs [LeadsTo_Un, subset_imp_LeadsTo] |
156 addIs [LeadsTo_Un, subset_imp_LeadsTo]) 1); |
161 addDs [LeadsToD]) 1); |
|
162 qed "LeadsTo_Un_post"; |
157 qed "LeadsTo_Un_post"; |
163 |
158 |
164 Goal "[| F : A LeadsTo B; F : B LeadsTo C |] \ |
159 Goal "[| F : A LeadsTo B; F : B LeadsTo C |] \ |
165 \ ==> F : (A Un B) LeadsTo C"; |
160 \ ==> F : (A Un B) LeadsTo C"; |
166 by (blast_tac (claset() addIs [LeadsTo_Un, subset_imp_LeadsTo, |
161 by (blast_tac (claset() addIs [LeadsTo_Un, subset_imp_LeadsTo, |
167 LeadsTo_weaken_L, LeadsTo_Trans] |
162 LeadsTo_weaken_L, LeadsTo_Trans] |
168 addDs [LeadsToD]) 1); |
163 addDs [LeadsTo_type RS subsetD]) 1); |
169 qed "LeadsTo_Trans_Un"; |
164 qed "LeadsTo_Trans_Un"; |
170 |
165 |
171 |
|
172 (** Distributive laws **) |
166 (** Distributive laws **) |
173 |
|
174 Goal "(F : (A Un B) LeadsTo C) <-> (F : A LeadsTo C & F : B LeadsTo C)"; |
167 Goal "(F : (A Un B) LeadsTo C) <-> (F : A LeadsTo C & F : B LeadsTo C)"; |
175 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken_L]) 1); |
168 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken_L]) 1); |
176 qed "LeadsTo_Un_distrib"; |
169 qed "LeadsTo_Un_distrib"; |
177 |
170 |
178 Goal "[| F:program; B:condition |] ==> \ |
171 Goal "(F : (UN i:I. A(i)) LeadsTo B) <-> (ALL i : I. F : A(i) LeadsTo B) & F:program"; |
179 \ (F : (UN i:I. A(i)) LeadsTo B) <-> (ALL i : I. F : A(i) LeadsTo B)"; |
172 by (blast_tac (claset() addDs [LeadsTo_type RS subsetD] |
180 by (blast_tac (claset() addIs [LeadsTo_UN, LeadsTo_weaken_L]) 1); |
173 addIs [LeadsTo_UN, LeadsTo_weaken_L]) 1); |
181 qed "LeadsTo_UN_distrib"; |
174 qed "LeadsTo_UN_distrib"; |
182 |
175 |
183 Goal "[| F:program; B:condition |] ==> \ |
176 Goal "(F:Union(S) LeadsTo B) <-> (ALL A : S. F : A LeadsTo B) & F:program"; |
184 \ (F : Union(S) LeadsTo B) <-> (ALL A : S. F : A LeadsTo B)"; |
177 by (blast_tac (claset() addDs [LeadsTo_type RS subsetD] |
185 by (blast_tac (claset() addIs [LeadsTo_Union, LeadsTo_weaken_L]) 1); |
178 addIs [LeadsTo_Union, LeadsTo_weaken_L]) 1); |
186 qed "LeadsTo_Union_distrib"; |
179 qed "LeadsTo_Union_distrib"; |
187 |
180 |
188 (** More rules using the premise "Always INV" **) |
181 (** More rules using the premise "Always(I)" **) |
189 |
182 |
190 Goal "F : A Ensures B ==> F : A LeadsTo B"; |
183 Goal "[| F:(A-B) Co (A Un B); F:transient (A-B) |] ==> F : A Ensures B"; |
191 by (asm_full_simp_tac |
|
192 (simpset() addsimps [Ensures_def, LeadsTo_def, leadsTo_Basis]) 1); |
|
193 qed "LeadsTo_Basis"; |
|
194 |
|
195 Goal "[| F : (A-B) Co (A Un B); F : transient (A-B) |] \ |
|
196 \ ==> F : A Ensures B"; |
|
197 by (asm_full_simp_tac |
184 by (asm_full_simp_tac |
198 (simpset() addsimps [Ensures_def, Constrains_eq_constrains]) 1); |
185 (simpset() addsimps [Ensures_def, Constrains_eq_constrains]) 1); |
199 by (blast_tac (claset() addIs [ensuresI, constrains_weaken, |
186 by (blast_tac (claset() addIs [ensuresI, constrains_weaken, |
200 transient_strengthen] |
187 transient_strengthen] |
201 addDs [constrainsD2]) 1); |
188 addDs [constrainsD2]) 1); |
202 qed "EnsuresI"; |
189 qed "EnsuresI"; |
203 |
190 |
204 Goal "[| F : Always(INV); \ |
191 Goal "[| F : Always(I); F : (I Int (A-A')) Co (A Un A'); \ |
205 \ F : (INV Int (A-A')) Co (A Un A'); \ |
192 \ F : transient (I Int (A-A')) |] \ |
206 \ F : transient (INV Int (A-A')) |] \ |
|
207 \ ==> F : A LeadsTo A'"; |
193 \ ==> F : A LeadsTo A'"; |
208 by (rtac Always_LeadsToI 1); |
194 by (rtac Always_LeadsToI 1); |
209 by (assume_tac 1); |
195 by (assume_tac 1); |
210 by (blast_tac (claset() addDs [ConstrainsD]) 2); |
|
211 by (blast_tac (claset() addIs [EnsuresI, LeadsTo_Basis, |
196 by (blast_tac (claset() addIs [EnsuresI, LeadsTo_Basis, |
212 Always_ConstrainsD RS Constrains_weaken, |
197 Always_ConstrainsD RS Constrains_weaken, |
213 transient_strengthen] |
198 transient_strengthen]) 1); |
214 addDs [AlwaysD2, ConstrainsD]) 1); |
|
215 qed "Always_LeadsTo_Basis"; |
199 qed "Always_LeadsTo_Basis"; |
216 |
200 |
217 (*Set difference: maybe combine with leadsTo_weaken_L?? |
201 (*Set difference: maybe combine with leadsTo_weaken_L?? |
218 This is the most useful form of the "disjunction" rule*) |
202 This is the most useful form of the "disjunction" rule*) |
219 Goal "[| F : (A-B) LeadsTo C; F : (A Int B) LeadsTo C; \ |
203 Goal "[| F : (A-B) LeadsTo C; F : (A Int B) LeadsTo C |] ==> F : A LeadsTo C"; |
220 \ A:condition; B:condition |] \ |
204 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken]) 1); |
221 \ ==> F : A LeadsTo C"; |
|
222 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken] |
|
223 addDs [LeadsToD]) 1); |
|
224 qed "LeadsTo_Diff"; |
205 qed "LeadsTo_Diff"; |
225 |
206 |
226 |
207 val [major, minor] = Goal |
227 Goal "[| ALL i:I. F: A(i) LeadsTo A'(i); F:program |] \ |
208 "[|(!!i. i:I ==> F: A(i) LeadsTo A'(i)); F:program |] \ |
228 \ ==> F : (UN i:I. A(i)) LeadsTo (UN i:I. A'(i))"; |
209 \ ==> F : (UN i:I. A(i)) LeadsTo (UN i:I. A'(i))"; |
|
210 by (cut_facts_tac [minor] 1); |
229 by (rtac LeadsTo_Union 1); |
211 by (rtac LeadsTo_Union 1); |
230 by (ALLGOALS(Clarify_tac)); |
212 by (ALLGOALS(Clarify_tac)); |
231 by (blast_tac (claset() addDs [LeadsToD]) 2); |
213 by (forward_tac [major] 1); |
232 by (blast_tac (claset() addIs [LeadsTo_weaken_R] |
214 by (blast_tac (claset() addIs [LeadsTo_weaken_R]) 1); |
233 addDs [LeadsToD]) 1); |
215 qed "LeadsTo_UN_UN"; |
234 bind_thm ("LeadsTo_UN_UN", ballI RS result()); |
|
235 |
|
236 |
|
237 (*Version with no index set*) |
|
238 Goal "[| ALL i. F: A(i) LeadsTo A'(i); F:program |] \ |
|
239 \ ==> F : (UN i:I. A(i)) LeadsTo (UN i:I. A'(i))"; |
|
240 by (blast_tac (claset() addIs [LeadsTo_UN_UN]) 1); |
|
241 qed "all_LeadsTo_UN_UN"; |
|
242 |
|
243 bind_thm ("LeadsTo_UN_UN_noindex", allI RS all_LeadsTo_UN_UN); |
|
244 |
216 |
245 (*Binary union version*) |
217 (*Binary union version*) |
246 Goal "[| F : A LeadsTo A'; F : B LeadsTo B' |] \ |
218 Goal "[| F:A LeadsTo A'; F:B LeadsTo B' |] ==> F:(A Un B) LeadsTo (A' Un B')"; |
247 \ ==> F : (A Un B) LeadsTo (A' Un B')"; |
219 by (blast_tac (claset() addIs [LeadsTo_Un, LeadsTo_weaken_R]) 1); |
248 by (blast_tac (claset() |
|
249 addIs [LeadsTo_Un, LeadsTo_weaken_R] |
|
250 addDs [LeadsToD]) 1); |
|
251 qed "LeadsTo_Un_Un"; |
220 qed "LeadsTo_Un_Un"; |
252 |
221 |
253 (** The cancellation law **) |
222 (** The cancellation law **) |
254 |
223 |
255 Goal "[| F : A LeadsTo (A' Un B); F : B LeadsTo B' |] \ |
224 Goal "[| F: A LeadsTo(A' Un B); F: B LeadsTo B' |] ==> F:A LeadsTo (A' Un B')"; |
256 \ ==> F : A LeadsTo (A' Un B')"; |
225 by (blast_tac (claset() addIs [LeadsTo_Un_Un, subset_imp_LeadsTo, LeadsTo_Trans] |
257 by (blast_tac (claset() addIs [LeadsTo_Un_Un, |
226 addDs [LeadsTo_type RS subsetD]) 1); |
258 subset_imp_LeadsTo, LeadsTo_Trans] |
|
259 addDs [LeadsToD]) 1); |
|
260 qed "LeadsTo_cancel2"; |
227 qed "LeadsTo_cancel2"; |
261 |
228 |
262 Goal "A Un (B - A) = A Un B"; |
229 Goal "A Un (B - A) = A Un B"; |
263 by Auto_tac; |
230 by Auto_tac; |
264 qed "Un_Diff"; |
231 qed "Un_Diff"; |
265 |
232 |
266 Goal "[| F : A LeadsTo (A' Un B); F : (B-A') LeadsTo B' |] \ |
233 Goal "[| F : A LeadsTo (A' Un B); F : (B-A') LeadsTo B' |] ==> F : A LeadsTo (A' Un B')"; |
267 \ ==> F : A LeadsTo (A' Un B')"; |
|
268 by (rtac LeadsTo_cancel2 1); |
234 by (rtac LeadsTo_cancel2 1); |
269 by (assume_tac 2); |
235 by (assume_tac 2); |
270 by (asm_simp_tac (simpset() addsimps [Un_Diff]) 1); |
236 by (asm_simp_tac (simpset() addsimps [Un_Diff]) 1); |
271 qed "LeadsTo_cancel_Diff2"; |
237 qed "LeadsTo_cancel_Diff2"; |
272 |
238 |
273 Goal "[| F : A LeadsTo (B Un A'); F : B LeadsTo B' |] \ |
239 Goal "[| F : A LeadsTo (B Un A'); F : B LeadsTo B' |] ==> F : A LeadsTo (B' Un A')"; |
274 \ ==> F : A LeadsTo (B' Un A')"; |
|
275 by (asm_full_simp_tac (simpset() addsimps [Un_commute]) 1); |
240 by (asm_full_simp_tac (simpset() addsimps [Un_commute]) 1); |
276 by (blast_tac (claset() addSIs [LeadsTo_cancel2]) 1); |
241 by (blast_tac (claset() addSIs [LeadsTo_cancel2]) 1); |
277 qed "LeadsTo_cancel1"; |
242 qed "LeadsTo_cancel1"; |
278 |
243 |
279 |
|
280 Goal "(B - A) Un A = B Un A"; |
244 Goal "(B - A) Un A = B Un A"; |
281 by Auto_tac; |
245 by Auto_tac; |
282 qed "Diff_Un2"; |
246 qed "Diff_Un2"; |
283 |
247 |
284 Goal "[| F : A LeadsTo (B Un A'); F : (B-A') LeadsTo B' |] \ |
248 Goal "[| F : A LeadsTo (B Un A'); F : (B-A') LeadsTo B' |] ==> F : A LeadsTo (B' Un A')"; |
285 \ ==> F : A LeadsTo (B' Un A')"; |
|
286 by (rtac LeadsTo_cancel1 1); |
249 by (rtac LeadsTo_cancel1 1); |
287 by (assume_tac 2); |
250 by (assume_tac 2); |
288 by (asm_simp_tac (simpset() addsimps [Diff_Un2]) 1); |
251 by (asm_simp_tac (simpset() addsimps [Diff_Un2]) 1); |
289 qed "LeadsTo_cancel_Diff1"; |
252 qed "LeadsTo_cancel_Diff1"; |
290 |
253 |
291 |
|
292 (** The impossibility law **) |
254 (** The impossibility law **) |
293 |
255 |
294 (*The set "A" may be non-empty, but it contains no reachable states*) |
256 (*The set "A" may be non-empty, but it contains no reachable states*) |
295 Goal "F : A LeadsTo 0 ==> F : Always (state -A)"; |
257 Goal "F : A LeadsTo 0 ==> F : Always (state -A)"; |
296 by (full_simp_tac (simpset() |
258 by (full_simp_tac (simpset() |
297 addsimps [LeadsTo_def,Always_eq_includes_reachable]) 1); |
259 addsimps [LeadsTo_def,Always_eq_includes_reachable]) 1); |
298 by (Clarify_tac 1); |
260 by (cut_facts_tac [reachable_type] 1); |
299 by (forward_tac [reachableD] 1); |
261 by (auto_tac (claset() addSDs [leadsTo_empty], simpset())); |
300 by (auto_tac (claset() addSDs [leadsTo_empty], |
|
301 simpset() addsimps [condition_def])); |
|
302 qed "LeadsTo_empty"; |
262 qed "LeadsTo_empty"; |
303 |
263 |
304 (** PSP: Progress-Safety-Progress **) |
264 (** PSP: Progress-Safety-Progress **) |
305 |
265 |
306 (*Special case of PSP: Misra's "stable conjunction"*) |
266 (*Special case of PSP: Misra's "stable conjunction"*) |
307 Goal "[| F : A LeadsTo A'; F : Stable(B) |] \ |
267 Goal "[| F : A LeadsTo A'; F : Stable(B) |]==> F:(A Int B) LeadsTo (A' Int B)"; |
308 \ ==> F : (A Int B) LeadsTo (A' Int B)"; |
268 by (asm_full_simp_tac (simpset() addsimps [LeadsTo_def, Stable_eq_stable]) 1); |
309 by (forward_tac [StableD2] 1); |
|
310 by (rotate_tac ~1 1); |
|
311 by (asm_full_simp_tac |
|
312 (simpset() addsimps [LeadsTo_eq_leadsTo, Stable_eq_stable]) 1); |
|
313 by (Clarify_tac 1); |
269 by (Clarify_tac 1); |
314 by (dtac psp_stable 1); |
270 by (dtac psp_stable 1); |
315 by (assume_tac 1); |
271 by (REPEAT(asm_full_simp_tac (simpset() addsimps (Int_absorb::Int_ac)) 1)); |
316 by (asm_full_simp_tac (simpset() addsimps (Int_absorb::Int_ac)) 1); |
|
317 qed "PSP_Stable"; |
272 qed "PSP_Stable"; |
318 |
273 |
319 Goal "[| F : A LeadsTo A'; F : Stable(B) |] \ |
274 Goal "[| F : A LeadsTo A'; F : Stable(B) |] ==> F : (B Int A) LeadsTo (B Int A')"; |
320 \ ==> F : (B Int A) LeadsTo (B Int A')"; |
|
321 by (asm_simp_tac (simpset() addsimps PSP_Stable::Int_ac) 1); |
275 by (asm_simp_tac (simpset() addsimps PSP_Stable::Int_ac) 1); |
322 qed "PSP_Stable2"; |
276 qed "PSP_Stable2"; |
323 |
277 |
324 Goal "[| F : A LeadsTo A'; F : B Co B' |] \ |
278 Goal "[| F:A LeadsTo A'; F:B Co B'|]==> F : (A Int B') LeadsTo ((A' Int B) Un (B' - B))"; |
325 \ ==> F : (A Int B') LeadsTo ((A' Int B) Un (B' - B))"; |
279 by (full_simp_tac (simpset() addsimps [LeadsTo_def, Constrains_eq_constrains]) 1); |
326 by (full_simp_tac |
|
327 (simpset() addsimps [LeadsTo_def, Constrains_eq_constrains]) 1); |
|
328 by (blast_tac (claset() addDs [psp] addIs [leadsTo_weaken]) 1); |
280 by (blast_tac (claset() addDs [psp] addIs [leadsTo_weaken]) 1); |
329 qed "PSP"; |
281 qed "PSP"; |
330 |
282 |
331 Goal "[| F : A LeadsTo A'; F : B Co B' |] \ |
283 Goal "[| F : A LeadsTo A'; F : B Co B' |]==> F:(B' Int A) LeadsTo ((B Int A') Un (B' - B))"; |
332 \ ==> F : (B' Int A) LeadsTo ((B Int A') Un (B' - B))"; |
|
333 by (asm_simp_tac (simpset() addsimps PSP::Int_ac) 1); |
284 by (asm_simp_tac (simpset() addsimps PSP::Int_ac) 1); |
334 qed "PSP2"; |
285 qed "PSP2"; |
335 |
286 |
336 |
|
337 Goal |
287 Goal |
338 "[| F : A LeadsTo A'; F : B Unless B' |] \ |
288 "[| F : A LeadsTo A'; F : B Unless B'|]==> F:(A Int B) LeadsTo ((A' Int B) Un B')"; |
339 \ ==> F : (A Int B) LeadsTo ((A' Int B) Un B')"; |
|
340 by (forward_tac [LeadsToD] 1); |
|
341 by (forward_tac [UnlessD] 1); |
|
342 by (rewrite_goals_tac [Unless_def]); |
289 by (rewrite_goals_tac [Unless_def]); |
343 by (dtac PSP 1); |
290 by (dtac PSP 1); |
344 by (assume_tac 1); |
291 by (assume_tac 1); |
345 by (blast_tac (claset() |
292 by (blast_tac (claset() addIs [LeadsTo_Diff, LeadsTo_weaken, subset_imp_LeadsTo]) 1); |
346 addIs [LeadsTo_Diff, |
|
347 LeadsTo_weaken, subset_imp_LeadsTo]) 1); |
|
348 qed "PSP_Unless"; |
293 qed "PSP_Unless"; |
349 |
294 |
350 (*** Induction rules ***) |
295 (*** Induction rules ***) |
351 |
296 |
352 (** Meta or object quantifier ????? **) |
297 (** Meta or object quantifier ????? **) |
353 Goal "[| wf(r); \ |
298 Goal "[| wf(r); \ |
354 \ ALL m:I. F : (A Int f-``{m}) LeadsTo \ |
299 \ ALL m:I. F : (A Int f-``{m}) LeadsTo \ |
355 \ ((A Int f-``(converse(r) `` {m})) Un B); \ |
300 \ ((A Int f-``(converse(r) `` {m})) Un B); \ |
356 \ field(r)<=I; A<=f-``I; F:program; A:condition; B:condition |] \ |
301 \ field(r)<=I; A<=f-``I; F:program |] \ |
357 \ ==> F : A LeadsTo B"; |
302 \ ==> F : A LeadsTo B"; |
358 by (full_simp_tac (simpset() addsimps [LeadsTo_eq_leadsTo]) 1); |
303 by (full_simp_tac (simpset() addsimps [LeadsTo_def]) 1); |
359 by Safe_tac; |
304 by Safe_tac; |
360 by (eres_inst_tac [("I", "I"), ("f", "f")] leadsTo_wf_induct 1); |
305 by (eres_inst_tac [("I", "I"), ("f", "f")] leadsTo_wf_induct 1); |
361 by (ALLGOALS(Clarify_tac)); |
306 by (ALLGOALS(Clarify_tac)); |
362 by (dres_inst_tac [("x", "m")] bspec 4); |
307 by (dres_inst_tac [("x", "m")] bspec 2); |
363 by Safe_tac; |
308 by Safe_tac; |
364 by (res_inst_tac [("A'", |
309 by (res_inst_tac |
365 "reachable(F) Int (A Int f -``(converse(r)``{m}) Un B)")] |
310 [("A'", "reachable(F) Int (A Int f -``(converse(r)``{m}) Un B)")]leadsTo_weaken_R 2); |
366 leadsTo_weaken_R 4); |
311 by (asm_simp_tac (simpset() addsimps [Int_assoc]) 2); |
367 by (asm_simp_tac (simpset() addsimps [Int_assoc]) 4); |
312 by (asm_simp_tac (simpset() addsimps [Int_assoc]) 3); |
368 by (asm_simp_tac (simpset() addsimps [Int_assoc]) 5); |
|
369 by (REPEAT(Blast_tac 1)); |
313 by (REPEAT(Blast_tac 1)); |
370 qed "LeadsTo_wf_induct"; |
314 qed "LeadsTo_wf_induct"; |
371 |
315 |
372 |
316 |
373 |
317 |
374 Goal "[| ALL m:nat. F:(A Int f-``{m}) LeadsTo ((A Int f-``lessThan(m,nat)) Un B); \ |
318 Goal "[| ALL m:nat. F:(A Int f-``{m}) LeadsTo ((A Int f-``lessThan(m,nat)) Un B); \ |
375 \ A<=f-``nat; F:program; A:condition; B:condition |] \ |
319 \ A<=f-``nat; F:program |] ==> F : A LeadsTo B"; |
376 \ ==> F : A LeadsTo B"; |
|
377 by (res_inst_tac [("A1", "nat"), ("I", "nat")] (wf_less_than RS LeadsTo_wf_induct) 1); |
320 by (res_inst_tac [("A1", "nat"), ("I", "nat")] (wf_less_than RS LeadsTo_wf_induct) 1); |
378 by (ALLGOALS(asm_full_simp_tac |
321 by (ALLGOALS(asm_full_simp_tac |
379 (simpset() addsimps [nat_less_than_field]))); |
322 (simpset() addsimps [nat_less_than_field]))); |
380 by (Clarify_tac 1); |
323 by (Clarify_tac 1); |
381 by (ALLGOALS(asm_full_simp_tac |
324 by (ALLGOALS(asm_full_simp_tac |