author  wenzelm 
Sat, 07 Apr 2012 16:41:59 +0200  
changeset 47389  e8552cba702d 
parent 46355  42a01315d998 
permissions  rwrr 
45111  1 
(* Author: Tobias Nipkow *) 
2 

3 
theory Abs_Int0 

4 
imports Abs_State 

5 
begin 

6 

7 
subsection "Computable Abstract Interpretation" 

8 

45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

9 
text{* Abstract interpretation over type @{text st} instead of 
45111  10 
functions. *} 
11 

46346
10c18630612a
removed duplicate definitions that made locale inconsistent
nipkow
parents:
46334
diff
changeset

12 
context Gamma 
45111  13 
begin 
14 

46063  15 
fun aval' :: "aexp \<Rightarrow> 'av st \<Rightarrow> 'av" where 
46039  16 
"aval' (N n) S = num' n"  
45111  17 
"aval' (V x) S = lookup S x"  
18 
"aval' (Plus a1 a2) S = plus' (aval' a1 S) (aval' a2 S)" 

19 

45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

20 
lemma aval'_sound: "s : \<gamma>\<^isub>f S \<Longrightarrow> aval a s : \<gamma>(aval' a S)" 
46334  21 
by (induction a) (auto simp: gamma_num' gamma_plus' \<gamma>_st_def lookup_def) 
45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

22 

f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

23 
end 
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

24 

46063  25 
text{* The forclause (here and elsewhere) only serves the purpose of fixing 
26 
the name of the type parameter @{typ 'av} which would otherwise be renamed to 

27 
@{typ 'a}. *} 

28 

46346
10c18630612a
removed duplicate definitions that made locale inconsistent
nipkow
parents:
46334
diff
changeset

29 
locale Abs_Int = Gamma where \<gamma>=\<gamma> for \<gamma> :: "'av::SL_top \<Rightarrow> val set" 
45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

30 
begin 
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

31 

46063  32 
fun step' :: "'av st option \<Rightarrow> 'av st option acom \<Rightarrow> 'av st option acom" where 
45655
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

33 
"step' S (SKIP {P}) = (SKIP {S})"  
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

34 
"step' S (x ::= e {P}) = 
45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

35 
x ::= e {case S of None \<Rightarrow> None  Some S \<Rightarrow> Some(update S x (aval' e S))}"  
45655
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

36 
"step' S (c1; c2) = step' S c1; step' (post c1) c2"  
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

37 
"step' S (IF b THEN c1 ELSE c2 {P}) = 
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

38 
(let c1' = step' S c1; c2' = step' S c2 
45111  39 
in IF b THEN c1' ELSE c2' {post c1 \<squnion> post c2})"  
45655
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

40 
"step' S ({Inv} WHILE b DO c {P}) = 
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

41 
{S \<squnion> post c} WHILE b DO step' Inv c {Inv}" 
45111  42 

46063  43 
definition AI :: "com \<Rightarrow> 'av st option acom option" where 
45655
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

44 
"AI = lpfp\<^isub>c (step' \<top>)" 
45127
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

45 

d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

46 

45655
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

47 
lemma strip_step'[simp]: "strip(step' S c) = strip c" 
45111  48 
by(induct c arbitrary: S) (simp_all add: Let_def) 
49 

50 

45127
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

51 
text{* Soundness: *} 
45111  52 

46039  53 
lemma in_gamma_update: 
45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

54 
"\<lbrakk> s : \<gamma>\<^isub>f S; i : \<gamma> a \<rbrakk> \<Longrightarrow> s(x := i) : \<gamma>\<^isub>f(update S x a)" 
46039  55 
by(simp add: \<gamma>_st_def lookup_update) 
45111  56 

45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

57 
text{* The soundness proofs are textually identical to the ones for the step 
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

58 
function operating on states as functions. *} 
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

59 

46068  60 
lemma step_preserves_le: 
46334  61 
"\<lbrakk> S \<subseteq> \<gamma>\<^isub>o S'; c \<le> \<gamma>\<^isub>c c' \<rbrakk> \<Longrightarrow> step S c \<le> \<gamma>\<^isub>c (step' S' c')" 
62 
proof(induction c arbitrary: c' S S') 

46068  63 
case SKIP thus ?case by(auto simp:SKIP_le map_acom_SKIP) 
45111  64 
next 
65 
case Assign thus ?case 

46068  66 
by (fastforce simp: Assign_le map_acom_Assign intro: aval'_sound in_gamma_update 
45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

67 
split: option.splits del:subsetD) 
45111  68 
next 
46068  69 
case Semi thus ?case apply (auto simp: Semi_le map_acom_Semi) 
45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

70 
by (metis le_post post_map_acom) 
45111  71 
next 
46334  72 
case (If b c1 c2 P) 
73 
then obtain c1' c2' P' where 

74 
"c' = IF b THEN c1' ELSE c2' {P'}" 

75 
"P \<subseteq> \<gamma>\<^isub>o P'" "c1 \<le> \<gamma>\<^isub>c c1'" "c2 \<le> \<gamma>\<^isub>c c2'" 

46068  76 
by (fastforce simp: If_le map_acom_If) 
46334  77 
moreover have "post c1 \<subseteq> \<gamma>\<^isub>o(post c1' \<squnion> post c2')" 
78 
by (metis (no_types) `c1 \<le> \<gamma>\<^isub>c c1'` join_ge1 le_post mono_gamma_o order_trans post_map_acom) 

79 
moreover have "post c2 \<subseteq> \<gamma>\<^isub>o(post c1' \<squnion> post c2')" 

80 
by (metis (no_types) `c2 \<le> \<gamma>\<^isub>c c2'` join_ge2 le_post mono_gamma_o order_trans post_map_acom) 

46068  81 
ultimately show ?case using `S \<subseteq> \<gamma>\<^isub>o S'` by (simp add: If.IH subset_iff) 
45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

82 
next 
46334  83 
case (While I b c1 P) 
84 
then obtain c1' I' P' where 

85 
"c' = {I'} WHILE b DO c1' {P'}" 

86 
"I \<subseteq> \<gamma>\<^isub>o I'" "P \<subseteq> \<gamma>\<^isub>o P'" "c1 \<le> \<gamma>\<^isub>c c1'" 

46068  87 
by (fastforce simp: map_acom_While While_le) 
46334  88 
moreover have "S \<union> post c1 \<subseteq> \<gamma>\<^isub>o (S' \<squnion> post c1')" 
89 
using `S \<subseteq> \<gamma>\<^isub>o S'` le_post[OF `c1 \<le> \<gamma>\<^isub>c c1'`, simplified] 

46039  90 
by (metis (no_types) join_ge1 join_ge2 le_sup_iff mono_gamma_o order_trans) 
45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

91 
ultimately show ?case by (simp add: While.IH subset_iff) 
45111  92 
qed 
93 

46070  94 
lemma AI_sound: "AI c = Some c' \<Longrightarrow> CS c \<le> \<gamma>\<^isub>c c'" 
45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

95 
proof(simp add: CS_def AI_def) 
45655
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

96 
assume 1: "lpfp\<^isub>c (step' \<top>) c = Some c'" 
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

97 
have 2: "step' \<top> c' \<sqsubseteq> c'" by(rule lpfpc_pfp[OF 1]) 
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

98 
have 3: "strip (\<gamma>\<^isub>c (step' \<top> c')) = c" 
45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

99 
by(simp add: strip_lpfpc[OF _ 1]) 
46066  100 
have "lfp (step UNIV) c \<le> \<gamma>\<^isub>c (step' \<top> c')" 
45903  101 
proof(rule lfp_lowerbound[simplified,OF 3]) 
45655
a49f9428aba4
simplified Collecting1 and renamed: step > step', step_cs > step
nipkow
parents:
45623
diff
changeset

102 
show "step UNIV (\<gamma>\<^isub>c (step' \<top> c')) \<le> \<gamma>\<^isub>c (step' \<top> c')" 
46068  103 
proof(rule step_preserves_le[OF _ _]) 
46039  104 
show "UNIV \<subseteq> \<gamma>\<^isub>o \<top>" by simp 
105 
show "\<gamma>\<^isub>c (step' \<top> c') \<le> \<gamma>\<^isub>c c'" by(rule mono_gamma_c[OF 2]) 

45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

106 
qed 
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

107 
qed 
46066  108 
from this 2 show "lfp (step UNIV) c \<le> \<gamma>\<^isub>c c'" 
46039  109 
by (blast intro: mono_gamma_c order_trans) 
45623
f682f3f7b726
Abstract interpretation is now based uniformly on annotated programs,
nipkow
parents:
45127
diff
changeset

110 
qed 
45111  111 

112 
end 

113 

114 

45127
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

115 
subsubsection "Monotonicity" 
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

116 

d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

117 
locale Abs_Int_mono = Abs_Int + 
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

118 
assumes mono_plus': "a1 \<sqsubseteq> b1 \<Longrightarrow> a2 \<sqsubseteq> b2 \<Longrightarrow> plus' a1 a2 \<sqsubseteq> plus' b1 b2" 
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

119 
begin 
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

120 

d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

121 
lemma mono_aval': "S \<sqsubseteq> S' \<Longrightarrow> aval' e S \<sqsubseteq> aval' e S'" 
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

122 
by(induction e) (auto simp: le_st_def lookup_def mono_plus') 
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

123 

d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

124 
lemma mono_update: "a \<sqsubseteq> a' \<Longrightarrow> S \<sqsubseteq> S' \<Longrightarrow> update S x a \<sqsubseteq> update S' x a'" 
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

125 
by(auto simp add: le_st_def lookup_def update_def) 
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

126 

46153  127 
lemma mono_step': "S \<sqsubseteq> S' \<Longrightarrow> c \<sqsubseteq> c' \<Longrightarrow> step' S c \<sqsubseteq> step' S' c'" 
128 
apply(induction c c' arbitrary: S S' rule: le_acom.induct) 

129 
apply (auto simp: Let_def mono_update mono_aval' mono_post le_join_disj 

130 
split: option.split) 

45127
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

131 
done 
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

132 

45111  133 
end 
45127
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

134 

46158  135 

136 
subsubsection "Ascending Chain Condition" 

137 

46334  138 
hide_const (open) acc 
46158  139 

140 
abbreviation "strict r == r \<inter> (r^1)" 

141 
abbreviation "acc r == wf((strict r)^1)" 

142 

143 
lemma strict_inv_image: "strict(inv_image r f) = inv_image (strict r) f" 

144 
by(auto simp: inv_image_def) 

145 

146 
lemma acc_inv_image: 

147 
"acc r \<Longrightarrow> acc (inv_image r f)" 

148 
by (metis converse_inv_image strict_inv_image wf_inv_image) 

149 

150 
text{* ACC for option type: *} 

151 

152 
lemma acc_option: assumes "acc {(x,y::'a::preord). x \<sqsubseteq> y}" 

46355
42a01315d998
removed accidental dependance of abstract interpreter on gamma
nipkow
parents:
46346
diff
changeset

153 
shows "acc {(x,y::'a::preord option). x \<sqsubseteq> y}" 
46158  154 
proof(auto simp: wf_eq_minimal) 
155 
fix xo :: "'a option" and Qo assume "xo : Qo" 

156 
let ?Q = "{x. Some x \<in> Qo}" 

157 
show "\<exists>yo\<in>Qo. \<forall>zo. yo \<sqsubseteq> zo \<and> ~ zo \<sqsubseteq> yo \<longrightarrow> zo \<notin> Qo" (is "\<exists>zo\<in>Qo. ?P zo") 

158 
proof cases 

159 
assume "?Q = {}" 

160 
hence "?P None" by auto 

161 
moreover have "None \<in> Qo" using `?Q = {}` `xo : Qo` 

162 
by auto (metis not_Some_eq) 

163 
ultimately show ?thesis by blast 

164 
next 

165 
assume "?Q \<noteq> {}" 

166 
with assms show ?thesis 

167 
apply(auto simp: wf_eq_minimal) 

168 
apply(erule_tac x="?Q" in allE) 

169 
apply auto 

170 
apply(rule_tac x = "Some z" in bexI) 

171 
by auto 

172 
qed 

173 
qed 

174 

175 
text{* ACC for abstract states, via measure functions. *} 

176 

177 
(*FIXME mv*) 

178 
lemma setsum_strict_mono1: 

179 
fixes f :: "'a \<Rightarrow> 'b::{comm_monoid_add, ordered_cancel_ab_semigroup_add}" 

180 
assumes "finite A" and "ALL x:A. f x \<le> g x" and "EX a:A. f a < g a" 

181 
shows "setsum f A < setsum g A" 

182 
proof 

183 
from assms(3) obtain a where a: "a:A" "f a < g a" by blast 

184 
have "setsum f A = setsum f ((A{a}) \<union> {a})" 

185 
by(simp add:insert_absorb[OF `a:A`]) 

186 
also have "\<dots> = setsum f (A{a}) + setsum f {a}" 

187 
using `finite A` by(subst setsum_Un_disjoint) auto 

188 
also have "setsum f (A{a}) \<le> setsum g (A{a})" 

189 
by(rule setsum_mono)(simp add: assms(2)) 

190 
also have "setsum f {a} < setsum g {a}" using a by simp 

191 
also have "setsum g (A  {a}) + setsum g {a} = setsum g((A{a}) \<union> {a})" 

192 
using `finite A` by(subst setsum_Un_disjoint[symmetric]) auto 

193 
also have "\<dots> = setsum g A" by(simp add:insert_absorb[OF `a:A`]) 

194 
finally show ?thesis by (metis add_right_mono add_strict_left_mono) 

195 
qed 

196 

197 
lemma measure_st: assumes "(strict{(x,y::'a::SL_top). x \<sqsubseteq> y})^1 <= measure m" 

46355
42a01315d998
removed accidental dependance of abstract interpreter on gamma
nipkow
parents:
46346
diff
changeset

198 
and "\<forall>x y::'a::SL_top. x \<sqsubseteq> y \<and> y \<sqsubseteq> x \<longrightarrow> m x = m y" 
42a01315d998
removed accidental dependance of abstract interpreter on gamma
nipkow
parents:
46346
diff
changeset

199 
shows "(strict{(S,S'::'a::SL_top st). S \<sqsubseteq> S'})^1 \<subseteq> 
46158  200 
measure(%fd. \<Sum>x x\<in>set(dom fd) \<and> ~ \<top> \<sqsubseteq> fun fd x. m(fun fd x)+1)" 
201 
proof 

202 
{ fix S S' :: "'a st" assume "S \<sqsubseteq> S'" "~ S' \<sqsubseteq> S" 

203 
let ?X = "set(dom S)" let ?Y = "set(dom S')" 

204 
let ?f = "fun S" let ?g = "fun S'" 

205 
let ?X' = "{x:?X. ~ \<top> \<sqsubseteq> ?f x}" let ?Y' = "{y:?Y. ~ \<top> \<sqsubseteq> ?g y}" 

206 
from `S \<sqsubseteq> S'` have "ALL y:?Y'\<inter>?X. ?f y \<sqsubseteq> ?g y" 

207 
by(auto simp: le_st_def lookup_def) 

208 
hence 1: "ALL y:?Y'\<inter>?X. m(?g y)+1 \<le> m(?f y)+1" 

209 
using assms(1,2) by(fastforce) 

210 
from `~ S' \<sqsubseteq> S` obtain u where u: "u : ?X" "~ lookup S' u \<sqsubseteq> ?f u" 

211 
by(auto simp: le_st_def) 

212 
hence "u : ?X'" by simp (metis preord_class.le_trans top) 

213 
have "?Y'?X = {}" using `S \<sqsubseteq> S'` by(fastforce simp: le_st_def lookup_def) 

214 
have "?Y'\<inter>?X <= ?X'" apply auto 

215 
apply (metis `S \<sqsubseteq> S'` le_st_def lookup_def preord_class.le_trans) 

216 
done 

217 
have "(\<Sum>y\<in>?Y'. m(?g y)+1) = (\<Sum>y\<in>(?Y'?X) \<union> (?Y'\<inter>?X). m(?g y)+1)" 

218 
by (metis Un_Diff_Int) 

219 
also have "\<dots> = (\<Sum>y\<in>?Y'\<inter>?X. m(?g y)+1)" 

220 
using `?Y'?X = {}` by (metis Un_empty_left) 

221 
also have "\<dots> < (\<Sum>x\<in>?X'. m(?f x)+1)" 

222 
proof cases 

223 
assume "u \<in> ?Y'" 

224 
hence "m(?g u) < m(?f u)" using assms(1) `S \<sqsubseteq> S'` u 

225 
by (fastforce simp: le_st_def lookup_def) 

226 
have "(\<Sum>y\<in>?Y'\<inter>?X. m(?g y)+1) < (\<Sum>y\<in>?Y'\<inter>?X. m(?f y)+1)" 

227 
using `u:?X` `u:?Y'` `m(?g u) < m(?f u)` 

228 
by(fastforce intro!: setsum_strict_mono1[OF _ 1]) 

229 
also have "\<dots> \<le> (\<Sum>y\<in>?X'. m(?f y)+1)" 

230 
by(simp add: setsum_mono3[OF _ `?Y'\<inter>?X <= ?X'`]) 

231 
finally show ?thesis . 

232 
next 

233 
assume "u \<notin> ?Y'" 

234 
with `?Y'\<inter>?X <= ?X'` have "?Y'\<inter>?X  {u} <= ?X'  {u}" by blast 

235 
have "(\<Sum>y\<in>?Y'\<inter>?X. m(?g y)+1) = (\<Sum>y\<in>?Y'\<inter>?X  {u}. m(?g y)+1)" 

236 
proof 

237 
have "?Y'\<inter>?X = ?Y'\<inter>?X  {u}" using `u \<notin> ?Y'` by auto 

238 
thus ?thesis by metis 

239 
qed 

240 
also have "\<dots> < (\<Sum>y\<in>?Y'\<inter>?X{u}. m(?g y)+1) + (\<Sum>y\<in>{u}. m(?f y)+1)" by simp 

241 
also have "(\<Sum>y\<in>?Y'\<inter>?X{u}. m(?g y)+1) \<le> (\<Sum>y\<in>?Y'\<inter>?X{u}. m(?f y)+1)" 

242 
using 1 by(blast intro: setsum_mono) 

243 
also have "\<dots> \<le> (\<Sum>y\<in>?X'{u}. m(?f y)+1)" 

244 
by(simp add: setsum_mono3[OF _ `?Y'\<inter>?X{u} <= ?X'{u}`]) 

245 
also have "\<dots> + (\<Sum>y\<in>{u}. m(?f y)+1)= (\<Sum>y\<in>(?X'{u}) \<union> {u}. m(?f y)+1)" 

246 
using `u:?X'` by(subst setsum_Un_disjoint[symmetric]) auto 

247 
also have "\<dots> = (\<Sum>x\<in>?X'. m(?f x)+1)" 

248 
using `u : ?X'` by(simp add:insert_absorb) 

249 
finally show ?thesis by (blast intro: add_right_mono) 

250 
qed 

251 
finally have "(\<Sum>y\<in>?Y'. m(?g y)+1) < (\<Sum>x\<in>?X'. m(?f x)+1)" . 

252 
} thus ?thesis by(auto simp add: measure_def inv_image_def) 

253 
qed 

254 

255 
text{* ACC for acom. First the ordering on acom is related to an ordering on 

256 
lists of annotations. *} 

257 

258 
(* FIXME mv and add [simp] *) 

259 
lemma listrel_Cons_iff: 

260 
"(x#xs, y#ys) : listrel r \<longleftrightarrow> (x,y) \<in> r \<and> (xs,ys) \<in> listrel r" 

261 
by (blast intro:listrel.Cons) 

262 

263 
lemma listrel_app: "(xs1,ys1) : listrel r \<Longrightarrow> (xs2,ys2) : listrel r 

264 
\<Longrightarrow> (xs1@xs2, ys1@ys2) : listrel r" 

265 
by(auto simp add: listrel_iff_zip) 

266 

267 
lemma listrel_app_same_size: "size xs1 = size ys1 \<Longrightarrow> size xs2 = size ys2 \<Longrightarrow> 

268 
(xs1@xs2, ys1@ys2) : listrel r \<longleftrightarrow> 

269 
(xs1,ys1) : listrel r \<and> (xs2,ys2) : listrel r" 

270 
by(auto simp add: listrel_iff_zip) 

271 

272 
lemma listrel_converse: "listrel(r^1) = (listrel r)^1" 

273 
proof 

274 
{ fix xs ys 

275 
have "(xs,ys) : listrel(r^1) \<longleftrightarrow> (ys,xs) : listrel r" 

276 
apply(induct xs arbitrary: ys) 

277 
apply (fastforce simp: listrel.Nil) 

278 
apply (fastforce simp: listrel_Cons_iff) 

279 
done 

280 
} thus ?thesis by auto 

281 
qed 

282 

283 
(* It would be nice to get rid of refl & trans and build them into the proof *) 

284 
lemma acc_listrel: fixes r :: "('a*'a)set" assumes "refl r" and "trans r" 

285 
and "acc r" shows "acc (listrel r  {([],[])})" 

286 
proof 

287 
have refl: "!!x. (x,x) : r" using `refl r` unfolding refl_on_def by blast 

288 
have trans: "!!x y z. (x,y) : r \<Longrightarrow> (y,z) : r \<Longrightarrow> (x,z) : r" 

289 
using `trans r` unfolding trans_def by blast 

290 
from assms(3) obtain mx :: "'a set \<Rightarrow> 'a" where 

291 
mx: "!!S x. x:S \<Longrightarrow> mx S : S \<and> (\<forall>y. (mx S,y) : strict r \<longrightarrow> y \<notin> S)" 

292 
by(simp add: wf_eq_minimal) metis 

293 
let ?R = "listrel r  {([], [])}" 

294 
{ fix Q and xs :: "'a list" 

295 
have "xs \<in> Q \<Longrightarrow> \<exists>ys. ys\<in>Q \<and> (\<forall>zs. (ys, zs) \<in> strict ?R \<longrightarrow> zs \<notin> Q)" 

296 
(is "_ \<Longrightarrow> \<exists>ys. ?P Q ys") 

297 
proof(induction xs arbitrary: Q rule: length_induct) 

298 
case (1 xs) 

299 
{ have "!!ys Q. size ys < size xs \<Longrightarrow> ys : Q \<Longrightarrow> EX ms. ?P Q ms" 

300 
using "1.IH" by blast 

301 
} note IH = this 

302 
show ?case 

303 
proof(cases xs) 

304 
case Nil with `xs : Q` have "?P Q []" by auto 

305 
thus ?thesis by blast 

306 
next 

307 
case (Cons x ys) 

308 
let ?Q1 = "{a. \<exists>bs. size bs = size ys \<and> a#bs : Q}" 

309 
have "x : ?Q1" using `xs : Q` Cons by auto 

310 
from mx[OF this] obtain m1 where 

311 
1: "m1 \<in> ?Q1 \<and> (\<forall>y. (m1,y) \<in> strict r \<longrightarrow> y \<notin> ?Q1)" by blast 

312 
then obtain ms1 where "size ms1 = size ys" "m1#ms1 : Q" by blast+ 

313 
hence "size ms1 < size xs" using Cons by auto 

314 
let ?Q2 = "{bs. \<exists>m1'. (m1',m1):r \<and> (m1,m1'):r \<and> m1'#bs : Q \<and> size bs = size ms1}" 

315 
have "ms1 : ?Q2" using `m1#ms1 : Q` by(blast intro: refl) 

316 
from IH[OF `size ms1 < size xs` this] 

317 
obtain ms where 2: "?P ?Q2 ms" by auto 

318 
then obtain m1' where m1': "(m1',m1) : r \<and> (m1,m1') : r \<and> m1'#ms : Q" 

319 
by blast 

320 
hence "\<forall>ab. (m1'#ms,ab) : strict ?R \<longrightarrow> ab \<notin> Q" using 1 2 

321 
apply (auto simp: listrel_Cons_iff) 

322 
apply (metis `length ms1 = length ys` listrel_eq_len trans) 

323 
by (metis `length ms1 = length ys` listrel_eq_len trans) 

324 
with m1' show ?thesis by blast 

325 
qed 

326 
qed 

327 
} 

328 
thus ?thesis unfolding wf_eq_minimal by (metis converse_iff) 

329 
qed 

330 

331 

332 
fun annos :: "'a acom \<Rightarrow> 'a list" where 

333 
"annos (SKIP {a}) = [a]"  

334 
"annos (x::=e {a}) = [a]"  

335 
"annos (c1;c2) = annos c1 @ annos c2"  

336 
"annos (IF b THEN c1 ELSE c2 {a}) = a # annos c1 @ annos c2"  

337 
"annos ({i} WHILE b DO c {a}) = i # a # annos c" 

338 

339 
lemma size_annos_same: "strip c1 = strip c2 \<Longrightarrow> size(annos c1) = size(annos c2)" 

340 
apply(induct c2 arbitrary: c1) 

341 
apply (auto simp: strip_eq_SKIP strip_eq_Assign strip_eq_Semi strip_eq_If strip_eq_While) 

342 
done 

343 

46246  344 
lemmas size_annos_same2 = eqTrueI[OF size_annos_same] 
345 

346 
lemma set_annos_anno: "set (annos (anno a c)) = {a}" 

347 
by(induction c)(auto) 

348 

46158  349 
lemma le_iff_le_annos: "c1 \<sqsubseteq> c2 \<longleftrightarrow> 
350 
(annos c1, annos c2) : listrel{(x,y). x \<sqsubseteq> y} \<and> strip c1 = strip c2" 

351 
apply(induct c1 c2 rule: le_acom.induct) 

46246  352 
apply (auto simp: listrel.Nil listrel_Cons_iff listrel_app size_annos_same2) 
46158  353 
apply (metis listrel_app_same_size size_annos_same)+ 
354 
done 

355 

356 
lemma le_acom_subset_same_annos: 

357 
"(strict{(c,c'::'a::preord acom). c \<sqsubseteq> c'})^1 \<subseteq> 

358 
(strict(inv_image (listrel{(a,a'::'a). a \<sqsubseteq> a'}  {([],[])}) annos))^1" 

359 
by(auto simp: le_iff_le_annos) 

360 

361 
lemma acc_acom: "acc {(a,a'::'a::preord). a \<sqsubseteq> a'} \<Longrightarrow> 

362 
acc {(c,c'::'a acom). c \<sqsubseteq> c'}" 

363 
apply(rule wf_subset[OF _ le_acom_subset_same_annos]) 

364 
apply(rule acc_inv_image[OF acc_listrel]) 

365 
apply(auto simp: refl_on_def trans_def intro: le_trans) 

366 
done 

367 

368 
text{* Termination of the fixedpoint finders, assuming monotone functions: *} 

369 

370 
lemma pfp_termination: 

371 
fixes x0 :: "'a::preord" 

372 
assumes mono: "\<And>x y. x \<sqsubseteq> y \<Longrightarrow> f x \<sqsubseteq> f y" and "acc {(x::'a,y). x \<sqsubseteq> y}" 

373 
and "x0 \<sqsubseteq> f x0" shows "EX x. pfp f x0 = Some x" 

374 
proof(simp add: pfp_def, rule wf_while_option_Some[where P = "%x. x \<sqsubseteq> f x"]) 

375 
show "wf {(x, s). (s \<sqsubseteq> f s \<and> \<not> f s \<sqsubseteq> s) \<and> x = f s}" 

376 
by(rule wf_subset[OF assms(2)]) auto 

377 
next 

378 
show "x0 \<sqsubseteq> f x0" by(rule assms) 

379 
next 

380 
fix x assume "x \<sqsubseteq> f x" thus "f x \<sqsubseteq> f(f x)" by(rule mono) 

381 
qed 

382 

383 
lemma lpfpc_termination: 

384 
fixes f :: "(('a::SL_top)option acom \<Rightarrow> 'a option acom)" 

385 
assumes "acc {(x::'a,y). x \<sqsubseteq> y}" and "\<And>x y. x \<sqsubseteq> y \<Longrightarrow> f x \<sqsubseteq> f y" 

386 
and "\<And>c. strip(f c) = strip c" 

387 
shows "\<exists>c'. lpfp\<^isub>c f c = Some c'" 

388 
unfolding lpfp\<^isub>c_def 

389 
apply(rule pfp_termination) 

390 
apply(erule assms(2)) 

391 
apply(rule acc_acom[OF acc_option[OF assms(1)]]) 

392 
apply(simp add: bot_acom assms(3)) 

393 
done 

394 

46334  395 
context Abs_Int_mono 
396 
begin 

397 

398 
lemma AI_Some_measure: 

399 
assumes "(strict{(x,y::'a). x \<sqsubseteq> y})^1 <= measure m" 

400 
and "\<forall>x y::'a. x \<sqsubseteq> y \<and> y \<sqsubseteq> x \<longrightarrow> m x = m y" 

401 
shows "\<exists>c'. AI c = Some c'" 

402 
unfolding AI_def 

403 
apply(rule lpfpc_termination) 

404 
apply(rule wf_subset[OF wf_measure measure_st[OF assms]]) 

405 
apply(erule mono_step'[OF le_refl]) 

406 
apply(rule strip_step') 

407 
done 

46158  408 

45127
d2eb07a1e01b
separated monotonicity reasoning and defined narrowing with while_option
nipkow
parents:
45111
diff
changeset

409 
end 
46334  410 

411 
end 