theory Hoare_Clean imports Hoare_MonadSE
Clean begin
subsection‹Clean Control Rules›
lemma break1: "{λσ. P (σ ( break_status := True )) } break {λr σ. P σ ∧ break_status σ }" unfolding hoare3_def break_def unit_SE_def by auto
lemma unset_break1: "{λσ. P (σ ( break_status := False )) } unset_break_status {λr σ. P σ ∧¬ break_status σ}" unfolding hoare3_def unset_break_status_def unit_SE_def by auto
lemma set_return1: "{λσ. P (σ ( return_status := True )) } set_return_status {λr σ. P σ ∧ return_status σ }" unfolding hoare3_def set_return_status_def unit_SE_def by auto
lemma unset_return1: "{λσ. P (σ ( return_status := False )) } unset_return_status {λr σ. P σ ∧¬return_status σ }" unfolding hoare3_def unset_return_status_def unit_SE_def by auto
subsection‹Clean Skip Rules›
lemma assign_global_skip: "{λσ. exec_stop σ ∧ P σ } upd :==G rhs {λr σ. exec_stop σ ∧ P σ }" unfolding hoare3_def skipSE_def unit_SE_def by (simp add: assign_def assign_global_def)
lemma assign_local_skip: "{λσ. exec_stop σ ∧ P σ } upd :==L rhs {λr σ. exec_stop σ ∧ P σ }" unfolding hoare3_def skipSE_def unit_SE_def by (simp add: assign_def assign_local_def)
lemma return_skip: "{λσ. exec_stop σ ∧ P σ } returnC upd rhs {λr σ. exec_stop σ ∧ P σ }" unfolding hoare3_def returnC_def returnC0_def unit_SE_def assign_local_def assign_def
bind_SE'_def bind_SE_def by auto
lemma assign_clean_skip: "{λσ. exec_stop σ ∧ P σ } assign tr {λr σ. exec_stop σ ∧ P σ }" unfolding hoare3_def skipSE_def unit_SE_def by (simp add: assign_def assign_def)
lemma if_clean_skip: "{λσ. exec_stop σ ∧ P σ } ifC C then E else F fi {λr σ. exec_stop σ ∧ P σ }" unfolding hoare3_def skipSE_def unit_SE_def if_SE_def by (simp add: if_C_def)
lemma while_clean_skip: "{λσ. exec_stop σ ∧ P σ } whileC cond do body od {λr σ. exec_stop σ ∧ P σ }" unfolding hoare3_def skipSE_def unit_SE_def while_C_def by auto
lemma if_opcall_skip: "{λσ. exec_stop σ ∧ P σ} (callC M A1) {λr σ. exec_stop σ ∧ P σ}" unfolding hoare3_def skipSE_def unit_SE_def callC_def by simp
lemma if_funcall_skip: "{λσ. exec_stop σ ∧ P σ}(ptmp← callC fun E ; assign_local upd (λσ. ptmp)) {λr σ. exec_stop σ ∧ P σ}" unfolding hoare3_def skipSE_def unit_SE_def callC_def assign_local_def assign_def by (simp add: bind_SE_def)
lemma if_funcall_skip': "{λσ. exec_stop σ ∧ P σ }(ptmp← callC fun E ; assign_global upd (λσ. ptmp)) {λr σ. exec_stop σ ∧ P σ }" unfolding hoare3_def skipSE_def unit_SE_def callC_def assign_global_def assign_def by (simp add: bind_SE_def)
lemma return_assign: assumes * : "♯ (upd ∘ upd_hd)" shows"{λ σ. ▹ σ ∧ P ((upd ∘ upd_hd) (λ_. rhs σ) (σ ( return_status := True )))} return(rhs) {λr σ. P σ ∧ return_status σ }" unfolding returnC_def returnC0_def hoare3_def skipSE_def unit_SE_def assign_local_def assign_def
set_return_status_def bind_SE'_def bind_SE_def proof (auto) fix σ :: "'b control_state_scheme" assume a1: "P (upd (upd_hd (λ_. rhs σ)) (σ(return_status := True)))" assume"▹ σ" show"P (upd (upd_hd (λ_. rhs σ)) σ(return_status := True))" using a1 assms exec_stop_vs_control_independence' by fastforce qed (* do we need independence of rhs ? Not really. 'Normal' programs would never
be control-state dependent, and 'artificial' ones would still be correct ...*)
subsection‹Clean Construct Rules›
lemma cond_clean : " {λσ. ▹ σ ∧ P σ ∧ cond σ} M {Q} ==>{λσ. ▹ σ ∧ P σ ∧¬ cond σ} M' {Q} ==>{λσ. ▹ σ ∧ P σ} ifC cond then M else M' fi{Q}" unfolding hoare3_def hoare3'_def bind_SE_def if_SE_def by (simp add: if_C_def)
text‹There is a particular difficulty with a verification of (terminating) while rules
a Hoare-logic for a language involving break. The first is, that break is not used
the toplevel of a body of a loop (there might be breaks inside an inner loop, though).
scheme is covered by the rule below, which is a generalisation of the classical
loop (as presented by @{thm while}.›
lemma while_clean_no_break : assumes * : "{λσ. ¬ break_status σ ∧ cond σ ∧ P σ} M {λ_. λσ. ¬ break_status σ ∧ P σ }" and measure: "∀σ. ¬ exec_stop σ ∧ cond σ ∧ P σ ⟶ M σ ≠ None ∧ f(snd(the(M σ))) < ((f σ)::nat) "
(is"∀σ. _ ∧ cond σ ∧ P σ ⟶ ?decrease σ") shows"{λσ. ▹ σ ∧ P σ} whileC cond do M od {λ_ σ. (return_status σ ∨¬ cond σ) ∧¬ break_status σ ∧ P σ}"
(is"{?pre} whileC cond do M od {λ_ σ. ?post1 σ ∧ ?post2 σ}") unfolding while_C_def hoare3_def hoare3'_def proof (simp add: hoare3_def[symmetric],rule sequence') show"{?pre} whileSE (λσ. ▹ σ ∧ cond σ) do M od {λ_ σ. ¬ ( ▹ σ ∧ cond σ) ∧¬ break_status σ ∧ P σ}"
(is"{?pre} whileSE ?cond' do M od {λ_ σ. ¬ ( ?cond' σ) ∧ ?post2 σ}") proof (rule consequence_unit) fix σ show" ?pre σ ⟶ ?post2 σ"using exec_stop1 by blast next show"{?post2}whileSE ?cond' do M od{λx σ. ¬(?cond' σ) ∧ ?post2 σ}" proof (rule_tac f = "f"in while, rule consequence_unit) fix σ show"?cond' σ ∧ ?post2 σ ⟶¬break_status σ ∧ cond σ ∧ P σ"by simp next show"{λσ. ¬ break_status σ ∧ cond σ ∧ P σ} M {λx σ. ?post2 σ}"using"*"by blast next fix σ show"?post2 σ ⟶ ?post2 σ"by blast next show"∀σ.?cond' σ ∧ ?post2 σ ⟶ ?decrease σ"using measure by blast qed next fix σ show" ¬?cond' σ ∧ ?post2 σ ⟶¬?cond' σ ∧ ?post2 σ"by blast qed next show"{λσ. ¬ (▹ σ ∧ cond σ) ∧ ?post2 σ} unset_break_status {λ_ σ'. (return_status σ' ∨¬ cond σ') ∧ ?post2 σ'}"
(is"{λσ. ¬ (?cond'' σ) ∧ ?post2 σ} unset_break_status {λ_ σ'. ?post3 σ' ∧ ?post2 σ' }") proof (rule consequence_unit) fix σ show"¬ ?cond'' σ ∧ ?post2 σ ⟶ (λσ. P σ ∧ ?post3 σ) (σ(break_status := False))" by (metis (full_types) exec_stop_def surjective update_convs(1)) next show"{λσ. (λσ. P σ ∧ ?post3 σ) (σ(break_status := False))} unset_break_status {λx σ. ?post3 σ ∧¬ break_status σ ∧ P σ}" apply(subst (2) conj_commute,subst conj_assoc,subst (2) conj_commute) by(rule unset_break1) next fix σ show"?post3 σ ∧ ?post2 σ ⟶ ?post3 σ ∧ ?post2 σ"by simp qed qed
text‹In the following we present a version allowing a break inside the body, which implies that the
invariant has been established at the break-point and the condition is irrelevant.
A return may occur, but the @{term "break_status"} is guaranteed to be true
after leaving the loop.›
lemma while_clean': assumes M_inv : "{λσ. ▹ σ ∧ cond σ ∧ P σ} M {λ_. P}" and cond_idpc : "∀x σ. (cond (σ(break_status := x))) = cond σ " and inv_idpc : "∀x σ. (P (σ(break_status := x))) = P σ " and f_is_measure : "∀σ. ▹ σ ∧ cond σ ∧ P σ ⟶ M σ ≠ None ∧ f(snd(the(M σ))) < ((f σ)::nat)" shows"{λσ. ▹ σ ∧ P σ} whileC cond do M od {λ_ σ. ¬ break_status σ ∧ P σ}" unfolding while_C_def hoare3_def hoare3'_def proof (simp add: hoare3_def[symmetric], rule sequence') show"{λσ. ▹ σ ∧ P σ} whileSE (λσ. ▹ σ ∧ cond σ) do M od {λ_ σ. P (σ(break_status := False))}" apply(rule consequence_unit, rule impI, erule conjunct2) apply(rule_tac f = "f"in while) using M_inv f_is_measure inv_idpc by auto next show"{λσ. P (σ(break_status := False))} unset_break_status {λx σ. ¬ break_status σ ∧ P σ}" apply(subst conj_commute) by(rule Hoare_Clean.unset_break1) qed
text‹Consequence and Sequence rules where inherited from the underlying Hoare-Monad theory.›
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-10)
¤
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.