@@ -6,7 +6,7 @@ This file contains a proof of the protocol from the following paper:
66
77Hagit Attiya, Amotz Bar-Noy, and Danny Dolev.
88Sharing Memory Robustly in Message-passing Systems.
9- J. ACM 42, 1 (1995), 124– 142.
9+ J. ACM 42, 1 (1995), 124- 142.
1010
1111This protocol implements two operations Read and Write on a single register
1212that is replicated for fault-tolerance and shared across a collection of clients.
@@ -189,14 +189,15 @@ preserves call ValidTimeStamp();
189189preserves call TimeStampQuorum();
190190preserves call ValueStoreInv#3 (LeastTimeStamp(), InitValue);
191191{
192- var {:layer 2 } q: ReplicaSet;
193192 var old_ts: TimeStamp;
194- var {:layer 2 , 3 } w: ReplicaSet;
195193 var ts: TimeStamp;
194+ // tsq is the quorum witnessing the global timestamp TS
195+ var {:layer 2 , 3 } tsq: ReplicaSet;
196+ var {:layer 2 } tsq': ReplicaSet;
196197
197- par old_ts, w := Begin(one_pid) | ValueStoreInv#1 (LeastTimeStamp(), InitValue) | ValidTimeStamp() | ValueStoreInv#3 (LeastTimeStamp(), InitValue);
198+ par old_ts, tsq := Begin(one_pid) | ValueStoreInv#1 (LeastTimeStamp(), InitValue) | ValidTimeStamp() | ValueStoreInv#3 (LeastTimeStamp(), InitValue);
198199 call Yield#4 ();
199- call q, ts, value := Read(one_pid, old_ts, w );
200+ call ts, value, tsq' := Read(one_pid, old_ts, tsq );
200201 call Yield#4 ();
201202 par End(one_pid, ts);
202203}
@@ -219,7 +220,7 @@ preserves call ValueStoreInv#3(LeastTimeStamp(), InitValue);
219220
220221 par old_ts, tsq := Begin(one_pid) | ValidTimeStamp() | ValueStoreInv#3 (LeastTimeStamp(), InitValue);
221222 call Yield#4 ();
222- call lwq', tsq', ts := Write(one_pid, value, lwq, old_ts , tsq);
223+ call ts, lwq', tsq' := Write(one_pid, value, old_ts, lwq , tsq);
223224 call Yield#4 ();
224225 call End(one_pid, ts);
225226}
@@ -238,7 +239,7 @@ ensures {:layer 3} IsQuorum(tsq);
238239}
239240
240241yield procedure {:layer 3 } Read({:linear} one_pid: One ProcessId, old_ts: TimeStamp, {:hide} {:layer 2 , 3 } tsq: ReplicaSet)
241- returns ({:hide} {:layer 2 } tsq': ReplicaSet, ts: TimeStamp, value: Value )
242+ returns (ts: TimeStamp, value: Value, {:hide} {:layer 2 } tsq': ReplicaSet)
242243refines action {:layer 4 } _ {
243244 assume le(old_ts, ts);
244245 assume Map_Contains(value_store, ts);
@@ -257,13 +258,13 @@ preserves call ValueStoreInv#3(LeastTimeStamp(), InitValue);
257258 var {:layer 1 } old_replica_store: [ReplicaId]StampedValue;
258259
259260 call {:layer 1 } old_replica_store := Copy(replica_store);
260- call ts, value, tsq' := QueryPhase(old_replica_store, old_ts , tsq);
261+ call ts, value, tsq' := QueryPhase(old_ts, old_replica_store , tsq);
261262 par tsq' := UpdatePhase(ts, value) | MonotonicInduction#2 (tsq, old_ts, 0 ) | ValidTimeStamp() | ValueStoreInv#1 (LeastTimeStamp(), InitValue);
262263}
263264
264265yield procedure {:layer 3 }
265- Write({:linear} one_pid: One ProcessId, value: Value, {:hide} {:layer 1 } lwq: ReplicaSet, old_ts: TimeStamp , {:hide} {:layer 2 , 3 } tsq: ReplicaSet)
266- returns ({:hide} {:layer 1 } lwq': ReplicaSet, {:hide} {:layer 2 } tsq': ReplicaSet, ts: TimeStamp )
266+ Write({:linear} one_pid: One ProcessId, value: Value, old_ts: TimeStamp, {:hide} {:layer 1 } lwq: ReplicaSet, {:hide} {:layer 2 , 3 } tsq: ReplicaSet)
267+ returns (ts: TimeStamp, {:hide} {:layer 1 } lwq': ReplicaSet, {:hide} {:layer 2 } tsq': ReplicaSet)
267268refines action {:layer 4 } _ {
268269 assume lt(old_ts, ts);
269270 assume ! Map_Contains(value_store, ts);
@@ -286,15 +287,15 @@ preserves call ValueStoreInv#3(LeastTimeStamp(), InitValue);
286287 var {:layer 1 } old_replica_store: [ReplicaId]StampedValue;
287288
288289 call {:layer 1 } old_replica_store := Copy(replica_store);
289- par ts, _value, q := QueryPhase(old_replica_store, old_ts , tsq) | LastWriteInv(one_pid, TimeStamp(last_write[one_pid-> val], one_pid-> val));
290+ par ts, _value, q := QueryPhase(old_ts, old_replica_store , tsq) | LastWriteInv(one_pid, TimeStamp(last_write[one_pid-> val], one_pid-> val));
290291 ts := TimeStamp(ts-> t + 1 , one_pid-> val);
291292 call AddToValueStore(one_pid, ts, value);
292293 par q := UpdatePhase(ts, value) | LastWriteInv(one_pid, ts) | MonotonicInduction#2 (tsq, old_ts, 0 ) | ValidTimeStamp();
293294 lwq' := q;
294295 tsq' := q;
295296}
296297
297- yield right procedure {:layer 3 } QueryPhase({:layer 1 } old_replica_store: [ReplicaId]StampedValue, old_ts: TimeStamp , {:layer 2 , 3 } tsq: ReplicaSet)
298+ yield right procedure {:layer 3 } QueryPhase(old_ts: TimeStamp, {:layer 1 } old_replica_store: [ReplicaId]StampedValue, {:layer 2 , 3 } tsq: ReplicaSet)
298299 returns (max_ts: TimeStamp, max_value: Value, q: ReplicaSet)
299300preserves call ValueStoreInv#1 (LeastTimeStamp(), InitValue);
300301preserves call ReplicaInv();
@@ -310,11 +311,11 @@ ensures {:layer 3} le(old_ts, max_ts);
310311ensures {:layer 3 } Map_Contains(value_store, max_ts) && Map_At(value_store, max_ts) == max_value;
311312{
312313 assume IsQuorum(q);
313- call max_ts, max_value := QueryPhaseHelper(0 , q, old_replica_store, old_ts , tsq);
314+ call max_ts, max_value := QueryPhaseHelper(0 , q, old_ts, old_replica_store , tsq);
314315}
315316
316317yield right procedure {:layer 3 }
317- QueryPhaseHelper(i: int, q: ReplicaSet, {:layer 1 } old_replica_store: [ReplicaId]StampedValue, old_ts: TimeStamp , {:layer 2 , 3 } tsq: ReplicaSet)
318+ QueryPhaseHelper(i: int, q: ReplicaSet, old_ts: TimeStamp, {:layer 1 } old_replica_store: [ReplicaId]StampedValue, {:layer 2 , 3 } tsq: ReplicaSet)
318319 returns (max_ts: TimeStamp, max_value: Value)
319320requires {:layer 1 , 2 } IsReplica(i) || i == numReplicas;
320321preserves call ValueStoreInv#1 (LeastTimeStamp(), InitValue);
@@ -339,7 +340,7 @@ ensures {:layer 3} Map_Contains(value_store, max_ts) && Map_At(value_store, max_
339340 return ;
340341 }
341342 par ts, value := Query#2 (i, q, old_replica_store[i]-> ts, old_ts, tsq) |
342- max_ts, max_value := QueryPhaseHelper(i + 1 , q, old_replica_store, old_ts , tsq);
343+ max_ts, max_value := QueryPhaseHelper(i + 1 , q, old_ts, old_replica_store , tsq);
343344 if (lt(max_ts, ts))
344345 {
345346 max_ts := ts;
0 commit comments