Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Prolog - логическое программирование

Даня Даня Ученик (91), на голосовании 1 неделю назад
Здравствуйте, разбираю тему "Рекурсия" в рамках изучения Пролога в университете, решил составить программу в Visual Prolog, которая считала бы сумму первых N чисел:
 domains 
a = integer
predicates
nondeterm sum(a,a)
clauses
sum(0,0).
sum(X,Sum) :- X1 = X - 1, sum(X1,Sum1), Sum = Sum1 + X, write(Sum),nl.
goal
write("Vvedite N: "), readint(N),sum(N,Sum),nl.

Программа выдает неоднозначный результат, вроде считает все верно, но в конце пишет "PROGRAMM ERROR. 1010". Был бы очень рад если сможете объяснить что это за ошибка такая и как от нее избавиться.

(То что раздел domains можно убрать и сразу в разделе предикатов писать nondeterm sum(integer,integer) это я знаю, просто мне так удобнее, навряд ли ведь это дает такую ошибку?)
Голосование за лучший ответ
Thomas Falcone Профи (760) 1 месяц назад
Ошибка "PROGRAMM ERROR. 1010" в Visual Prolog обычно связана с проблемами в логике программы или с неправильным использованием переменных. В вашем коде есть несколько моментов, которые стоит рассмотреть и исправить.

▎Проблемы в коде:

1. Вывод суммы на каждом уровне рекурсии: Ваша программа выводит сумму на каждом уровне рекурсии, что может привести к множественным выводам. Это не обязательно является ошибкой, но может быть нежелательным.

2. Необходимость определения базового случая: У вас правильно определён базовый случай sum(0, 0), но если N будет меньше 0, программа не сможет корректно обработать этот случай.

3. Неправильное использование переменных: В Prolog переменные должны быть правильно инициализированы и использоваться. В данном случае вы используете X1 = X - 1, что может вызвать проблемы.

▎Исправленный код:

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

domains
a = integer

predicates
nondeterm sum(a, a)

clauses
sum(0, 0).
sum(X, Sum) :-
X > 0,
X1 = X - 1,
sum(X1, Sum1),
Sum = Sum1 + X.

goal
write("Vvedite N: "),
readint(N),
(N >= 0 -> sum(N, Sum) ; write("N dolzhen byt' neotritsatelnym"), nl),
write("Summa pervykh N chisel: "),
write(Sum), nl.


▎Объяснение изменений:

1. Проверка на неотрицательное значение: Добавлена проверка N >= 0 перед вызовом sum/2. Это предотвратит вызов функции с отрицательным значением.

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

3. Корректное использование переменной X: Проверка X > 0 гарантирует, что мы не будем пытаться вычислить сумму для отрицательных значений.

Попробуйте запустить исправленный код. Если возникнут дополнительные ошибки или вопросы, дайте знать!
Даня ДаняУченик (91) 1 месяц назад
Спасибо, добавил подцель N>0, ошибка пропала, и в самом деле такая проверка имеет смысл хоть и изначально подразумевается что N неотрицательное
Похожие вопросы