Kindly Requesting Guidance and Direction

Hello swi-prolog,

Thank you in advance for your time and advice.

I have been tasked to write a single predicate and single rule prolog that takes in a list and find if it have 3 items in decreasing by order of 2. true if it does and false if not.

My single predicate and single rule:

three_by_two([A, B, C | T]) :- B is C - 2, A is B - 2, three_by_two([B, C | T]).

Tests:
three_by_two([1, 10, 5, 3, 42, 23, 5]). %“false”

three_by_two([5, 23, 42, 3, 5, 10, 1]). % “true, for [5, 3,1].”

During trace, I see that the predicate and rule is not performing the rule through all the elements of the list. Kindly requesting guidance and direction as to how to properly solve the problem and understand the solution.

Allowed constructs:
1.“is”
2.“-”
3.“:-”
4.“,”
5.“;”
6. “
7.“[H|T]”
8. “!”

Thank you,
hcxs

Thank you for your reply, but “select” wasn’t allowed by the task.

Well, there’s select/3 and permutation/2 , as hints.

On the swi-prolog pages, you can click on the orange circle, to see the source code.

Thank you very much for your guidance and for most cases it would work! But for the single predicate, single rule requirement in addition to the constraints the recursive predicate for select/member and permutations would not fit it.

This are the predicates I cant use because of the requirements and constraints:

  1. member/select (from: https://www.tutorialspoint.com/prolog/prolog_lists.htm)

list_member(X,[X|]).
list_member(X,[
|TAIL]) :- list_member(X,TAIL).

This one is the permutation_sort from ([LogicLambda: https://youtu.be/yi30r4gU4uE

Why is that acceptable - it’s not 10 elements?

Apologies, typo. 3 instead of 10. Corrected.

Can’t use why? These commands are built-in, ready for use.

Presumably your programming teacher thinks it’s a good idea to put you through this frustration, rather than enjoy the power of the language?

I don’t think it’s a good way to teach or learn :frowning_face:

I completely agree. Thank you Brebs for your inputs, it means a lot. Have a great weekend!

Here’s 3 predicates to show how it can be done (with the first 2 initially hidden, in case you just want a clue):

select_3_minus_2
select_3_minus_2(Lst, Three) :-
    select_forward(N1, Lst, Lst0),
    select_num_minus_2(Lst0, N1, N2, Lst00),
    select_num_minus_2(Lst00, N2, N3, _),
    Three = [N1, N2, N3]. 
select_num_minus_2
select_num_minus_2(Lst, N, Minus2, Lst0) :-
    Minus2 is N - 2,
    select_forward(Minus2, Lst, Lst0).
select_forward(E, [H|T], F) :- 
    select_forward_(T, H, E, F).

select_forward_(T, H, H, T).
select_forward_([H|T], _, E, F) :-
    select_forward_(T, H, E, F).

Result:

?- select_3_minus_2([5, 23, 42, 3, 5, 10, 1], L).
L = [5, 3, 1] ;
false.

Add the cut (i.e. !) if desired.

Thank you Brebs!