(* * Copyright 2014, NICTA * * This software may be distributed and modified according to the terms of * the BSD 2-Clause license. Note that NO WARRANTY is provided. * See "LICENSE_BSD2.txt" for details. * * @TAG(NICTA_BSD) *) theory XPres imports SIMPL_Lemmas begin (* We don't really care if the computation gets stuck or faults, only that xf isn't changed *) definition xpres :: "('s \ 'a) \ 'a \ ('i \ ('s, 'i, 'x) com) \ ('s, 'i, 'x) com \ bool" where "xpres xf v \ c \ \s t. \ \ \c, s\ \ t \ s \ Normal ` {s. xf s = v} \ (\t'. t = Normal t' \ t = Abrupt t' \ xf t' = v)" lemma xpresI: "\\s t t'. \\ \ \c, Normal s\ \ t; xf s = v; t = Normal t' \ t = Abrupt t' \ \ xf t' = v\ \ xpres xf v \ c" unfolding xpres_def by auto (* Sometimes it's easier to reason syntactically --- the two are more or less equivalent, under the assumption that c doesn't fault or get stuck *) lemma xpres_hoareI: "\ \ {s. xf s = v } c {s. xf s = v} \ xpres xf v \ c" apply (rule xpresI) apply (drule hoare_sound) apply (simp add:HoarePartialDef.valid_def cvalid_def) apply (drule spec, drule spec, drule (1) mp) apply clarsimp done lemma xpres_skip: "xpres xf v \ Skip" apply (rule xpres_hoareI) apply rule done lemma xpres_basic: assumes rl: "\s. xf s = v \ xf (f s) = v" shows "xpres xf v \ (Basic f)" apply (rule xpresI) apply (drule rl) apply (erule exec_Normal_elim_cases) apply clarsimp done lemma xpres_exec0: assumes xp: "xpres xf v \ c" and ex: "\ \ \c, Normal s\ \ y" and xy: "y = Normal s' \ y = Abrupt s'" and xf: "xf s = v" shows "xf s' = v" using xp ex xy xf unfolding xpres_def apply - apply (drule spec, drule spec, drule (1) mp) apply (erule disjE) apply (drule mp, simp) apply simp apply (drule mp, simp) apply simp done lemma xpres_exec: assumes xp: "xpres xf v \ c" and ex: "\ \ \c, Normal s\ \ Normal s'" and xf: "xf s = v" shows "xf s' = v" using xp ex xf by (auto intro: xpres_exec0) lemma xpresD: assumes xf: "xf s = v" and xp: "xpres xf v \ a" and ex: "\ \ \a, Normal s\ \ Normal s'" shows "xf s' = v" by (rule xpres_exec [OF xp ex]) fact+ lemma xpres_abruptD: assumes xf: "xf s = v" and xp: "xpres xf v \ a" and ex: "\ \ \a, Normal s\ \ Abrupt s'" shows "xf s' = v" by (rule xpres_exec0 [OF xp ex], simp) fact+ lemma xpres_seq: assumes xa: "xpres xf v \ a" and xb: "xpres xf v \ b" shows "xpres xf v \ (a ;; b)" apply (rule xpresI) apply (erule exec_Normal_elim_cases) apply (erule disjE) apply simp apply (erule Normal_resultE) apply simp apply (drule (1) xpresD [OF _ xa]) apply (erule (1) xpresD [OF _ xb]) apply simp apply (erule Abrupt_resultE) apply simp apply (drule (1) xpresD [OF _ xa]) apply (erule (1) xpres_abruptD [OF _ xb]) apply simp apply (drule Abrupt_end, rule refl) apply simp apply (erule (1) xpres_abruptD [OF _ xa]) done lemma xpres_while0: assumes ex: "\\ \d,s\ \ t" and xp: "xpres xf v \ a" and d: "d = While b a" and s: "s \ Normal ` {s. xf s = v} \ Abrupt ` {s. xf s = v}" and t: "t = Normal t' \ t = Abrupt t'" shows "xf t' = v" using ex d s t proof (induct) case (WhileTrue s' b' c' t u) hence eqs: "b' = b" "c' = a" and xfs: "xf s' = v" by auto { fix w assume tv: "t = Normal w" and "\ \ \a, Normal s'\ \ Normal w" have ?thesis proof (rule WhileTrue.hyps(5)) have "xf w = v" using xfs xp by (rule xpresD) fact+ thus "t \ Normal ` {s. xf s = v} \ Abrupt ` {s. xf s = v}" using tv by simp qed fact+ } moreover { fix w assume tv: "t = Abrupt w" and "\ \ \a, Normal s'\ \ Abrupt w" have ?thesis proof (rule WhileTrue.hyps(5)) have "xf w = v" using xfs xp by (rule xpres_abruptD) fact+ thus "t \ Normal ` {s. xf s = v} \ Abrupt ` {s. xf s = v}" using tv by simp qed fact+ } ultimately show ?thesis using WhileTrue.prems(3) WhileTrue.hyps(2) WhileTrue.hyps(4) eqs apply - apply (erule disjE) apply simp apply (erule Normal_resultE) apply simp apply simp apply (erule Abrupt_resultE) apply simp apply simp done qed auto lemma xpres_while: assumes xp: "xpres xf v \ x" shows "xpres xf v \ (While b x)" apply (rule xpresI) apply (erule xpres_while0 [OF _ xp refl]) apply simp apply simp done lemma xpres_call: assumes ret: "\s t. xf s = v \ xf (r s t) = v" and xp: "\s t. xpres xf v \ (c s t)" shows "xpres xf v \ (call i f r c)" apply (rule xpresI) apply (erule exec_call_Normal_elim) apply (erule (1) xpres_exec0 [OF xp]) apply (erule ret) apply simp apply (erule subst, erule ret) apply simp apply simp apply simp done lemma xpres_catch: assumes xpb: "xpres xf v \ b" and xpc: "xpres xf v \ c" shows "xpres xf v \ (Catch b c)" apply (rule xpresI) apply (erule exec_Normal_elim_cases) apply (drule (1) xpres_abruptD [OF _ xpb]) apply (erule (2) xpres_exec0 [OF xpc]) apply (erule (2) xpres_exec0 [OF xpb]) done lemma xpres_guard: assumes xp: "xpres xf v \ c" shows "xpres xf v \ (Guard f g c)" apply (rule xpresI) apply (erule exec_Normal_elim_cases) apply (erule (2) xpres_exec0 [OF xp]) apply simp done lemma xpres_cond: assumes xpa: "xpres xf v \ a" and xpb: "xpres xf v \ b" shows "xpres xf v \ (Cond x a b)" apply (rule xpresI) apply (erule exec_Normal_elim_cases) apply (erule (2) xpres_exec0 [OF xpa]) apply (erule (2) xpres_exec0 [OF xpb]) done lemma xpres_throw: shows "xpres xf v \ Throw" apply (rule xpresI) apply (erule exec_Normal_elim_cases) apply simp done lemma xpres_creturn: assumes xfu: "\s f. xf (xfu f s) = xf s" and xfg: "\s f. xf (exnu f s) = xf s" shows "xpres xf v \ (creturn exnu xfu v')" unfolding creturn_def apply (rule xpresI) apply (clarsimp elim!: exec_Normal_elim_cases simp add: xfg xfu)+ done lemma xpres_creturn_void: assumes xfg: "\s f. xf (exnu f s) = xf s" shows "xpres xf v \ (creturn_void exnu)" unfolding creturn_void_def apply (rule xpresI) apply (clarsimp elim!: exec_Normal_elim_cases simp add: xfg) done lemma xpres_cbreak: assumes xfg: "\s f. xf (exnu f s) = xf s" shows "xpres xf v \ (cbreak exnu)" unfolding cbreak_def apply (rule xpresI) apply (clarsimp elim!: exec_Normal_elim_cases simp add: xfg) done lemma xpres_catchbrk_C: shows "xpres xf v \ (ccatchbrk exnu)" unfolding ccatchbrk_def apply (rule xpresI) apply (fastforce elim!: exec_Normal_elim_cases) done lemma xpres_lvar_nondet_init: assumes xfg: "\s f. xf (st f s) = xf s" shows "xpres xf v \ (lvar_nondet_init gt st)" apply (rule xpresI) apply (simp add: lvar_nondet_init_def) apply (auto elim!: exec_Normal_elim_cases simp add: xfg) done (* We ignore DynCom and Call and (for now) Spec. The first two are covered by xpres_call *) lemmas xpres_rules = xpres_skip xpres_basic xpres_seq xpres_while xpres_call xpres_catch xpres_skip xpres_guard xpres_cond xpres_throw xpres_creturn xpres_creturn_void xpres_cbreak xpres_catchbrk_C xpres_lvar_nondet_init end