Advertisement
Guest User

Untitled

a guest
Oct 20th, 2019
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.78 KB | None | 0 0
  1. %% DATA TYPES
  2. % Trains
  3. % We have 2 main trains and two spare trains.
  4. sort Train = struct t1 | t2 | sp1 | sp2;
  5. % We have several sections;
  6. sort Section = struct
  7. finishA | finishB | waitA | waitB |
  8. mergeWait | unload | forkSafety |
  9. safetySpotA | safetyPass | safetySpotB |
  10. mergeSafety | load | forkStart |
  11. startA | startB |
  12. raceA1 | raceB1 | raceA2 | raceB2 | raceA3 | raceB3 | raceA4 | raceB4 | raceA5 | raceB5;
  13.  
  14. sort SectionList = List(Section);
  15. map finishSections : SectionList;
  16. waitSections : SectionList;
  17. mustMoveSections : SectionList;
  18.  
  19. eqn finishSections = [finishA, finishB];
  20. waitSections = [waitA, waitB];
  21. mustMoveSections = [raceA1, raceA2, raceA3, raceA4, raceA5,
  22. raceB1, raceB2, raceB3, raceB4, raceB5,
  23. finishA, finishB,
  24. forkSafety, forkStart,
  25. mergeWait, mergeSafety,
  26. safetyPass
  27. ];
  28.  
  29.  
  30. % position of a switch.
  31. sort Position = struct A | center | B;
  32. % Moving indicator.
  33. sort Movement = struct Moving | Stationary;
  34. % Up down position
  35. sort BinaryPosition = struct Up | Down;
  36. % Occupancy
  37. sort Occupancy = struct Occupied | Free;
  38. % Section occupancy map
  39. sort SectionOccupancy = Section -> Occupancy;
  40. % Train section map
  41. sort TrainSection = Train -> Section;
  42. % Train movement map
  43. sort TrainMovement = Train -> Movement;
  44. % Switch position map
  45. sort SwitchPosition = Section -> Position;
  46.  
  47. %% ACTIONS
  48. act
  49. % Switch actions
  50. % Request switch to move
  51. switch_move : Section # Position;
  52. % Switch indicating the switch is moving or stationary
  53. switch_moving : Section # Movement;
  54. % Switch indicating the current position of the switch
  55. switch_pos : Section # Position;
  56.  
  57. % Train actions
  58. % train step, i.e. the train is moving and stepping to the next section
  59. train_step : Train;
  60. % train moving indicator, i.e. the train sents to the controller it is moving or stationary
  61. train_moving: Train # Movement;
  62. % train stop, i.e. the train receives a stop signal from the controller
  63. train_stop : Train;
  64. % train move, i.e. the train receives a move signal from the controller
  65. train_move : Train;
  66. % train indicating wheter it is empty or not
  67. train_empty : Train # Occupancy;
  68.  
  69. % Flag actions
  70. flag_move : Section # BinaryPosition; % Request flag to move
  71. flag_pos : Section # BinaryPosition; % Flag indicating the current position of the flag
  72.  
  73. % bar actions
  74. bars_move : Train # BinaryPosition; % Request bars to move
  75. bars_pos : Train # BinaryPosition; % Bars indicating the current position of the bars
  76.  
  77. % Section actions
  78. % Section indicating it is occupied or free
  79. occupied : Section # Occupancy;
  80.  
  81. % The control panel buttons
  82. loaded;
  83. emergency;
  84. add_train : Bool;
  85.  
  86. % Maintenance calls
  87. maintenance_train : Train;
  88. maintenence_defect_train : Train;
  89. maintenance_defect_switch : Section;
  90. maintenance_object_on_section : Section;
  91.  
  92. %% Communicating actions
  93. load : Train; load_in : Train; load_out : Train;
  94. load_done; load_done_in; load_done_out;
  95. unload : Train; unload_in : Train; unload_out : Train;
  96. unload_done; unload_done_in; unload_done_out;
  97. emergency_propagation; emergency_propagation_in; emergency_propagation_out;
  98. safety_maintenance : Train; safety_maintenance_in : Train; safety_maintenance_out : Train;
  99. verify_train_move : Train; verify_train_move_in : Train; verify_train_move_out : Train;
  100. verify_switch_move : Section; verify_switch_move_in : Section; verify_switch_move_out : Section;
  101. verify_section_occupancy : TrainSection; verify_section_occupancy_in : TrainSection; verify_section_occupancy_out : TrainSection;
  102. spare_trains : Bool; spare_trains_in : Bool; spare_trains_out : Bool;
  103.  
  104.  
  105. map safetySection : Position -> Section;
  106. var p : Position;
  107. eqn (p == A) -> safetySection(p) = safetySpotA;
  108. (p == B) -> safetySection(p) = safetySpotB;
  109. (p == center) -> safetySection(p) = safetyPass;
  110.  
  111. map startSection : Position -> Section;
  112. var p : Position;
  113. eqn (p == A) -> startSection(p) = startA;
  114. (p == B) -> startSection(p) = startB;
  115.  
  116. map occupiedSection : TrainSection # Section -> Bool;
  117. var ts : TrainSection;
  118. s : Section;
  119. eqn occupiedSection(ts, s) = ts(t1) == s || ts(t2) == s || ts(sp1) == s || ts(sp2) == s;
  120.  
  121. % Returns whether the next two sections of the given train is not occupied
  122. map clearHeadWay2 : TrainSection # SwitchPosition # Train -> Bool;
  123. var ts : TrainSection;
  124. sp : SwitchPosition;
  125. t : Train;
  126. eqn clearHeadWay2(ts, sp, t) = !(exists u : Train . (u != t) && (
  127. (ts(u) in [
  128. nextSection(ts(t), sp),
  129. nextSection(nextSection(ts(t), sp), sp)
  130. ])
  131. ));
  132.  
  133. % Given a section and the positions of both switches, give the next section.
  134. % Argument 2 is the position of the safety fork
  135. % Argument 3 is the position of the start fork
  136. map nextSection: Section # SwitchPosition -> Section;
  137. var s : Section;
  138. sp : SwitchPosition;
  139. q : Nat;
  140. eqn (startA == s) -> nextSection(s, sp) = raceA1;
  141. (raceA1 == s) -> nextSection(s, sp) = raceA2;
  142. (raceA2 == s) -> nextSection(s, sp) = raceA3;
  143. (raceA3 == s) -> nextSection(s, sp) = raceA4;
  144. (raceA4 == s) -> nextSection(s, sp) = raceA5;
  145. (raceA5 == s) -> nextSection(s, sp) = finishA;
  146.  
  147. (startB == s) -> nextSection(s, sp) = raceB1;
  148. (raceB1 == s) -> nextSection(s, sp) = raceB2;
  149. (raceB2 == s) -> nextSection(s, sp) = raceB3;
  150. (raceB3 == s) -> nextSection(s, sp) = raceB4;
  151. (raceB4 == s) -> nextSection(s, sp) = raceB5;
  152. (raceB5 == s) -> nextSection(s, sp) = finishB;
  153.  
  154. (finishA == s) -> nextSection(s, sp) = waitA;
  155. (finishB == s) -> nextSection(s, sp) = waitB;
  156. (waitA == s) -> nextSection(s, sp) = mergeWait;
  157. (waitB == s) -> nextSection(s, sp) = mergeWait;
  158. (mergeWait == s) -> nextSection(s, sp) = unload;
  159. (unload == s) -> nextSection(s, sp) = forkSafety;
  160.  
  161. (forkSafety == s) -> nextSection(s, sp) = safetySection(sp(forkSafety));
  162.  
  163. (safetySpotA == s) -> nextSection(s, sp) = mergeSafety;
  164. (safetyPass == s) -> nextSection(s, sp) = mergeSafety;
  165. (safetySpotB == s) -> nextSection(s, sp) = mergeSafety;
  166. (mergeSafety == s) -> nextSection(s, sp) = load;
  167. (load == s) -> nextSection(s, sp) = forkStart;
  168.  
  169. (forkStart == s) -> nextSection(s, sp) = startSection(sp(forkStart));
  170.  
  171.  
  172. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  173. % Parallel controller components
  174. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  175. proc movement_manager_proc(ts : TrainSection, tm : TrainMovement, sp : SwitchPosition, raiseFlag : Bool, spare_enabled : Bool, emergency_enabled : Bool) =
  176. emergency_enabled -> (
  177. emergency_propagation_in . movement_manager_proc(ts, tm, sp, raiseFlag, spare_enabled, true)
  178. ) <> (
  179. % Request the movement of switches (TODO: not always)
  180. emergency_propagation_in . train_stop(t1) . train_stop(t2) . train_stop(sp1) . train_stop(sp2) . movement_manager_proc(ts, tm, sp, raiseFlag, spare_enabled, false)
  181. + !occupiedSection(ts, forkStart) ->
  182. (
  183. (occupiedSection(ts, startA) && sp(forkStart) == A) -> switch_move(forkStart, B) . verify_switch_move_out(forkStart) . movement_manager_proc(ts, tm, sp, raiseFlag, spare_enabled, false)
  184. + (!occupiedSection(ts, startA) && sp(forkStart) == B) -> switch_move(forkStart, A) . verify_switch_move_out(forkStart) . movement_manager_proc(ts, tm, sp, raiseFlag, spare_enabled, false)
  185. )
  186. + verify_section_occupancy_out(ts) . movement_manager_proc(ts, tm, sp, raiseFlag, spare_enabled, false)
  187. % Update switch position map when the switches indicate a new position
  188. + sum p : Position . switch_pos(forkSafety, p) . movement_manager_proc(ts, tm, sp[forkSafety -> p], raiseFlag, spare_enabled, false)
  189. + sum p : Position . (p != center) -> switch_pos(forkStart, p) . movement_manager_proc(ts, tm, sp[forkStart -> p], raiseFlag, spare_enabled, false)
  190. % Train is moving, raise flag if the next section is a finish section and the raiseFlag boolean is true
  191. + sum t : Train . (tm(t) == Moving) -> train_step(t). (
  192. (nextSection(ts(t), sp) in finishSections) ->
  193. (
  194. raiseFlag -> flag_move(nextSection(ts(t), sp), Up) . movement_manager_proc(ts[t->nextSection(ts(t), sp)], tm, sp, false, spare_enabled, false)
  195. <>
  196. movement_manager_proc(ts[t->nextSection(ts(t), sp)], tm, sp, true, spare_enabled, false)
  197. )
  198. <>
  199. ((nextSection(ts(t), sp) in waitSections) ->
  200. flag_move(finishA, Down) . flag_move(finishB, Down) . movement_manager_proc(ts[t->nextSection(ts(t), sp)], tm, sp, raiseFlag, spare_enabled, false)
  201. <>
  202. movement_manager_proc(ts[t->nextSection(ts(t), sp)], tm, sp, raiseFlag, spare_enabled,false)
  203. )
  204. )
  205. + sum u, v : Train . (ts(u) == waitA && ts(v) == waitB && clearHeadWay2(ts, sp, u)) -> train_move(u).verify_train_move_out(u).movement_manager_proc(ts, tm[u->Moving], sp, raiseFlag, spare_enabled, false)
  206.  
  207. + sum u : Train . (ts(u) == waitB && !occupiedSection(ts, waitA) && clearHeadWay2(ts, sp, u)) -> train_move(u).verify_train_move_out(u).movement_manager_proc(ts, tm[u->Moving], sp, raiseFlag, spare_enabled, false)
  208.  
  209. + sum u : Train . (ts(u) == unload && clearHeadWay2(ts, sp, u)) -> unload_out(u).unload_done_in.switch_moving(forkSafety, Stationary).train_move(u).verify_train_move_out(u).movement_manager_proc(ts, tm[u->Moving], sp, raiseFlag, spare_enabled, false)
  210.  
  211. + sum u : Train . (ts(u) == load && clearHeadWay2(ts, sp, u)) -> load_out(u).load_done_in.switch_moving(forkStart, Stationary).train_move(u).verify_train_move_out(u).movement_manager_proc(ts, tm[u->Moving], sp, raiseFlag, spare_enabled, false)
  212.  
  213. + sum u, v : Train . (ts(u) == startA && ts(v) == startB && clearHeadWay2(ts, sp, u) && clearHeadWay2(ts, sp, v)) -> train_move(u).train_move(v).verify_train_move_out(u).verify_train_move_out(v).movement_manager_proc(ts, tm[u->Moving][v->Moving], sp, raiseFlag, spare_enabled, false)
  214.  
  215. + sum u : Train . (spare_enabled && (ts(u) == safetySpotA || ts(u) == safetySpotB) && clearHeadWay2(ts, sp, u)) -> train_move(u).verify_train_move_out(u).movement_manager_proc(ts, tm[u->Moving], sp, raiseFlag, spare_enabled, false)
  216. % TODO explain
  217. + sum t : Train . (clearHeadWay2(ts, sp, t) && ts(t) in mustMoveSections)->
  218. (
  219. train_move(t).verify_train_move_out(t).movement_manager_proc(ts, tm[t->Moving], sp, raiseFlag, spare_enabled, false)
  220. )
  221. <>
  222. (
  223. train_stop(t).movement_manager_proc(ts, tm[t->Stationary], sp, raiseFlag, spare_enabled, false)
  224. )
  225. + sum b : Bool . spare_trains_in(b) . movement_manager_proc(ts, tm, sp, raiseFlag, b, emergency_enabled)
  226. );
  227.  
  228. proc maintenance_manager_proc =
  229. sum t : Train . safety_maintenance_in(t) . maintenance_train(t) . maintenance_manager_proc
  230. % Verify the train is actually moving
  231. + sum t : Train . verify_train_move_in(t) . (train_moving(t, Moving) + (train_moving(t, Stationary) . maintenence_defect_train(t) . emergency_propagation_out)) . maintenance_manager_proc
  232. % Verify the switch is actually moving
  233. + verify_switch_move_in(forkSafety) . (switch_moving(forkSafety, Moving) + (switch_moving(forkSafety, Stationary) . maintenance_defect_switch(forkSafety) )) . maintenance_manager_proc
  234. + verify_switch_move_in(forkStart) . (switch_moving(forkStart, Moving) + (switch_moving(forkStart, Stationary) . maintenance_defect_switch(forkStart) )) . maintenance_manager_proc
  235. % Verify no object is on the track (that is not a train)
  236. + sum ts : TrainSection . verify_section_occupancy_in(ts) . ( sum s : Section . occupied(s, Occupied) . (
  237. (ts(t1) != s && ts(t2) != s && ts(sp1) != s && ts(sp2) != s) -> maintenance_object_on_section(s) . emergency_propagation_out
  238. ) ) . maintenance_manager_proc;
  239.  
  240. proc operator_manager_proc(emergency_enabled : Bool, add_train_position : Bool) =
  241. emergency_enabled -> (
  242. emergency_propagation_out . operator_manager_proc(true, add_train_position)
  243. ) <> (
  244. % Train load request
  245. sum t : Train . load_in(t) . bars_move(t, Up) . bars_pos(t, Up) . loaded . bars_move(t, Down) . bars_pos(t, Down) . load_done_out . operator_manager_proc(false, add_train_position)
  246. % Train unload request
  247. + sum t : Train . unload_in(t) . bars_move(t, Up) . bars_pos(t, Up) . train_empty(t, Free) . bars_move(t, Down) . bars_pos(t, Down) . unload_done_out . operator_manager_proc(false, add_train_position)
  248. % Ignore button presses when no load in progress
  249. + loaded . operator_manager_proc(false, add_train_position)
  250. + emergency . emergency_propagation_out . operator_manager_proc(true, add_train_position)
  251. + sum b : Bool . add_train(b) . (b != add_train_position) -> ( spare_trains_out(b) . operator_manager_proc(false, b) )
  252. );
  253.  
  254. glob dummySection : Section;
  255. dummyPosition : Position;
  256.  
  257. %init switch_proc(mergeWait, center) || switch_proc(forkSafety, center);
  258. init hide({
  259. train_stop, emergency, switch_move, switch_pos,
  260. flag_move
  261. },
  262. allow({
  263. train_move, train_moving, train_step, train_stop, train_empty,
  264. switch_move, switch_moving, switch_pos,
  265. flag_move, flag_pos,
  266. bars_move, bars_pos,
  267. loaded, add_train, emergency,
  268. occupied, load, load_done, unload, unload_done,
  269. safety_maintenance, verify_train_move,
  270. verify_switch_move, verify_section_occupancy,
  271. maintenance_train, maintenance_defect_train, maintenance_defect_switch, maintenance_object_on_section,
  272. emergency_propagation
  273. },
  274. comm({
  275. load_in | load_out -> load,
  276. unload_in | unload_out -> unload,
  277. load_done_in | load_done_out -> load_done,
  278. unload_done_in | unload_done_out -> unload_done,
  279. safety_maintenance_in | safety_maintenance_out -> safety_maintenance,
  280. verify_train_move_in | verify_train_move_out -> verify_train_move,
  281. verify_switch_move_in | verify_switch_move_out -> verify_switch_move,
  282. verify_section_occupancy_in | verify_section_occupancy_out -> verify_section_occupancy,
  283. emergency_propagation_in | emergency_propagation_out -> emergency_propagation
  284. },
  285. movement_manager_proc(
  286. (lambda t : Train . dummySection)
  287. [t1 -> startA]
  288. [t2 -> startB]
  289. [sp1 -> safetySpotA]
  290. [sp2 -> safetySpotB],
  291. (lambda t : Train . Moving),
  292. (lambda s : Section . dummyPosition)
  293. [forkSafety -> center]
  294. [forkStart -> A],
  295. true, false, false)
  296. || operator_manager_proc(false, false)
  297. )));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement