This object of this famous puzzle is to move N disks from the left peg to the right peg using the center peg as an auxiliary holding peg. At no time can a larger disk be placed upon a smaller disk. The following diagram depicts the starting setup for N=3 disks.
Here is a recursive Prolog program that solves the puzzle. It consists of two clauses.
The variables filled in by '_' (or any variables beginning with underscore) are 'don't-care' variables. Prolog allows these variables to freely match any structure, but no variable binding results from this gratuitous matching.move(1,X,Y,_) :- write('Move top disk from '), write(X), write(' to '), write(Y), nl. move(N,X,Y,Z) :- N>1, M is N-1, move(M,X,Z,Y), move(1,X,Y,_), move(M,Z,Y,X).
Here is what happens when Prolog solves the case N=3.
?- move(3,left,right,center). Move top disk from left to right Move top disk from left to center Move top disk from right to center Move top disk from left to right Move top disk from center to left Move top disk from center to right Move top disk from left to right yes
The first clause in the program describes the move of a single disk. The second clause declares how a solution could be obtained, recursively. For example, a declarative reading of the second clause for N=3, X=left, Y=right, and Z=center amounts to the following:
move(3,left,right,center) ifThis declarative reading of the clause is obviously correct. The procedural reading is closely related to the declarative interpretation of the recursive clause. The procedural interpretation would go something like this:
move(2,left,center,right) and ] *
move(1,left,right,center) and
move(2,center,right,left). ] **
In order to satisfy the goal ?- move(3,left,right,center) do this :Also, we could write the declarative readings for N=2:
satisfy the goal ?-move(2,left,center,right), and then
satisfy the goal ?-move(1,left,right,center), and then
satisfy the goal ?-move(2,center,right,left).
move(2,left,center,right) if ] *Now substitute the bodies of these last two implications for the heads and one can "see" the solution that the prolog goal generates.
move(1,left,right,center) and
move(1,left,center,right) and
move(1,right,center,left).
move(2,center,right,left) if ] **
move(1,center,left,right) and
move(1,center,right,left) and
move(1,left,right,center).
move(3,left,right,center) ifA procedural reading for this last big implication should be obvious. This example illustrates well three major operations of Prolog:
move(1,left,right,center) and
move(1,left,center,right) and *
move(1,right,center,left) and
---------------------------
move(1,left,right,center) and
---------------------------
move(1,center,left,right) and
move(1,center,right,left) and **
move(1,left,right,center).
1) Goals are matched against the head of a rule, andThe variable matching process is called unification.2) the body of the rule (with variables appropriately bound) becomes a new sequence of goals, repeatedly,
until
3) some base goal or condition is satisfied, or some simple action is taken (like printing something).
Exercise 2.3.1 Draw a program clause tree for the goal 'move(3,left,right,center)' show that it is a consequence of the program. How is this clause tree related to the substitution process explained above?
Exercise 2.3.2 Try the Prolog goal ?-move(3,left,right,left). What's wrong? Suggest a way to fix this and follow through to see that the fix works.