src/HOL/Hoare/Pointer_Examples.thy
changeset 13773 58dc4ab362d0
parent 13772 73d041cc6a66
child 13875 12997e3ddd8d
equal deleted inserted replaced
13772:73d041cc6a66 13773:58dc4ab362d0
   168 
   168 
   169 subsection "Merging two lists"
   169 subsection "Merging two lists"
   170 
   170 
   171 text"This is still a bit rough, especially the proof."
   171 text"This is still a bit rough, especially the proof."
   172 
   172 
       
   173 constdefs
       
   174  cor :: "bool \<Rightarrow> bool \<Rightarrow> bool"
       
   175 "cor P Q == if P then True else Q"
       
   176  cand :: "bool \<Rightarrow> bool \<Rightarrow> bool"
       
   177 "cand P Q == if P then Q else False"
       
   178 
   173 consts merge :: "'a list * 'a list * ('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list"
   179 consts merge :: "'a list * 'a list * ('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list"
   174 
   180 
   175 recdef merge "measure(%(xs,ys,f). size xs + size ys)"
   181 recdef merge "measure(%(xs,ys,f). size xs + size ys)"
   176 "merge(x#xs,y#ys,f) = (if f x y then x # merge(xs,y#ys,f)
   182 "merge(x#xs,y#ys,f) = (if f x y then x # merge(xs,y#ys,f)
   177                                 else y # merge(x#xs,ys,f))"
   183                                 else y # merge(x#xs,ys,f))"
   178 "merge(x#xs,[],f) = x # merge(xs,[],f)"
   184 "merge(x#xs,[],f) = x # merge(xs,[],f)"
   179 "merge([],y#ys,f) = y # merge([],ys,f)"
   185 "merge([],y#ys,f) = y # merge([],ys,f)"
   180 "merge([],[],f) = []"
   186 "merge([],[],f) = []"
   181 
   187 
   182 lemma imp_disjCL: "(P|Q \<longrightarrow> R) = ((P \<longrightarrow> R) \<and> (~P \<longrightarrow> Q \<longrightarrow> R))"
   188 text{* Simplifies the proof a little: *}
       
   189 
       
   190 lemma [simp]: "({} = insert a A \<inter> B) = (a \<notin> B & {} = A \<inter> B)"
   183 by blast
   191 by blast
   184 
   192 lemma [simp]: "({} = A \<inter> insert b B) = (b \<notin> A & {} = A \<inter> B)"
   185 declare imp_disjL[simp del] imp_disjCL[simp]
   193 by blast
       
   194 lemma [simp]: "({} = A \<inter> (B \<union> C)) = ({} = A \<inter> B & {} = A \<inter> C)"
       
   195 by blast
   186 
   196 
   187 lemma "VARS hd tl p q r s
   197 lemma "VARS hd tl p q r s
   188  {List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {} \<and>
   198  {List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {} \<and>
   189   (p \<noteq> Null \<or> q \<noteq> Null)}
   199   (p \<noteq> Null \<or> q \<noteq> Null)}
   190  IF if q = Null then True else p \<noteq> Null \<and> p^.hd \<le> q^.hd
   200  IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd))
   191  THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI;
   201  THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI;
   192  s := r;
   202  s := r;
   193  WHILE p \<noteq> Null \<or> q \<noteq> Null
   203  WHILE p \<noteq> Null \<or> q \<noteq> Null
   194  INV {EX rs ps qs a. Path tl r rs s \<and> List tl p ps \<and> List tl q qs \<and>
   204  INV {EX rs ps qs a. Path tl r rs s \<and> List tl p ps \<and> List tl q qs \<and>
   195       distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and>
   205       distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and>
   196       merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) =
   206       merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) =
   197       rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and>
   207       rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and>
   198       (tl a = p \<or> tl a = q)}
   208       (tl a = p \<or> tl a = q)}
   199  DO IF if q = Null then True else p \<noteq> Null \<and> p^.hd \<le> q^.hd
   209  DO IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd))
   200     THEN s^.tl := p; p := p^.tl ELSE s^.tl := q; q := q^.tl FI;
   210     THEN s^.tl := p; p := p^.tl ELSE s^.tl := q; q := q^.tl FI;
   201     s := s^.tl
   211     s := s^.tl
   202  OD
   212  OD
   203  {List tl r (merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y))}"
   213  {List tl r (merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y))}"
   204 apply vcg_simp
   214 apply vcg_simp
       
   215 apply (simp_all add: cand_def cor_def)
   205 
   216 
   206 apply (fastsimp)
   217 apply (fastsimp)
   207 
   218 
   208 (* One big fastsimp does not seem to converge: *)
   219 apply clarsimp
       
   220 apply(rule conjI)
   209 apply clarsimp
   221 apply clarsimp
   210 apply(rule conjI)
   222 apply(rule conjI)
   211 apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv)
   223 apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv)
   212 apply clarsimp
   224 apply clarsimp
   213 apply(rule conjI)
   225 apply(rule conjI)
       
   226 apply (clarsimp)
       
   227 apply(rule_tac x = "rs @ [a]" in exI)
       
   228 apply(clarsimp simp:eq_sym_conv)
       
   229 apply(rule_tac x = "bs" in exI)
       
   230 apply(clarsimp simp:eq_sym_conv)
       
   231 apply(rule_tac x = "ya#bsa" in exI)
       
   232 apply(simp)
       
   233 apply(clarsimp simp:eq_sym_conv)
       
   234 apply(rule_tac x = "rs @ [a]" in exI)
       
   235 apply(clarsimp simp:eq_sym_conv)
       
   236 apply(rule_tac x = "y#bs" in exI)
       
   237 apply(clarsimp simp:eq_sym_conv)
       
   238 apply(rule_tac x = "bsa" in exI)
       
   239 apply(simp)
   214 apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv)
   240 apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv)
   215 apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv)
       
   216 
   241 
   217 apply(clarsimp simp add:List_app)
   242 apply(clarsimp simp add:List_app)
   218 done
   243 done
   219 
   244 
   220 (* merging with islist/list instead of List? Unlikely to be simpler *)
   245 
       
   246 text{* More of the proof can be automated, but the runtime goes up
       
   247 drastically. In general it is usually more efficient to give the
       
   248 witness directly than to have it found by proof.
       
   249 
       
   250 Now we try a functional version of the abstraction relation @{term
       
   251 Path}. Since the result is not that convincing, we do not prove any of
       
   252 the lemmas.*}
       
   253 
       
   254 consts ispath:: "('a \<Rightarrow> 'a ref) \<Rightarrow> 'a ref \<Rightarrow> 'a ref \<Rightarrow> bool"
       
   255        path:: "('a \<Rightarrow> 'a ref) \<Rightarrow> 'a ref \<Rightarrow> 'a ref \<Rightarrow> 'a list"
       
   256 
       
   257 ML"set quick_and_dirty"
       
   258 
       
   259 text"First some basic lemmas:"
       
   260 
       
   261 lemma [simp]: "ispath f p p"
       
   262 sorry
       
   263 lemma [simp]: "path f p p = []"
       
   264 sorry
       
   265 lemma [simp]: "ispath f p q \<Longrightarrow> a \<notin> set(path f p q) \<Longrightarrow> ispath (f(a := r)) p q"
       
   266 sorry
       
   267 lemma [simp]: "ispath f p q \<Longrightarrow> a \<notin> set(path f p q) \<Longrightarrow>
       
   268  path (f(a := r)) p q = path f p q"
       
   269 sorry
       
   270 
       
   271 text"Some more specific lemmas needed by the example:"
       
   272 
       
   273 lemma [simp]: "ispath (f(a := q)) p (Ref a) \<Longrightarrow> ispath (f(a := q)) p q"
       
   274 sorry
       
   275 lemma [simp]: "ispath (f(a := q)) p (Ref a) \<Longrightarrow>
       
   276  path (f(a := q)) p q = path (f(a := q)) p (Ref a) @ [a]"
       
   277 sorry
       
   278 lemma [simp]: "ispath f p (Ref a) \<Longrightarrow> f a = Ref b \<Longrightarrow>
       
   279  b \<notin> set (path f p (Ref a))"
       
   280 sorry
       
   281 lemma [simp]: "ispath f p (Ref a) \<Longrightarrow> f a = Null \<Longrightarrow> islist f p"
       
   282 sorry
       
   283 lemma [simp]: "ispath f p (Ref a) \<Longrightarrow> f a = Null \<Longrightarrow> list f p = path f p (Ref a) @ [a]"
       
   284 sorry
       
   285 
       
   286 lemma [simp]: "islist f p \<Longrightarrow> distinct (list f p)"
       
   287 sorry
       
   288 ML"reset quick_and_dirty"
       
   289 
       
   290 lemma "VARS hd tl p q r s
       
   291  {islist tl p & Ps = list tl p \<and> islist tl q & Qs = list tl q \<and>
       
   292   set Ps \<inter> set Qs = {} \<and>
       
   293   (p \<noteq> Null \<or> q \<noteq> Null)}
       
   294  IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd))
       
   295  THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI;
       
   296  s := r;
       
   297  WHILE p \<noteq> Null \<or> q \<noteq> Null
       
   298  INV {EX rs ps qs a. ispath tl r s & rs = path tl r s \<and>
       
   299       islist tl p & ps = list tl p \<and> islist tl q & qs = list tl q \<and>
       
   300       distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and>
       
   301       merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) =
       
   302       rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and>
       
   303       (tl a = p \<or> tl a = q)}
       
   304  DO IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd))
       
   305     THEN s^.tl := p; p := p^.tl ELSE s^.tl := q; q := q^.tl FI;
       
   306     s := s^.tl
       
   307  OD
       
   308  {islist tl r & list tl r = (merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y))}"
       
   309 apply vcg_simp
       
   310 
       
   311 apply (simp_all add: cand_def cor_def)
       
   312   apply (fastsimp)
       
   313  apply (fastsimp simp: eq_sym_conv)
       
   314 apply(clarsimp)
       
   315 done
       
   316 
       
   317 text"The proof is automatic, but requires a numbet of special lemmas."
       
   318 
   221 
   319 
   222 subsection "Storage allocation"
   320 subsection "Storage allocation"
   223 
   321 
   224 constdefs new :: "'a set \<Rightarrow> 'a"
   322 constdefs new :: "'a set \<Rightarrow> 'a"
   225 "new A == SOME a. a \<notin> A"
   323 "new A == SOME a. a \<notin> A"