Search code examples
prologcollatz

collatz-list implementation using Prolog


I am trying to create a function called collatz_list in Prolog. This function takes two arguments, the first one is a number and the second in a list. This list will be my output of this function. So, here's my function:

collatz_list(1,[1]).
collatz_list(N,[H|T]) :-
   N > 1,
   N mod 2 =:= 0,
   collatz_list(N, [H|T]).  
collatz_list(N,[H|T]) :-
   N > 1,
   N mod 2 =:= 1,
   N is N*3 +1,
   collatz_list(N,[H|T]). 

I am struggling with creating the output list. Can anyone help me on that?

Thanks.


Solution

  • Assuming you want to write a collatz_list/2 predicate with parameters (int, list), where list is the collatz sequence starting with int and eventually ending with 1 (we hope so! It's an open problem so far); you just have to code the recursive definition in the declarative way.

    Here's my attempt:

    /* if N = 1, we just stop */
    collatz_list(1, []).
    
    /* case 1: N even
       we place N / 2 in the head of the list
       the tail is the collatz sequence starting from N / 2 */
    collatz_list(N, [H|T]) :-
        0 is N mod 2,
        H is N / 2, 
        collatz_list(H, T), !. 
    
    /* case 2: N is odd
       we place 3N + 1 in the head of the list
       the tail is the collatz sequence starting from 3N + 1 */
    collatz_list(N, [H|T]) :-
        H is 3 * N + 1, 
        collatz_list(H, T). 
    

    Modified version, includes starting number

    Let's test it:

    full_list(N, [N|T]) :-
        collatz_list(N, T).
    
    collatz_list(1, []).
    
    collatz_list(N, [H|T]) :-
        0 is N mod 2,
        H is N / 2, 
        collatz_list(H, T), !. 
    
    collatz_list(N, [H|T]) :-
        H is 3 * N + 1, 
        collatz_list(H, T). 
    
    ?- full_list(27, L).
    L = [27, 82, 41, 124, 62, 31, 94, 47, 142|...].