housamz
housamz

Reputation: 465

Prolog - Returning a List from a Recursive Predicate

I am using GNU-Prolog, and I have the following code that finds the numbers less than X which are divisible by Y. Assume X and Y > 0.

find_num(X, Y) :-
     findall(N, between(1,X,N), List),
     check_list(List, Y).

check_list([Head|Tail], Y) :-
    ( 
        divides(Head, Y) ->
            format('~w ~s ~w ~n', [Head, "divisible by", Y]);
        true
    ),

check_list(Tail, Y).

divides(X, Y) :-
    X mod Y =:= 0.

The code outputs a text for the numbers, but I want the result to be a list like X = [1,2,3].

I tried multiple ways to make the list, but didn't succeed, examples:

check_list([Head|Tail], Y) :-
( 
    divides(Head, Y) ->
        findall( X, determine_item(Head, X), List );
    true
),

check_list(Tail, Y).

or

find_num(X, Y) :-
    findall(N, between(1,X,N), List),
    findall(N, check_list(List, Y, N), List2),
    write(List2).

check_list([Head|Tail], Y, _) :-
    ( 
        divides(Head, Y) ->
            Head;
        true
    ),
    check_list(Tail, Y).

divides(X, Y) :-
    X mod Y =:= 0.

Any help would be appreciated.

Upvotes: 1

Views: 441

Answers (1)

max66
max66

Reputation: 66200

If you want a list, your find_num (and your check_list) needs a third argument so...

What about

divides(X, Y) :-
    X mod Y =:= 0.

find_num(X, Y, Lout) :-
     findall(N, between(1, X, N), Lin),
     check_list(Lin, Y, Lout).

check_list([], _, []).

check_list([H | Tin], Y, [H | Tout]) :-
  divides(H, Y),
  check_list(Tin, Y, Tout).

check_list([H | Tin], Y, Lout) :-
  \+ divides(H, Y),
  check_list(Tin, Y, Lout).

?

Upvotes: 1

Related Questions