-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSimplePathModel.tla
More file actions
195 lines (153 loc) · 8.46 KB
/
SimplePathModel.tla
File metadata and controls
195 lines (153 loc) · 8.46 KB
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
-------------------------- MODULE SimplePathModel --------------------------
(***************************************************************************)
(* Implements a rate-limited, simple path model for packets traversing it *)
(* to reach some destination. The model is able to unconditionally delay, *)
(* drop, or deliver the packets to the destination as will. *)
(* *)
(* ACKs are returned for each delivered packet (though the ACK itself can *)
(* be dropped as well, but that behavior can be changed). *)
(* *)
(* The model will trigger timeouts for dropped packets. *)
(***************************************************************************)
EXTENDS Integers, TLC, Sequences
(***************************************************************************)
(* C : The link capacity. After 't' timesteps, no more than 'C*t' *)
(* packets can be in the link. Any more is immediately *)
(* dropped. *)
(* MAX_ARRIVAL: The maximum rate of packet arrivals. *)
(* DROP_ACK : A boolean constant, if TRUE, the model can drop ACKs on *)
(* a whim. *)
(* nAck : The number of ACKs returned. *)
(* inFlight : The number of packets traversing the link. *)
(* timeout : If '1', a packet has not reached it's destination and has *)
(* timed out. *)
(***************************************************************************)
CONSTANT C, MAX_T, MAX_ARRIVAL, DROP_ACK
VARIABLES t, ticked, nAck, inFlight, timeout
timeVars == <<t, ticked>>
pathVars == <<nAck, inFlight, timeout>>
vars == <<t, ticked, nAck, inFlight, timeout>>
time == INSTANCE Time WITH t <- t, ticked <- ticked, MAX_T <- MAX_T
TypeOK == /\ timeout \in 0..1
/\ nAck \in Nat
/\ nAck >= 0
/\ inFlight \in Nat
/\ inFlight >= 0
/\ time!TypeOK
Init == /\ timeout = 0
/\ nAck = 0
/\ inFlight = 0
/\ time!Init
Finished == time!Finished
(***************************************************************************)
(* When the link contains more than 't*C' packets, excessive packets WILL *)
(* be dropped immediately, but triggering a timeout and then dropping the *)
(* number of packets to 't*C'. *)
(* *)
(* Certain buffering strategies can be employed here to help, as well as *)
(* some token bucket filters, but we will not implement that yet. *)
(***************************************************************************)
ExcessivePacketDropIsEnabled == /\ inFlight > t * C
(***************************************************************************)
(* At the end of each timestep, the path model may accept new packets into *)
(* the link as inflight packets. *)
(***************************************************************************)
PacketInjectionIsEnabled == /\ ticked = 1
/\ Finished = FALSE
(***************************************************************************)
(* Path model is only enabled at the start of each timestep. Before it *)
(* procedes to take actions per packet, it check whether or not excessive *)
(* packets are present. If so, the packets will be dropped. *)
(***************************************************************************)
PathModelIsEnabled == /\ inFlight > 0
/\ ticked = 0
/\ Finished = FALSE
/\ ~ExcessivePacketDropIsEnabled
\* Deliver packets and return ACKs
DeliverPacket == /\ PathModelIsEnabled
/\ timeout' = 0
/\ nAck' = nAck + 1
/\ inFlight' = inFlight - 1
/\ UNCHANGED timeVars
\* Deliver and return ACK, but trigger timeout
DeliverLate == /\ PathModelIsEnabled
/\ timeout' = 1
/\ nAck' = nAck + 1
/\ inFlight' = inFlight - 1
/\ UNCHANGED timeVars
\* Deliver the packet, but trigger timeout by dropping an ACK.
\* Can be disabled completely
DeliverAndDropAck == /\ PathModelIsEnabled
/\ DROP_ACK
/\ timeout' = 1
/\ nAck' = nAck
/\ inFlight' = inFlight - 1
/\ UNCHANGED timeVars
\* Drop the packet completely and trigger timeout
DropCompletely == /\ PathModelIsEnabled
/\ timeout' = 1
/\ nAck' = nAck
/\ inFlight' = inFlight - 1
/\ UNCHANGED timeVars
\* Drop packets exceeding the link capacity
DropExcess == /\ ExcessivePacketDropIsEnabled
/\ timeout' = 1
/\ inFlight' = t * C
/\ UNCHANGED <<timeVars, nAck>>
Next == \/ DeliverPacket
\/ DeliverLate
\/ DeliverAndDropAck
\/ DropCompletely
\/ DropExcess
\/ /\ ~ExcessivePacketDropIsEnabled
/\ time!Next
/\ UNCHANGED pathVars
\* Packet deliverance must remain strongly fair to prevent useless
\* scenarios.
Fairness == /\ time!Fairness
/\ SF_vars(DeliverPacket)
Spec == Init /\ [][Next]_vars /\ Fairness
(***************************************************************************)
(* Always either: *)
(* 1) The link utility is less than or equal to 1 *)
(* 2) We are at the start of taking actions per packet, which means *)
(* that if link utility is larger than 1, it will be immediately *)
(* corrected. *)
(***************************************************************************)
RateLimited == [] (inFlight <= t * C \/ ticked = 0)
(***************************************************************************)
(* To test the specification, we create another spec on top of the spec *)
(* above. This specification will allow for packet injections of random *)
(* values and if everything goes well, the invariants must remain true. *)
(***************************************************************************)
Max(a, b) == IF a > b THEN a ELSE b
newPacketsAllowed(timePassed, existingPackets) == Max(
timePassed * MAX_ARRIVAL - existingPackets - 1, 0
)
getRandomArrival(timePassed, existingPackets) ==
RandomElement(0..newPacketsAllowed(timePassed, existingPackets))
InjectPackets == /\ PacketInjectionIsEnabled
/\ inFlight' = inFlight + getRandomArrival(t, inFlight)
/\ nAck' = nAck
/\ timeout' = timeout
/\ time!DoTick
NextTest == \/ Next
\/ InjectPackets
(***************************************************************************)
(* For the same reason that delivering packets must be strongly fair, *)
(* having packets to deliver in the first place must also be strongly *)
(* fair! *)
(***************************************************************************)
FairnessTest == /\ time!Fairness
/\ SF_vars(DeliverPacket)
/\ SF_vars(InjectPackets)
SpecTest == Init /\ [][NextTest]_vars /\ FairnessTest
(***************************************************************************)
(* Termination condition just to check we have not overriden the time *)
(* module. *)
(***************************************************************************)
Termination == time!Termination
=============================================================================
\* Modification History
\* Last modified Wed Nov 02 15:57:14 IRST 2022 by Arvin
\* Created Thu Oct 27 00:16:46 IRST 2022 by Arvin