4 imports Abs_Int_init |
4 imports Abs_Int_init |
5 begin |
5 begin |
6 |
6 |
7 subsection "Orderings" |
7 subsection "Orderings" |
8 |
8 |
9 class preord = |
9 notation |
10 fixes le :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infix "\<sqsubseteq>" 50) |
10 Orderings.bot ("\<bottom>") and |
11 assumes le_refl[simp]: "x \<sqsubseteq> x" |
11 Orderings.top ("\<top>") |
12 and le_trans: "x \<sqsubseteq> y \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> x \<sqsubseteq> z" |
12 |
13 begin |
13 declare order_trans[trans] |
14 |
14 |
15 definition mono where "mono f = (\<forall>x y. x \<sqsubseteq> y \<longrightarrow> f x \<sqsubseteq> f y)" |
15 class join = order + |
16 |
|
17 declare le_trans[trans] |
|
18 |
|
19 end |
|
20 |
|
21 text{* Note: no antisymmetry. Allows implementations where some abstract |
|
22 element is implemented by two different values @{prop "x \<noteq> y"} |
|
23 such that @{prop"x \<sqsubseteq> y"} and @{prop"y \<sqsubseteq> x"}. Antisymmetry is not |
|
24 needed because we never compare elements for equality but only for @{text"\<sqsubseteq>"}. |
|
25 *} |
|
26 |
|
27 class join = preord + |
|
28 fixes join :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<squnion>" 65) |
16 fixes join :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<squnion>" 65) |
29 |
17 |
30 class semilattice = join + |
18 class semilattice = join + top + |
31 fixes Top :: "'a" ("\<top>") |
19 assumes join_ge1 [simp]: "x \<le> x \<squnion> y" |
32 assumes join_ge1 [simp]: "x \<sqsubseteq> x \<squnion> y" |
20 and join_ge2 [simp]: "y \<le> x \<squnion> y" |
33 and join_ge2 [simp]: "y \<sqsubseteq> x \<squnion> y" |
21 and join_least: "x \<le> z \<Longrightarrow> y \<le> z \<Longrightarrow> x \<squnion> y \<le> z" |
34 and join_least: "x \<sqsubseteq> z \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> x \<squnion> y \<sqsubseteq> z" |
22 begin |
35 and top[simp]: "x \<sqsubseteq> \<top>" |
23 |
36 begin |
24 lemma join_le_iff[simp]: "x \<squnion> y \<le> z \<longleftrightarrow> x \<le> z \<and> y \<le> z" |
37 |
25 by (metis join_ge1 join_ge2 join_least order_trans) |
38 lemma join_le_iff[simp]: "x \<squnion> y \<sqsubseteq> z \<longleftrightarrow> x \<sqsubseteq> z \<and> y \<sqsubseteq> z" |
26 |
39 by (metis join_ge1 join_ge2 join_least le_trans) |
27 lemma le_join_disj: "x \<le> y \<or> x \<le> z \<Longrightarrow> x \<le> y \<squnion> z" |
40 |
28 by (metis join_ge1 join_ge2 order_trans) |
41 lemma le_join_disj: "x \<sqsubseteq> y \<or> x \<sqsubseteq> z \<Longrightarrow> x \<sqsubseteq> y \<squnion> z" |
29 |
42 by (metis join_ge1 join_ge2 le_trans) |
30 end |
43 |
31 |
44 end |
32 |
45 |
33 instantiation "fun" :: (type, semilattice) semilattice |
46 instantiation "fun" :: (type, preord) preord |
34 begin |
47 begin |
35 |
48 |
36 definition "f \<squnion> g = (\<lambda>x. f x \<squnion> g x)" |
49 definition "f \<sqsubseteq> g = (\<forall>x. f x \<sqsubseteq> g x)" |
37 |
|
38 lemma join_apply[simp]: "(f \<squnion> g) x = f x \<squnion> g x" |
|
39 by (simp add: join_fun_def) |
50 |
40 |
51 instance |
41 instance |
52 proof |
42 proof |
53 case goal2 thus ?case by (metis le_fun_def preord_class.le_trans) |
|
54 qed (simp_all add: le_fun_def) |
43 qed (simp_all add: le_fun_def) |
55 |
44 |
56 end |
45 end |
57 |
46 |
58 |
47 |
59 instantiation "fun" :: (type, semilattice) semilattice |
48 instantiation option :: (order)order |
60 begin |
49 begin |
61 |
50 |
62 definition "f \<squnion> g = (\<lambda>x. f x \<squnion> g x)" |
51 fun less_eq_option where |
63 definition "\<top> = (\<lambda>x. \<top>)" |
52 "Some x \<le> Some y = (x \<le> y)" | |
64 |
53 "None \<le> y = True" | |
65 lemma join_apply[simp]: "(f \<squnion> g) x = f x \<squnion> g x" |
54 "Some _ \<le> None = False" |
66 by (simp add: join_fun_def) |
55 |
67 |
56 definition less_option where "x < (y::'a option) = (x \<le> y \<and> \<not> y \<le> x)" |
68 instance |
57 |
69 proof |
58 lemma [simp]: "(x \<le> None) = (x = None)" |
70 qed (simp_all add: le_fun_def Top_fun_def) |
|
71 |
|
72 end |
|
73 |
|
74 |
|
75 instantiation acom :: (preord) preord |
|
76 begin |
|
77 |
|
78 fun le_acom :: "('a::preord)acom \<Rightarrow> 'a acom \<Rightarrow> bool" where |
|
79 "le_acom (SKIP {S}) (SKIP {S'}) = (S \<sqsubseteq> S')" | |
|
80 "le_acom (x ::= e {S}) (x' ::= e' {S'}) = (x=x' \<and> e=e' \<and> S \<sqsubseteq> S')" | |
|
81 "le_acom (C1;C2) (D1;D2) = (C1 \<sqsubseteq> D1 \<and> C2 \<sqsubseteq> D2)" | |
|
82 "le_acom (IF b THEN {p1} C1 ELSE {p2} C2 {S}) (IF b' THEN {q1} D1 ELSE {q2} D2 {S'}) = |
|
83 (b=b' \<and> p1 \<sqsubseteq> q1 \<and> C1 \<sqsubseteq> D1 \<and> p2 \<sqsubseteq> q2 \<and> C2 \<sqsubseteq> D2 \<and> S \<sqsubseteq> S')" | |
|
84 "le_acom ({I} WHILE b DO {p} C {P}) ({I'} WHILE b' DO {p'} C' {P'}) = |
|
85 (b=b' \<and> p \<sqsubseteq> p' \<and> C \<sqsubseteq> C' \<and> I \<sqsubseteq> I' \<and> P \<sqsubseteq> P')" | |
|
86 "le_acom _ _ = False" |
|
87 |
|
88 lemma [simp]: "SKIP {S} \<sqsubseteq> C \<longleftrightarrow> (\<exists>S'. C = SKIP {S'} \<and> S \<sqsubseteq> S')" |
|
89 by (cases C) auto |
|
90 |
|
91 lemma [simp]: "x ::= e {S} \<sqsubseteq> C \<longleftrightarrow> (\<exists>S'. C = x ::= e {S'} \<and> S \<sqsubseteq> S')" |
|
92 by (cases C) auto |
|
93 |
|
94 lemma [simp]: "C1;C2 \<sqsubseteq> C \<longleftrightarrow> (\<exists>D1 D2. C = D1;D2 \<and> C1 \<sqsubseteq> D1 \<and> C2 \<sqsubseteq> D2)" |
|
95 by (cases C) auto |
|
96 |
|
97 lemma [simp]: "IF b THEN {p1} C1 ELSE {p2} C2 {S} \<sqsubseteq> C \<longleftrightarrow> |
|
98 (\<exists>q1 q2 D1 D2 S'. C = IF b THEN {q1} D1 ELSE {q2} D2 {S'} \<and> |
|
99 p1 \<sqsubseteq> q1 \<and> C1 \<sqsubseteq> D1 \<and> p2 \<sqsubseteq> q2 \<and> C2 \<sqsubseteq> D2 \<and> S \<sqsubseteq> S')" |
|
100 by (cases C) auto |
|
101 |
|
102 lemma [simp]: "{I} WHILE b DO {p} C {P} \<sqsubseteq> W \<longleftrightarrow> |
|
103 (\<exists>I' p' C' P'. W = {I'} WHILE b DO {p'} C' {P'} \<and> p \<sqsubseteq> p' \<and> C \<sqsubseteq> C' \<and> I \<sqsubseteq> I' \<and> P \<sqsubseteq> P')" |
|
104 by (cases W) auto |
|
105 |
|
106 instance |
|
107 proof |
|
108 case goal1 thus ?case by (induct x) auto |
|
109 next |
|
110 case goal2 thus ?case |
|
111 apply(induct x y arbitrary: z rule: le_acom.induct) |
|
112 apply (auto intro: le_trans) |
|
113 done |
|
114 qed |
|
115 |
|
116 end |
|
117 |
|
118 |
|
119 instantiation option :: (preord)preord |
|
120 begin |
|
121 |
|
122 fun le_option where |
|
123 "Some x \<sqsubseteq> Some y = (x \<sqsubseteq> y)" | |
|
124 "None \<sqsubseteq> y = True" | |
|
125 "Some _ \<sqsubseteq> None = False" |
|
126 |
|
127 lemma [simp]: "(x \<sqsubseteq> None) = (x = None)" |
|
128 by (cases x) simp_all |
59 by (cases x) simp_all |
129 |
60 |
130 lemma [simp]: "(Some x \<sqsubseteq> u) = (\<exists>y. u = Some y \<and> x \<sqsubseteq> y)" |
61 lemma [simp]: "(Some x \<le> u) = (\<exists>y. u = Some y \<and> x \<le> y)" |
131 by (cases u) auto |
62 by (cases u) auto |
132 |
63 |
133 instance proof |
64 instance proof |
134 case goal1 show ?case by(cases x, simp_all) |
65 case goal1 show ?case by(rule less_option_def) |
135 next |
66 next |
136 case goal2 thus ?case |
67 case goal2 show ?case by(cases x, simp_all) |
137 by(cases z, simp, cases y, simp, cases x, auto intro: le_trans) |
68 next |
|
69 case goal3 thus ?case by(cases z, simp, cases y, simp, cases x, auto) |
|
70 next |
|
71 case goal4 thus ?case by(cases y, simp, cases x, auto) |
138 qed |
72 qed |
139 |
73 |
140 end |
74 end |
141 |
75 |
142 instantiation option :: (join)join |
76 instantiation option :: (join)join |
155 end |
89 end |
156 |
90 |
157 instantiation option :: (semilattice)semilattice |
91 instantiation option :: (semilattice)semilattice |
158 begin |
92 begin |
159 |
93 |
160 definition "\<top> = Some \<top>" |
94 definition top_option where "\<top> = Some \<top>" |
161 |
95 |
162 instance proof |
96 instance proof |
163 case goal1 thus ?case by(cases x, simp, cases y, simp_all) |
97 case goal1 show ?case by(cases a, simp_all add: top_option_def) |
164 next |
98 next |
165 case goal2 thus ?case by(cases y, simp, cases x, simp_all) |
99 case goal2 thus ?case by(cases x, simp, cases y, simp_all) |
166 next |
100 next |
167 case goal3 thus ?case by(cases z, simp, cases y, simp, cases x, simp_all) |
101 case goal3 thus ?case by(cases y, simp, cases x, simp_all) |
168 next |
102 next |
169 case goal4 thus ?case by(cases x, simp_all add: Top_option_def) |
103 case goal4 thus ?case by(cases z, simp, cases y, simp, cases x, simp_all) |
170 qed |
104 qed |
171 |
105 |
172 end |
106 end |
173 |
107 |
174 class bot = preord + |
108 instantiation option :: (order)bot |
175 fixes bot :: "'a" ("\<bottom>") |
|
176 assumes bot[simp]: "\<bottom> \<sqsubseteq> x" |
|
177 |
|
178 instantiation option :: (preord)bot |
|
179 begin |
109 begin |
180 |
110 |
181 definition bot_option :: "'a option" where |
111 definition bot_option :: "'a option" where |
182 "\<bottom> = None" |
112 "\<bottom> = None" |
183 |
113 |
190 |
120 |
191 |
121 |
192 definition bot :: "com \<Rightarrow> 'a option acom" where |
122 definition bot :: "com \<Rightarrow> 'a option acom" where |
193 "bot c = anno None c" |
123 "bot c = anno None c" |
194 |
124 |
195 lemma bot_least: "strip C = c \<Longrightarrow> bot c \<sqsubseteq> C" |
125 lemma bot_least: "strip C = c \<Longrightarrow> bot c \<le> C" |
196 by(induct C arbitrary: c)(auto simp: bot_def) |
126 by(induct C arbitrary: c)(auto simp: bot_def) |
197 |
127 |
198 lemma strip_bot[simp]: "strip(bot c) = c" |
128 lemma strip_bot[simp]: "strip(bot c) = c" |
199 by(simp add: bot_def) |
129 by(simp add: bot_def) |
200 |
130 |
201 |
131 |
202 subsubsection "Post-fixed point iteration" |
132 subsubsection "Post-fixed point iteration" |
203 |
133 |
204 definition pfp :: "(('a::preord) \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a option" where |
134 definition pfp :: "(('a::order) \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a option" where |
205 "pfp f = while_option (\<lambda>x. \<not> f x \<sqsubseteq> x) f" |
135 "pfp f = while_option (\<lambda>x. \<not> f x \<le> x) f" |
206 |
136 |
207 lemma pfp_pfp: assumes "pfp f x0 = Some x" shows "f x \<sqsubseteq> x" |
137 lemma pfp_pfp: assumes "pfp f x0 = Some x" shows "f x \<le> x" |
208 using while_option_stop[OF assms[simplified pfp_def]] by simp |
138 using while_option_stop[OF assms[simplified pfp_def]] by simp |
209 |
139 |
210 lemma while_least: |
140 lemma while_least: |
211 assumes "\<forall>x\<in>L.\<forall>y\<in>L. x \<sqsubseteq> y \<longrightarrow> f x \<sqsubseteq> f y" and "\<forall>x. x \<in> L \<longrightarrow> f x \<in> L" |
141 fixes q :: "'a::order" |
212 and "\<forall>x \<in> L. b \<sqsubseteq> x" and "b \<in> L" and "f q \<sqsubseteq> q" and "q \<in> L" |
142 assumes "\<forall>x\<in>L.\<forall>y\<in>L. x \<le> y \<longrightarrow> f x \<le> f y" and "\<forall>x. x \<in> L \<longrightarrow> f x \<in> L" |
|
143 and "\<forall>x \<in> L. b \<le> x" and "b \<in> L" and "f q \<le> q" and "q \<in> L" |
213 and "while_option P f b = Some p" |
144 and "while_option P f b = Some p" |
214 shows "p \<sqsubseteq> q" |
145 shows "p \<le> q" |
215 using while_option_rule[OF _ assms(7)[unfolded pfp_def], |
146 using while_option_rule[OF _ assms(7)[unfolded pfp_def], |
216 where P = "%x. x \<in> L \<and> x \<sqsubseteq> q"] |
147 where P = "%x. x \<in> L \<and> x \<le> q"] |
217 by (metis assms(1-6) le_trans) |
148 by (metis assms(1-6) order_trans) |
218 |
149 |
219 lemma pfp_inv: |
150 lemma pfp_inv: |
220 "pfp f x = Some y \<Longrightarrow> (\<And>x. P x \<Longrightarrow> P(f x)) \<Longrightarrow> P x \<Longrightarrow> P y" |
151 "pfp f x = Some y \<Longrightarrow> (\<And>x. P x \<Longrightarrow> P(f x)) \<Longrightarrow> P x \<Longrightarrow> P y" |
221 unfolding pfp_def by (metis (lifting) while_option_rule) |
152 unfolding pfp_def by (metis (lifting) while_option_rule) |
222 |
153 |
282 where "\<gamma>\<^isub>o == \<gamma>_option \<gamma>\<^isub>s" |
213 where "\<gamma>\<^isub>o == \<gamma>_option \<gamma>\<^isub>s" |
283 |
214 |
284 abbreviation \<gamma>\<^isub>c :: "'av st option acom \<Rightarrow> state set acom" |
215 abbreviation \<gamma>\<^isub>c :: "'av st option acom \<Rightarrow> state set acom" |
285 where "\<gamma>\<^isub>c == map_acom \<gamma>\<^isub>o" |
216 where "\<gamma>\<^isub>c == map_acom \<gamma>\<^isub>o" |
286 |
217 |
287 lemma gamma_s_Top[simp]: "\<gamma>\<^isub>s Top = UNIV" |
218 lemma gamma_s_Top[simp]: "\<gamma>\<^isub>s \<top> = UNIV" |
288 by(simp add: Top_fun_def \<gamma>_fun_def) |
219 by(simp add: top_fun_def \<gamma>_fun_def) |
289 |
220 |
290 lemma gamma_o_Top[simp]: "\<gamma>\<^isub>o Top = UNIV" |
221 lemma gamma_o_Top[simp]: "\<gamma>\<^isub>o \<top> = UNIV" |
291 by (simp add: Top_option_def) |
222 by (simp add: top_option_def) |
292 |
223 |
293 lemma mono_gamma_s: "f1 \<sqsubseteq> f2 \<Longrightarrow> \<gamma>\<^isub>s f1 \<subseteq> \<gamma>\<^isub>s f2" |
224 lemma mono_gamma_s: "f1 \<le> f2 \<Longrightarrow> \<gamma>\<^isub>s f1 \<subseteq> \<gamma>\<^isub>s f2" |
294 by(auto simp: le_fun_def \<gamma>_fun_def dest: mono_gamma) |
225 by(auto simp: le_fun_def \<gamma>_fun_def dest: mono_gamma) |
295 |
226 |
296 lemma mono_gamma_o: |
227 lemma mono_gamma_o: |
297 "S1 \<sqsubseteq> S2 \<Longrightarrow> \<gamma>\<^isub>o S1 \<subseteq> \<gamma>\<^isub>o S2" |
228 "S1 \<le> S2 \<Longrightarrow> \<gamma>\<^isub>o S1 \<subseteq> \<gamma>\<^isub>o S2" |
298 by(induction S1 S2 rule: le_option.induct)(simp_all add: mono_gamma_s) |
229 by(induction S1 S2 rule: less_eq_option.induct)(simp_all add: mono_gamma_s) |
299 |
230 |
300 lemma mono_gamma_c: "C1 \<sqsubseteq> C2 \<Longrightarrow> \<gamma>\<^isub>c C1 \<le> \<gamma>\<^isub>c C2" |
231 lemma mono_gamma_c: "C1 \<le> C2 \<Longrightarrow> \<gamma>\<^isub>c C1 \<le> \<gamma>\<^isub>c C2" |
301 by (induction C1 C2 rule: le_acom.induct) (simp_all add:mono_gamma_o) |
232 by (induction C1 C2 rule: less_eq_acom.induct) (simp_all add:mono_gamma_o) |
302 |
233 |
303 text{* Soundness: *} |
234 text{* Soundness: *} |
304 |
235 |
305 lemma aval'_sound: "s : \<gamma>\<^isub>s S \<Longrightarrow> aval a s : \<gamma>(aval' a S)" |
236 lemma aval'_sound: "s : \<gamma>\<^isub>s S \<Longrightarrow> aval a s : \<gamma>(aval' a S)" |
306 by (induct a) (auto simp: gamma_num' gamma_plus' \<gamma>_fun_def) |
237 by (induct a) (auto simp: gamma_num' gamma_plus' \<gamma>_fun_def) |
341 end |
272 end |
342 |
273 |
343 |
274 |
344 subsubsection "Monotonicity" |
275 subsubsection "Monotonicity" |
345 |
276 |
346 lemma mono_post: "C1 \<sqsubseteq> C2 \<Longrightarrow> post C1 \<sqsubseteq> post C2" |
277 lemma mono_post: "C1 \<le> C2 \<Longrightarrow> post C1 \<le> post C2" |
347 by(induction C1 C2 rule: le_acom.induct) (auto) |
278 by(induction C1 C2 rule: less_eq_acom.induct) (auto) |
348 |
279 |
349 locale Abs_Int_Fun_mono = Abs_Int_Fun + |
280 locale Abs_Int_Fun_mono = Abs_Int_Fun + |
350 assumes mono_plus': "a1 \<sqsubseteq> b1 \<Longrightarrow> a2 \<sqsubseteq> b2 \<Longrightarrow> plus' a1 a2 \<sqsubseteq> plus' b1 b2" |
281 assumes mono_plus': "a1 \<le> b1 \<Longrightarrow> a2 \<le> b2 \<Longrightarrow> plus' a1 a2 \<le> plus' b1 b2" |
351 begin |
282 begin |
352 |
283 |
353 lemma mono_aval': "S \<sqsubseteq> S' \<Longrightarrow> aval' e S \<sqsubseteq> aval' e S'" |
284 lemma mono_aval': "S \<le> S' \<Longrightarrow> aval' e S \<le> aval' e S'" |
354 by(induction e)(auto simp: le_fun_def mono_plus') |
285 by(induction e)(auto simp: le_fun_def mono_plus') |
355 |
286 |
356 lemma mono_update: "a \<sqsubseteq> a' \<Longrightarrow> S \<sqsubseteq> S' \<Longrightarrow> S(x := a) \<sqsubseteq> S'(x := a')" |
287 lemma mono_update: "a \<le> a' \<Longrightarrow> S \<le> S' \<Longrightarrow> S(x := a) \<le> S'(x := a')" |
357 by(simp add: le_fun_def) |
288 by(simp add: le_fun_def) |
358 |
289 |
359 lemma mono_step': "S1 \<sqsubseteq> S2 \<Longrightarrow> C1 \<sqsubseteq> C2 \<Longrightarrow> step' S1 C1 \<sqsubseteq> step' S2 C2" |
290 lemma mono_step': "S1 \<le> S2 \<Longrightarrow> C1 \<le> C2 \<Longrightarrow> step' S1 C1 \<le> step' S2 C2" |
360 apply(induction C1 C2 arbitrary: S1 S2 rule: le_acom.induct) |
291 apply(induction C1 C2 arbitrary: S1 S2 rule: less_eq_acom.induct) |
361 apply (auto simp: Let_def mono_update mono_aval' mono_post le_join_disj |
292 apply (auto simp: Let_def mono_update mono_aval' mono_post le_join_disj |
362 split: option.split) |
293 split: option.split) |
363 done |
294 done |
364 |
295 |
365 end |
296 end |