#prolog
#пролог
Вопрос:
У меня проблема с преобразованием числа в список цифр. Что случилось? Все работает хорошо, пока не вернется из рекурсии.
number_to_digits(0, [_ | _]).
number_to_digits(Number, List) :-
Number > 0,
NewNumber is div(Number, 10),
Digit is mod(Number, 10),
append([Digit], List, NewList),
number_to_digits(NewNumber, NewList).
Комментарии:
1. Вы добавляете его к
NewList
, который вы передаете рекурсивно. Но это наоборот.List
является результатом , тогда какNewList
будет (временным) результатом дляNewNumber
.2. Я пытался поменять местами newList и List, но у меня все равно не работает.
3.
number_to_digits(0,[a,b,c])
успешно
Ответ №1:
Одним из наиболее важных навыков программирования в Prolog является предоставление действительно четких имен переменным и предикатам. Вот ваше второе предложение с немного измененными именами переменных:
number_to_digits(Number, Digits) :-
Number > 0,
RemainingNumber is div(Number, 10),
LastDigit is mod(Number, 10),
append([LastDigit], Digits, RemainingDigits),
number_to_digits(RemainingNumber, RemainingDigits).
Например, если Number
есть 123
, то его LastDigit
есть 3
, а RemainingNumber
после разделения LastDigit
есть 12
.
Предполагая, что это number_to_digits
работает правильно, RemainingDigits
тогда должно быть [1, 2]
. Итак, ваш append
вызов:
append([3], Digits, [1, 2])
но это не может иметь никаких решений. Скорее, цифры 123
могут быть получены путем вызова:
append([1, 2], [3], Digits)
Итак, ваш код должен читать:
append(RemainingDigits, [LastDigit], Digits)
Если вы также исправите свое первое предложение (действительно ли цифры 0
какого-либо непустого списка?), То это позволит вам добиться прогресса:
?- number_to_digits(123, Digits).
Digits = [1, 2, 3] ;
% nontermination
Это находит правильное решение, но оно переходит в бесконечный поиск, когда вы запрашиваете у него больше ответов. Это связано с тем, что во RemainingDigits
момент append
вызова недостаточно информации о, поэтому Prolog пробует все более и более длинные списки. Проблема устранена, если поменять местами последние две цели, т. Е. поместить append
вызов после рекурсивного number_to_digits
вызова:
?- number_to_digits(123, Digits).
Digits = [1, 2, 3] ;
false.
При запросе дополнительных ответов Пролог теперь правильно сообщает нам, что их больше нет.