forked from wenhuizhang/summer-school-2020
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexercise01.dfy
61 lines (51 loc) · 2.33 KB
/
exercise01.dfy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//#title Midterm Project
//#desc Build a distributed lock server. Define how a host implements your
//#desc protocol in host.i; write your safety spec and proof here.
// This challenge differs from LockServer (from chapters 03 and 04) in two
// ways. First, there is no central server that coordinates the activity.
// Second, the hosts can communicate only via asynchronous messages; a single
// state machine transition cannot simultaneously read or update the state of
// two hosts.
//
// To guard against duplicate messages, the nodes associate a monotonically
// increasing epoch number with the lock. Initially, node 0 holds the lock and
// its epoch number is 1. A node that holds the lock can “grant” it to another
// node by sending them a “Grant” message which has an epoch number that is
// greater than the node's epoch number. A node that receives such a message
// will become the new holder and will set its epoch number to the message’s
// epoch number.
// You'll first need to modify 'host.i.dfy' to define the protocol message
// format and the host behavior.
// Then come back here define the safety condition and prove that the
// distributed system made from that protocol maintains it.
include "distributed_system.s.dfy"
module SafetySpec {
import opened HostIdentifiers
import DistributedSystem
// No two hosts think they hold the lock simulatneously.
predicate Safety(c:DistributedSystem.Constants, v:DistributedSystem.Variables) {
false // Replace this placeholder with an appropriate safety condition: no two clients hold
}
}
module Proof {
import opened HostIdentifiers
import Host
import opened DistributedSystem
import opened SafetySpec
// Here's a predicate that will be very useful in constructing inviariant conjuncts.
predicate InFlight(c:Constants, v:Variables, message:Host.Message) {
&& v.WF(c)
&& message in v.network.sentMsgs
&& false // ...and then add a check that the message's epoch is still valid.
}
predicate Inv(c: Constants, v:Variables) {
true // Replace this placeholder with an invariant that's inductive and supports Safety.
}
lemma SafetyProof(c: Constants, v:Variables, v':Variables)
ensures Init(c, v) ==> Inv(c, v)
ensures Inv(c, v) && Next(c, v, v') ==> Inv(c, v')
ensures Inv(c, v) ==> Safety(c, v)
{
// Develop any necessary proof here.
}
}