src/HOL/IMPP/Hoare.thy
changeset 58254 c1c65a805d0f
parent 58249 180f1b3508ed
child 58310 91ea607a34d8
equal deleted inserted replaced
58253:30e7fecc9e42 58254:c1c65a805d0f
   105              X:=CALL pn(a) .{Q}"
   105              X:=CALL pn(a) .{Q}"
   106 
   106 
   107 
   107 
   108 section {* Soundness and relative completeness of Hoare rules wrt operational semantics *}
   108 section {* Soundness and relative completeness of Hoare rules wrt operational semantics *}
   109 
   109 
   110 lemma single_stateE: 
   110 lemma single_stateE:
   111   "state_not_singleton ==> !t. (!s::state. s = t) --> False"
   111   "state_not_singleton ==> !t. (!s::state. s = t) --> False"
   112 apply (unfold state_not_singleton_def)
   112 apply (unfold state_not_singleton_def)
   113 apply clarify
   113 apply clarify
   114 apply (case_tac "ta = t")
   114 apply (case_tac "ta = t")
   115 apply blast
   115 apply blast
   119 declare peek_and_def [simp]
   119 declare peek_and_def [simp]
   120 
   120 
   121 
   121 
   122 subsection "validity"
   122 subsection "validity"
   123 
   123 
   124 lemma triple_valid_def2: 
   124 lemma triple_valid_def2:
   125   "|=n:{P}.c.{Q} = (!Z s. P Z s --> (!s'. <c,s> -n-> s' --> Q Z s'))"
   125   "|=n:{P}.c.{Q} = (!Z s. P Z s --> (!s'. <c,s> -n-> s' --> Q Z s'))"
   126 apply (unfold triple_valid_def)
   126 apply (unfold triple_valid_def)
   127 apply auto
   127 apply auto
   128 done
   128 done
   129 
   129 
   150 done
   150 done
   151 
   151 
   152 
   152 
   153 subsection "derived rules"
   153 subsection "derived rules"
   154 
   154 
   155 lemma conseq12: "[| G|-{P'}.c.{Q'}; !Z s. P Z s -->  
   155 lemma conseq12: "[| G|-{P'}.c.{Q'}; !Z s. P Z s -->
   156                          (!s'. (!Z'. P' Z' s --> Q' Z' s') --> Q Z s') |]  
   156                          (!s'. (!Z'. P' Z' s --> Q' Z' s') --> Q Z s') |]
   157        ==> G|-{P}.c.{Q}"
   157        ==> G|-{P}.c.{Q}"
   158 apply (rule hoare_derivs.conseq)
   158 apply (rule hoare_derivs.conseq)
   159 apply blast
   159 apply blast
   160 done
   160 done
   161 
   161 
   167 lemma conseq2: "[| G|-{P}.c.{Q'}; !Z s. Q' Z s --> Q Z s |] ==> G|-{P}.c.{Q}"
   167 lemma conseq2: "[| G|-{P}.c.{Q'}; !Z s. Q' Z s --> Q Z s |] ==> G|-{P}.c.{Q}"
   168 apply (erule conseq12)
   168 apply (erule conseq12)
   169 apply fast
   169 apply fast
   170 done
   170 done
   171 
   171 
   172 lemma Body1: "[| G Un (%p. {P p}.      BODY p  .{Q p})`Procs   
   172 lemma Body1: "[| G Un (%p. {P p}.      BODY p  .{Q p})`Procs
   173           ||- (%p. {P p}. the (body p) .{Q p})`Procs;  
   173           ||- (%p. {P p}. the (body p) .{Q p})`Procs;
   174     pn:Procs |] ==> G|-{P pn}. BODY pn .{Q pn}"
   174     pn:Procs |] ==> G|-{P pn}. BODY pn .{Q pn}"
   175 apply (drule hoare_derivs.Body)
   175 apply (drule hoare_derivs.Body)
   176 apply (erule hoare_derivs.weaken)
   176 apply (erule hoare_derivs.weaken)
   177 apply fast
   177 apply fast
   178 done
   178 done
   179 
   179 
   180 lemma BodyN: "(insert ({P}. BODY pn .{Q}) G) |-{P}. the (body pn) .{Q} ==>  
   180 lemma BodyN: "(insert ({P}. BODY pn .{Q}) G) |-{P}. the (body pn) .{Q} ==>
   181   G|-{P}. BODY pn .{Q}"
   181   G|-{P}. BODY pn .{Q}"
   182 apply (rule Body1)
   182 apply (rule Body1)
   183 apply (rule_tac [2] singletonI)
   183 apply (rule_tac [2] singletonI)
   184 apply clarsimp
   184 apply clarsimp
   185 done
   185 done
   229 
   229 
   230 lemma derivs_insertD: "G||-insert t ts ==> G|-t & G||-ts"
   230 lemma derivs_insertD: "G||-insert t ts ==> G|-t & G||-ts"
   231 apply (fast intro: hoare_derivs.weaken)
   231 apply (fast intro: hoare_derivs.weaken)
   232 done
   232 done
   233 
   233 
   234 lemma finite_pointwise [rule_format (no_asm)]: "[| finite U;  
   234 lemma finite_pointwise [rule_format (no_asm)]: "[| finite U;
   235   !p. G |-     {P' p}.c0 p.{Q' p}       --> G |-     {P p}.c0 p.{Q p} |] ==>  
   235   !p. G |-     {P' p}.c0 p.{Q' p}       --> G |-     {P p}.c0 p.{Q p} |] ==>
   236       G||-(%p. {P' p}.c0 p.{Q' p}) ` U --> G||-(%p. {P p}.c0 p.{Q p}) ` U"
   236       G||-(%p. {P' p}.c0 p.{Q' p}) ` U --> G||-(%p. {P p}.c0 p.{Q p}) ` U"
   237 apply (erule finite_induct)
   237 apply (erule finite_induct)
   238 apply simp
   238 apply simp
   239 apply clarsimp
   239 apply clarsimp
   240 apply (drule derivs_insertD)
   240 apply (drule derivs_insertD)
   243 done
   243 done
   244 
   244 
   245 
   245 
   246 subsection "soundness"
   246 subsection "soundness"
   247 
   247 
   248 lemma Loop_sound_lemma: 
   248 lemma Loop_sound_lemma:
   249  "G|={P &> b}. c .{P} ==>  
   249  "G|={P &> b}. c .{P} ==>
   250   G|={P}. WHILE b DO c .{P &> (Not o b)}"
   250   G|={P}. WHILE b DO c .{P &> (Not o b)}"
   251 apply (unfold hoare_valids_def)
   251 apply (unfold hoare_valids_def)
   252 apply (simp (no_asm_use) add: triple_valid_def2)
   252 apply (simp (no_asm_use) add: triple_valid_def2)
   253 apply (rule allI)
   253 apply (rule allI)
   254 apply (subgoal_tac "!d s s'. <d,s> -n-> s' --> d = WHILE b DO c --> ||=n:G --> (!Z. P Z s --> P Z s' & ~b s') ")
   254 apply (subgoal_tac "!d s s'. <d,s> -n-> s' --> d = WHILE b DO c --> ||=n:G --> (!Z. P Z s --> P Z s' & ~b s') ")
   258 apply (simp_all (no_asm))
   258 apply (simp_all (no_asm))
   259 apply fast
   259 apply fast
   260 apply fast
   260 apply fast
   261 done
   261 done
   262 
   262 
   263 lemma Body_sound_lemma: 
   263 lemma Body_sound_lemma:
   264    "[| G Un (%pn. {P pn}.      BODY pn  .{Q pn})`Procs  
   264    "[| G Un (%pn. {P pn}.      BODY pn  .{Q pn})`Procs
   265          ||=(%pn. {P pn}. the (body pn) .{Q pn})`Procs |] ==>  
   265          ||=(%pn. {P pn}. the (body pn) .{Q pn})`Procs |] ==>
   266         G||=(%pn. {P pn}.      BODY pn  .{Q pn})`Procs"
   266         G||=(%pn. {P pn}.      BODY pn  .{Q pn})`Procs"
   267 apply (unfold hoare_valids_def)
   267 apply (unfold hoare_valids_def)
   268 apply (rule allI)
   268 apply (rule allI)
   269 apply (induct_tac n)
   269 apply (induct_tac n)
   270 apply  (fast intro: Body_triple_valid_0)
   270 apply  (fast intro: Body_triple_valid_0)
   300 section "completeness"
   300 section "completeness"
   301 
   301 
   302 (* Both versions *)
   302 (* Both versions *)
   303 
   303 
   304 (*unused*)
   304 (*unused*)
   305 lemma MGT_alternI: "G|-MGT c ==>  
   305 lemma MGT_alternI: "G|-MGT c ==>
   306   G|-{%Z s0. !s1. <c,s0> -c-> s1 --> Z=s1}. c .{%Z s1. Z=s1}"
   306   G|-{%Z s0. !s1. <c,s0> -c-> s1 --> Z=s1}. c .{%Z s1. Z=s1}"
   307 apply (unfold MGT_def)
   307 apply (unfold MGT_def)
   308 apply (erule conseq12)
   308 apply (erule conseq12)
   309 apply auto
   309 apply auto
   310 done
   310 done
   311 
   311 
   312 (* requires com_det *)
   312 (* requires com_det *)
   313 lemma MGT_alternD: "state_not_singleton ==>  
   313 lemma MGT_alternD: "state_not_singleton ==>
   314   G|-{%Z s0. !s1. <c,s0> -c-> s1 --> Z=s1}. c .{%Z s1. Z=s1} ==> G|-MGT c"
   314   G|-{%Z s0. !s1. <c,s0> -c-> s1 --> Z=s1}. c .{%Z s1. Z=s1} ==> G|-MGT c"
   315 apply (unfold MGT_def)
   315 apply (unfold MGT_def)
   316 apply (erule conseq12)
   316 apply (erule conseq12)
   317 apply auto
   317 apply auto
   318 apply (case_tac "? t. <c,?s> -c-> t")
   318 apply (case_tac "? t. <c,?s> -c-> t")
   320 apply clarsimp
   320 apply clarsimp
   321 apply (drule single_stateE)
   321 apply (drule single_stateE)
   322 apply blast
   322 apply blast
   323 done
   323 done
   324 
   324 
   325 lemma MGF_complete: 
   325 lemma MGF_complete:
   326  "{}|-(MGT c::state triple) ==> {}|={P}.c.{Q} ==> {}|-{P}.c.{Q::state assn}"
   326  "{}|-(MGT c::state triple) ==> {}|={P}.c.{Q} ==> {}|-{P}.c.{Q::state assn}"
   327 apply (unfold MGT_def)
   327 apply (unfold MGT_def)
   328 apply (erule conseq12)
   328 apply (erule conseq12)
   329 apply (clarsimp simp add: hoare_valids_def eval_eq triple_valid_def2)
   329 apply (clarsimp simp add: hoare_valids_def eval_eq triple_valid_def2)
   330 done
   330 done
   331 
   331 
   332 declare WTs_elim_cases [elim!]
   332 declare WTs_elim_cases [elim!]
   333 declare not_None_eq [iff]
   333 declare not_None_eq [iff]
   334 (* requires com_det, escape (i.e. hoare_derivs.conseq) *)
   334 (* requires com_det, escape (i.e. hoare_derivs.conseq) *)
   335 lemma MGF_lemma1 [rule_format (no_asm)]: "state_not_singleton ==>  
   335 lemma MGF_lemma1 [rule_format (no_asm)]: "state_not_singleton ==>
   336   !pn:dom body. G|-{=}.BODY pn.{->} ==> WT c --> G|-{=}.c.{->}"
   336   !pn:dom body. G|-{=}.BODY pn.{->} ==> WT c --> G|-{=}.c.{->}"
   337 apply (induct_tac c)
   337 apply (induct_tac c)
   338 apply        (tactic {* ALLGOALS (clarsimp_tac @{context}) *})
   338 apply        (tactic {* ALLGOALS (clarsimp_tac @{context}) *})
   339 prefer 7 apply        (fast intro: domI)
   339 prefer 7 apply        (fast intro: domI)
   340 apply (erule_tac [6] MGT_alternD)
   340 apply (erule_tac [6] MGT_alternD)
   341 apply       (unfold MGT_def)
   341 apply       (unfold MGT_def)
   342 apply       (drule_tac [7] bspec, erule_tac [7] domI)
   342 apply       (drule_tac [7] bspec, erule_tac [7] domI)
   343 apply       (rule_tac [7] escape, tactic {* clarsimp_tac @{context} 7 *},
   343 apply       (rule_tac [7] escape, tactic {* clarsimp_tac @{context} 7 *},
       
   344   rename_tac [7] "fun" y Z,
   344   rule_tac [7] P1 = "%Z' s. s= (setlocs Z newlocs) [Loc Arg ::= fun Z]" in hoare_derivs.Call [THEN conseq1], erule_tac [7] conseq12)
   345   rule_tac [7] P1 = "%Z' s. s= (setlocs Z newlocs) [Loc Arg ::= fun Z]" in hoare_derivs.Call [THEN conseq1], erule_tac [7] conseq12)
   345 apply        (erule_tac [!] thin_rl)
   346 apply        (erule_tac [!] thin_rl)
   346 apply (rule hoare_derivs.Skip [THEN conseq2])
   347 apply (rule hoare_derivs.Skip [THEN conseq2])
   347 apply (rule_tac [2] hoare_derivs.Ass [THEN conseq1])
   348 apply (rule_tac [2] hoare_derivs.Ass [THEN conseq1])
   348 apply        (rule_tac [3] escape, tactic {* clarsimp_tac @{context} 3 *},
   349 apply        (rule_tac [3] escape, tactic {* clarsimp_tac @{context} 3 *},
       
   350   rename_tac [3] loc "fun" y Z,
   349   rule_tac [3] P1 = "%Z' s. s= (Z[Loc loc::=fun Z])" in hoare_derivs.Local [THEN conseq1],
   351   rule_tac [3] P1 = "%Z' s. s= (Z[Loc loc::=fun Z])" in hoare_derivs.Local [THEN conseq1],
   350   erule_tac [3] conseq12)
   352   erule_tac [3] conseq12)
   351 apply         (erule_tac [5] hoare_derivs.Comp, erule_tac [5] conseq12)
   353 apply         (erule_tac [5] hoare_derivs.Comp, erule_tac [5] conseq12)
   352 apply         (tactic {* (rtac @{thm hoare_derivs.If} THEN_ALL_NEW etac @{thm conseq12}) 6 *})
   354 apply         (tactic {* (rtac @{thm hoare_derivs.If} THEN_ALL_NEW etac @{thm conseq12}) 6 *})
   353 apply          (rule_tac [8] hoare_derivs.Loop [THEN conseq2], erule_tac [8] conseq12)
   355 apply          (rule_tac [8] hoare_derivs.Loop [THEN conseq2], erule_tac [8] conseq12)
   359 lemma nesting_lemma [rule_format]:
   361 lemma nesting_lemma [rule_format]:
   360   assumes "!!G ts. ts <= G ==> P G ts"
   362   assumes "!!G ts. ts <= G ==> P G ts"
   361     and "!!G pn. P (insert (mgt_call pn) G) {mgt(the(body pn))} ==> P G {mgt_call pn}"
   363     and "!!G pn. P (insert (mgt_call pn) G) {mgt(the(body pn))} ==> P G {mgt_call pn}"
   362     and "!!G c. [| wt c; !pn:U. P G {mgt_call pn} |] ==> P G {mgt c}"
   364     and "!!G c. [| wt c; !pn:U. P G {mgt_call pn} |] ==> P G {mgt c}"
   363     and "!!pn. pn : U ==> wt (the (body pn))"
   365     and "!!pn. pn : U ==> wt (the (body pn))"
   364   shows "finite U ==> uG = mgt_call`U ==>  
   366   shows "finite U ==> uG = mgt_call`U ==>
   365   !G. G <= uG --> n <= card uG --> card G = card uG - n --> (!c. wt c --> P G {mgt c})"
   367   !G. G <= uG --> n <= card uG --> card G = card uG - n --> (!c. wt c --> P G {mgt c})"
   366 apply (induct_tac n)
   368 apply (induct_tac n)
   367 apply  (tactic {* ALLGOALS (clarsimp_tac @{context}) *})
   369 apply  (tactic {* ALLGOALS (clarsimp_tac @{context}) *})
   368 apply  (subgoal_tac "G = mgt_call ` U")
   370 apply  (subgoal_tac "G = mgt_call ` U")
   369 prefer 2
   371 prefer 2
   385 apply (drule finite_subset)
   387 apply (drule finite_subset)
   386 apply (erule finite_imageI)
   388 apply (erule finite_imageI)
   387 apply (simp (no_asm_simp))
   389 apply (simp (no_asm_simp))
   388 done
   390 done
   389 
   391 
   390 lemma MGT_BodyN: "insert ({=}.BODY pn.{->}) G|-{=}. the (body pn) .{->} ==>  
   392 lemma MGT_BodyN: "insert ({=}.BODY pn.{->}) G|-{=}. the (body pn) .{->} ==>
   391   G|-{=}.BODY pn.{->}"
   393   G|-{=}.BODY pn.{->}"
   392 apply (unfold MGT_def)
   394 apply (unfold MGT_def)
   393 apply (rule BodyN)
   395 apply (rule BodyN)
   394 apply (erule conseq2)
   396 apply (erule conseq2)
   395 apply force
   397 apply force
   412 
   414 
   413 
   415 
   414 (* Version: simultaneous recursion in call rule *)
   416 (* Version: simultaneous recursion in call rule *)
   415 
   417 
   416 (* finiteness not really necessary here *)
   418 (* finiteness not really necessary here *)
   417 lemma MGT_Body: "[| G Un (%pn. {=}.      BODY pn  .{->})`Procs  
   419 lemma MGT_Body: "[| G Un (%pn. {=}.      BODY pn  .{->})`Procs
   418                           ||-(%pn. {=}. the (body pn) .{->})`Procs;  
   420                           ||-(%pn. {=}. the (body pn) .{->})`Procs;
   419   finite Procs |] ==>   G ||-(%pn. {=}.      BODY pn  .{->})`Procs"
   421   finite Procs |] ==>   G ||-(%pn. {=}.      BODY pn  .{->})`Procs"
   420 apply (unfold MGT_def)
   422 apply (unfold MGT_def)
   421 apply (rule hoare_derivs.Body)
   423 apply (rule hoare_derivs.Body)
   422 apply (erule finite_pointwise)
   424 apply (erule finite_pointwise)
   423 prefer 2 apply (assumption)
   425 prefer 2 apply (assumption)
   425 apply (erule conseq2)
   427 apply (erule conseq2)
   426 apply auto
   428 apply auto
   427 done
   429 done
   428 
   430 
   429 (* requires empty, insert, com_det *)
   431 (* requires empty, insert, com_det *)
   430 lemma MGF_lemma2_simult [rule_format (no_asm)]: "[| state_not_singleton; WT_bodies;  
   432 lemma MGF_lemma2_simult [rule_format (no_asm)]: "[| state_not_singleton; WT_bodies;
   431   F<=(%pn. {=}.the (body pn).{->})`dom body |] ==>  
   433   F<=(%pn. {=}.the (body pn).{->})`dom body |] ==>
   432      (%pn. {=}.     BODY pn .{->})`dom body||-F"
   434      (%pn. {=}.     BODY pn .{->})`dom body||-F"
   433 apply (frule finite_subset)
   435 apply (frule finite_subset)
   434 apply (rule finite_dom_body [THEN finite_imageI])
   436 apply (rule finite_dom_body [THEN finite_imageI])
   435 apply (rotate_tac 2)
   437 apply (rotate_tac 2)
   436 apply (tactic "make_imp_tac 1")
   438 apply (tactic "make_imp_tac 1")
   473 lemma trueI: "G|-{P}.c.{%Z s. True}"
   475 lemma trueI: "G|-{P}.c.{%Z s. True}"
   474 apply (rule hoare_derivs.conseq)
   476 apply (rule hoare_derivs.conseq)
   475 apply (fast intro!: falseE)
   477 apply (fast intro!: falseE)
   476 done
   478 done
   477 
   479 
   478 lemma disj: "[| G|-{P}.c.{Q}; G|-{P'}.c.{Q'} |]  
   480 lemma disj: "[| G|-{P}.c.{Q}; G|-{P'}.c.{Q'} |]
   479         ==> G|-{%Z s. P Z s | P' Z s}.c.{%Z s. Q Z s | Q' Z s}"
   481         ==> G|-{%Z s. P Z s | P' Z s}.c.{%Z s. Q Z s | Q' Z s}"
   480 apply (rule hoare_derivs.conseq)
   482 apply (rule hoare_derivs.conseq)
   481 apply (fast elim: conseq12)
   483 apply (fast elim: conseq12)
   482 done (* analogue conj non-derivable *)
   484 done (* analogue conj non-derivable *)
   483 
   485 
   499 apply (rule hoare_derivs.conseq)
   501 apply (rule hoare_derivs.conseq)
   500 apply auto
   502 apply auto
   501 done
   503 done
   502 
   504 
   503 
   505 
   504 lemma weak_Local: "[| G|-{P}. c .{Q}; !k Z s. Q Z s --> Q Z (s[Loc Y::=k]) |] ==>  
   506 lemma weak_Local: "[| G|-{P}. c .{Q}; !k Z s. Q Z s --> Q Z (s[Loc Y::=k]) |] ==>
   505     G|-{%Z s. P Z (s[Loc Y::=a s])}. LOCAL Y:=a IN c .{Q}"
   507     G|-{%Z s. P Z (s[Loc Y::=a s])}. LOCAL Y:=a IN c .{Q}"
   506 apply (rule export_s)
   508 apply (rule export_s)
   507 apply (rule hoare_derivs.Local)
   509 apply (rule hoare_derivs.Local)
   508 apply (erule conseq2)
   510 apply (erule conseq2)
   509 apply (erule spec)
   511 apply (erule spec)