I want to print the divisors of a number in Prolog and I have made the following code:
find_and_display_divisors(N) :-
write('Divisors of '), write(N), write(':'), nl,
find_divisors(N, 1).
find_divisors(N, D) :-
D =< N,
0 is N mod D,
write(D), write(' '),
NextD is D + 1,
find_divisors(N, NextD).
find_divisors(_, _).
The problem that I have is that when I call my program with find_and_display_divisors(8), it only prints 1 2 true; however, it is missing the other values like 4 and 8. What am I missing?
When a number is not a divisor, you still need to go to next step.
find_divisors(_, _)
just stops the iteration at the first non-divisor.
So you will need a new clause covering the non-divisor part.
find_divisors(N, D) :-
D =< N,
M is N mod D,
M > 0,
NextD is D + 1,
find_divisors(N, NextD).
You might want to include this if you want the predicate to succeed.
find_divisors(N, D) :- N < D.
PS: TA_intern's answer is idiomatic way to do it. Decouple side effects from logic code as much as possible.
Full working code:
find_and_display_divisors(N) :-
write('Divisors of '), write(N), write(':'), nl,
find_divisors(N, 1).
find_divisors(N, D) :-
D =< N,
0 is N mod D,
write(D), write(' '),
NextD is D + 1,
find_divisors(N, NextD).
find_divisors(N, D) :-
D =< N,
M is N mod D, M > 0,
NextD is D + 1,
find_divisors(N, NextD).
find_divisors(N, D) :- N < D. % you can ignore this if you just need to print