1 (* Author: Tobias Nipkow *) |
1 (* Author: Tobias Nipkow *) |
2 |
2 |
3 theory Abs_Int1 |
3 theory Abs_Int1 |
4 imports Abs_State |
4 imports Abs_State |
5 begin |
5 begin |
|
6 |
|
7 (* FIXME mv *) |
|
8 instantiation acom :: (type) vars |
|
9 begin |
|
10 |
|
11 definition "vars_acom = vars o strip" |
|
12 |
|
13 instance .. |
|
14 |
|
15 end |
|
16 |
|
17 lemma finite_Cvars: "finite(vars(C::'a acom))" |
|
18 by(simp add: vars_acom_def) |
|
19 |
6 |
20 |
7 lemma le_iff_le_annos_zip: "C1 \<le> C2 \<longleftrightarrow> |
21 lemma le_iff_le_annos_zip: "C1 \<le> C2 \<longleftrightarrow> |
8 (\<forall> (a1,a2) \<in> set(zip (annos C1) (annos C2)). a1 \<le> a2) \<and> strip C1 = strip C2" |
22 (\<forall> (a1,a2) \<in> set(zip (annos C1) (annos C2)). a1 \<le> a2) \<and> strip C1 = strip C2" |
9 by(induct C1 C2 rule: less_eq_acom.induct) (auto simp: size_annos_same2) |
23 by(induct C1 C2 rule: less_eq_acom.induct) (auto simp: size_annos_same2) |
10 |
24 |
11 lemma le_iff_le_annos: "C1 \<le> C2 \<longleftrightarrow> |
25 lemma le_iff_le_annos: "C1 \<le> C2 \<longleftrightarrow> |
12 strip C1 = strip C2 \<and> (\<forall> i<size(annos C1). annos C1 ! i \<le> annos C2 ! i)" |
26 strip C1 = strip C2 \<and> (\<forall> i<size(annos C1). annos C1 ! i \<le> annos C2 ! i)" |
13 by(auto simp add: le_iff_le_annos_zip set_zip) (metis size_annos_same2) |
27 by(auto simp add: le_iff_le_annos_zip set_zip) (metis size_annos_same2) |
14 |
28 |
15 |
29 (* FIXME mv *) |
16 lemma mono_fun_L[simp]: "F \<in> L X \<Longrightarrow> F \<le> G \<Longrightarrow> x : X \<Longrightarrow> fun F x \<le> fun G x" |
30 lemma post_in_annos: "post C \<in> set(annos C)" |
17 by(simp add: mono_fun L_st_def) |
|
18 |
|
19 lemma bot_in_L[simp]: "bot c \<in> L(vars c)" |
|
20 by(simp add: L_acom_def bot_def) |
|
21 |
|
22 lemma L_acom_simps[simp]: "SKIP {P} \<in> L X \<longleftrightarrow> P \<in> L X" |
|
23 "(x ::= e {P}) \<in> L X \<longleftrightarrow> x : X \<and> vars e \<subseteq> X \<and> P \<in> L X" |
|
24 "(C1;C2) \<in> L X \<longleftrightarrow> C1 \<in> L X \<and> C2 \<in> L X" |
|
25 "(IF b THEN {P1} C1 ELSE {P2} C2 {Q}) \<in> L X \<longleftrightarrow> |
|
26 vars b \<subseteq> X \<and> C1 \<in> L X \<and> C2 \<in> L X \<and> P1 \<in> L X \<and> P2 \<in> L X \<and> Q \<in> L X" |
|
27 "({I} WHILE b DO {P} C {Q}) \<in> L X \<longleftrightarrow> |
|
28 I \<in> L X \<and> vars b \<subseteq> X \<and> P \<in> L X \<and> C \<in> L X \<and> Q \<in> L X" |
|
29 by(auto simp add: L_acom_def) |
|
30 |
|
31 lemma post_in_annos: "post C : set(annos C)" |
|
32 by(induction C) auto |
31 by(induction C) auto |
33 |
|
34 lemma post_in_L[simp]: "C \<in> L X \<Longrightarrow> post C \<in> L X" |
|
35 by(simp add: L_acom_def post_in_annos) |
|
36 |
32 |
37 |
33 |
38 subsection "Computable Abstract Interpretation" |
34 subsection "Computable Abstract Interpretation" |
39 |
35 |
40 text{* Abstract interpretation over type @{text st} instead of functions. *} |
36 text{* Abstract interpretation over type @{text st} instead of functions. *} |
45 fun aval' :: "aexp \<Rightarrow> 'av st \<Rightarrow> 'av" where |
41 fun aval' :: "aexp \<Rightarrow> 'av st \<Rightarrow> 'av" where |
46 "aval' (N i) S = num' i" | |
42 "aval' (N i) S = num' i" | |
47 "aval' (V x) S = fun S x" | |
43 "aval' (V x) S = fun S x" | |
48 "aval' (Plus a1 a2) S = plus' (aval' a1 S) (aval' a2 S)" |
44 "aval' (Plus a1 a2) S = plus' (aval' a1 S) (aval' a2 S)" |
49 |
45 |
50 lemma aval'_sound: "s : \<gamma>\<^isub>s S \<Longrightarrow> vars a \<subseteq> dom S \<Longrightarrow> aval a s : \<gamma>(aval' a S)" |
46 lemma aval'_sound: "s : \<gamma>\<^isub>s S \<Longrightarrow> aval a s : \<gamma>(aval' a S)" |
51 by (induction a) (auto simp: gamma_num' gamma_plus' \<gamma>_st_def) |
47 by (induction a) (auto simp: gamma_num' gamma_plus' \<gamma>_st_def) |
52 |
48 |
53 lemma gamma_Step_subcomm: fixes C1 C2 :: "'a::semilattice_sup acom" |
49 lemma gamma_Step_subcomm: fixes C1 C2 :: "'a::semilattice_sup acom" |
54 assumes "!!x e S. x : X \<Longrightarrow> vars e \<subseteq> X \<Longrightarrow> S \<in> L X \<Longrightarrow> f1 x e (\<gamma>\<^isub>o S) \<subseteq> \<gamma>\<^isub>o (f2 x e S)" |
50 assumes "!!x e S. f1 x e (\<gamma>\<^isub>o S) \<subseteq> \<gamma>\<^isub>o (f2 x e S)" |
55 "!!b S. S \<in> L X \<Longrightarrow> vars b \<subseteq> X \<Longrightarrow> g1 b (\<gamma>\<^isub>o S) \<subseteq> \<gamma>\<^isub>o (g2 b S)" |
51 "!!b S. g1 b (\<gamma>\<^isub>o S) \<subseteq> \<gamma>\<^isub>o (g2 b S)" |
56 shows "C \<in> L X \<Longrightarrow> S \<in> L X \<Longrightarrow> Step f1 g1 (\<gamma>\<^isub>o S) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c (Step f2 g2 S C)" |
52 shows "Step f1 g1 (\<gamma>\<^isub>o S) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c (Step f2 g2 S C)" |
57 proof(induction C arbitrary: S) |
53 proof(induction C arbitrary: S) |
58 qed (auto simp: assms intro!: mono_gamma_o post_in_L sup_ge1 sup_ge2) |
54 qed (auto simp: assms intro!: mono_gamma_o sup_ge1 sup_ge2) |
59 |
55 |
60 lemma in_gamma_update: "\<lbrakk> s : \<gamma>\<^isub>s S; i : \<gamma> a \<rbrakk> \<Longrightarrow> s(x := i) : \<gamma>\<^isub>s(update S x a)" |
56 lemma in_gamma_update: "\<lbrakk> s : \<gamma>\<^isub>s S; i : \<gamma> a \<rbrakk> \<Longrightarrow> s(x := i) : \<gamma>\<^isub>s(update S x a)" |
61 by(simp add: \<gamma>_st_def) |
57 by(simp add: \<gamma>_st_def) |
62 |
58 |
63 end |
59 end |
64 |
|
65 |
|
66 lemma Step_in_L: fixes C :: "'a::semilatticeL acom" |
|
67 assumes "!!x e S. \<lbrakk>S \<in> L X; x \<in> X; vars e \<subseteq> X\<rbrakk> \<Longrightarrow> f x e S \<in> L X" |
|
68 "!!b S. S \<in> L X \<Longrightarrow> vars b \<subseteq> X \<Longrightarrow> g b S \<in> L X" |
|
69 shows"\<lbrakk> C \<in> L X; S \<in> L X \<rbrakk> \<Longrightarrow> Step f g S C \<in> L X" |
|
70 proof(induction C arbitrary: S) |
|
71 case Assign thus ?case |
|
72 by(auto simp: L_st_def assms split: option.splits) |
|
73 qed (auto simp: assms) |
|
74 |
60 |
75 |
61 |
76 text{* The for-clause (here and elsewhere) only serves the purpose of fixing |
62 text{* The for-clause (here and elsewhere) only serves the purpose of fixing |
77 the name of the type parameter @{typ 'av} which would otherwise be renamed to |
63 the name of the type parameter @{typ 'av} which would otherwise be renamed to |
78 @{typ 'a}. *} |
64 @{typ 'a}. *} |
83 definition "step' = Step |
69 definition "step' = Step |
84 (\<lambda>x e S. case S of None \<Rightarrow> None | Some S \<Rightarrow> Some(update S x (aval' e S))) |
70 (\<lambda>x e S. case S of None \<Rightarrow> None | Some S \<Rightarrow> Some(update S x (aval' e S))) |
85 (\<lambda>b S. S)" |
71 (\<lambda>b S. S)" |
86 |
72 |
87 definition AI :: "com \<Rightarrow> 'av st option acom option" where |
73 definition AI :: "com \<Rightarrow> 'av st option acom option" where |
88 "AI c = pfp (step' (Top(vars c))) (bot c)" |
74 "AI c = pfp (step' \<top>) (bot c)" |
89 |
75 |
90 |
76 |
91 lemma strip_step'[simp]: "strip(step' S C) = strip C" |
77 lemma strip_step'[simp]: "strip(step' S C) = strip C" |
92 by(simp add: step'_def) |
78 by(simp add: step'_def) |
93 |
79 |
94 |
80 |
95 text{* Soundness: *} |
81 text{* Soundness: *} |
96 |
82 |
97 lemma step_step': "C \<in> L X \<Longrightarrow> S \<in> L X \<Longrightarrow> step (\<gamma>\<^isub>o S) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c (step' S C)" |
83 lemma step_step': "step (\<gamma>\<^isub>o S) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c (step' S C)" |
98 unfolding step_def step'_def |
84 unfolding step_def step'_def |
99 by(rule gamma_Step_subcomm) |
85 by(rule gamma_Step_subcomm) |
100 (auto simp: L_st_def intro!: aval'_sound in_gamma_update split: option.splits) |
86 (auto simp: intro!: aval'_sound in_gamma_update split: option.splits) |
101 |
|
102 lemma step'_in_L[simp]: "\<lbrakk> C \<in> L X; S \<in> L X \<rbrakk> \<Longrightarrow> step' S C \<in> L X" |
|
103 unfolding step'_def |
|
104 by(rule Step_in_L)(auto simp: L_st_def step'_def split: option.splits) |
|
105 |
87 |
106 lemma AI_sound: "AI c = Some C \<Longrightarrow> CS c \<le> \<gamma>\<^isub>c C" |
88 lemma AI_sound: "AI c = Some C \<Longrightarrow> CS c \<le> \<gamma>\<^isub>c C" |
107 proof(simp add: CS_def AI_def) |
89 proof(simp add: CS_def AI_def) |
108 assume 1: "pfp (step' (Top(vars c))) (bot c) = Some C" |
90 assume 1: "pfp (step' \<top>) (bot c) = Some C" |
109 have "C \<in> L(vars c)" |
91 have pfp': "step' \<top> C \<le> C" by(rule pfp_pfp[OF 1]) |
110 by(rule pfp_inv[where P = "%C. C \<in> L(vars c)", OF 1 _ bot_in_L]) |
92 have 2: "step (\<gamma>\<^isub>o \<top>) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c C" --"transfer the pfp'" |
111 (erule step'_in_L[OF _ Top_in_L]) |
|
112 have pfp': "step' (Top(vars c)) C \<le> C" by(rule pfp_pfp[OF 1]) |
|
113 have 2: "step (\<gamma>\<^isub>o(Top(vars c))) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c C" |
|
114 proof(rule order_trans) |
93 proof(rule order_trans) |
115 show "step (\<gamma>\<^isub>o (Top(vars c))) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c (step' (Top(vars c)) C)" |
94 show "step (\<gamma>\<^isub>o \<top>) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c (step' \<top> C)" by(rule step_step') |
116 by(rule step_step'[OF `C \<in> L(vars c)` Top_in_L]) |
95 show "... \<le> \<gamma>\<^isub>c C" by (metis mono_gamma_c[OF pfp']) |
117 show "\<gamma>\<^isub>c (step' (Top(vars c)) C) \<le> \<gamma>\<^isub>c C" |
|
118 by(rule mono_gamma_c[OF pfp']) |
|
119 qed |
96 qed |
120 have 3: "strip (\<gamma>\<^isub>c C) = c" by(simp add: strip_pfp[OF _ 1] step'_def) |
97 have 3: "strip (\<gamma>\<^isub>c C) = c" by(simp add: strip_pfp[OF _ 1] step'_def) |
121 have "lfp c (step (\<gamma>\<^isub>o(Top(vars c)))) \<le> \<gamma>\<^isub>c C" |
98 have "lfp c (step (\<gamma>\<^isub>o \<top>)) \<le> \<gamma>\<^isub>c C" |
122 by(rule lfp_lowerbound[simplified,where f="step (\<gamma>\<^isub>o(Top(vars c)))", OF 3 2]) |
99 by(rule lfp_lowerbound[simplified,where f="step (\<gamma>\<^isub>o \<top>)", OF 3 2]) |
123 thus "lfp c (step UNIV) \<le> \<gamma>\<^isub>c C" by simp |
100 thus "lfp c (step UNIV) \<le> \<gamma>\<^isub>c C" by simp |
124 qed |
101 qed |
125 |
102 |
126 end |
103 end |
127 |
104 |
128 |
105 |
129 subsubsection "Monotonicity" |
106 subsubsection "Monotonicity" |
130 |
107 |
131 lemma le_sup_disj: "y \<in> L X \<Longrightarrow> (z::_::semilatticeL) \<in> L X \<Longrightarrow> |
108 lemma le_sup_disj: "x \<le> y \<or> x \<le> z \<Longrightarrow> x \<le> y \<squnion> (z::_::semilattice_sup)" |
132 x \<le> y \<or> x \<le> z \<Longrightarrow> x \<le> y \<squnion> z" |
|
133 by (metis sup_ge1 sup_ge2 order_trans) |
109 by (metis sup_ge1 sup_ge2 order_trans) |
134 |
110 |
135 theorem mono2_Step: fixes C1 :: "'a::semilatticeL acom" |
111 theorem mono2_Step: fixes C1 :: "'a::semilattice acom" |
136 assumes "!!x e S1 S2. \<lbrakk>S1 \<in> L X; S2 \<in> L X; x \<in> X; vars e \<subseteq> X; S1 \<le> S2\<rbrakk> \<Longrightarrow> f x e S1 \<le> f x e S2" |
112 assumes "!!x e S1 S2. S1 \<le> S2 \<Longrightarrow> f x e S1 \<le> f x e S2" |
137 "!!b S1 S2. S1 \<in> L X \<Longrightarrow> S2 \<in> L X \<Longrightarrow> vars b \<subseteq> X \<Longrightarrow> S1 \<le> S2 \<Longrightarrow> g b S1 \<le> g b S2" |
113 "!!b S1 S2. S1 \<le> S2 \<Longrightarrow> g b S1 \<le> g b S2" |
138 shows "S1 \<in> L X \<Longrightarrow> S2 \<in> L X \<Longrightarrow> C1 \<in> L X \<Longrightarrow> C2 \<in> L X \<Longrightarrow> |
114 shows "S1 \<le> S2 \<Longrightarrow> C1 \<le> C2 \<Longrightarrow> Step f g S1 C1 \<le> Step f g S2 C2" |
139 S1 \<le> S2 \<Longrightarrow> C1 \<le> C2 \<Longrightarrow> Step f g S1 C1 \<le> Step f g S2 C2" |
|
140 by(induction C1 C2 arbitrary: S1 S2 rule: less_eq_acom.induct) |
115 by(induction C1 C2 arbitrary: S1 S2 rule: less_eq_acom.induct) |
141 (auto simp: mono_post assms le_sup_disj le_sup_disj[OF post_in_L post_in_L]) |
116 (auto simp: mono_post assms le_sup_disj) |
142 |
117 |
143 |
118 |
144 locale Abs_Int_mono = Abs_Int + |
119 locale Abs_Int_mono = Abs_Int + |
145 assumes mono_plus': "a1 \<le> b1 \<Longrightarrow> a2 \<le> b2 \<Longrightarrow> plus' a1 a2 \<le> plus' b1 b2" |
120 assumes mono_plus': "a1 \<le> b1 \<Longrightarrow> a2 \<le> b2 \<Longrightarrow> plus' a1 a2 \<le> plus' b1 b2" |
146 begin |
121 begin |
147 |
122 |
148 lemma mono_aval': |
123 lemma mono_aval': "S1 \<le> S2 \<Longrightarrow> aval' e S1 \<le> aval' e S2" |
149 "S1 \<le> S2 \<Longrightarrow> S1 \<in> L X \<Longrightarrow> S2 \<in> L X \<Longrightarrow> vars e \<subseteq> X \<Longrightarrow> aval' e S1 \<le> aval' e S2" |
124 by(induction e) (auto simp: mono_plus' mono_fun) |
150 by(induction e) (auto simp: less_eq_st_def mono_plus' L_st_def) |
125 |
151 |
126 theorem mono_step': "S1 \<le> S2 \<Longrightarrow> C1 \<le> C2 \<Longrightarrow> step' S1 C1 \<le> step' S2 C2" |
152 theorem mono_step': "S1 \<in> L X \<Longrightarrow> S2 \<in> L X \<Longrightarrow> C1 \<in> L X \<Longrightarrow> C2 \<in> L X \<Longrightarrow> |
|
153 S1 \<le> S2 \<Longrightarrow> C1 \<le> C2 \<Longrightarrow> step' S1 C1 \<le> step' S2 C2" |
|
154 unfolding step'_def |
127 unfolding step'_def |
155 by(rule mono2_Step) (auto simp: mono_aval' split: option.split) |
128 by(rule mono2_Step) (auto simp: mono_aval' split: option.split) |
156 |
129 |
157 lemma mono_step'_top: "C \<in> L X \<Longrightarrow> C' \<in> L X \<Longrightarrow> |
130 lemma mono_step'_top: "C \<le> C' \<Longrightarrow> step' \<top> C \<le> step' \<top> C'" |
158 C \<le> C' \<Longrightarrow> step' (Top X) C \<le> step' (Top X) C'" |
131 by (metis mono_step' order_refl) |
159 by (metis Top_in_L mono_step' order_refl) |
132 |
160 |
133 lemma AI_least_pfp: assumes "AI c = Some C" "step' \<top> C' \<le> C'" "strip C' = c" |
161 lemma pfp_bot_least: |
|
162 assumes "\<forall>x\<in>L(vars c)\<inter>{C. strip C = c}.\<forall>y\<in>L(vars c)\<inter>{C. strip C = c}. |
|
163 x \<le> y \<longrightarrow> f x \<le> f y" |
|
164 and "\<forall>C. C \<in> L(vars c)\<inter>{C. strip C = c} \<longrightarrow> f C \<in> L(vars c)\<inter>{C. strip C = c}" |
|
165 and "f C' \<le> C'" "strip C' = c" "C' \<in> L(vars c)" "pfp f (bot c) = Some C" |
|
166 shows "C \<le> C'" |
134 shows "C \<le> C'" |
167 by(rule while_least[OF assms(1,2) _ _ assms(3) _ assms(6)[unfolded pfp_def]]) |
135 by(rule pfp_bot_least[OF _ _ assms(2,3) assms(1)[unfolded AI_def]]) |
168 (simp_all add: assms(4,5) bot_least) |
|
169 |
|
170 lemma AI_least_pfp: assumes "AI c = Some C" |
|
171 and "step' (Top(vars c)) C' \<le> C'" "strip C' = c" "C' \<in> L(vars c)" |
|
172 shows "C \<le> C'" |
|
173 by(rule pfp_bot_least[OF _ _ assms(2-4) assms(1)[unfolded AI_def]]) |
|
174 (simp_all add: mono_step'_top) |
136 (simp_all add: mono_step'_top) |
175 |
137 |
176 end |
138 end |
177 |
139 |
178 |
140 |
194 by (blast intro: I mono) |
156 by (blast intro: I mono) |
195 qed |
157 qed |
196 |
158 |
197 |
159 |
198 locale Measure1 = |
160 locale Measure1 = |
199 fixes m :: "'av::order \<Rightarrow> nat" |
161 fixes m :: "'av::{order,top} \<Rightarrow> nat" |
200 fixes h :: "nat" |
162 fixes h :: "nat" |
201 assumes h: "m x \<le> h" |
163 assumes h: "m x \<le> h" |
202 begin |
164 begin |
203 |
165 |
204 definition m_s :: "'av st \<Rightarrow> nat" ("m\<^isub>s") where |
166 definition m_s :: "vname set \<Rightarrow> 'av st \<Rightarrow> nat" ("m\<^isub>s") where |
205 "m_s S = (\<Sum> x \<in> dom S. m(fun S x))" |
167 "m_s X S = (\<Sum> x \<in> X. m(fun S x))" |
206 |
168 |
207 lemma m_s_h: "x \<in> L X \<Longrightarrow> finite X \<Longrightarrow> m_s x \<le> h * card X" |
169 lemma m_s_h: "finite X \<Longrightarrow> m_s X S \<le> h * card X" |
208 by(simp add: L_st_def m_s_def) |
170 by(simp add: m_s_def) (metis nat_mult_commute of_nat_id setsum_bounded[OF h]) |
209 (metis nat_mult_commute of_nat_id setsum_bounded[OF h]) |
171 |
210 |
172 definition m_o :: "vname set \<Rightarrow> 'av st option \<Rightarrow> nat" ("m\<^isub>o") where |
211 definition m_o :: "nat \<Rightarrow> 'av st option \<Rightarrow> nat" ("m\<^isub>o") where |
173 "m_o X opt = (case opt of None \<Rightarrow> h * card X + 1 | Some S \<Rightarrow> m_s X S)" |
212 "m_o d opt = (case opt of None \<Rightarrow> h*d+1 | Some S \<Rightarrow> m_s S)" |
174 |
213 |
175 lemma m_o_h: "finite X \<Longrightarrow> m_o X opt \<le> (h*card X + 1)" |
214 lemma m_o_h: "ost \<in> L X \<Longrightarrow> finite X \<Longrightarrow> m_o (card X) ost \<le> (h*card X + 1)" |
176 by(auto simp add: m_o_def m_s_h le_SucI split: option.split dest:m_s_h) |
215 by(auto simp add: m_o_def m_s_h split: option.split dest!:m_s_h) |
|
216 |
177 |
217 definition m_c :: "'av st option acom \<Rightarrow> nat" ("m\<^isub>c") where |
178 definition m_c :: "'av st option acom \<Rightarrow> nat" ("m\<^isub>c") where |
218 "m_c C = (\<Sum>i<size(annos C). m_o (card(vars(strip C))) (annos C ! i))" |
179 "m_c C = (\<Sum>i<size(annos C). m_o (vars C) (annos C ! i))" |
219 |
180 |
220 lemma m_c_h: assumes "C \<in> L(vars(strip C))" |
181 text{* Upper complexity bound: *} |
221 shows "m_c C \<le> size(annos C) * (h * card(vars(strip C)) + 1)" |
182 lemma m_c_h: "m_c C \<le> size(annos C) * (h * card(vars C) + 1)" |
222 proof- |
183 proof- |
223 let ?X = "vars(strip C)" let ?n = "card ?X" let ?a = "size(annos C)" |
184 let ?X = "vars C" let ?n = "card ?X" let ?a = "size(annos C)" |
224 { fix i assume "i < ?a" |
185 have "m_c C = (\<Sum>i<?a. m_o ?X (annos C ! i))" by(simp add: m_c_def) |
225 hence "annos C ! i \<in> L ?X" using assms by(simp add: L_acom_def) |
|
226 note m_o_h[OF this finite_cvars] |
|
227 } note 1 = this |
|
228 have "m_c C = (\<Sum>i<?a. m_o ?n (annos C ! i))" by(simp add: m_c_def) |
|
229 also have "\<dots> \<le> (\<Sum>i<?a. h * ?n + 1)" |
186 also have "\<dots> \<le> (\<Sum>i<?a. h * ?n + 1)" |
230 apply(rule setsum_mono) using 1 by simp |
187 apply(rule setsum_mono) using m_o_h[OF finite_Cvars] by simp |
231 also have "\<dots> = ?a * (h * ?n + 1)" by simp |
188 also have "\<dots> = ?a * (h * ?n + 1)" by simp |
232 finally show ?thesis . |
189 finally show ?thesis . |
233 qed |
190 qed |
234 |
191 |
235 end |
192 end |
236 |
193 |
|
194 text{* The predicates @{text "top_on X a"} that follow describe that @{text a} is some object |
|
195 that maps all variables in @{text X} to @{term \<top>}. |
|
196 This is an important invariant for the termination proof where we argue that only |
|
197 the finitely many variables in the program change. That the others do not change |
|
198 follows because they remain @{term \<top>}. *} |
|
199 |
|
200 class top_on = |
|
201 fixes top_on :: "vname set \<Rightarrow> 'a \<Rightarrow> bool" |
|
202 |
|
203 instantiation st :: (top)top_on |
|
204 begin |
|
205 |
|
206 fun top_on_st :: "vname set \<Rightarrow> 'a st \<Rightarrow> bool" where |
|
207 "top_on_st X F = (\<forall>x\<in>X. fun F x = \<top>)" |
|
208 |
|
209 instance .. |
|
210 |
|
211 end |
|
212 |
|
213 instantiation option :: (top_on)top_on |
|
214 begin |
|
215 |
|
216 fun top_on_option :: "vname set \<Rightarrow> 'a option \<Rightarrow> bool" where |
|
217 "top_on_option X (Some F) = top_on X F" | |
|
218 "top_on_option X None = True" |
|
219 |
|
220 instance .. |
|
221 |
|
222 end |
|
223 |
|
224 instantiation acom :: (top_on)top_on |
|
225 begin |
|
226 |
|
227 definition top_on_acom :: "vname set \<Rightarrow> 'a acom \<Rightarrow> bool" where |
|
228 "top_on_acom X C = (\<forall>a \<in> set(annos C). top_on X a)" |
|
229 |
|
230 instance .. |
|
231 |
|
232 end |
|
233 |
|
234 lemma top_on_top: "top_on X (\<top>::_ st option)" |
|
235 by(auto simp: top_option_def fun_top) |
|
236 |
|
237 lemma top_on_bot: "top_on X (bot c)" |
|
238 by(auto simp add: top_on_acom_def bot_def) |
|
239 |
|
240 lemma top_on_post: "top_on X C \<Longrightarrow> top_on X (post C)" |
|
241 by(simp add: top_on_acom_def post_in_annos) |
|
242 |
|
243 lemma top_on_acom_simps: |
|
244 "top_on X (SKIP {Q}) = top_on X Q" |
|
245 "top_on X (x ::= e {Q}) = top_on X Q" |
|
246 "top_on X (C1;C2) = (top_on X C1 \<and> top_on X C2)" |
|
247 "top_on X (IF b THEN {P1} C1 ELSE {P2} C2 {Q}) = |
|
248 (top_on X P1 \<and> top_on X C1 \<and> top_on X P2 \<and> top_on X C2 \<and> top_on X Q)" |
|
249 "top_on X ({I} WHILE b DO {P} C {Q}) = |
|
250 (top_on X I \<and> top_on X C \<and> top_on X P \<and> top_on X Q)" |
|
251 by(auto simp add: top_on_acom_def) |
|
252 |
|
253 lemma top_on_sup: |
|
254 "top_on X o1 \<Longrightarrow> top_on X o2 \<Longrightarrow> top_on X (o1 \<squnion> o2 :: _ st option)" |
|
255 apply(induction o1 o2 rule: sup_option.induct) |
|
256 apply(auto) |
|
257 by transfer simp |
|
258 |
|
259 lemma top_on_Step: fixes C :: "('a::semilattice)st option acom" |
|
260 assumes "!!x e S. \<lbrakk>top_on X S; x \<notin> X; vars e \<subseteq> -X\<rbrakk> \<Longrightarrow> top_on X (f x e S)" |
|
261 "!!b S. top_on X S \<Longrightarrow> vars b \<subseteq> -X \<Longrightarrow> top_on X (g b S)" |
|
262 shows "\<lbrakk> vars C \<subseteq> -X; top_on X S; top_on X C \<rbrakk> \<Longrightarrow> top_on X (Step f g S C)" |
|
263 proof(induction C arbitrary: S) |
|
264 qed (auto simp: top_on_acom_simps vars_acom_def top_on_post top_on_sup assms) |
|
265 |
|
266 |
237 locale Measure = Measure1 + |
267 locale Measure = Measure1 + |
238 assumes m2: "x < y \<Longrightarrow> m x > m y" |
268 assumes m2: "x < y \<Longrightarrow> m x > m y" |
239 begin |
269 begin |
240 |
270 |
241 lemma m1: "x \<le> y \<Longrightarrow> m x \<ge> m y" |
271 lemma m1: "x \<le> y \<Longrightarrow> m x \<ge> m y" |
242 by(auto simp: le_less m2) |
272 by(auto simp: le_less m2) |
243 |
273 |
244 lemma m_s2: "finite(dom S1) \<Longrightarrow> S1 < S2 \<Longrightarrow> m_s S1 > m_s S2" |
274 lemma m_s2_rep: assumes "finite(X)" and "S1 = S2 on -X" and "\<forall>x. S1 x \<le> S2 x" and "S1 \<noteq> S2" |
245 proof(auto simp add: less_st_def less_eq_st_def m_s_def) |
275 shows "(\<Sum>x\<in>X. m (S2 x)) < (\<Sum>x\<in>X. m (S1 x))" |
246 assume "finite(dom S2)" and 0: "\<forall>x\<in>dom S2. fun S1 x \<le> fun S2 x" |
276 proof- |
247 hence 1: "\<forall>x\<in>dom S2. m(fun S1 x) \<ge> m(fun S2 x)" by (metis m1) |
277 from assms(3) have 1: "\<forall>x\<in>X. m(S1 x) \<ge> m(S2 x)" by (simp add: m1) |
248 fix x assume "x \<in> dom S2" "\<not> fun S2 x \<le> fun S1 x" |
278 from assms(2,3,4) have "EX x:X. S1 x < S2 x" |
249 hence 2: "\<exists>x\<in>dom S2. m(fun S1 x) > m(fun S2 x)" by (metis 0 m2 less_le_not_le) |
279 by(simp add: fun_eq_iff) (metis Compl_iff le_neq_trans) |
250 from setsum_strict_mono_ex1[OF `finite(dom S2)` 1 2] |
280 hence 2: "\<exists>x\<in>X. m(S1 x) > m(S2 x)" by (metis m2) |
251 show "(\<Sum>x\<in>dom S2. m (fun S2 x)) < (\<Sum>x\<in>dom S2. m (fun S1 x))" . |
281 from setsum_strict_mono_ex1[OF `finite X` 1 2] |
252 qed |
282 show "(\<Sum>x\<in>X. m (S2 x)) < (\<Sum>x\<in>X. m (S1 x))" . |
253 |
283 qed |
254 lemma m_o2: "finite X \<Longrightarrow> o1 \<in> L X \<Longrightarrow> o2 \<in> L X \<Longrightarrow> |
284 |
255 o1 < o2 \<Longrightarrow> m_o (card X) o1 > m_o (card X) o2" |
285 lemma m_s2: "finite(X) \<Longrightarrow> fun S1 = fun S2 on -X \<Longrightarrow> S1 < S2 \<Longrightarrow> m_s X S1 > m_s X S2" |
|
286 apply(auto simp add: less_st_def m_s_def) |
|
287 apply (transfer fixing: m) |
|
288 apply(simp add: less_eq_st_rep_iff eq_st_def m_s2_rep) |
|
289 done |
|
290 |
|
291 lemma m_o2: "finite X \<Longrightarrow> top_on (-X) o1 \<Longrightarrow> top_on (-X) o2 \<Longrightarrow> |
|
292 o1 < o2 \<Longrightarrow> m_o X o1 > m_o X o2" |
256 proof(induction o1 o2 rule: less_eq_option.induct) |
293 proof(induction o1 o2 rule: less_eq_option.induct) |
257 case 1 thus ?case by (auto simp: m_o_def L_st_def m_s2 less_option_def) |
294 case 1 thus ?case by (auto simp: m_o_def m_s2 less_option_def) |
258 next |
295 next |
259 case 2 thus ?case by(auto simp: m_o_def less_option_def le_imp_less_Suc m_s_h) |
296 case 2 thus ?case by(auto simp: m_o_def less_option_def le_imp_less_Suc m_s_h) |
260 next |
297 next |
261 case 3 thus ?case by (auto simp: less_option_def) |
298 case 3 thus ?case by (auto simp: less_option_def) |
262 qed |
299 qed |
263 |
300 |
264 lemma m_o1: "finite X \<Longrightarrow> o1 \<in> L X \<Longrightarrow> o2 \<in> L X \<Longrightarrow> |
301 lemma m_o1: "finite X \<Longrightarrow> top_on (-X) o1 \<Longrightarrow> top_on (-X) o2 \<Longrightarrow> |
265 o1 \<le> o2 \<Longrightarrow> m_o (card X) o1 \<ge> m_o (card X) o2" |
302 o1 \<le> o2 \<Longrightarrow> m_o X o1 \<ge> m_o X o2" |
266 by(auto simp: le_less m_o2) |
303 by(auto simp: le_less m_o2) |
267 |
304 |
268 lemma m_c2: "C1 \<in> L(vars(strip C1)) \<Longrightarrow> C2 \<in> L(vars(strip C2)) \<Longrightarrow> |
305 |
|
306 lemma m_c2: "top_on (-vars C1) C1 \<Longrightarrow> top_on (-vars C2) C2 \<Longrightarrow> |
269 C1 < C2 \<Longrightarrow> m_c C1 > m_c C2" |
307 C1 < C2 \<Longrightarrow> m_c C1 > m_c C2" |
270 proof(auto simp add: le_iff_le_annos m_c_def size_annos_same[of C1 C2] less_acom_def L_acom_def) |
308 proof(auto simp add: le_iff_le_annos m_c_def size_annos_same[of C1 C2] vars_acom_def less_acom_def) |
271 let ?X = "vars(strip C2)" |
309 let ?X = "vars(strip C2)" |
272 let ?n = "card ?X" |
310 assume top: "top_on (- vars(strip C2)) C1" "top_on (- vars(strip C2)) C2" |
273 assume V1: "\<forall>a\<in>set(annos C1). a \<in> L ?X" |
311 and strip_eq: "strip C1 = strip C2" |
274 and V2: "\<forall>a\<in>set(annos C2). a \<in> L ?X" |
312 and 0: "\<forall>i<size(annos C2). annos C1 ! i \<le> annos C2 ! i" |
275 and strip_eq: "strip C1 = strip C2" |
313 hence 1: "\<forall>i<size(annos C2). m_o ?X (annos C1 ! i) \<ge> m_o ?X (annos C2 ! i)" |
276 and 0: "\<forall>i<size(annos C2). annos C1 ! i \<le> annos C2 ! i" |
314 apply (auto simp: all_set_conv_all_nth vars_acom_def top_on_acom_def) |
277 hence 1: "\<forall>i<size(annos C2). m_o ?n (annos C1 ! i) \<ge> m_o ?n (annos C2 ! i)" |
315 by (metis finite_cvars m_o1 size_annos_same2) |
278 by (auto simp: all_set_conv_all_nth) |
316 fix i assume i: "i < size(annos C2)" "\<not> annos C2 ! i \<le> annos C1 ! i" |
279 (metis finite_cvars m_o1 size_annos_same2) |
317 have topo1: "top_on (- ?X) (annos C1 ! i)" |
280 fix i assume "i < size(annos C2)" "\<not> annos C2 ! i \<le> annos C1 ! i" |
318 using i(1) top(1) by(simp add: top_on_acom_def size_annos_same[OF strip_eq]) |
281 hence "m_o ?n (annos C1 ! i) > m_o ?n (annos C2 ! i)" (is "?P i") |
319 have topo2: "top_on (- ?X) (annos C2 ! i)" |
282 by(metis m_o2[OF finite_cvars] V1 V2 nth_mem size_annos_same[OF strip_eq] 0 less_option_def) |
320 using i(1) top(2) by(simp add: top_on_acom_def size_annos_same[OF strip_eq]) |
|
321 from i have "m_o ?X (annos C1 ! i) > m_o ?X (annos C2 ! i)" (is "?P i") |
|
322 by (metis 0 less_option_def m_o2[OF finite_cvars topo1] topo2) |
283 hence 2: "\<exists>i < size(annos C2). ?P i" using `i < size(annos C2)` by blast |
323 hence 2: "\<exists>i < size(annos C2). ?P i" using `i < size(annos C2)` by blast |
284 show "(\<Sum>i<size(annos C2). m_o ?n (annos C2 ! i)) |
324 show "(\<Sum>i<size(annos C2). m_o ?X (annos C2 ! i)) |
285 < (\<Sum>i<size(annos C2). m_o ?n (annos C1 ! i))" |
325 < (\<Sum>i<size(annos C2). m_o ?X (annos C1 ! i))" |
286 apply(rule setsum_strict_mono_ex1) using 1 2 by (auto) |
326 apply(rule setsum_strict_mono_ex1) using 1 2 by (auto) |
287 qed |
327 qed |
288 |
328 |
289 end |
329 end |
|
330 |
290 |
331 |
291 locale Abs_Int_measure = |
332 locale Abs_Int_measure = |
292 Abs_Int_mono where \<gamma>=\<gamma> + Measure where m=m |
333 Abs_Int_mono where \<gamma>=\<gamma> + Measure where m=m |
293 for \<gamma> :: "'av::semilattice \<Rightarrow> val set" and m :: "'av \<Rightarrow> nat" |
334 for \<gamma> :: "'av::semilattice \<Rightarrow> val set" and m :: "'av \<Rightarrow> nat" |
294 begin |
335 begin |
295 |
336 |
|
337 lemma top_on_step': "\<lbrakk> vars C \<subseteq> -X; top_on X C \<rbrakk> \<Longrightarrow> top_on X (step' \<top> C)" |
|
338 unfolding step'_def |
|
339 by(rule top_on_Step) |
|
340 (auto simp add: top_option_def fun_top split: option.splits) |
|
341 |
296 lemma AI_Some_measure: "\<exists>C. AI c = Some C" |
342 lemma AI_Some_measure: "\<exists>C. AI c = Some C" |
297 unfolding AI_def |
343 unfolding AI_def |
298 apply(rule pfp_termination[where I = "\<lambda>C. strip C = c \<and> C \<in> L(vars c)" and m="m_c"]) |
344 apply(rule pfp_termination[where I = "\<lambda>C. strip C = c \<and> top_on (- vars C) C" and m="m_c"]) |
299 apply(simp_all add: m_c2 mono_step'_top bot_least) |
345 apply(simp_all add: m_c2 mono_step'_top bot_least top_on_bot) |
|
346 apply(auto simp add: top_on_step' vars_acom_def) |
300 done |
347 done |
301 |
348 |
302 end |
349 end |
303 |
350 |
304 end |
351 end |