Trying to find a solution to a predicate conception

I am trying to find a solution for the following predicate:

Predicate: line_predicate(I, List_Integers, List_Next_To)
- I is an Integer (>=1),
- List_Integers is a List of Integers that does not include I, and are sorted
- List_Next_To is a List that is obtained from List_Integers, that are the values next to I
- line_predicate(2, [4,5,10,12], [4])
- line_predicate(14, [4,5,10,12], [12])
- line_predicate(7, [4,5,10,12], [5,10])

I have already written some code, but it does not work:

line_predicate(_, [], []) :- !.

line_predicate(_, [H | []], [H | []]) :- !.

line_predicate(I, [P | R], [H | T]) :-
    P > I, !,
    H = P,
    line_predicate(I, R, T).

line_predicate(I, [P,S | R], [H,J | T]) :-
    between(P, S, I), !,
    H = P,
    J = S,
    line_predicate(I, R, T).

line_predicate(_, [_ | R], T) :-
    line_predicate(_, R, T).

I would appreciate all your help on finding a solution to this problem, without using any external library.
Any explanation why the above code is not working would be very important in order to be able to improve my skills.


Have you tried using trace/0, gtrace/0 or failure slice?

Thanks for your comment. Yes I tried. But I am learning Prolog and I am still struggling.

When using recursion the first things to get correct is the base cases, E.g empty list, then go after the recursive cases. You seem to have started this correctly but then something wrong happened.

If you find yourself guessing at the changes more than know the changes use unit test to to make sure you did not break other cases that work when trying to fix the code for more cases.

Doing the problem with pen and paper before starting to code is sometimes useful.

1 Like

Thanks for your help. I solved it by using gtrace.

1 Like

Then post what worked and explain why so others can learn from it.

Figure out through gtrace that List Trail unification to empty List was missing.

New Prolog programmers use =/2 in their code. However most production code will refactor the code to remove the use of =/2.

line_predicate(I, [P,S | R], [P,S | T]) :-
    between(P, S, I), !,
    line_predicate(I, R, T).

I did the changes in this post so check it.

Thanks. Really helpful.

Also look at Useful Prolog References

1 Like