(* * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) * * SPDX-License-Identifier: BSD-2-Clause *) theory SpecValid_R imports ExtraCorres begin definition spec_valid :: "'s \ ('s \ bool) \ ('s, 'r) nondet_monad \ ('r \ 's \ bool) \ bool" ("_ \ /\_\/ _ /\_\" [60,0,0,0] 100) where "spec_valid st P f Q \ valid (\s. s = st \ P s) f Q" definition spec_validE :: "'s \ ('s \ bool) \ ('s, 'e + 'r) nondet_monad \ ('r \ 's \ bool) \ ('e \ 's \ bool) \ bool" ("_ \ /\_\/ _ /(\_\, /\_\)" [60,0,0,0] 100) where "spec_validE st P f Q E \ validE (\s. s = st \ P s) f Q E" lemma use_spec': assumes x: "\s. s \ \P\ f \Q\" shows "\P\ f \Q\" apply (clarsimp simp: valid_def) apply (cut_tac s=s in x) apply (clarsimp simp: valid_def spec_valid_def) apply (erule(1) my_BallE, simp) done lemma use_specE': "\ \s. s \ \P'\ f' \Q'\,\E\ \ \ \P'\ f' \Q'\,\E\" apply (simp add: validE_def spec_validE_def) apply (fold spec_valid_def) apply (simp add: use_spec') done lemmas use_spec = use_spec' use_specE' lemma drop_equalled_validE: "\P\ f \Q\,\E\ \ \\s. s = s' \ P s\ f \Q\,\E\" by (erule hoare_pre, clarsimp) lemma drop_spec_valid[wp_split]: "\P\ f \Q\ \ s \ \P\ f \Q\" apply (simp add: spec_valid_def) apply (erule hoare_vcg_precond_imp) apply clarsimp done lemma drop_spec_validE[wp_split]: "\P\ f \Q\,\E\ \ s \ \P\ f \Q\,\E\" apply (simp add: spec_validE_def) apply (erule hoare_vcg_precond_impE) apply clarsimp done lemma split_spec_bindE[wp_split]: assumes x: "\rv s''. (Inr rv, s'') \ fst (f s') \ s'' \ \B rv\ g rv \C\,\E\" shows "s' \ \A\ f \B\,\E\ \ s' \ \A\ f >>=E g \C\,\E\" apply (clarsimp simp: spec_validE_def validE_def valid_def bind_def bindE_def lift_def split_def) apply (case_tac a) apply (clarsimp simp add: throwError_def return_def) apply (erule(1) my_BallE, simp) apply clarsimp apply (erule(1) my_BallE, simp) apply (drule x) apply (clarsimp simp: spec_validE_def validE_def valid_def split_def) apply (erule(1) my_BallE, simp) done lemma split_spec_bind[wp_split]: assumes x: "\rv s''. (rv, s'') \ fst (f s') \ s'' \ \B rv\ g rv \C\" shows "s' \ \A\ f \B\ \ s' \ \A\ f >>= g \C\" apply (clarsimp simp: spec_valid_def valid_def bind_def lift_def split_def) apply (erule(1) my_BallE, simp) apply (drule x) apply (fastforce simp: spec_valid_def valid_def split_def) done lemma split_spec_if[wp_split]: "\ G \ s' \ \P\ f \Q\; \ G \ s' \ \P'\ f' \Q\ \ \ s' \ \\s. (G \ P s) \ (\ G \ P' s)\ if G then f else f' \Q\" by (cases G, simp+) lemma split_spec_ifE[wp_split]: "\ G \ s' \ \P\ f \Q\,\E\; \ G \ s' \ \P'\ f' \Q\,\E\ \ \ s' \ \\s. (G \ P s) \ (\ G \ P' s)\ if G then f else f' \Q\,\E\" by (cases G, simp+) lemma split_spec_unlessE[wp_split]: "\ \ G \ s' \ \P\ f \Q\,\E\ \ \ s' \ \\s. (G \ Q () s) \ (\ G \ P s)\ unlessE G f \Q\,\E\" apply (cases G, simp_all add: unlessE_def) apply wp done lemma spec_fun_applyE [wp_split]: "s \ \P\ f x \Q\,\E\ \ s \ \P\ f $ x \Q\,\E\" by simp lemma split_spec_K_bind[wp_split]: "s \ \P\ f \Q\ \ s \ \P\ K_bind f x \Q\" by simp lemma split_spec_K_bindE[wp_split]: "s \ \P\ f \Q\,\E\ \ s \ \P\ K_bind f x \Q\,\E\" by simp lemma fudge_hoare: "s \ \P\ \s. f s \Q\,\E\ \ s \ \P\ f \Q\,\E\" . lemma split_spec_whenE [wp_split]: "\ G \ s' \ \P\ f \Q\,\E\ \ \ s' \ \\s. (G \ P s) \ (\ G \ Q () s)\ whenE G f \Q\,\E\" apply (cases G, simp_all add: whenE_def) apply wp done lemma spec_valid_conj_lift: "\ s \ \P\ f \Q\; s \ \P'\ f \Q'\ \ \ s \ \\s. P s \ P' s\ f \\rv s. Q rv s \ Q' rv s\" apply (simp add: spec_valid_def) apply (drule(1) hoare_vcg_conj_lift) apply (simp add: conj_comms) done lemma spec_valid_conj_liftE1: "\ \P\ f \Q\,-; s \ \P'\ f \Q'\,\E'\ \ \ s \ \\s. P s \ P' s\ f \\rv s. Q rv s \ Q' rv s\,\E'\" apply (simp add: spec_validE_def) apply (drule(1) hoare_vcg_conj_liftE1) apply (simp add: conj_comms pred_conj_def) done lemma spec_valid_conj_liftE2: "\ \P\ f \Q'\,-; s \ \P'\ f \Q\,\E'\ \ \ s \ \\s. P s \ P' s\ f \\rv s. Q rv s \ Q' rv s\,\E'\" apply (simp add: spec_validE_def) apply (drule(1) hoare_vcg_conj_liftE1) apply (simp add: conj_comms pred_conj_def) done lemma hoare_pre_spec_valid: "\ s \ \P'\ f \Q\; P s \ P' s \ \ s \ \P\ f \Q\" apply (simp add: spec_valid_def) apply (erule hoare_pre) apply clarsimp done lemma hoare_pre_spec_validE: "\ s \ \P'\ f \Q\,\E\; P s \ P' s \ \ s \ \P\ f \Q\,\E\" apply (simp add: spec_validE_def) apply (erule hoare_pre) apply clarsimp done lemma spec_validE_if: "\ G \ s \ \P\ f \Q\,\E\; \ G \ s \ \P'\ g \Q\,\E\ \ \ s \ \P and P'\ if G then f else g \Q\,\E\" apply (cases G, simp_all) apply (clarsimp elim!: hoare_pre_spec_validE)+ done lemma spec_strengthen_post: "\ s \ \P\ f \Q'\; \s r. Q' s r \ Q s r \ \ s \ \P\ f \Q\" by (simp add: spec_valid_def valid_def split_def split: sum.splits) lemma spec_strengthen_postE: "\ s \ \P\ f \Q'\, \E\; \s r. Q' s r \ Q s r \ \ s \ \P\ f \Q\, \E\" by (simp add: spec_valid_def spec_validE_def validE_def valid_def split_def split: sum.splits) end