I am brand new to Prolog. Literally this week. I am looking to write a recursive Prolog predicate that accepts two numbers X, Y as input. It should output to screen a list of all numbers less than or equal to X that are evenly divisible by Y.
I have been looking into this over the last few days and am thouroghly confused. I have started by trying to divide Y into 1, displaying this on screen and then repeating the process. Would anyone have tips on gettingthis working. Once I get that, I will then be trying to ensure these are less than or equal to X.
So far I have the below, which may be completely wrong. Any help is appreciated. Apologies if the formatting comes off badly.
divide(X, Y) :-
S is 1,
Z is Y / S,
S is S 1,
write(Z),
divide(X, Y).
CodePudding user response:
The numbers less than 20 which divide by 3 start 3, 6, 9, ... i.e. start with the divisor 3 and count up adding 3 each time until you get past the cutoff.
e.g.
countup(X, Y, Counter) :- % if the counter is below the limit,
Counter =< X,
writeln(Counter), % print it.
Next is Counter Y, % count up by Y, e.g. 3
countup(X, Y, Next). % loop.
countup(X, _, Counter) :- % if the counter is past the limit,
Counter > X. % stop.
divide(X, Y) :- % start counting from Y, e.g. 3
countup(X, Y, Y).
In your code, this line:
S is S 1
is you saying "keep going if 2 is 3" and Prolog will say "it's not, case closed, stop here" and end your program. When you do S 1 you need to use a new variable for the result. Only the Prolog system can change variables, you can't (simplification).
This is the shape of an infinite loop:
divide(X, Y) :-
____,
____,
divide(X, Y).
X and Y never change so it's the same call each time; if it got past that S=S 1 then it would go round and round forever.
This shape:
divide(X, Y) :-
S is 1,
____,
divide(X, Y).
If it worked how you are trying, it would reset S back to 1 each time.
Since you need some case to handle looping and some case to handle stopping, and some test for passing the limit and something to pass S on through the loops, and I wanted words as variable names, quickly your short code turns into my much longer code even though it doesn't do much more.
(I didn't start from X and divide down because that would mean X had to be a multiple of Y. I thought you should be able to ask for the numbers less than 10 which are divisible by 9 and get 9 without having to deal with 10/9=1.11...)