Math Prolog-写连续数_
我的任务是:让这个河内程序在写每个句子之前先写一个连续的数字 河内计划是这样的:Math Prolog-写连续数_,math,prolog,towers-of-hanoi,Math,Prolog,Towers Of Hanoi,我的任务是:让这个河内程序在写每个句子之前先写一个连续的数字 河内计划是这样的: hanoi(N):-move(N,left,middle,right). move(0,_,_,_):- !. move(N,A,B,C):- M is N-1, move(M,A,C,B), inform(A,B), move(M,C,B,A). inform(A,B):- write('MOVING DISK FROM '), write(A),write(' TO '),write(B),nl. 我希
hanoi(N):-move(N,left,middle,right).
move(0,_,_,_):- !.
move(N,A,B,C):- M is N-1, move(M,A,C,B), inform(A,B), move(M,C,B,A).
inform(A,B):- write('MOVING DISK FROM '), write(A),write(' TO '),write(B),nl.
我希望输出像这样:
1: MOVING DISK FROM left TO middle
2: MOVING DISK FROM left TO right
3: MOVING DISK FROM middle TO right
4: MOVING DISK FROM left TO middle
5: MOVING DISK FROM right TO left
6: MOVING DISK FROM right TO middle
7: MOVING DISK FROM left TO middle
直接的方法是使用表示行号的动态谓词。使用assert/retract并不是实时友好的,但是对于这样的应用程序来说它工作得很好。为了可读性,我重新格式化了您的工作河内代码,并添加了注释行:
% hanoi
%
:- dynamic(line/1). % Define a dynamic predicate "line"
hanoi(N) :-
assertz(line(1)), % Assert the first line as 1
move(N, left, middle, right).
move(0, _, _, _) :- !.
move(N, A, B, C) :-
M is N-1,
move(M, A, C, B),
inform(A, B),
move(M, C, B, A).
inform(A, B) :-
line(N), % get the current line number
NextN is N + 1, % next line number will be current one plus 1
retract(line(_)), % retract the old line number
assertz(line(NextN)), % assert the next line number for next time
write(N), % write the line number
write(': '), % and a delimiter
write('MOVING DISK FROM '),
write(A),
write(' TO '),
write(B),
nl.
还有其他生成连续数字的方法,例如以下最简单的情况
sequence(1).
sequence(X) :- sequence(Y), X is Y + 1.
| ?- sequence(X).
X = 1 ? ;
X = 2 ? ;
X = 3 ? ;
X = 4 ?
在某些情况下,类似的内容可以与谓词集成,以提供序列号。由于<代码>河内<代码>谓词具有树状递归,所以我发现使用<代码> AsjDist机制更容易。 < P>首先考虑使用DCG来描述移动列表:
hanoi(N, Moves) :- phrase(moves(N,left,middle,right), Moves).
moves(0,_,_,_) --> [].
moves(N,A,B,C) --> { N #> 0, M #= N-1 }, moves(M,A,C,B), [A->B], moves(M,C,B,A).
这样可以将程序逻辑与打印结果等副作用分开。一旦您有了移动列表,就可以轻松地编写它们,例如:
write_moves([], _).
write_moves([From->To|Ms], N) :-
format("~w: move disk from ~w to ~w\n", [N,From,To]),
N1 #= N + 1,
write_moves(Ms, N1).
示例查询及其结果:
?- hanoi(3, Moves), write_moves(Moves, 1).
1: move disk from left to middle
2: move disk from left to right
3: move disk from middle to right
4: move disk from left to middle
5: move disk from right to left
6: move disk from right to middle
7: move disk from left to middle
Moves = [ (left->middle), (left->right), (middle->right), ...].