Repository navigation
Expand file tree
/
Copy pathRobot.mch
More file actions
226 lines (189 loc) · 8.46 KB
/
Copy pathRobot.mch
File metadata and controls
226 lines (189 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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/* Robot
* Author: Suwadith
* Creation date: 12/15/2019
*/
/* Operations
MoveNorth:
Moves the robot 1 square towards North by increasing the current y axis value by 1. (y+1)
MoveEast:
Moves the robot 1 square towards East by increasing the current x axis value by 1. (x+1)
MoveSouth:
Moves the robot 1 square towards South by decreasing the current y axis value by 1. (y-1)
MoveWest:
Moves the robot 1 square towards West by decreasing the current x axis value by 1. (x-1)
Teleport:
Teleports the robot from one square to another square where the squares are both empty (Non Internal Walls).
Teleport only works after an initial movement has been made. (E.g:- After the first MoveNorth Operation)
getPosition:
Returns the current position of the robot (x |-> y)
foundExit:
Returns yes/no depending on whether the robot has reached the exit square or not.
visitedSquare:
Returns whether the robot has visited a given square already (yes/no)
robotsRoute:
Returns the sequence of the path that the robot has gone through ({(1 |-> (x1 |-> y1)), (2 |-> (x2 |-> y2))})
*/
MACHINE
Robot
SEES
Maze
SETS
REPORT = {Exceeding_Maze_Boundary, Maze_Wall_Crash, Moved_North, Moved_East, Moved_South, Moved_West, Cannot_Teleport_Immediately, Cannot_Teleport_To_The_Same_Square, Teleported, yes, no}
// ENQUIRY = {yes, no}
VARIABLES
robotXPosition,
robotYPosition,
currentPosition,
visitedSquares
INVARIANT
// Robot's x-axis position is within the Maze's x-axis range (1-7)
robotXPosition : x_axis_range &
// Robot's y-axis position is within the Maze's y-axis range (1-5)
robotYPosition : y_axis_range &
// current position of the Robot (maplet (x |-> y)) is an element of the maze
currentPosition : maze &
// squares which have been visited by the Robot is stored as a sequence of Maze maplets
visitedSquares : seq(maze)
INITIALISATION
// Initializes all the position related variables by assigning (1, 1) as the initial suqare
robotXPosition := 1 ||
robotYPosition := 1 ||
currentPosition := ( 1 |-> 1 ) ||
visitedSquares := [( 1 |-> 1 )]
OPERATIONS
report <-- MoveNorth =
PRE report : REPORT
THEN
// Checks whether the square above the current position is within the maze
IF (robotYPosition + 1 > max(y_axis_range))
THEN
report := Exceeding_Maze_Boundary
// Checks whether the square above the current position is not an internal wall
ELSIF ((robotXPosition |-> robotYPosition + 1) : internal_walls)
THEN
report := Maze_Wall_Crash
ELSE
visitedSquares := (visitedSquares <- (robotXPosition |-> robotYPosition + 1)) ||
currentPosition := (robotXPosition |-> robotYPosition + 1) ||
robotYPosition := robotYPosition + 1 ||
report := Moved_North
END
END;
report <-- MoveEast =
PRE report : REPORT
THEN
// Checks whether the square to the right of the current position is within the maze
IF (robotXPosition + 1 > max(x_axis_range))
THEN
report := Exceeding_Maze_Boundary
// Checks whether the square to the right of the current position is not an internal wall
ELSIF ((robotXPosition + 1 |-> robotYPosition) : internal_walls)
THEN
report := Maze_Wall_Crash
ELSE
visitedSquares := (visitedSquares <- (robotXPosition + 1 |-> robotYPosition)) ||
currentPosition := (robotXPosition + 1 |-> robotYPosition) ||
robotXPosition := robotXPosition + 1 ||
report := Moved_East
END
END;
report <-- MoveSouth =
PRE report : REPORT
THEN
// Checks whether the square below the current position is within the maze
IF (robotYPosition - 1 < min(y_axis_range))
THEN
report := Exceeding_Maze_Boundary
// Checks whether the square below the current position is not an internal wall
ELSIF ((robotXPosition |-> robotYPosition - 1) : internal_walls)
THEN
report := Maze_Wall_Crash
ELSE
visitedSquares := (visitedSquares <- (robotXPosition |-> robotYPosition - 1)) ||
currentPosition := (robotXPosition |-> robotYPosition - 1) ||
robotYPosition := robotYPosition - 1 ||
report := Moved_South
END
END;
report <-- MoveWest =
PRE report : REPORT
THEN
// Checks whether the square to the left of the current position is within the maze
IF (robotXPosition - 1 < min(x_axis_range))
THEN
report := Exceeding_Maze_Boundary
// Checks whether the square to the left of the current position is not an internal wall
ELSIF ((robotXPosition - 1 |-> robotYPosition) : internal_walls)
THEN
report := Maze_Wall_Crash
ELSE
visitedSquares := (visitedSquares <- (robotXPosition - 1 |-> robotYPosition)) ||
currentPosition := (robotXPosition - 1 |-> robotYPosition) ||
robotXPosition := robotXPosition - 1 ||
report := Moved_West
END
END;
report <-- Teleport(teleportXPosition, teleportYPosition) =
PRE report : REPORT & teleportXPosition : NATURAL1 & teleportYPosition : NATURAL1
THEN
// Makes sure that this is not the first move
IF (size(visitedSquares) = 1)
THEN
report := Cannot_Teleport_Immediately
// Makes sure that the robot doesn't teleport to an internal wall
ELSIF ((teleportXPosition |-> teleportYPosition) : internal_walls)
THEN
report := Maze_Wall_Crash
// Makes sure that the robot doesn't teleport to the same current square
ELSIF (teleportXPosition = robotXPosition & teleportYPosition = robotYPosition)
THEN
report := Cannot_Teleport_To_The_Same_Square
// Makes sure that the robot doesn't teleport itself out of the maze
ELSIF ((teleportXPosition |-> teleportYPosition) /: maze)
THEN
report := Exceeding_Maze_Boundary
ELSE
visitedSquares := (visitedSquares <- (teleportXPosition |-> teleportYPosition)) ||
currentPosition := (teleportXPosition |-> teleportYPosition) ||
robotXPosition := teleportXPosition ||
robotYPosition := teleportYPosition ||
report := Teleported
END
END;
position <-- getPosition =
BEGIN
position := currentPosition
END;
enquiry <-- foundExit =
PRE enquiry : REPORT
THEN
// Checks if the robot's current position is the exit square
IF (currentPosition : exit_square)
THEN
enquiry := yes
ELSE
enquiry := no
END
END;
visited <-- visitedSquare(visitedXPosition, visitedYPosition) =
PRE visited : REPORT & visitedXPosition : NATURAL1 & visitedYPosition : NATURAL1
THEN
// Makes sure that the visited square x,y coordinates are within the maze
IF ((visitedXPosition |-> visitedYPosition) : maze)
THEN
// Checks if the robot has already visited a particular square (Doesn't include the current square, but all the previouse squares)
IF ((visitedXPosition |-> visitedYPosition) : ran(front(visitedSquares)))
THEN
visited := yes
ELSE
visited := no
END
ELSE
visited := Exceeding_Maze_Boundary
END
END;
route <-- robotsRoute =
BEGIN
route := visitedSquares
END
END