(* Title: expstab.thy Author: John Wickerson, University of Cambridge Computer Laboratory Description: A formalisation of several properties of Explicit Stabilisation, as presented in Section 3 of the ESOP 2010 paper `Explicit Stabilisation for Modular Rely-Guarantee Reasoning' by John Wickerson, Mike Dodds and Matthew Parkinson Copyright 2010 University of Cambridge *) theory expstab imports Main begin typedecl state types rely = "state \ state \ bool" ass = "state \ bool" (* NB: This is a shallow embedding *) constdefs tt :: ass "tt \ \s. True" ff :: ass "ff \ \s. False" TT :: rely "TT \ \s. \s'. True" FF :: rely "FF \ \s. \s'. False" conj :: "ass \ ass \ ass" (infixr "\" 60) "p \ p' \ \s. p s \ p' s" disj :: "ass \ ass \ ass" (infixr "\" 60) "p \ p' \ \s. p s \ p' s" not_ass :: "ass \ ass" ("\ _" [70] 70) "\ p \ \s. \ p s" floor :: "ass \ rely \ ass" ("\_\_" [50, 90] 80) "\p\R \ \s. \s'. R^** s s' \ p s'" ceil :: "ass \ rely \ ass" ("\_\_" [50, 90] 80) "\p\R \ \s. \s'. R^** s' s \ p s'" (* Remark on syntax: the Transitive_Closure library writes R^** for the transitive closure of a binary predicate R :: 'a \ 'a \ bool, while R^* denotes the transitive closure of a relation R :: ('a \ 'a) set. *) definition stronger :: "ass \ ass \ bool" (infixr "\" 20) where "p \ q \ (\s. p s \ q s)" definition samestrength :: "ass \ ass \ bool" (infixr "\" 20) where "p \ q \ (\s. p s = q s)" definition stab :: "ass \ rely \ bool" (infix "stab" 30) where "(p stab R) \ (\s s'. p s \ R s s' \ p s')" (* Here is an equivalent formulation of the stab predicate that uses R^** instead of R *) lemma stab_def_manystep: "(p stab R) = (\s s'. p s \ R^** s s' \ p s')" unfolding stab_def proof(intro iffI) assume "\s s'. p s \ R s s' \ p s'" thus "\s s'. p s \ R^** s s' \ p s'" proof(intro allI impI) fix s::state and s'::state assume a1:"\s s'. p s \ R s s' \ p s'" and a2:"p s" and a3:"R^** s s'" thus "p s'" using rtranclp_induct[OF a3, of p] by auto qed qed(auto) (* alternative definition of samestrength in terms of stronger *) lemma samestrength_def_symstronger: "((p::ass) \ (q::ass)) = ((p \ q) \ (q \ p))" unfolding samestrength_def and stronger_def by auto lemma samestrength_sym: "(p::ass) \ (q::ass) \ q \ p" unfolding samestrength_def by auto (* - - - - - - - - - - - *) (* FUNDAMENTAL PROPERTIES *) lemma floor_stronger: "\p\R \ p" unfolding floor_def and stronger_def by auto lemma ceil_weaker: "p \ \p\R" unfolding ceil_def and stronger_def by auto lemma floor_is_stab: "\p\R stab R" unfolding stab_def and floor_def proof(intro allI impI) fix s::state and s'::state and s''::state assume a1: "\s'. R^** s s' \ p s'" and a2: "R s s'" and a3: "R^** s' s''" from a2 and a3 have "R^** s s''" by auto with a1 show "p s''" by auto qed lemma ceil_is_stab: "\p\R stab R" unfolding stab_def and ceil_def proof (intro allI impI) fix s::state and s'::state assume "\s''. R^** s'' s \ p s''" and "R s s'" hence "\s''. R^** s'' s \ R^** s s' \ p s''" by auto thus "\s''. R^** s'' s' \ p s''" using rtranclp_trans[of R] by auto qed lemma floor_weakest: "q \ p \ q stab R \ q \ \p\R" unfolding stab_def_manystep and floor_def and stronger_def by auto lemma ceil_weakest: "p \ q \ q stab R \ \p\R \ q" unfolding ceil_def and stab_def_manystep and stronger_def by auto lemma true_stab: "tt stab R" unfolding stab_def and tt_def by auto lemma false_stab: "ff stab R" unfolding ff_def and stab_def by auto lemma conj_pres_stab: "\p stab R; q stab R\ \ p \ q stab R" unfolding stab_def and conj_def by auto lemma disj_pres_stab: "\p stab R; q stab R\ \ p \ q stab R" unfolding stab_def and disj_def by auto lemma floor_mono: "p \ p' \ \p\R \ \p'\R" unfolding floor_def and stronger_def by auto lemma ceil_mono: "p \ p' \ \p\R \ \p'\R" unfolding ceil_def and stronger_def by auto lemma duality_floor_ceil: "(\(\ p)\R) \ \(\p\(R^--1))" unfolding samestrength_def and not_ass_def and ceil_def and floor_def proof(intro allI iffI) fix s::state assume "\s'. R^** s' s \ \ p s'" thus "\ (\s'. (R^--1)^** s s' \ p s')" using rtranclp_converseI [of R] by auto next fix s::state assume "\ (\s'. (R^--1)^** s s' \ p s')" thus "\s'. R^** s' s \ \ p s'" using rtranclp_converseD [of R] by auto qed lemma floor_of_stab: "p stab R \ p \ \p\R" unfolding samestrength_def and stab_def_manystep and floor_def by auto lemma ceil_of_stab: "p stab R \ p \ \p\R" unfolding samestrength_def and stab_def_manystep and ceil_def by auto lemma floor_of_FF: "\p\FF \ p" unfolding samestrength_def and FF_def and floor_def proof(intro allI iffI) fix s::state and s'::state assume a1: "p s" thus "(\s s'. False)^** s s' \ p s'" proof(intro impI) assume a2: "(\s s'. False)^** s s'" with a1 show "p s'" using converse_rtranclpE[OF a2, of "p s'"] by auto qed qed(auto) lemma ceil_of_FF: "\p\FF \ p" unfolding samestrength_def and FF_def and ceil_def proof(intro allI iffI) fix s::state assume "\s'. (\s s'. False)^** s' s \ p s'" then obtain s' where a:"(\s s'. False)^** s' s" and "p s'" by auto thus "p s" using converse_rtranclpE[OF a, of "p s"] by auto qed(auto) lemma dist_floor_conj: "\p \ q\R \ \p\R \ \q\R" unfolding floor_def and conj_def and samestrength_def by auto lemma dist_ceil_conj: "\p \ q\R \ \p\R \ \q\R" unfolding ceil_def and conj_def and stronger_def by auto lemma dist_floor_disj: "\p\R \ \q\R \ \p \ q\R" unfolding floor_def and disj_def and stronger_def by auto lemma dist_ceil_disj: "\p \ q\R \ \p\R \ \q\R" unfolding ceil_def and disj_def and samestrength_def by auto lemma stab_antitone: "R \ R' \ p stab R' \ p stab R" unfolding stab_def by auto lemma ceil_rely: "R \ R' \ \p\R \ \p\R'" unfolding ceil_def and stronger_def using rtranclp_mono by auto lemma floor_rely: "R \ R' \ \p\R' \ \p\R" unfolding floor_def and stronger_def using rtranclp_mono by auto (* - - - - - - - - - *) (* DERIVED PROPERTIES *) lemma floor_floor1: "R \ R' \ \\p\R\R' \ \p\R'" proof - assume a: "R \ R'" have "\\p\R\R' \ \p\R'" using floor_stronger[of p R] and floor_mono[of "\p\R" p R'] by auto moreover have "\p\R' \ \\p\R\R'" using floor_rely[OF a, of p] and floor_weakest[of "\p\R'" "\p\R" R'] and floor_is_stab[of p R'] by auto ultimately show "\\p\R\R' \ \p\R'" using samestrength_def_symstronger by auto qed lemma floor_floor2: "R \ R' \ \\p\R'\R \ \p\R'" proof - assume a:"R \ R'" thus "\\p\R'\R \ \p\R'" using floor_of_stab[of "\p\R'" R] and floor_is_stab[of p R'] and stab_antitone[OF a, of "\p\R'"] and samestrength_sym by auto qed lemma ceil_floor: "R \ R' \ \\p\R'\R \ \p\R'" proof - assume a:"R \ R'" thus "\\p\R'\R \\p\R'" using ceil_of_stab[of "\p\R'" R] and floor_is_stab[of p R'] and stab_antitone[OF a, of "\p\R'"] and samestrength_sym by auto qed lemma ceil_ceil1: "R \ R' \ \\p\R\R' \ \p\R'" proof - assume a: "R \ R'" have "\p\R' \ \\p\R\R'" using ceil_mono[OF ceil_weaker, of p R' R] by auto moreover have "\\p\R\R' \ \p\R'" using ceil_weakest[of "\p\R" "\p\R'" R'] and ceil_rely[OF a, of p] and ceil_is_stab[of p R'] by auto ultimately show "\\p\R\R' \ \p\R'" using samestrength_def_symstronger by auto qed lemma ceil_ceil2: "R \ R' \ \\p\R'\R \ \p\R'" proof - assume a: "R \ R'" thus "\\p\R'\R \ \p\R'" using ceil_of_stab[of "\p\R'" R] and ceil_is_stab[of p R'] and stab_antitone[OF a, of "\p\R'"] and samestrength_sym by auto qed lemma floor_ceil: "R \ R' \ \\p\R'\R \ \p\R'" proof - assume a: "R \ R'" thus "\\p\R'\R \ \p\R'" using floor_of_stab[of "\p\R'" R] and ceil_is_stab[of p R'] and stab_antitone[OF a, of "\p\R'"] and samestrength_sym by auto qed end