(* * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) * * SPDX-License-Identifier: BSD-2-Clause *) theory WPBang imports WP ProvePart NonDetMonadVCG begin lemma conj_meta_forward: "P \ Q \ (P \ P') \ (Q \ Q') \ P' \ Q'" by simp text \Applying safe WP rules.\ ML \ structure WP_Safe = struct fun check_has_frees_tac Ps (_ : int) thm = let val fs = Term.add_frees (Thm.prop_of thm) [] |> filter (member (=) Ps) in if null fs then Seq.empty else Seq.single thm end fun wp_bang wp_safe_rules ctxt = let val wp_safe_rules_conj = ((wp_safe_rules RL @{thms hoare_vcg_conj_lift hoare_vcg_R_conj}) RL @{thms hoare_strengthen_post hoare_post_imp_R}) |> map (rotate_prems 1) in resolve_tac ctxt wp_safe_rules_conj THEN' Split_To_Conj.get_split_tac "P" ctxt (fn Ps => fn i => eresolve0_tac [@{thm conj_meta_forward}] i THEN (REPEAT_ALL_NEW ((CHANGED o asm_full_simp_tac ctxt) ORELSE' Classical.safe_steps_tac ctxt) THEN_ALL_NEW Partial_Prove.cleanup_tac ctxt Ps) i THEN (Partial_Prove.finish_tac ctxt Ps THEN' (assume_tac ctxt)) i ) end val wpe_args = Attrib.thms >> curry (fn (rules, ctxt) => Method.SIMPLE_METHOD ( wp_bang rules ctxt 1 ) ); end \ method_setup wpe = \WP_Safe.wpe_args\ "applies 'safe' wp rules to eliminate postcondition components" text \Testing.\ lemma assumes x: "\ P \ f \ \rv. Q \" and y: "\ P \ f \ \rv. R \" shows "\ P \ f \ \rv s. \x y. (fst rv = Some x \ Q s) \ (snd rv = Some y \ Q s ) \ R s \" apply (rule hoare_pre) apply (simp add: all_conj_distrib) apply (rule hoare_vcg_conj_lift) apply (wpe x) apply wp apply (wpe x) apply (wp y) apply simp done end