Created
January 6, 2012 13:53
-
-
Save iogakos/1570713 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% | |
% Authors: | |
% - Ioannis Gakos, 3634 | |
% - Alkis Livathinos, 3690 | |
%% | |
% Place disk on a pole | |
% | |
:- dynamic disk_state/2. | |
% Retract all predicates first | |
% | |
:- retractall(disk_state(_,_)). | |
% Fixed initialization | |
% | |
:- forall( | |
member(X, [1, 2, 3, 4, 5]), assert(disk_state(X, 1)) | |
). | |
% Use the following predicate to initialize the game | |
% | |
% N: disks | |
% P: pole to place the disks given | |
% | |
% Example: state_initialization([1,2,3,4,5], 3) | |
% | |
state_initialization(N, P) :- | |
forall( | |
member(X, N), assert(disk_state(X, P)) | |
). | |
% Show in which state the game is by printing to std | |
% out, on which pole each disk has been placed | |
% | |
% OUT: D:1 on P:2, means disk 1 is placed on pole 2 | |
% | |
show_state(N) :- | |
forall( | |
member(X, N), ( | |
disk_state(X, Y), | |
write('D:'), write(X), | |
write(' on '), | |
write('P:'), write(Y), | |
nl | |
) | |
). | |
% The following minimum related predicates are used | |
% to find the minimum element of a list | |
% | |
minimum([Min], Min). % minimum found | |
minimum([H,K|T],M) :- | |
H =< K, % H is less than or equal to K | |
minimum([H|T],M). % so use H | |
minimum([H,K|T],M) :- | |
H > K, % H is greater than K | |
minimum([K|T],M). % so use K | |
% Check if legal move | |
legal_move(Disk, Dest) :- | |
is_ontop(Disk), % check if on top | |
smaller_than(Disk, Dest). % check if smaller disk exists | |
% Checks if the top disk on the destination pole | |
% is bigger than the one to be placed | |
% | |
smaller_than(Disk, Dest) :- | |
findall(X, (member(Pole, [Dest]), disk_state(X, Pole)), Disks), | |
minimum(Disks, Min) -> Disk<Min ; \+ fail. | |
% Checks if the disk to be moved is on top of the pole | |
% | |
is_ontop(Disk) :- | |
disk_state(Disk, S), % Find where the disk is located | |
findall(X, (member(Pole, [S]), disk_state(X, Pole)), Disks), | |
minimum(Disks, Min), | |
write(Min), write('-'), write(Disk), nl, | |
Min =:= Disk. | |
% Check if problem solved by evaluating all disk_state | |
% predicates | |
% | |
validate :- | |
forall( | |
member(X, [1,2,3,4,5]), disk_state(X, 3) | |
). | |
% Implement the move of a disk, by calling place predicate. | |
% For example, if you like to move disk 1, to pole 3, | |
% call place(1, 3) | |
% | |
place(Disk, Dest) :- | |
legal_move(Disk, Dest) -> write('Legal move'), nl, | |
disk_state(Disk, S), % Find where the disk is located | |
retract(disk_state(Disk, S)), % retract from previous state | |
assert(disk_state(Disk, Dest)), % store new state | |
show_state([1,2,3,4,5]), | |
(validate -> write('Problem solved'); write('Not yet solved')); | |
write('Illegal move'), fail. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment