Extended Exercise: Missionaries and Cannibals

external ~<#71687#>The solution to this extended exercise requires many ``domain knowledge'' functions, structurally recursive functions on lists, algorithms, and accumulators. Ask students to annotate each function with the appropriate design recipe: domain knowledge, structural, and generative. If a function maintains an accumulator invariant, the function must contain an appropriate comment. The structurally recursive functions are instances of <#67813#><#42807#>map<#42807#><#67813#> and <#67814#><#42808#>filter<#42808#><#67814#>; <#67815#><#42809#>build-list<#42809#><#67815#>, <#67816#><#42810#>foldl<#42810#><#67816#> and <#67817#><#42811#>append<#42811#><#67817#> can also be used. There are also plenty of other opportunities for abstraction. Make sure students ``edit'' functions; if they don't, quiz them on how many changes they have to make for some possible modification of the problem. <#42812#>Warning<#42812#> The function is computationally intensive. It can take about a minute to run on a SparcStation.<#71687#> On occasion, accumulators are a part of a piece of compound data because a function manages many pieces of data (in the same class) at the same time. The following story poses just such a problem:
``Once upon a time, three cannibals were guiding three missionaries through a jungle. They were on their way to the nearest mission station. After some time, they arrived at a wide river, filled with deadly snakes and fish. There was no way to cross the river without a boat. Fortunately, they found a row boat with two oars after a short search. Unfortunately, the boat was too small to carry all of them. It could barely carry two people at a time. Worse, because of the river's width there was no way to bring the boat back other than to row it back. ``Since the missionaries could not trust the cannibals they had to figure out a plan to get all six of them safely across the river. The problem was that these cannibals would kill and eat missionaries as soon as there were more cannibals than missionaries at some place. Thus, our missionary-programmer had to devise a plan that guaranteed that there were never any missionaries in the minority at either side of the river. The cannibals, however, can be trusted to cooperate otherwise. Specifically, they won't abandon any potential food, just as the missionaries won't abandon any potential converts. Luckily one of the missionaries had taken a Scheme course and knew how to solve this problem.''
While we can solve the problem by hand, solving it with a Scheme function is more fun and more general. If the same story comes up again with different numbers of cannibals and missionaries or different boat sizes, we can use the same function to solve the problem again. As with every problem, we begin by laying out how to represent the problem in our data language and then study how to represent certain actions in the real world in our programming language. Here are two basic constants concerning the data representation:
<#42833#>(define<#42833#> <#42834#>MC<#42834#> <#42835#>3)<#42835#>
<#42836#>(define<#42836#> <#42837#>BOAT-CAPACITY<#42837#> <#42838#>2)<#42838#> 
Formulate the function in terms of these constants.
<#42844#>Exercise 32.2.1<#42844#> Provide a data representation for the states of a river crossing. A state should record the number of missionaries and cannibals on each side of the river and the location of the boat. Here is a graphical representation of the states:
rawhtml52
The two lines represent the river, the black and white dots the missionaries and cannibals, the black rectangle the boat. Determine the initial and final state of the game.~ external Solution<#67825#><#67825#> <#42851#>Exercise 32.2.2<#42851#> Develop a data representation for boat loads. Define <#67826#><#42853#>BOAT-LOADS<#42853#><#67826#>, the list of all possible boat loads. Develop the function <#67827#><#42854#>make-BOAT-LOADS<#42854#><#67827#>, which consumes boat's maximal capacity and constructs the list of possible boat loads.~ external Solution<#67828#><#67828#>
One way to deal with search problems in a systematic manner is to generate all possible successor states for the states we have reach so far, to filter out the interesting ones, and to start the search over from those. A successor state is reached by using a feasible transition, for example, an enabled move in a game, a boat trip, etc. Here is a graphical illustration of the situation for our problem: rawhtml53 The initial state in the top row has five possible successor states, one per feasible boat load. They are shown in the second row. Two of these successor states are illegal, because one side contains more cannibals than missionaries. One of the legal ones is the state in which one missionary and cannibal reached the right side of the river; it has three successor states in turn. The following exercises deal with generating the successor states and filtering out the interesting ones.

<#42864#>Tests<#42864#>:\ Formulate all tests as boolean-valued expressions that produce <#67829#><#42865#>true<#42865#><#67829#> if the expected value is the computed one, and <#67830#><#42866#>false<#42866#><#67830#> if not.~<#67831#><#67831#> <#42869#>Exercise 32.2.3<#42869#> Develop a function that consumes a state and returns a list of all possible successor states, that is, all those states that are reachable with one boat trip from one side of the river to the other. Develop a generalized version that consumes a list of states, and returns a list of states reachable with one crossing.~ external Solution<#67832#><#67832#> <#42876#>Exercise 32.2.4<#42876#> Develop a function that determines whether a give state is legal. A state is legal if it contains the proper number of missionaries and cannibals and if the missionaries on each side of the river are safe. Develop a generalized function that consumes a list of states and returns the sublist of legal states.~ external Solution<#67833#><#67833#> <#42883#>Exercise 32.2.5<#42883#> Develop a function that consumes a state and determines if it is final. Develop a generalized version that consumes a list of states and returns the sublist of final states.~ external Solution<#67834#><#67834#>
The functions we have developed can generate the successor states of a list of states and can detect whether any of the states reached so far are legal. Now we can develop a function that determines whether we can transport the missionaries and cannibals across the river.
<#42894#>Exercise 32.2.6<#42894#> Develop <#67835#><#42896#>mc-solvable?<#42896#><#67835#>, which consumes a list of states and generates the list of all successor states until it has found a final state. The function should simply produce <#67836#><#42897#>true<#42897#><#67836#> when it finds a final state.~ external Solution<#67837#><#67837#> <#42903#>Exercise 32.2.7<#42903#> Develop <#67838#><#42905#>mc-solution<#42905#><#67838#>. The function is an adaptation of <#67839#><#42906#>mc-solvable?<#42906#><#67839#> that not only produces <#67840#><#42907#>true<#42907#><#67840#> when it finds a solution but a list of river crossings if a given missionary-and-cannibal problem is solvable. <#42908#>Hint:<#42908#> \ Modify the state representations so that they accumulate the list of crossings that got the group to this particular state. For the initial state, this is just the empty list; for a final state, it is the desired solution.~ external Solution<#67841#><#67841#> <#42914#>Exercise 32.2.8<#42914#> A series of boat trips may bring the group of missionaries and cannibals back to the initial state (or some other previous state). The series may include two, four, or more boat trips. In short, the ``game'' contains cycles. Make up an example. The function <#67842#><#42916#>mc-solution<#42916#><#67842#> generates all those states reachable with, say, seven boat trips before it generates all those states reachable with eight crossings. Therefore we do not have to worry about cycles in solution attempts. Why? Modify the solution so that a state reached via a cycle is also illegal.

<#42917#>Note<#42917#>:\ This shows how the accumulator inside the state representation has two uses.~ external Solution<#67843#><#67843#>