Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Archive-of-Formal-Proofs/thys/Simpl/   (Sammlung formaler Beweise Version 2026-5©)  Datei vom 29.4.2026 mit Größe 68 kB image not shown  

Quelle  HoarePartial.thy

  Sprache: Isabelle
 

(*
    Author:      Norbert Schirmer
    Maintainer:  Norbert Schirmer, norbert.schirmer at web de

Copyright (C) 2004-2008 Norbert Schirmer
Copyright (c) 2022 Apple Inc. All rights reserved.

*)


section Derived Hoare Rules for Partial Correctness

theory HoarePartial imports HoarePartialProps begin

lemma conseq_no_aux:
  "[Γ,ΘF P' c Q',A';
    s. s P (sP' (Q' Q) (A' A))]
  ==>
  Γ,ΘF P c Q,A"
  by (rule conseq [where P'="λZ. P'" and Q'="λZ. Q'" and A'="λZ. A'"]) auto


lemma conseq_exploit_pre:
             "[s P. Γ,ΘF ({s} P) c Q,A]
              ==>
              Γ,ΘF P c Q,A"
  apply (rule Conseq)
  apply clarify
  apply (rule_tac x="{s} P" in exI)
  apply (rule_tac x="Q" in exI)
  apply (rule_tac x="A" in exI)
  by simp


lemma conseq:"[Z. Γ,ΘF (P' Z) c (Q' Z),(A' Z);
              s. s P ( Z. sP' Z (Q' Z Q) (A' Z A))]
              ==>
              Γ,ΘF P c Q,A"
  by (rule Conseq') blast

lemma Lem: "[Z. Γ,ΘF (P' Z) c (Q' Z),(A' Z);
             P {s. Z. sP' Z (Q' Z Q) (A' Z A)}]
             ==>
             Γ,ΘF P (lem x c) Q,A"
  apply (unfold lem_def)
  apply (erule conseq)
  apply blast
  done

lemma LemAnno:
assumes conseq:  "P {s. Z. sP' Z
                     (t. t Q' Z t Q) (t. t A' Z t A)}"
assumes lem: "Z. Γ,ΘF (P' Z) c (Q' Z),(A' Z)"
shows "Γ,ΘF P (lem x c) Q,A"
  apply (rule Lem [OF lem])
  using conseq
  by blast

lemma LemAnnoNoAbrupt:
assumes conseq:  "P {s. Z. sP' Z (t. t Q' Z t Q)}"
assumes lem: "Z. Γ,ΘF (P' Z) c (Q' Z),{}"
shows "Γ,ΘF P (lem x c) Q,{}"
  apply (rule Lem [OF lem])
  using conseq
  by blast

lemma TrivPost: "Z. Γ,ΘF (P' Z) c (Q' Z),(A' Z)
                 ==>
                 Z. Γ,ΘF (P' Z) c UNIV,UNIV"
apply (rule allI)
apply (erule conseq)
apply auto
done

lemma TrivPostNoAbr: "Z. Γ,ΘF (P' Z) c (Q' Z),{}
                 ==>
                 Z. Γ,ΘF (P' Z) c UNIV,{}"
apply (rule allI)
apply (erule conseq)
apply auto
done

lemma conseq_under_new_pre:"[Γ,ΘF P' c Q',A';
        s P. s P' Q' Q A' A]
\<Longrightarrow> Γ,ΘF P c Q,A"
apply (rule conseq)
apply (rule allI)
apply assumption
apply auto
done

lemma conseq_Kleymann:"[Z. Γ,ΘF (P' Z) c (Q' Z),(A' Z);
              s P. (Z. sP' Z (Q' Z Q) (A' Z A))]
              ==>
              Γ,ΘF P c Q,A"
  by (rule Conseq') blast

lemma DynComConseq:
  assumes "P {s. P' Q' A'. Γ,ΘF P' (c s) Q',A' P P' Q' Q A' A}"
  shows "Γ,ΘF P DynCom c Q,A"
  using assms
  apply -
  apply (rule DynCom)
  apply clarsimp
  apply (rule Conseq)
  apply clarsimp
  apply blast
  done

lemma SpecAnno:
 assumes consequence: "P {s. ( Z. sP' Z (Q' Z Q) (A' Z A))}"
 assumes spec: "Z. Γ,ΘF (P' Z) (c Z) (Q' Z),(A' Z)"
 assumes bdy_constant:  "Z. c Z = c undefined"
 shows   "Γ,ΘF P (specAnno P' c Q' A') Q,A"
proof -
  from spec bdy_constant
  have "Z. Γ,ΘF ((P' Z)) (c undefined) (Q' Z),(A' Z)"
    apply -
    apply (rule allI)
    apply (erule_tac x=Z in allE)
    apply (erule_tac x=Z in allE)
    apply simp
    done
  with consequence show ?thesis
    apply (simp add: specAnno_def)
    apply (erule conseq)
    apply blast
    done
qed

lemma SpecAnno':
 "[P {s. Z. sP' Z
            (t. t Q' Z t Q) (t. t A' Z t A)};
   Z. Γ,ΘF (P' Z) (c Z) (Q' Z),(A' Z);
   Z. c Z = c undefined
  ] ==>
    Γ,ΘF P (specAnno P' c Q' A') Q,A"
apply (simp only: subset_iff [THEN sym])
apply (erule (1) SpecAnno)
apply assumption
done


lemma SpecAnnoNoAbrupt:
 "[P {s. Z. sP' Z
            (t. t Q' Z t Q)};
   Z. Γ,ΘF (P' Z) (c Z) (Q' Z),{};
   Z. c Z = c undefined
  ] ==>
    Γ,ΘF P (specAnno P' c Q' (λs. {})) Q,A"
apply (rule SpecAnno')
apply auto
done

lemma Skip: "P Q ==> Γ,ΘF P Skip Q,A"
  by (rule hoarep.Skip [THEN conseqPre],simp)

lemma Basic: "P {s. (f s) Q} ==> Γ,ΘF P (Basic f) Q,A"
  by (rule hoarep.Basic [THEN conseqPre])

lemma BasicCond:
  "[P {s. (b s f sQ) (¬ b s g sQ)}] ==>
   Γ,ΘF P Basic (λs. if b s then f s else g s) Q,A"
  apply (rule Basic)
  apply auto
  done

lemma Spec: "P {s. (t. (s,t) r t Q) (t. (s,t) r)}
            ==> Γ,ΘF P (Spec r) Q,A"
by (rule hoarep.Spec [THEN conseqPre])

lemma SpecIf:
  "[P {s. (b s f s Q) (¬ b s g s Q h s Q)}] ==>
   Γ,ΘF P Spec (if_rel b f g h) Q,A"
  apply (rule Spec)
  apply (auto simp add: if_rel_def)
  done


lemma Seq [trans, intro?]:
  "[Γ,ΘF P c1 R,A; Γ,ΘF R c2 Q,A] ==> Γ,ΘF P (Seq c1 c2) Q,A"
  by (rule hoarep.Seq)

lemma SeqSame:
  "[Γ,ΘF P c1 Q,A; Γ,ΘF Q c2 Q,A] ==> Γ,ΘF P (Seq c1 c2) Q,A"
  by (rule hoarep.Seq)


lemma SeqSwap:
  "[Γ,ΘF R c2 Q,A; Γ,ΘF P c1 R,A] ==> Γ,ΘF P (Seq c1 c2) Q,A"
  by (rule Seq)

lemma BSeq:
  "[Γ,ΘF P c1 R,A; Γ,ΘF R c2 Q,A] ==> Γ,ΘF P (bseq c1 c2) Q,A"
  by (unfold bseq_def) (rule Seq)

lemma BSeqSame:
  "[Γ,ΘF P c1 Q,A; Γ,ΘF Q c2 Q,A] ==> Γ,ΘF P (bseq c1 c2) Q,A"
  by (rule BSeq)

lemma Cond:
  assumes wp: "P {s. (sb sP1) (sb sP2)}"
  assumes deriv_c1: "Γ,ΘF P1 c1 Q,A"
  assumes deriv_c2: "Γ,ΘF P2 c2 Q,A"
  shows "Γ,ΘF P (Cond b c1 c2) Q,A"
proof (rule hoarep.Cond [THEN conseqPre])
  from deriv_c1
  show "Γ,ΘF ({s. (s b s P1) (s b s P2)} b) c1 Q,A"
    by (rule conseqPre) blast
next
  from deriv_c2
  show "Γ,ΘF ({s. (s b s P1) (s b s P2)} - b) c2 Q,A"
    by (rule conseqPre) blast
next
  show "P {s. (sb sP1) (sb sP2)}" by (rule wp)
qed


lemma CondSwap:
  "[Γ,ΘF P1 c1 Q,A; Γ,ΘF P2 c2 Q,A; P {s. (sb sP1) (sb sP2)}]
   ==>
   Γ,ΘF P (Cond b c1 c2) Q,A"
  by (rule Cond)

lemma Cond':
  "[P {s. (b P1) (- b P2)};Γ,ΘF P1 c1 Q,A; Γ,ΘF P2 c2 Q,A]
   ==>
   Γ,ΘF P (Cond b c1 c2) Q,A"
  by (rule CondSwap) blast+

lemma CondInv:
  assumes wp: "P Q"
  assumes inv: "Q {s. (sb sP1) (sb sP2)}"
  assumes deriv_c1: "Γ,ΘF P1 c1 Q,A"
  assumes deriv_c2: "Γ,ΘF P2 c2 Q,A"
  shows "Γ,ΘF P (Cond b c1 c2) Q,A"
proof -
  from wp inv
  have "P {s. (sb sP1) (sb sP2)}"
    by blast
  from Cond [OF this deriv_c1 deriv_c2]
  show ?thesis .
qed

lemma CondInv':
  assumes wp: "P I"
  assumes inv: "I {s. (sb sP1) (sb sP2)}"
  assumes wp': "I Q"
  assumes deriv_c1: "Γ,ΘF P1 c1 I,A"
  assumes deriv_c2: "Γ,ΘF P2 c2 I,A"
  shows "Γ,ΘF P (Cond b c1 c2) Q,A"
proof -
  from CondInv [OF wp inv deriv_c1 deriv_c2]
  have "Γ,ΘF P (Cond b c1 c2) I,A".
  from conseqPost [OF this wp' subset_refl]
  show ?thesis .
qed


lemma switchNil:
  "P Q ==> Γ,ΘF P (switch v []) Q,A"
  by (simp add: Skip)

lemma switchCons:
  "[P {s. (v s V s P1) (v s V s P2)};
        Γ,ΘF P1 c Q,A;
        Γ,ΘF P2 (switch v vs) Q,A]
\<Longrightarrow> Γ,ΘF P (switch v ((V,c)#vs)) Q,A"
  by (simp add: Cond)

lemma Guard:
 "[P g R; Γ,ΘF R c Q,A]
  ==> Γ,ΘF P (Guard f g c) Q,A"
apply (rule Guard [THEN conseqPre, of _ _ _ _ R])
apply (erule conseqPre)
apply auto
done

lemma GuardSwap:
 "[ Γ,ΘF R c Q,A; P g R]
  ==> Γ,ΘF P (Guard f g c) Q,A"
  by (rule Guard)

lemma Guarantee:
 "[P {s. s g s R}; Γ,ΘF R c Q,A; f F]
  ==> Γ,ΘF P (Guard f g c) Q,A"
apply (rule Guarantee [THEN conseqPre, of _ _ _ _ _ "{s. s g s R}"])
apply   assumption
apply  (erule conseqPre)
apply auto
done

lemma GuaranteeSwap:
 "[ Γ,ΘF R c Q,A; P {s. s g s R}; f F]
  ==> Γ,ΘF P (Guard f g c) Q,A"
  by (rule Guarantee)

lemma GuardStrip:
 "[P R; Γ,ΘF R c Q,A; f F]
  ==> Γ,ΘF P (Guard f g c) Q,A"
apply (rule Guarantee [THEN conseqPre])
apply auto
done

lemma GuardStripSame:
 "[Γ,ΘF P c Q,A; f F]
  ==> Γ,ΘF P (Guard f g c) Q,A"
  by (rule GuardStrip [OF subset_refl])

lemma GuardStripSwap:
 "[Γ,ΘF R c Q,A; P R; f F]
  ==> Γ,ΘF P (Guard f g c) Q,A"
  by (rule GuardStrip)

lemma GuaranteeStrip:
 "[P R; Γ,ΘF R c Q,A; f F]
  ==> Γ,ΘF P (guaranteeStrip f g c) Q,A"
  by (unfold guaranteeStrip_def) (rule GuardStrip)

lemma GuaranteeStripSwap:
 "[Γ,ΘF R c Q,A; P R; f F]
  ==> Γ,ΘF P (guaranteeStrip f g c) Q,A"
  by (unfold guaranteeStrip_def) (rule GuardStrip)

lemma GuaranteeAsGuard:
 "[P g R; Γ,ΘF R c Q,A]
  ==> Γ,ΘF P (guaranteeStrip f g c) Q,A"
  by (unfold guaranteeStrip_def) (rule Guard)


lemma GuaranteeAsGuardSwap:
 "[ Γ,ΘF R c Q,A; P g R]
  ==> Γ,ΘF P (guaranteeStrip f g c) Q,A"
  by (rule GuaranteeAsGuard)

lemma GuardsNil:
  "Γ,ΘF P c Q,A ==>
   Γ,ΘF P (guards [] c) Q,A"
  by simp

lemma GuardsCons:
  "Γ,ΘF P Guard f g (guards gs c) Q,A ==>
   Γ,ΘF P (guards ((f,g)#gs) c) Q,A"
  by simp

lemma GuardsConsGuaranteeStrip:
  "Γ,ΘF P guaranteeStrip f g (guards gs c) Q,A ==>
   Γ,ΘF P (guards (guaranteeStripPair f g#gs) c) Q,A"
  by (simp add: guaranteeStripPair_def guaranteeStrip_def)

lemma While:
  assumes P_I: "P I"
  assumes deriv_body: "Γ,ΘF (I b) c I,A"
  assumes I_Q: "I -b Q"
  shows "Γ,ΘF P (whileAnno b I V c) Q,A"
proof -
  from deriv_body P_I I_Q
  show ?thesis
    apply (simp add: whileAnno_def)
    apply (erule conseqPrePost [OF HoarePartialDef.While])
    apply simp_all
    done
qed

text @{term "J"} will be instantiated by tactic with @{term "gs' I"} for
 those guards that are not stripped.

lemma  WhileAnnoG:
  "Γ,ΘF P (guards gs
                    (whileAnno b J V (Seq c (guards gs Skip)))) Q,A
        ==>
        Γ,ΘF P (whileAnnoG gs b I V c) Q,A"
  by (simp add: whileAnnoG_def whileAnno_def while_def)


text This form stems from @{term "strip_guards F (whileAnnoG gs b I V c)"}

lemma WhileNoGuard':
  assumes P_I: "P I"
  assumes deriv_body: "Γ,ΘF (I b) c I,A"
  assumes I_Q: "I -b Q"
  shows "Γ,ΘF P (whileAnno b I V (Seq c Skip)) Q,A"
  apply (rule While [OF P_I _ I_Q])
  apply (rule Seq)
  apply  (rule deriv_body)
  apply (rule hoarep.Skip)
  done

lemma WhileAnnoFix:
assumes consequence: "P {s. ( Z. sI Z (I Z -b Q)) }"
assumes bdy: "Z. Γ,ΘF (I Z b) (c Z) (I Z),A"
assumes bdy_constant:  "Z. c Z = c undefined"
shows "Γ,ΘF P (whileAnnoFix b I V c) Q,A"
proof -
  from bdy bdy_constant
  have bdy': "Z. Γ,ΘF (I Z b) (c undefined) (I Z),A"
    apply -
    apply (rule allI)
    apply (erule_tac x=Z in allE)
    apply (erule_tac x=Z in allE)
    apply simp
    done
  have "Z. Γ,ΘF (I Z) (whileAnnoFix b I V c) (I Z -b),A"
    apply rule
    apply (unfold whileAnnoFix_def)
    apply (rule hoarep.While)
    apply (rule bdy' [rule_format])
    done
  then
  show ?thesis
    apply (rule conseq)
    using consequence
    by blast
qed

lemma WhileAnnoFix':
assumes consequence: "P {s. ( Z. sI Z
                               (t. t I Z -b t Q)) }"
assumes bdy: "Z. Γ,ΘF (I Z b) (c Z) (I Z),A"
assumes bdy_constant:  "Z. c Z = c undefined"
shows "Γ,ΘF P (whileAnnoFix b I V c) Q,A"
  apply (rule WhileAnnoFix [OF _ bdy bdy_constant])
  using consequence by blast

lemma WhileAnnoGFix:
assumes whileAnnoFix:
  "Γ,ΘF P (guards gs
                (whileAnnoFix b J V (λZ. (Seq (c Z) (guards gs Skip))))) Q,A"
shows "Γ,ΘF P (whileAnnoGFix gs b I V c) Q,A"
  using whileAnnoFix
  by (simp add: whileAnnoGFix_def whileAnnoFix_def while_def)

lemma Bind:
  assumes adapt: "P {s. s P' s}"
  assumes c: "s. Γ,ΘF (P' s) (c (e s)) Q,A"
  shows "Γ,ΘF P (bind e c) Q,A"
apply (rule conseq [where P'="λZ. {s. s=Z s P' Z}" and Q'="λZ. Q" and
A'="λZ. A"])
apply  (rule allI)
apply  (unfold bind_def)
apply  (rule DynCom)
apply  (rule ballI)
apply  simp
apply  (rule conseqPre)
apply   (rule c [rule_format])
apply  blast
using adapt
apply blast
done

lemma Block_exn:
assumes adapt: "P {s. init s P' s}"
assumes bdy: "s. Γ,ΘF (P' s) bdy {t. return s t R s t},{t. result_exn (return s t) t A}"
assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
shows "Γ,ΘF P (block_exn init bdy return result_exn c) Q,A"
apply (rule conseq [where P'="λZ. {s. s=Z init s P' Z}" and Q'="λZ. Q" and
A'="λZ. A"])
prefer 2
using adapt
apply  blast
apply (rule allI)
apply (unfold block_exn_def)
apply (rule DynCom)
apply (rule ballI)
apply clarsimp
apply (rule_tac R="{t. return Z t R Z t}" in SeqSwap )
apply  (rule_tac  P'="λZ'. {t. t=Z' return Z t R Z t}" and
          Q'="λZ'. Q" and A'="λZ'. A" in conseq)
prefer 2 apply simp
apply  (rule allI)
apply  (rule DynCom)
apply  (clarsimp)
apply  (rule SeqSwap)
apply   (rule c [rule_format])
apply  (rule Basic)
apply  clarsimp
apply (rule_tac R="{t. result_exn (return Z t) t A}" in Catch)
apply  (rule_tac R="{i. i P' Z}" in Seq)
apply   (rule Basic)
apply   clarsimp
apply  simp
apply  (rule bdy [rule_format])
apply (rule SeqSwap)
apply  (rule Throw)
apply (rule Basic)
apply simp
done

lemma Block:
assumes adapt: "P {s. init s P' s}"
assumes bdy: "s. Γ,ΘF (P' s) bdy {t. return s t R s t},{t. return s t A}"
assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
shows "Γ,ΘF P (block init bdy return c) Q,A"
  unfolding block_def
  by (rule Block_exn [OF adapt bdy c])


lemma BlockSwap:
assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
assumes bdy: "s. Γ,ΘF (P' s) bdy {t. return s t R s t},{t. return s t A}"
assumes adapt: "P {s. init s P' s}"
shows "Γ,ΘF P (block init bdy return c) Q,A"
using adapt bdy c
  by (rule Block)


lemma Block_exnSpec:
  assumes adapt: "P {s. Z. init s P' Z
                             (t. t Q' Z return s t R s t)
                             (t. t A' Z (result_exn (return s t) t) A)}"
  assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
  assumes bdy: "Z. Γ,ΘF (P' Z) bdy (Q' Z),(A' Z)"
  shows "Γ,ΘF P (block_exn init bdy return result_exn c) Q,A"
apply (rule conseq [where P'="λZ. {s. init s P' Z
                             (t. t Q' Z return s t R s t)
                             (t. t A' Z (result_exn (return s t) t) A)}" and Q'="λZ. Q" and
A'="λZ. A"])
prefer 2
using adapt
apply  blast
apply (rule allI)
apply (unfold block_exn_def)
apply (rule DynCom)
apply (rule ballI)
apply clarsimp
apply (rule_tac R="{t. return s t R s t}" in SeqSwap )
apply  (rule_tac  P'="λZ'. {t. t=Z' return s t R s t}" and
          Q'="λZ'. Q" and A'="λZ'. A" in conseq)
prefer 2 apply simp
apply  (rule allI)
apply  (rule DynCom)
apply  (clarsimp)
apply  (rule SeqSwap)
apply   (rule c [rule_format])
apply  (rule Basic)
apply  clarsimp
apply (rule_tac R="{t. (result_exn (return s t) t) A}" in Catch)
apply  (rule_tac R="{i. i P' Z}" in Seq)
apply   (rule Basic)
apply   clarsimp
apply  simp
apply  (rule conseq [OF bdy])
apply  clarsimp
apply  blast
apply (rule SeqSwap)
apply  (rule Throw)
apply (rule Basic)
apply simp
  done

lemma BlockSpec:
  assumes adapt: "P {s. Z. init s P' Z
                             (t. t Q' Z return s t R s t)
                             (t. t A' Z return s t A)}"
  assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
  assumes bdy: "Z. Γ,ΘF (P' Z) bdy (Q' Z),(A' Z)"
  shows "Γ,ΘF P (block init bdy return c) Q,A"
  unfolding block_def
  by (rule Block_exnSpec [OF adapt c bdy])


lemma Throw: "P A ==> Γ,ΘF P Throw Q,A"
  by (rule hoarep.Throw [THEN conseqPre])

lemmas Catch = hoarep.Catch
lemma CatchSwap: "[Γ,ΘF R c2 Q,A; Γ,ΘF P c1 Q,R] ==> Γ,ΘF P Catch c1 c2 Q,A"
  by (rule hoarep.Catch)

lemma CatchSame: "[Γ,ΘF P c1 Q,A; Γ,ΘF A c2 Q,A] ==> Γ,ΘF P Catch c1 c2 Q,A"
  by (rule hoarep.Catch)

lemma raise: "P {s. f s A} ==> Γ,ΘF P raise f Q,A"
  apply (simp add: raise_def)
  apply (rule Seq)
  apply  (rule Basic)
  apply  (assumption)
  apply (rule Throw)
  apply (rule subset_refl)
  done

lemma condCatch: "[Γ,ΘF P c1 Q,((b R) (-b A));Γ,ΘF R c2 Q,A]
                  ==> Γ,ΘFP condCatch c1 b c2 Q,A"
  apply (simp add: condCatch_def)
  apply (rule Catch)
  apply  assumption
  apply (rule CondSwap)
  apply   (assumption)
  apply  (rule hoarep.Throw)
  apply blast
  done

lemma condCatchSwap: "[Γ,ΘF R c2 Q,A;Γ,ΘF P c1 Q,((b R) (-b A))]
                  ==> Γ,ΘFP condCatch c1 b c2 Q,A"
  by (rule condCatch)

lemma condCatchSame:
  assumes c1: "Γ,ΘF P c1 Q,A"
  assumes c2: "Γ,ΘF A c2 Q,A"
  shows "Γ,ΘFP condCatch c1 b c2 Q,A"
proof -
  have eq: "((b A) (-b A)) = A" by blast
  show ?thesis
    apply (rule condCatch [OF _ c2])
    apply (simp add: eq)
    apply (rule c1)
    done
qed

lemma ProcSpec:
  assumes adapt: "P {s. Z. init s P' Z
                             (t. t Q' Z return s t R s t)
                             (t. t A' Z return s t A)}"
  assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
  assumes p: "Z. Γ,ΘF (P' Z) Call p (Q' Z),(A' Z)"
  shows "Γ,ΘF P (call init p return c) Q,A"
using adapt c p
apply (unfold call_def)
by (rule BlockSpec)

lemma Proc_exnSpec:
  assumes adapt: "P {s. Z. init s P' Z
                             (t. t Q' Z return s t R s t)
                             (t. t A' Z result_exn (return s t) t A)}"
  assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
  assumes p: "Z. Γ,ΘF (P' Z) Call p (Q' Z),(A' Z)"
  shows "Γ,ΘF P (call_exn init p return result_exn c) Q,A"
using adapt c p
apply (unfold call_exn_def)
  by (rule Block_exnSpec)

lemma ProcSpec':
  assumes adapt: "P {s. Z. init s P' Z
                             (t Q' Z. return s t R s t)
                             (t A' Z. return s t A)}"
  assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
  assumes p: "Z. Γ,ΘF (P' Z) Call p (Q' Z),(A' Z)"
  shows "Γ,ΘF P (call init p return c) Q,A"
apply (rule ProcSpec [OF _ c p])
apply (insert adapt)
apply clarsimp
apply (drule (1) subsetD)
apply (clarsimp)
apply (rule_tac x=Z in exI)
apply blast
done

lemma Proc_exnSpecNoAbrupt:
  assumes adapt: "P {s. Z. init s P' Z
                             (t. t Q' Z return s t R s t)}"
  assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
  assumes p: "Z. Γ,ΘF (P' Z) Call p (Q' Z),{}"
  shows "Γ,ΘF P (call_exn init p return result_exn c) Q,A"
apply (rule Proc_exnSpec [OF _ c p])
using adapt
apply simp
  done

lemma ProcSpecNoAbrupt:
  assumes adapt: "P {s. Z. init s P' Z
                             (t. t Q' Z return s t R s t)}"
  assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
  assumes p: "Z. Γ,ΘF (P' Z) Call p (Q' Z),{}"
  shows "Γ,ΘF P (call init p return c) Q,A"
apply (rule ProcSpec [OF _ c p])
using adapt
apply simp
done

lemma FCall:
"Γ,ΘF P (call init p return (λs t. c (result t))) Q,A
\<Longrightarrow> Γ,ΘF P (fcall init p return result c) Q,A"
  by (simp add: fcall_def)


lemma ProcRec:
  assumes deriv_bodies:
   "pProcs.
    Z. Γ,Θ(pProcs. Z. {(P p Z,p,Q p Z,A p Z)})
        F (P p Z) (the (Γ p)) (Q p Z),(A p Z)"
  assumes Procs_defined: "Procs dom Γ"
  shows "pProcs. Z. Γ,ΘF(P p Z) Call p (Q p Z),(A p Z)"
  by (intro strip)
     (rule CallRec'
     [OF _   Procs_defined deriv_bodies],
     simp_all)

lemma ProcRec':
  assumes ctxt: "Θ' = Θ(pProcs. Z. {(P p Z,p,Q p Z,A p Z)})"
  assumes deriv_bodies:
   "pProcs. Z. Γ,Θ'F (P p Z) (the (Γ p)) (Q p Z),(A p Z)"
  assumes Procs_defined: "Procs dom Γ"
  shows "pProcs. Z. Γ,ΘF(P p Z) Call p (Q p Z),(A p Z)"
  using ctxt deriv_bodies
  apply simp
  apply (erule ProcRec [OF _ Procs_defined])
  done


lemma ProcRecList:
  assumes deriv_bodies:
   "pset Procs.
    Z. Γ,Θ(pset Procs. Z. {(P p Z,p,Q p Z,A p Z)})
        F (P p Z) (the (Γ p)) (Q p Z),(A p Z)"
  assumes dist: "distinct Procs"
  assumes Procs_defined: "set Procs dom Γ"
  shows "pset Procs. Z. Γ,ΘF(P p Z) Call p (Q p Z),(A p Z)"
  using deriv_bodies Procs_defined
  by (rule ProcRec)

lemma  ProcRecSpecs:
  "[(P,p,Q,A) Specs. Γ,ΘSpecsF P (the (Γ p)) Q,A;
    (P,p,Q,A) Specs. p dom Γ]
  ==> (P,p,Q,A) Specs. Γ,ΘF P (Call p) Q,A"
apply (auto intro: CallRec)
done


lemma ProcRec1:
  assumes deriv_body:
   "Z. Γ,Θ(Z. {(P Z,p,Q Z,A Z)})F (P Z) (the (Γ p)) (Q Z),(A Z)"
  assumes p_defined: "p dom Γ"
  shows "Z. Γ,ΘF (P Z) Call p (Q Z),(A Z)"
proof -
  from deriv_body p_defined
  have "p{p}. Z. Γ,ΘF (P Z) Call p (Q Z),(A Z)"
    by - (rule ProcRec [where A="λp. A" and P="λp. P" and Q="λp. Q"],
          simp_all)
  thus ?thesis
    by simp
qed

lemma ProcNoRec1:
  assumes deriv_body:
   "Z. Γ,ΘF (P Z) (the (Γ p)) (Q Z),(A Z)"
  assumes p_def: "p dom Γ"
  shows "Z. Γ,ΘF (P Z) Call p (Q Z),(A Z)"
proof -
from deriv_body
  have "Z. Γ,Θ(Z. {(P Z,p,Q Z,A Z)})
             F (P Z) (the (Γ p)) (Q Z),(A Z)"
    by (blast intro: hoare_augment_context)
  from this p_def
  show ?thesis
    by (rule ProcRec1)
qed

lemma ProcBody:
 assumes WP: "P P'"
 assumes deriv_body: "Γ,ΘF P' body Q,A"
 assumes body: "Γ p = Some body"
 shows "Γ,ΘF P Call p Q,A"
apply (rule conseqPre [OF _ WP])
apply (rule ProcNoRec1 [rule_format, where P="λZ. P'" and Q="λZ. Q" and A="λZ. A"])
apply  (insert body)
apply  simp
apply  (rule hoare_augment_context [OF deriv_body])
apply  blast
apply fastforce
done

lemma CallBody:
assumes adapt: "P {s. init s P' s}"
assumes bdy: "s. Γ,ΘF (P' s) body {t. return s t R s t},{t. return s t A}"
assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
assumes body: "Γ p = Some body"
shows "Γ,ΘF P (call init p return c) Q,A"
apply (unfold call_def)
apply (rule Block [OF adapt _ c])
apply (rule allI)
apply (rule ProcBody [where Γ=Γ, OF _ bdy [rule_format] body])
apply simp
done

lemma Call_exnBody:
assumes adapt: "P {s. init s P' s}"
assumes bdy: "s. Γ,ΘF (P' s) body {t. return s t R s t},{t. result_exn (return s t) t A}"
assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
assumes body: "Γ p = Some body"
shows "Γ,ΘF P (call_exn init p return result_exn c) Q,A"
apply (unfold call_exn_def)
apply (rule Block_exn [OF adapt _ c])
apply (rule allI)
apply (rule ProcBody [where Γ=Γ, OF _ bdy [rule_format] body])
apply simp
done

lemmas ProcModifyReturn = HoarePartialProps.ProcModifyReturn
lemmas ProcModifyReturnSameFaults = HoarePartialProps.ProcModifyReturnSameFaults
lemmas Proc_exnModifyReturn = HoarePartialProps.Proc_exnModifyReturn
lemmas Proc_exnModifyReturnSameFaults = HoarePartialProps.Proc_exnModifyReturnSameFaults

lemma Proc_exnModifyReturnNoAbr:
  assumes spec: "Γ,ΘF P (call_exn init p return' result_exn c) Q,A"
  assumes result_conform:
      "s t. t Modif (init s) (return' s t) = (return s t)"
  assumes modifies_spec:
  "σ. Γ,ΘUNIV {σ} Call p (Modif σ),{}"
  shows "Γ,ΘF P (call_exn init p return result_exn c) Q,A"
  by (rule Proc_exnModifyReturn [OF spec result_conform _ modifies_spec]) simp

lemma ProcModifyReturnNoAbr:
  assumes spec: "Γ,ΘF P (call init p return' c) Q,A"
  assumes result_conform:
      "s t. t Modif (init s) (return' s t) = (return s t)"
  assumes modifies_spec:
  "σ. Γ,ΘUNIV {σ} Call p (Modif σ),{}"
  shows "Γ,ΘF P (call init p return c) Q,A"
by (rule ProcModifyReturn [OF spec result_conform _ modifies_spec]) simp

lemma Proc_exnModifyReturnNoAbrSameFaults:
  assumes spec: "Γ,ΘF P (call_exn init p return' result_exn c) Q,A"
  assumes result_conform:
      "s t. t Modif (init s) (return' s t) = (return s t)"
  assumes modifies_spec:
  "σ. Γ,ΘF {σ} Call p (Modif σ),{}"
  shows "Γ,ΘF P (call_exn init p return result_exn c) Q,A"
  by (rule Proc_exnModifyReturnSameFaults [OF spec result_conform _ modifies_spec]) simp

lemma ProcModifyReturnNoAbrSameFaults:
  assumes spec: "Γ,ΘF P (call init p return' c) Q,A"
  assumes result_conform:
      "s t. t Modif (init s) (return' s t) = (return s t)"
  assumes modifies_spec:
  "σ. Γ,ΘF {σ} Call p (Modif σ),{}"
  shows "Γ,ΘF P (call init p return c) Q,A"
by (rule ProcModifyReturnSameFaults [OF spec result_conform _ modifies_spec]) simp

lemma DynProc_exn:
  assumes adapt: "P {s. Z. init s P' s Z
                          (t. t Q' s Z return s t R s t)
                          (t. t A' s Z result_exn (return s t) t A)}"
  assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
  assumes p: "s P. Z. Γ,ΘF (P' s Z) Call (p s) (Q' s Z),(A' s Z)"
  shows "Γ,ΘF P dynCall_exn f UNIV init p return result_exn c Q,A"
apply (rule conseq [where P'="λZ. {s. s=Z s P}"
  and Q'="λZ. Q" and A'="λZ. A"])
prefer 2
using adapt
apply  blast
apply (rule allI)
apply (unfold dynCall_exn_def call_exn_def maybe_guard_UNIV block_exn_def guards.simps)
apply (rule DynCom)
apply clarsimp
apply (rule DynCom)
apply clarsimp
apply (frule in_mono [rule_format, OF adapt])
apply clarsimp
apply (rename_tac Z')
apply (rule_tac R="Q' Z Z'" in Seq)
apply  (rule CatchSwap)
apply   (rule SeqSwap)
apply    (rule Throw)
apply    (rule subset_refl)
apply   (rule Basic)
apply   (rule subset_refl)
apply  (rule_tac R="{i. i P' Z Z'}" in Seq)
apply   (rule Basic)
apply   clarsimp
apply  simp
apply  (rule_tac Q'="Q' Z Z'" and A'="A' Z Z'" in conseqPost)
using p
apply    clarsimp
apply   simp
apply  clarsimp
apply  (rule_tac  P'="λZ''. {t. t=Z'' return Z t R Z t}" and
          Q'="λZ''. Q" and A'="λZ''. A" in conseq)
prefer 2 apply simp
apply (rule allI)
apply (rule DynCom)
apply clarsimp
apply (rule SeqSwap)
apply  (rule c [rule_format])
apply (rule Basic)
apply clarsimp
  done

lemma DynProc_exn_guards_cons:
  assumes p: "Γ,ΘF P dynCall_exn f UNIV init p return result_exn c Q,A"
  shows "Γ,ΘF (g P) dynCall_exn f g init p return result_exn c Q,A"
  using p apply (clarsimp simp add: dynCall_exn_def maybe_guard_def)
  apply (rule Guard)
   apply (rule subset_refl)
  apply assumption
  done

lemma DynProc:
  assumes adapt: "P {s. Z. init s P' s Z
                          (t. t Q' s Z return s t R s t)
                          (t. t A' s Z return s t A)}"
  assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
  assumes p: "s P. Z. Γ,ΘF (P' s Z) Call (p s) (Q' s Z),(A' s Z)"
  shows "Γ,ΘF P dynCall init p return c Q,A"
  using adapt c p unfolding dynCall_dynCall_exn by (rule DynProc_exn)

lemma DynProc_exn':
  assumes adapt: "P {s. Z. init s P' s Z
                          (t Q' s Z. return s t R s t)
                          (t A' s Z. result_exn (return s t) t A)}"
  assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
  assumes p: "s P. Z. Γ,ΘF (P' s Z) Call (p s) (Q' s Z),(A' s Z)"
  shows "Γ,ΘF P dynCall_exn f UNIV init p return result_exn c Q,A"
proof -
  from adapt have "P {s. Z. init s P' s Z
                          (t. t Q' s Z return s t R s t)
                          (t. t A' s Z result_exn (return s t) t A)}"
    by blast
  from this c p show ?thesis
    by (rule DynProc_exn)
qed

lemma DynProc':
  assumes adapt: "P {s. Z. init s P' s Z
                          (t Q' s Z. return s t R s t)
                          (t A' s Z. return s t A)}"
  assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
  assumes p: "s P. Z. Γ,ΘF (P' s Z) Call (p s) (Q' s Z),(A' s Z)"
  shows "Γ,ΘF P dynCall init p return c Q,A"
  using adapt c p unfolding dynCall_dynCall_exn by (rule DynProc_exn')

lemma DynProc_exnStaticSpec:
assumes adapt: "P {s. s S (Z. init s P' Z
                            (τ. τ Q' Z return s τ R s τ)
                            (τ. τ A' Z result_exn (return s τ) τ A))}"
assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
assumes spec: "sS. Z. Γ,ΘF (P' Z) Call (p s) (Q' Z),(A' Z)"
shows "Γ,ΘF P (dynCall_exn f UNIV init p return result_exn c) Q,A"
proof -
  from adapt have P_S: "P S"
    by blast
  have "Γ,ΘF (P S) (dynCall_exn f UNIV init p return result_exn c) Q,A"
    apply (rule DynProc_exn [where P'="λs Z. P' Z" and Q'="λs Z. Q' Z"
                         and A'="λs Z. A' Z", OF _ c])
    apply  clarsimp
    apply  (frule in_mono [rule_format, OF adapt])
    apply  clarsimp
    using spec
    apply clarsimp
    done
  thus ?thesis
    by (rule conseqPre) (insert P_S,blast)
qed

lemma DynProcStaticSpec:
assumes adapt: "P {s. s S (Z. init s P' Z
                            (τ. τ Q' Z return s τ R s τ)
                            (τ. τ A' Z return s τ A))}"
assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
assumes spec: "sS. Z. Γ,ΘF (P' Z) Call (p s) (Q' Z),(A' Z)"
shows "Γ,ΘF P (dynCall init p return c) Q,A"
  using adapt c spec unfolding dynCall_dynCall_exn by (rule DynProc_exnStaticSpec)

lemma DynProc_exnProcPar:
assumes adapt: "P {s. p s = q (Z. init s P' Z
                            (τ. τ Q' Z return s τ R s τ)
                            (τ. τ A' Z result_exn (return s τ) τ A))}"
assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
assumes spec: "Z. Γ,ΘF (P' Z) Call q (Q' Z),(A' Z)"
shows "Γ,ΘF P (dynCall_exn f UNIV init p return result_exn c) Q,A"
  apply (rule DynProc_exnStaticSpec [where S="{s. p s = q}",simplified, OF adapt c])
  using spec
  apply simp
  done

lemma DynProcProcPar:
assumes adapt: "P {s. p s = q (Z. init s P' Z
                            (τ. τ Q' Z return s τ R s τ)
                            (τ. τ A' Z return s τ A))}"
assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
assumes spec: "Z. Γ,ΘF (P' Z) Call q (Q' Z),(A' Z)"
shows "Γ,ΘF P (dynCall init p return c) Q,A"
  apply (rule DynProcStaticSpec [where S="{s. p s = q}",simplified, OF adapt c])
  using spec
  apply simp
  done

lemma DynProc_exnProcParNoAbrupt:
assumes adapt: "P {s. p s = q (Z. init s P' Z
                            (τ. τ Q' Z return s τ R s τ))}"
assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
assumes spec: "Z. Γ,ΘF (P' Z) Call q (Q' Z),{}"
shows "Γ,ΘF P (dynCall_exn f UNIV init p return result_exn c) Q,A"
proof -
  have "P {s. p s = q ( Z. init s P' Z
                      (t. t Q' Z return s t R s t)
                      (t. t {} result_exn (return s t) t A))}"
    (is "P ?P'")
  proof
    fix s
    assume P: "sP"
    with adapt obtain Z where
      Pre"p s = q init s P' Z" and
      adapt_Norm: "τ. τ Q' Z return s τ R s τ"
      by blast
    from  adapt_Norm
    have "t. t Q' Z return s t R s t"
      by auto
    then
    show "s?P'"
      using Pre by blast
  qed
  note P = this
  show ?thesis
    apply -
    apply (rule DynProc_exnStaticSpec [where S="{s. p s = q}",simplified, OF P c])
    apply (insert spec)
    apply auto
    done
qed

lemma DynProcProcParNoAbrupt:
assumes adapt: "P {s. p s = q (Z. init s P' Z
                            (τ. τ Q' Z return s τ R s τ))}"
assumes c: "s t. Γ,ΘF (R s t) (c s t) Q,A"
assumes spec: "Z. Γ,ΘF (P' Z) Call q (Q' Z),{}"
shows "Γ,ΘF P (dynCall init p return c) Q,A"
  using adapt c spec unfolding dynCall_dynCall_exn by (rule DynProc_exnProcParNoAbrupt)

lemma DynProc_exnModifyReturnNoAbr:
  assumes to_prove: "Γ,ΘF P (dynCall_exn f g init p return' result_exn c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes modif_clause:
            "s P. σ. Γ,ΘUNIV {σ} Call (p s) (Modif σ),{}"
  shows "Γ,ΘF P (dynCall_exn f g init p return result_exn c) Q,A"
proof -
  from ret_nrm_modif
  have "s t. t (Modif (init s))
         return' s t = return s t"
    by iprover
  then
  have ret_nrm_modif': "s t. t (Modif (init s))
                       return' s t = return s t"
    by simp
  have ret_abr_modif': "s t. t {}
                         result_exn (return' s t) t = result_exn (return s t) t"
    by simp
  from to_prove ret_nrm_modif' ret_abr_modif' modif_clause show ?thesis
    by (rule dynProc_exnModifyReturn)
qed

lemma DynProcModifyReturnNoAbr:
  assumes to_prove: "Γ,ΘF P (dynCall init p return' c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes modif_clause:
            "s P. σ. Γ,ΘUNIV {σ} Call (p s) (Modif σ),{}"
          shows "Γ,ΘF P (dynCall init p return c) Q,A"
  using to_prove ret_nrm_modif modif_clause unfolding dynCall_dynCall_exn
  by (rule DynProc_exnModifyReturnNoAbr)

lemma ProcDyn_exnModifyReturnNoAbrSameFaults:
  assumes to_prove: "Γ,ΘF P (dynCall_exn f g init p return' result_exn c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes modif_clause:
            "s P. σ. Γ,ΘF {σ} (Call (p s)) (Modif σ),{}"
  shows "Γ,ΘF P (dynCall_exn f g init p return result_exn c) Q,A"
proof -
  from ret_nrm_modif
  have "s t. t (Modif (init s))
         return' s t = return s t"
    by iprover
  then
  have ret_nrm_modif': "s t. t (Modif (init s))
                       return' s t = return s t"
    by simp
  have ret_abr_modif': "s t. t {}
                         result_exn (return' s t) t = result_exn (return s t) t"
    by simp
   from to_prove ret_nrm_modif' ret_abr_modif' modif_clause show ?thesis
     by (rule dynProc_exnModifyReturnSameFaults)
qed

lemma ProcDynModifyReturnNoAbrSameFaults:
  assumes to_prove: "Γ,ΘF P (dynCall init p return' c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes modif_clause:
            "s P. σ. Γ,ΘF {σ} (Call (p s)) (Modif σ),{}"
          shows "Γ,ΘF P (dynCall init p return c) Q,A"
  using to_prove ret_nrm_modif modif_clause unfolding dynCall_dynCall_exn
  by (rule ProcDyn_exnModifyReturnNoAbrSameFaults)

lemma Proc_exnProcParModifyReturn:
  assumes q: "P {s. p s = q} P'"
   ― @{thm[source] DynProcProcPar} introduces the same constraint as first conjunction in
 @{term P'}, so the vcg can simplify it.

  assumes to_prove: "Γ,ΘF P' (dynCall_exn f g init p return' result_exn c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes ret_abr_modif: "s t. t (ModifAbr (init s))
                             result_exn (return' s t) t = result_exn (return s t) t"
  assumes modif_clause:
          "σ. Γ,ΘUNIV {σ} (Call q) (Modif σ),(ModifAbr σ)"
  shows "Γ,ΘF P (dynCall_exn f g init p return result_exn c) Q,A"
proof -
  from to_prove have "Γ,ΘF ({s. p s = q} P') (dynCall_exn f g init p return' result_exn c) Q,A"
    by (rule conseqPre) blast
  from this ret_nrm_modif
       ret_abr_modif
  have "Γ,ΘF ({s. p s = q} P') (dynCall_exn f g init p return result_exn c) Q,A"
    by (rule dynProc_exnModifyReturn) (insert modif_clause,auto)
  from this q show ?thesis
    by (rule conseqPre)
qed


lemma ProcProcParModifyReturn:
  assumes q: "P {s. p s = q} P'"
   ― @{thm[source] DynProcProcPar} introduces the same constraint as first conjunction in
 @{term P'}, so the vcg can simplify it.

  assumes to_prove: "Γ,ΘF P' (dynCall init p return' c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes ret_abr_modif: "s t. t (ModifAbr (init s))
                             return' s t = return s t"
  assumes modif_clause:
          "σ. Γ,ΘUNIV {σ} (Call q) (Modif σ),(ModifAbr σ)"
        shows "Γ,ΘF P (dynCall init p return c) Q,A"
  using q to_prove ret_nrm_modif ret_abr_modif modif_clause unfolding dynCall_dynCall_exn
  by (rule Proc_exnProcParModifyReturn)

lemma Proc_exnProcParModifyReturnSameFaults:
  assumes q: "P {s. p s = q} P'"
   ― @{thm[source] DynProcProcPar} introduces the same constraint as first conjunction in
 @{term P'}, so the vcg can simplify it.

  assumes to_prove: "Γ,ΘF P' (dynCall_exn f g init p return' result_exn c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes ret_abr_modif: "s t. t (ModifAbr (init s))
                             result_exn (return' s t) t = result_exn (return s t) t"
  assumes modif_clause:
          "σ. Γ,ΘF {σ} Call q (Modif σ),(ModifAbr σ)"
  shows "Γ,ΘF P (dynCall_exn f g init p return result_exn c) Q,A"
proof -
  from to_prove
  have "Γ,ΘF ({s. p s = q} P') (dynCall_exn f g init p return' result_exn c) Q,A"
    by (rule conseqPre) blast
  from this ret_nrm_modif
       ret_abr_modif
  have "Γ,ΘF ({s. p s = q} P') (dynCall_exn f g init p return result_exn c) Q,A"
    by (rule dynProc_exnModifyReturnSameFaults) (insert modif_clause,auto)
  from this q show ?thesis
    by (rule conseqPre)
qed

lemma ProcProcParModifyReturnSameFaults:
  assumes q: "P {s. p s = q} P'"
   ― @{thm[source] DynProcProcPar} introduces the same constraint as first conjunction in
 @{term P'}, so the vcg can simplify it.

  assumes to_prove: "Γ,ΘF P' (dynCall init p return' c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes ret_abr_modif: "s t. t (ModifAbr (init s))
                             return' s t = return s t"
  assumes modif_clause:
          "σ. Γ,ΘF {σ} Call q (Modif σ),(ModifAbr σ)"
        shows "Γ,ΘF P (dynCall init p return c) Q,A"
  using q to_prove ret_nrm_modif ret_abr_modif modif_clause unfolding dynCall_dynCall_exn
  by (rule Proc_exnProcParModifyReturnSameFaults)

lemma Proc_exnProcParModifyReturnNoAbr:
  assumes q: "P {s. p s = q} P'"
   ― @{thm[source] DynProcProcParNoAbrupt} introduces the same constraint as
 first conjunction in @{term P'}, so the vcg can simplify it.

  assumes to_prove: "Γ,ΘF P' (dynCall_exn f g init p return' result_exn c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes modif_clause:
            "σ. Γ,ΘUNIV {σ} (Call q) (Modif σ),{}"
  shows "Γ,ΘF P (dynCall_exn f g init p return result_exn c) Q,A"
proof -
  from to_prove have "Γ,ΘF ({s. p s = q} P') (dynCall_exn f g init p return' result_exn c) Q,A"
    by (rule conseqPre) blast
  from this ret_nrm_modif
  have "Γ,ΘF ({s. p s = q} P') (dynCall_exn f g init p return result_exn c) Q,A"
    by (rule DynProc_exnModifyReturnNoAbr) (insert modif_clause,auto)
  from this q show ?thesis
    by (rule conseqPre)
qed

lemma ProcProcParModifyReturnNoAbr:
  assumes q: "P {s. p s = q} P'"
   ― @{thm[source] DynProcProcParNoAbrupt} introduces the same constraint as
 first conjunction in @{term P'}, so the vcg can simplify it.

  assumes to_prove: "Γ,ΘF P' (dynCall init p return' c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes modif_clause:
            "σ. Γ,ΘUNIV {σ} (Call q) (Modif σ),{}"
          shows "Γ,ΘF P (dynCall init p return c) Q,A"
  using q to_prove ret_nrm_modif modif_clause unfolding dynCall_dynCall_exn
  by (rule Proc_exnProcParModifyReturnNoAbr)

lemma Proc_exnProcParModifyReturnNoAbrSameFaults:
  assumes q: "P {s. p s = q} P'"
   ― @{thm[source] DynProcProcParNoAbrupt} introduces the same constraint as
 first conjunction in @{term P'}, so the vcg can simplify it.

  assumes to_prove: "Γ,ΘF P' (dynCall_exn f g init p return' result_exn c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes modif_clause:
            "σ. Γ,ΘF {σ} (Call q) (Modif σ),{}"
  shows "Γ,ΘF P (dynCall_exn f g init p return result_exn c) Q,A"
proof -
  from to_prove have
    "Γ,ΘF ({s. p s = q} P') (dynCall_exn f g init p return' result_exn c) Q,A"
    by (rule conseqPre) blast
  from this ret_nrm_modif
  have "Γ,ΘF ({s. p s = q} P') (dynCall_exn f g init p return result_exn c) Q,A"
    by (rule ProcDyn_exnModifyReturnNoAbrSameFaults) (insert modif_clause,auto)
  from this q show ?thesis
    by (rule conseqPre)
qed

lemma ProcProcParModifyReturnNoAbrSameFaults:
  assumes q: "P {s. p s = q} P'"
   ― @{thm[source] DynProcProcParNoAbrupt} introduces the same constraint as
 first conjunction in @{term P'}, so the vcg can simplify it.

  assumes to_prove: "Γ,ΘF P' (dynCall init p return' c) Q,A"
  assumes ret_nrm_modif: "s t. t (Modif (init s))
                             return' s t = return s t"
  assumes modif_clause:
            "σ. Γ,ΘF {σ} (Call q) (Modif σ),{}"
          shows "Γ,ΘF P (dynCall init p return c) Q,A"
  using q to_prove ret_nrm_modif modif_clause unfolding dynCall_dynCall_exn
  by (rule Proc_exnProcParModifyReturnNoAbrSameFaults)


lemma MergeGuards_iff: "Γ,ΘF P merge_guards c Q,A = Γ,ΘF P c Q,A"
  by (auto intro: MergeGuardsI MergeGuardsD)

lemma CombineStrip':
  assumes deriv: "Γ,ΘF P c' Q,A"
  assumes deriv_strip_triv: "Γ,{}{} P c'' UNIV,UNIV"
  assumes c'': "c''= mark_guards False (strip_guards (-F) c')"
  assumes c: "merge_guards c = merge_guards (mark_guards False c')"
  shows "Γ,Θ{} P c Q,A"
proof -
  from deriv_strip_triv have deriv_strip: "Γ,Θ{} P c'' UNIV,UNIV"
    by (auto intro: hoare_augment_context)
  from deriv_strip [simplified c'']
  have "Γ,Θ{} P (strip_guards (- F) c') UNIV,UNIV"
    by (rule MarkGuardsD)
  with deriv
  have "Γ,Θ{} P c' Q,A"
    by (rule CombineStrip)
  hence "Γ,Θ{} P mark_guards False c' Q,A"
    by (rule MarkGuardsI)
  hence "Γ,Θ{} P merge_guards (mark_guards False c') Q,A"
    by (rule MergeGuardsI)
  hence "Γ,Θ{} P merge_guards c Q,A"
    by (simp add: c)
  thus ?thesis
    by (rule MergeGuardsD)
qed

lemma CombineStrip'':
  assumes deriv: "Γ,Θ{True} P c' Q,A"
  assumes deriv_strip_triv: "Γ,{}{} P c'' UNIV,UNIV"
  assumes c'': "c''= mark_guards False (strip_guards ({False}) c')"
  assumes c: "merge_guards c = merge_guards (mark_guards False c')"
  shows "Γ,Θ{} P c Q,A"
  apply (rule CombineStrip' [OF deriv deriv_strip_triv _ c])
  apply (insert c'')
  apply (subgoal_tac "- {True} = {False}")
  apply auto
  done

lemma AsmUN:
  "(Z. {(P Z, p, Q Z,A Z)}) Θ
  ==>
  Z. Γ,ΘF (P Z) (Call p) (Q Z),(A Z)"
  by (blast intro: hoarep.Asm)

lemma augment_context':
  "[Θ Θ'; Z. Γ,ΘF (P Z) p (Q Z),(A Z)]
   ==> Z. Γ,Θ'F (P Z) p (Q Z),(A Z)"
  by (iprover intro: hoare_augment_context)


lemma hoarep_strip:
 "[Z. Γ,{}F (P Z) p (Q Z),(A Z); F' -F] ==>
    Z. strip F' Γ,{}F (P Z) p (Q Z),(A Z)"
  by (iprover intro: hoare_strip_Γ)

lemma augment_emptyFaults:
 "[Z. Γ,{}{} (P Z) p (Q Z),(A Z)] ==>
    Z. Γ,{}F (P Z) p (Q Z),(A Z)"
  by (blast intro: augment_Faults)

lemma augment_FaultsUNIV:
 "[Z. Γ,{}F (P Z) p (Q Z),(A Z)] ==>
    Z. Γ,{}UNIV (P Z) p (Q Z),(A Z)"
  by (blast intro: augment_Faults)

lemma PostConjI [trans]:
  "[Γ,ΘF P c Q,A; Γ,ΘF P c R,B] ==> Γ,ΘF P c (Q R),(A B)"
  by (rule PostConjI)

lemma PostConjI' :
  "[Γ,ΘF P c Q,A; Γ,ΘF P c Q,A ==> Γ,ΘF P c R,B]
  ==> Γ,ΘF P c (Q R),(A B)"
  by (rule PostConjI) iprover+

lemma PostConjE [consumes 1]:
  assumes conj: "Γ,ΘF P c (Q R),(A B)"
  assumes E: "[Γ,ΘF P c Q,A; Γ,ΘF P c R,B] ==> S"
  shows "S"
proof -
  from conj have "Γ,ΘF P c Q,A" by (rule conseqPost) blast+
  moreover
  from conj have "Γ,ΘF P c R,B" by (rule conseqPost) blast+
  ultimately show "S"
    by (rule E)
qed


subsection Rules for Single-Step Proof \label{sec:hoare-isar}

text 
 We are now ready to introduce a set of Hoare rules to be used in
 single-step structured proofs in Isabelle/Isar.

 \medskip Assertions of Hoare Logic may be manipulated in
 calculational proofs, with the inclusion expressed in terms of sets
 or predicates. Reversed order is supported as well.
 


lemma annotateI [trans]:
"[Γ,ΘFP anno Q,A; c = anno] ==> Γ,ΘFP c Q,A"
  by simp

lemma annotate_normI:
  assumes deriv_anno: "Γ,ΘFP anno Q,A"
  assumes norm_eq: "normalize c = normalize anno"
  shows "Γ,ΘFP c Q,A"
proof -
  from NormalizeI [OF deriv_anno] norm_eq
  have "Γ,ΘF P normalize c Q,A"
    by simp
  from NormalizeD [OF this]
  show ?thesis .
qed

lemma annotateWhile:
"[Γ,ΘF P (whileAnnoG gs b I V c) Q,A] ==> Γ,ΘF P (while gs b c) Q,A"
  by (simp add: whileAnnoG_def)


lemma reannotateWhile:
"[Γ,ΘF P (whileAnnoG gs b I V c) Q,A] ==> Γ,ΘF P (whileAnnoG gs b J V c) Q,A"
  by (simp add: whileAnnoG_def)

lemma reannotateWhileNoGuard:
"[Γ,ΘF P (whileAnno b I V c) Q,A] ==> Γ,ΘF P (whileAnno b J V c) Q,A"
  by (simp add: whileAnno_def)

lemma [trans] : "P' P ==> Γ,ΘF P c Q,A ==> Γ,ΘF P' c Q,A"
  by (rule conseqPre)

lemma [trans]: "Q Q' ==> Γ,ΘF P c Q,A ==> Γ,ΘF P c Q',A"
  by (rule conseqPost) blast+

lemma [trans]:
    "Γ,ΘF {s. P s} c Q,A ==> (s. P' s P s) ==> Γ,ΘF {s. P' s} c Q,A"
  by (rule conseqPre) auto

lemma [trans]:
    "(s. P' s P s) ==> Γ,ΘF {s. P s} c Q,A ==> Γ,ΘF {s. P' s} c Q,A"
  by (rule conseqPre) auto

lemma [trans]:
    "Γ,ΘFP c {s. Q s},A ==> (s. Q s Q' s) ==> Γ,ΘFP c {s. Q' s},A"
  by (rule conseqPost) auto

lemma [trans]:
    "(s. Q s Q' s) ==> Γ,ΘFP c {s. Q s},A ==> Γ,ΘFP c {s. Q' s},A"
  by (rule conseqPost) auto

lemma [intro?]: "Γ,ΘF P Skip P,A"
  by (rule Skip) auto

lemma CondInt [trans,intro?]:
  "[Γ,ΘF (P b) c1 Q,A; Γ,ΘF (P - b) c2 Q,A]
   ==>
   Γ,ΘF P (Cond b c1 c2) Q,A"
  by (rule Cond) auto

lemma CondConj [trans, intro?]:
  "[Γ,ΘF {s. P s b s} c1 Q,A; Γ,ΘF {s. P s ¬ b s} c2 Q,A]
   ==>
   Γ,ΘF {s. P s} (Cond {s. b s} c1 c2) Q,A"
  by (rule Cond) auto

lemma WhileInvInt [intro?]:
    "Γ,ΘF (P b) c P,A ==> Γ,ΘF P (whileAnno b P V c) (P -b),A"
  by (rule While) auto

lemma WhileInt [intro?]:
    "Γ,ΘF (P b) c P,A
    ==>
    Γ,ΘF P (whileAnno b {s. undefined} V c) (P -b),A"
  by (unfold whileAnno_def)
     (rule HoarePartialDef.While [THEN conseqPrePost],auto)

lemma WhileInvConj [intro?]:
  "Γ,ΘF {s. P s b s} c {s. P s},A
  ==> Γ,ΘF {s. P s} (whileAnno {s. b s} {s. P s} V c) {s. P s ¬ b s},A"
  by (simp add: While Collect_conj_eq Collect_neg_eq)

lemma WhileConj [intro?]:
  "Γ,ΘF {s. P s b s} c {s. P s},A
    ==>
\<Gamma>,ΘF {s. P s} (whileAnno {s. b s} {s. undefined} V c) {s. P s ¬ b s},A"
  by (unfold whileAnno_def)
     (simp add: HoarePartialDef.While [THEN conseqPrePost]
      Collect_conj_eq Collect_neg_eq)

(* fixme: Add rules for guarded while *)

end

Messung V0.5 in Prozent
C=75 H=96 G=86

¤ Dauer der Verarbeitung: 0.47 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.