ConcepteRecursivitate pe liste

Recursivitate pe liste

Pattern-ul de bază pentru orice prelucrare iterativă în Prolog: caz de bază pentru lista vidă, caz recursiv pentru [H | T].

28 exerciții folosesc acest concept cut-si-cazuri-de-bazapredicate-predefinite-pe-liste

Sumar

În Prolog nu avem for loops. Singura modalitate de a parcurge iterativ o listă este recursivitatea. Fiecare listă are două părți: capul (head, primul element) și coada (tail, restul listei).

?- [1, 2, 3, 4, 5] = [Head | Tail].
Head = 1
Tail = [2, 3, 4, 5]

Pattern-ul

my_predicate([], ...) :- base_case(...).
my_predicate([H | T], ...) :- ..., my_predicate(T, ...), ... .
  • Cazul de bază: ce se întâmplă când lista e vidă (sau are un singur element).
  • Cazul recursiv: descompune lista în [H | T], prelucrează H, recurge pe T, combină rezultatele.

Exemple

Lungimea unei liste:

list_length([], 0).
list_length([_ | T], Length) :-
    list_length(T, LengthTail),
    Length is LengthTail + 1.

Suma elementelor:

list_sum([], 0).
list_sum([H | T], Sum) :-
    list_sum(T, SumTail),
    Sum is SumTail + H.

Apartenență (member):

elements_of(X, [X | _]) :- !.
elements_of(X, [_ | T]) :-
    elements_of(X, T).

Două liste în paralel (zip / dot product):

dot([], [], 0) :- !.
dot([H1 | T1], [H2 | T2], Result) :-
    dot(T1, T2, ResultTail),
    Result is ResultTail + H1 * H2.

Atenție la cap și coadă

Din breviar:

Head-ul unei liste vide conduce la eroare! Tail-ul listei vide este lista vidă.

[H | T] = [1].      % H = 1, T = []
[H | T] = [].       % EROARE
[A, B | T] = [a, b, c, d].   % A = a, B = b, T = [c, d]
[A, B | T] = [a].   % EROARE — B nu se poate instanția

Idiomuri

Acumulator pentru calcule eficiente — vezi Fibonacci cu memoizare (Lab 2):

fib(F, _, N, N, F) :- !.
fib(F1, F0, Index, N, F) :-
    F2 is F1 + F0,
    NewIndex is Index + 1,
    fib(F2, F1, NewIndex, N, F).

efficient_fib(N, F) :- fib(1, 1, 1, N, F).

Transformare element cu element (map):

scalarMult(_, [], []) :- !.
scalarMult(X, [H | T], [HR | TR]) :-
    HR is X * H,
    scalarMult(X, T, TR).

Exerciții care folosesc acest concept

write_n/2 — triunghi la STDOUT Laboratorul 1, Exercițiul 4 intro fib/2 — Fibonacci, varianta ineficientă și cu memoizare Laboratorul 2, Exercițiul 1 (recapitulativ) medium concat_lists/3 — concatenare manuală Laboratorul 2, Exercițiul 10 intro remove_duplicates/2 — elimină duplicatele Laboratorul 2, Exercițiul 11 medium list_length/2 — lungimea unei liste Laboratorul 2, Exercițiul 2 intro list_sum/2 — suma elementelor Laboratorul 2, Exercițiul 3 intro elements_of/2 — apartenență la listă Laboratorul 2, Exercițiul 4 intro all_a/1 și all_symb/2 — listă formată dintr-un singur simbol Laboratorul 2, Exercițiul 5 intro trans_a_b/2 — translatează a-uri în b-uri Laboratorul 2, Exercițiul 6 intro scalarMult/3 — înmulțire cu scalari Laboratorul 2, Exercițiul 7 intro dot/3 — produs scalar Laboratorul 2, Exercițiul 8 intro max/2 — elementul maxim Laboratorul 2, Exercițiul 9 intro vars/2 — mulțimea variabilelor unei formule Laboratorul 3, Exercițiul 1 intro val/3 — valoarea unei variabile într-o evaluare Laboratorul 3, Exercițiul 2 intro eval/3 — evaluarea unei formule într-o valuare Laboratorul 3, Exercițiul 4 medium evals/3 — evaluare pe o listă de valuări Laboratorul 3, Exercițiul 5 intro evs/2 — toate valuările pe o mulțime de variabile Laboratorul 3, Exercițiul 6 advanced all_evals/2 — valorile formulei pe toate valuările Laboratorul 3, Exercițiul 7 medium taut/1 — test de tautologie Laboratorul 3, Exercițiul 8 medium Arbori binari — parcurgeri Laboratorul 5, Exercițiul 4 intro employee_with_good_salary/3 Model parțial, Exercițiul 1 medium employee_average_salary/2 Model parțial, Exercițiul 2 advanced sort_employee_average_salary/2 Model parțial, Exercițiul 3 advanced literalForResolution/3 — literal pentru rezoluție Șablon parțial (2026-04-22), Subiectul III a) [3 puncte] medium rezolvent/3 — rezolventul a două clauze Șablon parțial (2026-04-22), Subiectul III b) [7 puncte] advanced splitListEvenOdd/3 — separă pare și impare Șablon parțial (2026-04-22), Subiectul II a) [2 puncte] intro findSublist/3 — prima sublistă contiguă cu sumă dată Șablon parțial (2026-04-22), Subiectul II b) [5 puncte] advanced solution/3 — sublistă de pare sau impare cu constrângeri Șablon parțial (2026-04-22), Subiectul II c) [3 puncte] advanced