Пролог Базовый рекурсивный отдел - PullRequest
0 голосов
/ 02 марта 2012

Я новичок в Прологе, и мне трудно исправить ошибки моей первой программы.

Требование программы состоит в том, что она делит 2 входа с использованием рекурсии и возвращает 0, если дивиденд больше делителя, и игнорирует остатки.

%Author: Justin Taylor

testquotient :-
    repeat,

    var(Divident), var(Divisor), var(Answer), var(End),

    write('Enter Divident: '),
    read(Divident),

    write('Enter Divisor: '),
    read(Divisor),

    quotient(Divident, Divisor, Answer),
    nl,
    write('Quotient is = '),
    write(Answer),
    nl,

    write('Enter 0 to quit, 1 to continue: '),
    read(End),

    (End =:= 0),!.

    quotient(_, 0, 'Undefined').
    quotient(0, _, 0).
    quotient(Divisor == Divident -> Answer = 1).
    quotient(Divisor < Divident -> Answer = 0).

quotient(Divident, Divisor, Answer) :-
    (Divisor > Divident -> Divisor = Divisor - Divident,
    quotient(Divident, Divisor, Answer + 1);
    Answer = Answer).

1 Ответ

1 голос
/ 04 марта 2012

Сначала прочитайте is.Введите help(is). в приглашении SWI-Prolog.Прочитайте весь раздел об «Арифметике» внимательно.Во-вторых, ваши первые несколько предложений для quotient являются совершенно неосновными, неверный синтаксис.Я покажу вам, как переписать один из них, другой вам придется сделать самостоятельно:

%% WRONG: quotient(Divisor == Divident -> Answer = 1).
quotient(Divisor, Divident, Answer) :-
    Divisor =:= Divident -> Answer = 1.
%% WRONG: quotient(Divisor < Divident -> Answer = 0).
....

Обратите внимание на использование =:= вместо ==.

Ваше последнее предложение для quotient выглядит почти правильно с первого взгляда, за исключением основных ошибок: объединение пролога, =, это не , повтор не , оператор присваивания!Мы не меняем значения, присвоенные логическим переменным (если X равно 5, что тут можно изменить? Это то, что есть).Нет, вместо этого мы определяем логическую переменную new , например

( Divisor > Divident -> NewDivisor = Divisor - Divident,

, и мы используем it в рекурсивном вызове,

%% WRONG: quotient(Divident, NewDivisor, Answer + 1) ; 

но это тоже неправильно, с новым Answer.Если вы добавляете 1 на своем пути вниз (когда вы вычитаете Divident из вашего Divisor - кстати, не должно ли быть наоборот), проверьте свою логику или, по крайней мере, поменяйте местами имена, "делитель"вы делите на ), что означает, что вы должны были указать начальное значение.Но вы, похоже, задаете значение терминала как 0, и это означает, что вы должны строить свой результат на обратном пути из глубины рекурсии:

%%not quite right yet
quotient(Divident, NewDivisor, NewAnswer), Answer = NewAnswer + 1 ;

Далее, Answer = Answer всегда выполняется успешно.В таких случаях мы просто пишем true.

Наконец, вы действительно должны использовать is на каждом шаге рекурсии, а не только в самом конце:

( Divisor > Divident -> NewDivisor is Divisor - Divident,           %% use "is"
  quotient(Divident, NewDivisor, NewAnswer), Answer is NewAnswer+1  %% use "is"
; true ).                                          %% is this really necessary?

Ваш 'Undefined' вызовет ошибку на 0, но пока оставим это.Кроме того, вам не нужно «объявлять» свои var s в Прологе.Линия var(Divident), ..., var(End), не имеет смысла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...