% o prelucrare simplă pe liste % sumList(+L, -Suma) sumList([], 0). sumList([H|T], S) :- sumList(T, ST), S is ST + H. % ============ Generare % puterea generativă a limbajului: generarea unei liste % la consolă: % % ?- member(1, [1,2,3]) % ?- member(X, [1, 2, 3]). % ?- member(1, L). % ?- length(L, 3), member(1, L), member(2, L), member(3, L). % Dorim un predicat interval(X), adevărat pentru numerele întregi de la 0 la 10 % pe care să-l apelăm la consolă ca ?- interval(X). % și să obținem succesiv toate soluțiile %interval(X) :- X >= 0, X < 10. % eroare: X nu este instanțiat % construim soluția următoare pe baza unei soluții existente interval(0). interval(X) :- interval(Y), Y < 2, X is Y + 1. % dar începerea cu apel recursiv cu o variabilă nelegată duce la un ciclu infinit % Construim intervalul controlat, cu un argument I care este % mereu instanțiat și iterează prin interval. %interval2H(X, I) :- X = I. % sau: interval2H(X, X). interval2H(X, I) :- I < 10, I1 is I + 1, interval2H(X, I1). interval2(X) :- interval2H(X, 0). % ============================ cut si fail % minimul dintre X și Y este X dacă X este mai mic, și este Y dacă Y este mai mic. min1(X, Y, M) :- X < Y, M = X. min1(X, Y, M) :- X >= Y, M = Y. % Echivalent cu min, nu mai facem unificarea explicit min2(X, Y, X) :- X < Y. min2(X, Y, Y) :- X >= Y. % Greșit! A doua soluție nu va fi corectă dacă X este mai mic decât Y. min3(X, Y, X) :- X < Y. min3(_, Y, Y). min4(X, Y, X) :- X < Y, !. % dacă X este mai mic decât Y, % ignorăm alternativele pentru min4 min4(_, Y, Y). % se ajunge aici doar dacă X nu a fost mai mic decât Y myMem(E, [E|_]) :- !. % myMem oferă o singură soluție. myMem(E, [_|T]) :- myMem(E, T). % scriem predicatul pasăre pentru cazul general, % și avem un caz particular pentru care este fals. este(lili, liliac). este(fifi, papagal). zboara(liliac). zboara(papagal). pasare(X) :- este(X, liliac), !, fail. pasare(X) :- este(X, Clasa), zboara(Clasa). % =================== findall % findall(Template, Goal, Bag) % pune in Bag legari ale lui Template, % unde legarile satisfac Goal. % ne dorim un predicat prelucreaza(+LL, -LLO, -S2) care primește în % LL o listă de liste și leagă: % LLO la o listă de liste în care la listele de un element se adaugă % constanta unu ca prim element iar la listele de cel puțin 2 elemente % se adaugă lungimea listei ca prim element. % S2 va fi legat la suma elementelor lister=lor cu cel puțin 2 elemente. ll([[a], [1,2,3], [], [4,5], [xy], [], [5]]). % cu findall: prelucreaza(LL, LLO, S2) :- findall(EO, ( member(E, LL), ( E = [], EO = [] ; E = [X], EO = [unu, X] ; E = [_,_|_], length(E, LenE), EO = [LenE|E] ) ), LLO), findall(L2, (member(L2, LL), length(L2, LenL2), LenL2 >= 2), LL2), flatten(LL2, Flat), sumList(Flat, S2) . % recursiv + pattern-matching prel([], [], 0). prel([[] | LLR], [[] | LLOR], S2) :- !, prel(LLR, LLOR, S2). prel([[X] | LLR], [[unu, X] | LLOR], S2):-!, prel(LLR, LLOR, S2). prel([L2 | LLR], [[LenL2|L2] | LLOR], S2):- length(L2, LenL2), %LenL2 >= 2, prel(LLR, LLOR, S2R), sumList(L2, Sum), S2 is Sum + S2R.