Eiffel Approach to @pre/old � Restrict post-conditions to formulas of the form: t [ (t 1 )@pre/x 1 ,..., (t n )@pre/x n ] An Abstract Machine for the Old � Compute and save values of t 1 ,..., t n when the constrained Value Retrieval method is called � All implementations of @pre follow this approach: e.g. JML and USE, DOT, … Piotr Kosiuczenko ISI, WAT Warsaw Problems with this approach Solution Idea � Syntax restrictions Number method calls – a larger number means a later call � Define a history stack for every relevant attribute a to store a ’s � A potential increase of computational complexity � if 1+1=2 then true else q@pre endif snapshots Save a snapshot of a in its history stack, when a is modified for the � � Extensive cloning of system states - collections are the major first time during a call of a method slowdown factor � The lack of transparency in respect to object identity � Alternatively one could try to use the so the called fat structures as they are used in case of partially persistent structures The Formal Model Model of OO Computation: States Set of attributes and object locations � A = {a 1 ,..., a n }, OL � We model states of an oo-system and the corresponding Object store (store) - heap state � transitions by an abstract machine OS = df {os : A x OL ! OL ? } � States comprise the call-stack and the corresponding heap, Store history � and also: SH = df (OS x OP x N) + � method call number Attribute snpshot � � heap history H = df (OL x N) * � attributes’ history function Attribute history � AH = df {h : A x OL ! H ? } Computation state � CS = df SH x AH x N Initial stat e � inSt = df ((st ? , main, 0), h ? , 0) 1
Model of OO Computation: Transitions Model of OO Computation: Transitions cont. Let cs = (sh, h, n), cs’ = (sh', h', n'), cs R return(op) cs' , sh' = (st 0 , main, 0) ... (st k , op k-1 , n k-1 ) � sh = sh 0 (st k , op k , n k ), sh 0 = (st 0 , main, 0)...(st k-1 , op k-1 , n k-1 )(st k , op k , n k ) h(a, o) = ? Æ h(a, o) ≠ ² ) h(a, o) = ah 0 (o l , r l ), � |sh 0 | > 0 ) h' = h Æ n' = n � |sh 0 | = 0 ) 8 a 2 A, o 2 OL h'(a, o) = if h(a, o) ≠ ? then ² else ? Endif ah 0 = (o 0 , r 0 ) ... (o l-1 , r l-1 ) Æ n' = 0 cs R call(op) cs' , n' = n+1 Æ sh' = sh(st, op, n+1) Æ h' = h � cs R cleanTop(a, o) cs' , 1 < |h(a, o)| Æ n k 6 r l-1 Æ sh' = sh Æ n' = n Æ cs R set(a, o, o') cs' , n' = n Æ sh' = sh 0 (st ', op, m) Æ � � h' = h[(a, o) a ah 0 ] st ' = st[(a, o) a o'] Æ cs R cleanWhole(a, o) cs' , 1 < |h(a, o)| Æ sh' = sh Æ n' = n Æ � h(a, o) = ? ) h' = h[(a, o) a (o’, n k )] � � h(a, o) = ² Ç r l < n k Æ st k (a, o) ≠ o l ) h' = h[(a, o) a ah], where ah is obtained from ah 0 by removing snapshots with time-stamps not being a smallest upper bound of an h' = h[(a, o) a h(a, o)(st k (a, o), n k )] unterminated method call number � r l < n k Æ st k (a, o) = o l ) h' = h[(a, o) a ah 0 (o l , n k )] � h’ = h in other cases Invariant Invariant Preservation Theorem For cs = (sh, h, n) let sh = (st 0 , main, 0)(st 1 , op 1 , n 1 ) ... (st k , op k , n k ). For h(a, o) ≠ ? , we assume that h(a, o) = (o 1 , r 1 ) ... (o l , r l ). Inv is satisfied in the initial state inSt. If cs ² Inv and cs R step cs', where step is one of the transition steps, � 8 0 6 i < k st i (a, o) ≠ ? ) st i+1 (a, o) ≠ ? then cs' ² Inv. st k (a, o) = ? , h(a, o) = ? � h(a, o) ≠ ? ) 0 < n 1 < ... < n k 6 n � h(a, o) ≠ ? ) 0 < r 1 < ... < r l 6 n Lemma � � 8 0 6 i < k ? ≠ st i (a, o) ≠ st i+1 (a, o) ) 9 1 6 j 6 l n i+1 6 r j Let cs be a computation state as described in the invariant. If cs ² Inv and st i (a, o) ≠ ? , then 8 0 6 i < k, 0 6 j 6 l st i (a, o) ≠ ? Æ n i+1 6 r j Æ (1 6 j-1 ) r j-1 < n i+1 ) ) � st i+1 (a@pre, o) = st i (a, o) = o j if n i+1 6 r j Æ (0 < j - 1 ) r j-1 < n i+1 ) then o j else st i+1 (a, o) endif Flattening Method Calls Weak Bisimulation Theorem csa is a non-flattened computation state and csb is a flattened state ¼ is a kind of weak bisimulation relation; i.e. inSt ¼ inSt, and if, and only if, the following conditions are satisfied: if csa ¼ csb, then the following conditions hold: csa = ((stb 0 , main, 0)ih0 ... (sta m , rop m , na m )ih m , ha, na) � > call(iop) csa' ) csa' ¼ csb iop 2 IOp Æ csa - csb = ((stb 0 , main, 0)(stb 1 , rop 1 , nb 1 ) ... (stb m , rop m , nb m ), hb, nb) � - - - - - - � � > call(rop) csa' ) rop 2 ROp Æ csa - - - - - - - � A non-flattened state csa is equivalent to a flattened state csb 9 csb' csb - call(rop) csb' Æ csa' ¼ csb’ (csa ¼ csb) if, and only if, the following conditions are satisfied: - - - - - - > . . . If |ih j | > 0, then the last store in ih j equals stb j , for j = 0,..., m � � > return(rop) csb' ) rop 2 ROp Æ csb - If ih j = 0, then sta j = stb j , for j = 0,..., m - - - - - - � � 9 csa0,..., csan, csa’ csa = csa 0 Æ > return(iopi) csa i+1 Æ csa i+1 ¼ csb, for i = 0,..., n-1, Æ � csa i - - - - - - - > return(rop) csa' Æ csa' ¼ csb' � csa n - - - - - - - 2
Weak Bisimulation Weak Bisimulation > clean*(a, o) csa' ) csa' ¼ csb csa - - - - - - - � Lemma � Let csa, csb be computation states of the above form such that . . . � csa ¼ csb. For j = 1,..., m, if op j is a relevant method, then > return(iop) csa' ) csa' ¼ csb iop 2 IOp Æ csa - - - - - - - � sta j (a@pre, o) = stb j (a@pre, o). � return(rop) csa' ) rop 2 ROp Æ csa - - - - - - - > � 9 csb' csb - return(rop) csb' Æ csa' ¼ csb' - - - - - - > Sufficiently Persistent Structures Sufficiently Persistent Structures � We call a structure suffciently persistent, if for every non- � The old value archiving does not increase the complexity of terminated method call its version from before the call can be the instrumented methods accessed, but only the most recent version can be updated � The average time of old value retrieval is constant � Sufficiently persistent structures are related to the so called � It can be ensured without an increase method’s time- semi persistent structures as partially persistent structures to complexity that the history size is for every archived attribute persistent ones is of the linear order in respect to the call-stack size � The defined abstract machine corresponds to a general form of sufficiently persistent structures Example: Hanoi Towers Concluding Remarks � We defined an abstract machine for computing @pre o The standard solution relies on a recursive algorithm and � There is an invariant preserved by this machine, which requires an exponential number of moves in respect to n implies that the @pre value is computable on the basis of � The corresponding partially persistent structure has an history attributes exponential size order with respect to n � Calls of irrelevant methods can be abstracted away � The call-stack size is maximally n; consequently, we can � We defined the notion of sufficiently persistent structure and ensure that the sufficiently persistent structure has at most showed that they are more adequate in this case than the size order n^2 partially persistent ones 3
Recommend
More recommend