Reputation: 1
I have a trouble with conversion a number to list of digits. What's wrong? Everything works well until it returns from recursion.
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).
Upvotes: 0
Views: 510
Reputation: 9378
One of the most important skills for programming in Prolog is giving really clear names to variables and predicates. Here is your second clause with variable names changed a bit:
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).
For example, if Number
is 123
, then its LastDigit
is 3
, and the RemainingNumber
after splitting off the LastDigit
is 12
.
Assuming that number_to_digits
works correctly, RemainingDigits
should then be [1, 2]
. So your append
call is:
append([3], Digits, [1, 2])
but this cannot have any solutions. Rather, the digits of 123
can be obtained by calling:
append([1, 2], [3], Digits)
So your code should read:
append(RemainingDigits, [LastDigit], Digits)
If you correct your first clause as well (are the digits of 0
really any non-empty list?), then this allows you to make progress:
?- number_to_digits(123, Digits).
Digits = [1, 2, 3] ;
% nontermination
This finds the correct solution, but it goes into an infinite search when you ask it for more answers. This is because there is not enough information about RemainingDigits
at the time of the append
call, so Prolog tries longer and longer lists. The problem is fixed if you swap the last two goals, i.e., put the append
call after the recursive number_to_digits
call:
?- number_to_digits(123, Digits).
Digits = [1, 2, 3] ;
false.
When asking for more answers, Prolog now correctly tells us that there are no more.
Upvotes: 2