@@ -13,96 +13,118 @@ def foreachF = \s.\e.\com.\state.
1313 }
1414end ;
1515
16+ def foldM : (rec l . Unit + a * l ) -> b -> (b -> a -> Cmd b ) -> Cmd b =
17+ \xs . \b . \f . case xs
18+ (\_ . pure b )
19+ (λmatch \h . \t . b ' <- f b h; foldM t b' f )
20+ end
21+
1622// An infinite while cycle that carries a state.
17- def iterate = \state . \com .
18- n <- com state ;
19- iterate n com ;
20- end ;
23+ def iterate = \state . \com . n <- com state ; iterate n com end
2124
22- tydef RobotState = [gave_win : Bool , said_log_missing : Bool , said_loc : (Int * Int )] end ;
25+ // -------------------------------------------------------------------------
26+ // Robot State - this allows us to skip some commands, so that this hont robot
27+ // does not have to busy-wait to meet each robot
28+ tydef RobotState = [gave_win : Bool , said_loc : Int * Int , said_log_missing : Bool ] end
2329
2430// setters
25- def set_gave_win : Bool -> RobotState -> RobotState = \v . \s . [gave_win = v , said_log_missing = s . said_log_missing, said_loc = s . said_loc] end ;
26- def set_said_log_missing : Bool -> RobotState -> RobotState = \v . \s . [gave_win = s . gave_win, said_log_missing = v , said_loc = s . said_loc] end ;
27- def set_said_loc : (Int * Int ) -> RobotState -> RobotState = \v . \s . [gave_win = s . gave_win, said_log_missing = s . said_log_missing, said_loc = v ]end ;
31+ def set_gave_win : Bool -> RobotState -> RobotState
32+ = \v . \s .
33+ [gave_win = v , said_loc = s . said_loc, said_log_missing = s . said_log_missing]
34+ end
2835
29- tydef RobotsStateList = rec l . Unit + (Actor * RobotState * l ) end ;
36+ def set_said_log_missing : Bool -> RobotState -> RobotState
37+ = \v . \s .
38+ [gave_win = s . gave_win, said_loc = s . said_loc, said_log_missing = v ]
39+ end
3040
31- def emptyList = inl () end ;
41+ def set_said_loc : (Int * Int ) -> RobotState -> RobotState
42+ = \v . \s .
43+ [gave_win = s . gave_win, said_loc = v , said_log_missing = s . said_log_missing]
44+ end
3245
33- // At the beginning all robots can be given Win.
46+ // At the beginning each robot can be given Win.
3447def defaultState: RobotState =
35- [gave_win = False , said_log_missing = False , said_loc = (- 100 ,- 100 )]
36- end ;
48+ [gave_win = false , said_loc = (- 100 , - 100 ), said_log_missing = false ]
49+ end
3750
38- def query : Actor -> RobotsStateList -> RobotState = \rob . \l .
39- case l (\_ . defaultState) (λmatch \r . λmatch \s . \tail .
40- if (r == rob ) {s } {query rob tail }
41- )
42- end ;
51+ // The list of met robots
52+ tydef RobotsStateList = rec l . Unit + (Actor * RobotState * l ) end
4353
44- def update : Actor -> RobotState -> RobotsStateList -> RobotsStateList = \rob . \s . \l .
45- case l (\_ . inr (rob , s , emptyList)) (λmatch \nr . λmatch \ns . \tail .
46- if (nr == rob ) {
47- inr (rob , s , tail )
48- } {
49- inr (nr , ns , update rob s tail )
50- }
51- )
52- end ;
54+ def emptyList = inl () end
5355
54- myLoc <- whereami ;
56+ def query : Actor -> RobotsStateList -> RobotState
57+ = \rob . λcase
58+ (\_ . defaultState)
59+ (λmatch \r . λmatch \s . \rest .
60+ if (r == rob ) {s } {query rob rest }
61+ )
62+ end
5563
56- def foldM : (rec l . Unit + a * l ) -> b -> (b -> a -> Cmd b ) -> Cmd b =
57- \xs . \b . \f . case xs
58- (\_ . pure b )
59- (λmatch \h . \t . b2 <- f b h ; foldM t b2 f )
64+ def update : Actor -> RobotState -> RobotsStateList -> RobotsStateList
65+ = \rob . \s . λcase
66+ (\_ . inr (rob , s , emptyList))
67+ (λmatch \r . λmatch \os . \rest .
68+ if (r == rob ) {inr (rob , s , rest )} {inr (r , os , update rob s rest )}
69+ )
70+ end
71+
72+ // -------------------------------------------------------------------------
73+ // Running state
74+ tydef State = [can_wait : Bool , list : RobotsStateList ] end
75+
76+ def updateList: Actor -> RobotState -> State -> State
77+ = \rob . \rs . \state .
78+ [can_wait = true , list = update rob rs state . list]
6079end
6180
81+ // -------------------------------------------------------------------------
82+ // Running state
83+ myLoc <- whereami ;
84+
6285// Try to give a robot a Win, filtering out those that were already given a Win.
6386// The robot will also receive instructions, so it **must have a logger!**
64- def tryGive: Text -> RobotsStateList -> Cmd RobotsStateList = \msg . \ok .
87+ def tryGive: Text -> State -> Cmd State
88+ = \msg . \state .
89+ if (state . can_wait) {watch down ; wait 2048 } {};
6590 instant (
66- rs <- meetAll ;
67- foldM rs ok (\stateList . \ rob .
68- let state = query rob stateList in
91+ rs <- meetall ;
92+ foldM rs state (
93+ \stateAcc . \ rob . let state = query rob stateAcc . list in
6994 robLoc <- as rob {whereami };
7095 hasLog <- as rob {try {log " test" ; pure true } {pure false }};
7196 if (state . gave_win) {
72- // log $ "skipping the robot " ++ format rob ++ "because it already has a Win";
73- pure stateList
97+ pure stateAcc
7498 }
75- $ elif (robLoc != myLoc && state . said_loc != robLoc) {
76- log $ " the robot " ++ format rob ++ " is not in my cell" ;
77- pure (update rob (set_said_loc robLoc state ) stateList);
99+ $ elif (robLoc != myLoc && state . said_loc != robLoc) {
100+ log ( " the robot" ++ format rob ++ " is not in my cell" ) ;
101+ pure (updateList rob (set_said_loc robLoc state ) stateAcc)
78102 }
79- $ elif (not hasLog && state . said_log_missing)
80- {
81- say $ " the robot " ++ format rob ++ " is missing a logger!" ;
82- pure (update rob (set_said_log_missing true state ) stateList)
83- }
84- { // else
103+ $ elif (not hasLog && state . said_log_missing) {
104+ say (" the robot " ++ format rob ++ " is missing a logger!" );
105+ pure (updateList rob (set_said_log_missing true state ) stateAcc)
106+ } // else
107+ {
85108 try {
86- reprogram rob { log msg ; };
87- log $ " successfully reprogrammed robot " ++ format rob ;
109+ reprogram rob {log msg };
110+ log ( " successfully reprogrammed robot " ++ format rob ) ;
88111 give rob " Win" ;
89- log $ " successfully gave Win to robot " ++ format rob ;
90- pure (update rob (set_gave_win true state ) stateList )
112+ log ( " successfully gave Win to robot " ++ format rob ) ;
113+ pure (updateList rob (set_gave_win true state ) stateAcc )
91114 } {
92- log $ " the robot " ++ format rob ++ " is probably still active!" ;
93- pure stateList
94- };
115+ log ( " the robot " ++ format rob ++ " is probably still active!" ) ;
116+ pure [ can_wait = false , list = stateAcc . list]
117+ }
95118 }
96119 )
97120 )
98- end ;
121+ end
99122
100123// -------------------------------------------------------------------------
101124// RUN
102125// -------------------------------------------------------------------------
103-
104126log " Hi, I am the system hint robot" ;
105- iterate emptyList (tryGive
127+ iterate [ can_wait = true , list = emptyList] (tryGive
106128 $ " Send a robot to `salvage` me and come back to"
107129 ++ " `give base \ " Win\ " `. When the rescue robot stands"
108130 ++ " where I am and executes `salvage`, all my inventory"
@@ -111,4 +133,4 @@ iterate emptyList (tryGive
111133 ++ " NOTE: if you are still viewing me when I am salvaged,"
112134 ++ " you will be in for a surprise! If this happens just"
113135 ++ " type `view base` to return to viewing your base."
114- )
136+ )
0 commit comments