2013-02-21 4 views
1

Ладно, так что я новичок в Прологе, так что я извиняюсь, если я совсем не могу получить мой вопрос по очень ясно, но это, где я борюсь:Пролог - сделать рекурсивный делитель

divide_by(X, D, I, R) :- (D > X), I is 0, R is X. 

divide_by(X, D, I, R) :- 
X >= D, 
X_1 is X - D, 
I_1 is I + 1, 
divide_by(X_1, D, I_1, R), 
R is X_1. 

Я пытаюсь написать программу, которая будет принимать два аргумента (X и D) и вернуть Iterations (I) и Remainder (R), чтобы он мог отображать результат X/D, когда пользователь вводит: divide_by (8,3, I, R). например.

При отслеживании кода я знаю, что я неверен, потому что первое приращение делает его равным 0, поэтому счетчик ошибочен. Но я не знаю, как объявить, что я 0, без его сброса при каждом повторении цикла. (Я не хочу объявлять I как 0 в запросе)

Я также понял, что когда он закончит рекурсию (когда X < D), тогда я буду установлен в 0 из-за базового футляра.

Может ли быть любезным, чтобы показать мне, как я могу это исправить?

ответ

1

Вам необходимо ввести аккумулятор и использовать вспомогательный предикат, то вроде этого:

divide(_,0,_,_) :- !, fail . % X/0 is undefined and so can't be solved. 
divide(0,_,0,0) :- !.  % 0/X is always 0. 
divide(X,Y,Q,R) :-   % the ordinary case, simply invoke the 
    divrem(X,Y,0,Q,R)   % helper with the accumulator seeded with 0 
    . 

divrem(X,Y,Q,Q,X) :- % if X < Y, we're done. 
    X < Y .    % 
divrem(X,Y,T,Q,R) :- % otherwise... 
    X >= Y ,    % as long as X >= Y, 
    X1 is X - Y ,  % compute the next X 
    T1 is T + 1 ,  % increment the accumulator 
    divrem(X1,Y,T1,Q,R) % recurse down 
    .     % Easy! 
+0

Это делает так много смысла, спасибо! Так просто, но я просто не мог туда добраться. Хотя во втором случае вы хотите> = во втором случае, а просто <в первом, иначе divide_by (6,6, I, R) даст результат I = 0, R = 6. – user2096383

+0

@ user2096383: Исправлено это для вас , –

Смежные вопросы