CAPITULO 2. DESARROLLO DEL SISTEMA DE ACCESO BANCA ELECTRÓNICA
2.2 Análisis
2.2.4 Diagramas de actividad de los casos de uso del Sistema
In the previous example, we were able to construct the couplingsynchronouslybecause the two coupled walks meet at the same iteration. This may not be the case in more complex proofs. To demonstrate,
we consider an example of ashift coupling—a coupling where the two processes meet at two random timesteps. To construct this kind of coupling, we cannot use the synchronous rule[WHILE]since we may need to relate samples across different iterations. Instead, we will apply our asynchronous rule
[WHILE-GEN].
Our example is called theDynkin process.3 This process maintains a positionpos∈N, initialized to
start∈[0, . . . , 10]. Each step, it draws a uniformly random numberrfrom[1, . . . , 10]and increments the position byr. The process stops as soon asposexceedsT∈N, returning the final value as the output.
The following code implements the Dynkin process:
pos←start; hist←[start]; whilepos<T do r $ ←Unif([1, . . . , 10]); pos←pos+r;
hist←pos::hist
We call this programdynkinand we writedynbodyfor the loop body. We use a ghost variablehistto keep track of the history of visited positions, just like we did for the random walk. We will analyze two executions ofdynkinstarting at different locations and show the distributions over final positions converge asT increases.
Before seeing the proof in×PRHL, let’s first sketch the coupling argument. If the two processes have the same position, then we couple the samplings to return equal values; this keeps the two positions equal. Otherwise, we sample in the process that is behind, temporarily pausing the leading process. Since the sampled process moves at least one step forward in each iteration, the lagging process will overtake (or land on) the leading process in finitely many steps, when we will switch to one of the other cases.
We perform this reasoning in×PRHL using[WHILE-GEN]withK1=K2=1. We take the joint guard
e¬(pos〈1〉<T)∨(pos〈2〉<T),
and flags
p0¬pos〈1〉=pos〈2〉 and p1¬pos〈1〉<pos〈2〉 and p2¬pos〈1〉>pos〈2〉.
These cases are clearly mutually exclusive, and one is always true. Furthermore, they satisfy the necessary consistency requirements:|=p1∧e→(pos〈1〉<T)and|=p2∧e→(pos〈2〉<T)both hold. Finally, the loops are clearly lossless: the position increases by at least 1 every iteration, so we are in any case for at mostT iterations.
With the side-conditions out of the way, we now turn to the main premises. We take the following invariant: Θ¬ |hist〈1〉|>0∧ |hist〈2〉|>0
hist〈1〉 ∩hist〈2〉 6=∅→pos〈1〉=pos〈2〉 |pos〈1〉 −pos〈2〉| ≤10
hd(hist〈1〉) =pos〈1〉 ∧hd(hist〈2〉) =pos〈2〉
∀t∈t l(hist〈2〉), pos〈1〉>t∧ ∀t∈t l(hist〈1〉), pos〈2〉>t
Reading from the top, the first line states that the history lists are non-empty. The second conjunct says that if the two processes have visited the same position at some point in the past, then they currently have the same position. The third conjunct states that the coupled positions are at most 10 apart at all times. The fourth line states that the current position is the first element in each history list, and the last two conjuncts state that the position in each process is strictly larger than all the previous positions of the other process; this holds because we always move the lagging process. (We writet l(hist)for thetailof a listhist, consisting of all but the first element.)
We now prove the three main premises in[WHILE-GEN].
Premisep0
Whenp0is true,pos〈1〉=pos〈2〉and we need to prove `
§
Θ∧e∧p0
ª ifpos<T thendynbody
ifpos<T thendynbody
§
ΘªÉdynkin×0.
Since both guards are true, we use the two-sided rule[COND]. We use[SAMPLE]with f =id (the identity coupling), and then the usual assignment rule[ASSN]. The invariant is preserved sincep0remains true. So, we have the desired judgment with product programdynkin×0:
ifpos〈1〉<T then r〈1〉 $ ←Unif([1, . . . , 10]); r〈2〉 ←r〈1〉; pos〈1〉 ←pos〈1〉+r〈1〉; pos〈2〉 ←pos〈2〉+r〈2〉;
hist〈1〉 ←pos〈1〉::hist〈1〉;
hist〈2〉 ←pos〈2〉::hist〈2〉
Premisep1
Whenp1is true,pos〈1〉<pos〈2〉and we need to prove `
§
Θ∧(pos〈1〉<T)∧p1
ª ifpos<T thendynbody
skip
§
ΘªÉdynkin×1.
Since we are relating a program toskip, we apply the one-sided rules. To show we preserveΘ, note thathist〈1〉andhist〈2〉are both non-empty andhist〈1〉 ∩hist〈2〉is initially empty sincepos〈1〉<pos〈2〉, so ifhist〈1〉 ∩hist〈2〉 6=∅after the loop body then we must havepos〈1〉 ∈hist〈2〉. The next conjunct |pos〈1〉 −pos〈2〉| ≤10 also holds, since (i) it holds initially, (ii)pos〈1〉<pos〈2〉initially, and (iii)pos〈1〉 moves forward by at most 10. The conjuncts involving the head ofhistare clear. For the last two conjuncts,
hist〈2〉is unchanged whilepos〈1〉increases, so
∀t∈t l(hist〈2〉),pos〈1〉>t
continues to hold. Similarly, ifhist〈1〉is initiallyq::pswhereqis the initial value ofpos〈1〉, then it ends up beingpos〈1〉::q::ps. Sincepos〈2〉is initially greater than all elements inpsand also greater thanq
sincep1holds, we continue to have
∀t∈t l(hist〈1〉),pos〈2〉>t
after executing the body. So, we have the desired judgment with the following product programdynkin×1: ifpos〈1〉<T then
r〈1〉←$ Unif([1, . . . , 10]); pos〈1〉 ←pos〈1〉+r〈1〉;
hist〈1〉 ←pos〈1〉::hist〈1〉
Premisep2
This case is nearly identical to the previous case, using the right-side versions instead of left-side versions of the rules. By a symmetric argument, we have
`
§
Θ∧(p〈2〉<T)∧p2
ª
skip
ifpos<T thendynbody
§
Θ
ª
wheredynkin×2is the following product program: ifpos〈2〉<T then
r〈2〉←$ Unif([1, . . . , 10]); pos〈2〉 ←pos〈2〉+r〈2〉;
hist〈2〉 ←pos〈2〉::hist〈2〉
Putting it all together
Applying[WHILE-GEN], we have the judgment ` § start〈1〉,start〈2〉 ∈[1, . . . , 10] ª dynkin dynkin §
hist〈1〉 ∩hist〈2〉 6=∅→pos〈1〉=pos〈2〉
ª
Édynkin×
(3.2) for the following product programdynkin×:
pos〈1〉 ←start〈1〉;pos〈2〉 ←start〈2〉
hist〈1〉 ←[start〈1〉];hist〈2〉 ←[start〈2〉]; while(pos〈1〉<T)∨(pos〈2〉<T)do
ifpos〈1〉=pos〈2〉then ifpos〈1〉<T then
r〈1〉 $
←Unif([1, . . . , 10]);
r〈2〉 ←r〈1〉;
pos〈1〉 ←pos〈1〉+r〈1〉;pos〈2〉 ←pos〈2〉+r〈2〉;
hist〈1〉 ←pos〈1〉::hist〈1〉;hist〈2〉 ←pos〈2〉::hist〈2〉
else ifpos〈1〉<pos〈2〉then ifpos〈1〉<T then
r〈1〉←$ Unif([1, . . . , 10]); pos〈1〉 ←pos〈1〉+r〈1〉;
hist〈1〉 ←pos〈1〉::hist〈1〉
else
ifpos〈2〉<T then r〈2〉 $
←Unif([1, . . . , 10]);
pos〈2〉 ←pos〈2〉+r〈2〉;
hist〈2〉 ←pos〈2〉::hist〈2〉
This program models the informal coupling proof: if the positions are equal, we take equal samples and move both processes; otherwise, we move the lagging process while holding the leading process fixed. We can analyze this program to show convergence of two Dynkin processes.
Theorem 3.5.1. Let m1,m2be two memories such that m1(start),m2(start)∈[0, 10]. Letµ1,µ2be the final distributions over memories:
µ1¬¹dynkinºm1 and µ2¬¹dynkinºm2.
Letη1,η2be the final distributions over positions: η1¬¹posº
](µ1) and η
2¬¹posº
](µ2).
Then the distance between the two position distributions is at most dtv(η1,η2)≤(9/10)bT/10c−1.
Proof. If T ≤10, the claim is trivial. Otherwise, letµ×be the coupling in Eq. (3.2) and letη×be the coupling projected to the two positions:
µ×¬¹dynkin׺(m1,m2) and η׬¹(pos〈1〉,pos〈2〉)º
](µ
We directly calculate Pr (p1,p2)∼η× [p16=p2] = Pr (m1,m2)∼µ× [m1(pos)6=m2(pos)] ≤ Pr (m1,m2)∼µ× [(m1,m2)∈¹hist〈1〉 ∩hist〈2〉=∅º],
where the inequality follows by the post-condition of Eq. (3.2): pairs of memories wherehist〈1〉 ∩hist〈2〉 is non-empty do not have different positions.
We turn to the product program to bound the last quantity. If the two process have not met yet, then
hist〈1〉 ∩hist〈2〉=∅. Since the processes are at most 10 apart, in each iteration of the loop there is a
9/10 chance the lagging process misses the leading process, preservinghist〈1〉 ∩hist〈2〉=∅. Since both
processes move at most 10 positions each iteration, there are at leastbT/10c −1 iterations so Pr
(m1,m2)∼µ×
[(m1,m2)∈¹hist〈1〉 ∩hist〈2〉=∅º]≤(9/10)
bT/10c−1.
By the coupling method (Theorem2.1.16), we conclude
dtv(η1,η2)≤ Pr
(p1,p2)∼η×
[p16=p2]≤(9/10)bT/10c−1.