-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathNetworking.scala
73 lines (49 loc) · 1.82 KB
/
Networking.scala
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
62
63
64
65
66
67
68
69
70
71
72
73
package distribution
import Protocol._
import ProtocolProof._
import FifoNetwork._
import stainless.collection._
import stainless.proof.check
import stainless.lang._
import stainless.annotation._
object Networking {
abstract class ActorId
abstract class Message
abstract class State
abstract class Parameter
abstract class Actor {
val myId: ActorId
final def !!(receiver: ActorId, m: Message)(implicit net: VerifiedNetwork) = {
net send (myId,receiver,m)
}
@pure
def receivePre(sender: ActorId, m: Message)(implicit net: VerifiedNetwork): Boolean = (??? : Boolean)
def receive(sender: ActorId, m: Message)(implicit net: VerifiedNetwork): Unit = {
require(networkInvariant(net.param, net.states, net.messages, net.getActor) && receivePre(sender, m))
(??? : Unit)
}
final def state(implicit net: VerifiedNetwork) = {
require(net.states.contains(myId))
net.getState(myId)
}
final def update(s: State)(implicit net: VerifiedNetwork) = {
net.updateState(myId, s)
}
}
def runActors(p: Parameter, schedule: List[(ActorId,ActorId,Message)]): Unit = {
require(runActorsPrecondition(p, schedule))
val net = makeNetwork(p)
def loop(schedule: List[(ActorId,ActorId,Message)]): Unit = {
require(networkInvariant(net.param, net.states, net.messages, net.getActor))
schedule match {
case Nil() => ()
case Cons((sender, receiver, m), schedule2) =>
if (validId(net, sender) && validId(net, receiver) && peekMessageEnsuresReceivePre(net, sender, receiver, m) && net.applyMessage(sender, receiver, m))
loop(schedule2)
// else
// error[Unit]("schedule not valid")
}
} ensuring(_ => networkInvariant(net.param, net.states, net.messages, net.getActor))
loop(schedule)
}
}