Lecture 1: Logical, Physical & Causal Time
(Part 1)
Anish Arora
CSE 6333
Logical Clocks
• j, k
:
processes
• ch.j.k
:
channel from j to k – a sequence
• m
:
message
• e, f
:
events
• lc.j
:
logical clock of j – an integer
• lc.e
:
logical time of e – an integer
Logical Clocks program
Process j
{local event e}
lc.j, lc.e := lc.j+1, lc.j+1
{sent event e,
lc.j, lc.e := lc.j+1, lc.j+1
▯
from j to k}
; ch.j.k
:= (ch.j.k oe,lc.e)
▯
{receive event e,
lc.j, lc.e := (lc.j max lc.m)+1,
msg m from k to j}
(lc.j max lc.m)+1
; ch.k.j
:= tail(ch.k.j)
Logical Clocks invariant
Process j
{local event e}
lc.j, lc.e := lc.j+1, lc.j+1
{sent event e,
lc.j, lc.e := lc.j+1, lc.j+1
▯
from j to k}
; ch.j.k
:= (ch.j.k oe,lc.e)
▯
{receive event e,
lc.j, lc.e := (lc.j max lc.m)+1,
msg m from k to j}
(lc.j max lc.m)+1
; ch.j.k
:= tail(ch.k.j)
Invariant
( e,j : e occurs at j : lc.e lc.j)
( e,f:: e happens before f lc.e < lc.f)
( m,j,k : m ch.j.k : (e : e occurs at j: lc.e=lc.m))
Logical Clocks
Theorem : Invariant is closed in program of logical clocks
Proof : We show that for any “new” event, if Invariant holds
before the event occurs, then Invariant holds after it occurs
1) ( e,j : e occurs at j : lc.e lc.j)
•
If e is an old event, this term is preserved since lc.j cannot decrease
•
If e is a new event, and occurs at j, this term holds since lc.e = lc.j
•
If e is a new event, and occurs at a process other than j, this term
holds trivially
2) ( m,j,k : m ch.j.k : (e : e occurs at j : lc.e lc.m))
•
If m is an old message, term is trivially preserved by the same witness
•
If m is a new message, then this term holds since lc.m := lc.e,
where e is the new event
Logical Clocks
3) ( e,f : e happens before f lc.e < lc.f)
•
If e and f are old events, this term is trivially preserved
•
If e is the new event, there is no event in f such that e happens
before f
•
If e is an old event and f is the new event then,
I.
If e is the event immediately preceding f at the same process j,
then lc.e lc.f before f occurs and lc.e < lc.f after f occurs and lc.f
:= lc.j. Hence lc.e < lc.f
II. If e is the send event corresponding to the receive event f, then
lc.f > lc.m = lc.e
III. If e is some other event that happens before f, then e happens
before e’ such that I or II apply to e’. From Invariant, lc.e < lc.e’,
and from lc.e’ < lc.f. Hence lc.e < lc.f
Vector Clocks
Correctness requirement:
( e,f :: e happens before f vc.e < vc.f)
where
• e
:
events
• j, k
:
processes
• vc.j
:
vector clock of j – a vector 1..N of integers
• vc.e
:
vector time of e – a vector 1..N of integers
– 1..N
Vector Clocks
Process j
{local event e}
vc.j.j := vc.j.j+1
; vc.e := vc.j
▯
{sent event e}
vc.j.j := vc.j.j+1
; send msg with vc.e = vc.j
▯
{receive event e,
message m}
vc.j.j := vc.j.j+1
; (|| k :: vc.j.k := vc.j.k max vc.m.k)
Vector orderings :
vc.e < vc.f
(j :: vc.e.jvc.f.j) (j :: vc.e.j<vc.f.j)
Proof of Invariance for Vector Clocks
Let i,j,k be processes;
ai,bj be events at processes i and j respectively;
mk be a message sent by process k
R=
( i,j,mi :: vc.i.i vc.j.i
( ai,bj ::
ai hb bj
ai hb bj
vc.i.j vc.mi.j )
vc.ai < vc.bj
vc.ai.i vc.bj.i )
Theorem : R is an Invariant
Proof : We show that for any “new” event, if R holds before the
event occurs, then R holds after the event occurs
Vector Clocks
1) vc.i.i vc.j.i : If the events occurs at a process other than j and
i, this term is obviously preserved
If the event occurs at process i, then vc.i.i is
incremented thereby preserving this term
If the event occurs at process j, j i then vc.j.i either
remains unchanged or is set to the maximum of vc.j.i and vc.mk.i.
However, from R, vc.mk.i vc.k.i and vc.k.i vc.i.i, hence the
term is preserved
2) vc.i.j vc.mi.j : The timestamp of a message never changes, and
vc.i.j is nondecreasing. Hence this term is preserved
Vector Clocks
3) ai hb bj vc.ai < vc.bj : We consider three cases:
–
If both ai and bj are both not the new events, then this term is
preserved trivially
–
If ai is the new event but bj is not, then (ai hb bj) and this
term is true
–
If bj is the new event and ai is not, then
I. If j=i and ai is the event immediately before bj then
vc.bj.j = vc.ai.j + 1. Hence vc.ai < vc.bj
II. If bj is the receive event caused by the send event ai, then
vc.ai.j < vc.bj.j and vc.ai vc.bj. Hence vc.ai < vc.bj
III. If subcases I and II do not hold and ai hb bj then ai hb ck
such that for ck I or II apply. From R, vc.ai < vc.ck, and
since vc.ck < vc.bj , vc.ai < vc.bj
Vector Clocks
4) ai hb bj (vc.ai < vc.bj vc.ai.i vc.bj.i)
We prove the contrapositive : (ai hb bj) (vc.ai<vc.bj) (vc.ai.i>vc.bj.i)
We consider three cases:
–
If both ai and bj are both not the new events, then this term is
preserved trivially
–
If ai is the new event but bj is not, then vc.ai.i = vc.i.i > vc.j.i vc.bj.i.
Hence (vc.ai<vc.bj)
–
If ai is an old event and bj is the new event, then (ai hb ck) where ck
is any event such that I and II apply
(ai hb ck)
{from R}
vc.ai.i > vc.ck.i
{ij, else ai hb bj}
vc.ai.i > vc.bj.i
{definition of >}
vc.ai.i > vc.bj.i (vc.ai < vc.bj)
Restriction
•
Adding (conjoining) extra guards to any of the actions of a
program
•
The addition of these guards restricts the set of states in
which the restricted actions execute
•
Theorem: Every safety property of the program is a safety
property of the restricted program
(Hint: {P} s {Q} {P g} s {Q})
Superposition
•
Adding actions to a program that do not modify (write) the
program variables – they modify only the ‘superposed’
variables
•
The addition of the actions may be in
– parallel with program actions
– interleaved with program actions
•
Theorem: Every safety and progress property of the
program is a property of the superposed program
Proof: For progress, assume program actions are executed
fairly
Causal Broadcast (Birman-Schiper-Stepheson)
Causal ordering:
( e,f,j :
send.e happens before send.f
deliveredj.e happens before deliveredj.f )
• i, j, k
:
Processes
• m
:
message
• vc.i
:
vector clock of i
• vc.m
:
vector time of m
Causal Broadcast
Process i
{send message m}
vc.i.i := vc.i.i+1
; vc.m := vc.i
; send.m to all j
▯
{receive message m
(|| k : vc.i.k := vc.i.k
from j }
max
vc.i.j + 1 = vc.m.j
vc.m.k)
(k : kj : vc.i.k vc.m.k)
; deliver m to i
Causal Broadcast (safety)
Let P = (i,j,k,ai,bj,mi,nj :: vc.i.i vc.j.i
vc.i vc.mi
deliveredj.mi vc.j vc.mi
deliveredj.mi vc.j.i vc.mi.i
ai hb bj
vc.a vc.b
ai hb bj
vc.ai.i vc.bj.i
CB
)
where
CB = (mi,nj,k::send.mi hb send.nj deliveredk.nj deliveredk.mi)
Causal Broadcast (safety)
Theorem:
P is an invariant
Proof:
Every event is either a send or a deliver of a message.
Our obligation is to show that for every “new” event,
if P holds before the event then P holds after the event.
The first six conjuncts are easily verified.
We show that these six conjuncts imply CB
send.mi hb send.nj
{ 5th conjunct
vc.mi vc.nj
{ transitivity }
vc.mi vc.k
{ definition of for vectors }
vc.mi.i vc.k.i
{ 4th conjunct }
deliveredk.mi
,
deliveredk.nj
3rd conjunct }
vc.nj vc.k
Progress proof of Causal Broadcast (sketch)
•
If finitely many messages are sent, eventually all send actions are
disabled
•
In states where no send actions are enabled, eventually all (sent)
messages have been received
•
In states where no send actions are enabled and all messages have
been received, either all messages have been delivered or some
deliver action is enabled
•
This step requires proof: consider all undelivered messages at j, and
further consider only those which did not happen after any other
message in this set.
If the deliver action is disabled for all such messages mk, then:
vc.j.k + 1 = vc.mk.k (l : vc.j.l < vc.mk.l) which implies from the
invariant P that (ml : vc.mk.l = vc.ml.l :
deliveredj.ml deliveredk.ml send.ml hb send.mk) which is false
Therefore eventually all messages will be delivered
Note that this proof does not require any fairness of program execution
© Copyright 2026 Paperzz