Home > Net >  Prolog - division
Prolog - division

Time:06-06

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...)

  • Related