Making nested list of consecutive numbers in Prolog

72 Views Asked by At

Can anyone check whether this is a complete BS of a code or not. Obviously it doesn't work because I'm getting false as answer but I just wanna know if this is on the right track or just totally NOT it. Btw I've never programmed on prolog before, I am just learning the basics.

nested([], []).
nested([H1], [[H1]])
nested([H1,H2|T], [Out]) :- 
    H2 - H1 is 1, 
    nested([H2|T], [[H1|Out]]);
    nested([H2|T], [H1|Out]).
2

There are 2 best solutions below

0
brebs On

The question needs narrowing down.

I would suggest looking at Peano arithmetic, which has useful relational properties. As a simple case:

consecutive_peano_list([H|T]) :-
    consecutive_peano_list_(T, H).

consecutive_peano_list_([], _).
consecutive_peano_list_([H|T], P) :-
    H = s(P),
    consecutive_peano_list_(T, H).

This then creates an elegant list of successors, without caring about the starting point in the first element:

?- consecutive_peano_list(L).
L = [_] ;
L = [_A, s(_A)] ;
L = [_A, s(_A), s(s(_A))] ;
L = [_A, s(_A), s(s(_A)), s(s(s(_A)))] ;
2
slago On

To test equality use =:=/2 (predicate is/2 should be used with unbound left operand). Also, always use parentheses around disjunctions (;/2) and put them in evidence. So your code can be fixed as follows:

% nested(+List, -Nested)
 
  nested([], []).
  nested([X], [[X]]).
  nested([X1,X2|Xs], Out) :-
     X1 + 1 =:= X2,
     (   Out = [[X1|Ys]]
     ;   Out = [ X1|Ys ] ),
     nested([X2|Xs], Ys).

Example:

?- nested([1,2,3], N).
N = [[1, [2, [3]]]] ;
N = [[1, 2, [3]]] ;
N = [1, [2, [3]]] ;
N = [1, 2, [3]] ;
false.

To avoid unpacking/packing each list element twice, and provides determinism on the last answer, change your code as follows:

% nested(+List, -Nested)

  nested([], []).
  nested([X1|Xs], Out) :-     % unpack first element
      nested(Xs, X1, Out).

  nested([], X1, [[X1]]).
  nested([X2|Xs], X1, Out) :- % unpack second element
      X1 + 1 =:= X2,
      (   Out = [[X1|Ys]]
      ;   Out = [ X1|Ys ] ),
      nested(Xs, X2, Ys).     % no need to pack

Example:

?- nested([1,2,3], N).
N = [[1, [2, [3]]]] ;
N = [[1, 2, [3]]] ;
N = [1, [2, [3]]] ;
N = [1, 2, [3]].