(* * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) * * SPDX-License-Identifier: BSD-2-Clause *) (* WP-specific Eisbach methods *) theory Eisbach_WP imports Eisbach_Methods NonDetMonadVCG Conjuncts Rule_By_Method WPI begin text \ Methods for manipulating the post conditions of hoare triples as if they were proper subgoals. post_asm can be used with the @ attribute to modify existing proofs. Useful for proving large postconditions in one proof and then subsequently decomposing it. \ context begin definition "packed_valid P f si r s \ P si \ (r, s) \ fst (f si)" lemma packed_validE:"(\si r s. packed_valid P f si r s \ Q r s) \ \P\ f \Q\" by (clarsimp simp: valid_def packed_valid_def) lemma packed_validI: "\P\ f \Q\ \ \si r s. packed_valid P f si r s \ Q r s" apply (clarsimp simp: valid_def packed_valid_def) by auto definition "packed_validR P f si r s \ P si \ (Inr r, s) \ fst (f si)" lemma packed_validRE:"(\si r s. packed_validR P f si r s \ Q r s) \ \P\ f \Q\,-" apply (clarsimp simp: validE_R_def validE_def valid_def packed_validR_def) by (metis sum.case sumE) lemma packed_validRI: "\P\ f \Q\,- \ \si r s. packed_validR P f si r s \ Q r s" apply (clarsimp simp: valid_def validE_R_def validE_def packed_validR_def) by fastforce lemma trivial_imp: "\r s. Q r s \ Q r s" by simp lemma uncurry2: "\r s. Q r s \ Q' r s \ Q'' r s \ \r s. Q r s \ Q' r s \ Q'' r s" by simp named_theorems hoare_post_imps lemmas [hoare_post_imps] = hoare_post_imp_R hoare_post_imp[rotated] method post_asm_raw methods m = (drule hoare_post_imps, atomize (full), focus_concl \intro impI allI, m, atomize (full), ((rule uncurry2)+)?\, rule trivial_imp) method post_asm methods m = (post_asm_raw \(simp only: bipred_conj_def pred_conj_def)?,(elim conjE)?,m\) named_theorems packed_validEs lemmas [packed_validEs] = packed_validE packed_validRE named_theorems packed_validIs lemmas [packed_validIs] = packed_validI packed_validRI method post_raw methods m = (focus_concl \rule packed_validEs, focus_concl \m,fold_subgoals\, atomize (full), rule packed_validI\) method post_strong methods m_distinct m_all = (post_raw \(simp only: pred_conj_def bipred_conj_def)?, (intro impI conjI allI)?, distinct_subgoals_strong \m_distinct\, all \m_all\, fold_subgoals\) method post methods m = post_strong \(assumption | erule mp)+\ \m\ end text \ Method (meant to be used with @ as an attribute) used for producing multiple facts out of a single hoare triple with a conjunction in its post condition. \ context begin private lemma hoare_decompose: "\P\ f \\r s. Q r s \ Q' r s\ \ \P\ f \Q\ \ \P\ f \Q'\" by (fastforce simp add: valid_def pred_conj_def) private lemma hoare_decomposeE_R: "\P\ f \\r s. Q r s \ Q' r s\,- \ \P\ f \Q\,- \ \P\ f \Q'\,-" by (fastforce simp add: validE_R_def validE_def valid_def pred_conj_def split: prod.splits sum.splits) private lemma hoare_decomposeE_E: "\P\ f -,\\r s. Q r s \ Q' r s\ \ \P\ f -,\Q\ \ \P\ f -,\Q'\" by (fastforce simp add: validE_E_def validE_def valid_def pred_conj_def split: prod.splits sum.splits) private lemma hoare_decomposeE: "\P\ f \\r s. E r s \ E' r s\,\\r s. R r s \ R' r s\ \ \P\ f \E\,- \ \P\ f \E'\,- \ \P\ f -,\R\ \ \P\ f -,\R'\" by (fastforce simp add: validE_R_def validE_E_def validE_def valid_def pred_conj_def split: prod.splits sum.splits) private lemmas hoare_decomposes' = hoare_decompose hoare_decomposeE_R hoare_decomposeE_E hoare_decomposeE private method add_pred_conj = (subst pred_conj_def[symmetric]) private method add_bipred_conj = (subst bipred_conj_def[symmetric]) private lemmas hoare_decomposes[THEN conjE] = hoare_decomposes' hoare_decomposes'[# \add_pred_conj\] hoare_decomposes'[# \add_bipred_conj\] hoare_decomposeE[# \add_pred_conj, add_pred_conj\] hoare_decomposeE[# \add_bipred_conj, add_pred_conj\] hoare_decomposeE[# \add_pred_conj, add_bipred_conj\] hoare_decomposeE[# \add_bipred_conj, add_bipred_conj\] method hoare_decompose = (elim hoare_decomposes) end notepad begin fix A :: "'a \ bool" and B C D f assume A: "\s. A s = True" and B: "\s :: 'a. B s = True" and C: "\s :: 'a. C s = True" and D: "\s :: 'a. D s = True" and f: "f = (return () :: ('a,unit) nondet_monad)" have f_valid[@ \hoare_decompose\,conjuncts]: "\A\ f \\_. B and C and D\" apply (simp add: f) apply wp by (simp add: B C D) note f_valid' = conjuncts have f_d: "\A\ f \\_. D\" by (rule f_valid') have f_valid_interm: "\A\ f \\_. B and C and (\s. D s \ B s)\" apply (post_strong \simp\ \-\) apply (wp f_valid') by simp (* All rotations are attempted when strengthening *) have f_valid_interm: "\A\ f \\_. (\s. D s \ B s) and B and C \" apply (post_strong \simp\ \-\, wp f_valid') by simp end end