
% suma(L, S) gdy S to suma wartości liczb na liście L

suma(L, S) :- suma(L, 0, S).

% albo poprzedni wariant bezogonowy:
% suma([], 0).
% suma([X|L], S) :- suma(L, R1), S is R1 + X.

% suma(L, X, S) gdy S = suma(L) + X

suma([], X, X).

suma([X|L], X1, R) :- X2 is X1 + X, suma(L, X2, R).



% dlugosc(L, K) gdy K to liczba arytmetyczna bedaca długosca listy L

dlugosc(L, R) :- dlugosc(L, 0, R).

% dlugosc(L, X1, X2) gdy X2 to dlugosc listy L plus wartosc X1

dlugosc([], X, X).

dlugosc([_|L], X1, R) :- X2 is 1 + X1, dlugosc(L, X2, R).



% min(L, M) gdy M to minimalna wartosc na liscie liczb L

min([X|L], R) :- min(L, X, R).

% min(L, A, R) gdy R to minimum elementow listy [A|L]

min([], A, A).

min([X|L], A, R) :- X < A,  min(L, X, R).

min([X|L], A, R) :- X >= A, min(L, A, R).



% odwroc(L, R) gdy R to odwrocenie listy L

odwroc(L, R) :- odwroc(L, [], R).

% odwroc(L, A, R) gdy append(rev(L), A, R) czyli R jest konkatenacją odwrocenia L z A

odwroc([], A, A).

odwroc([X|L], A, R) :- odwroc(L, [X|A], R).



% palindrom(Slowo) gdy Slowo to lista ktora jest palindromem

palindrom(S) :- odwroc(S, S).


% slowo(Slowo) gdy Slowo to lista postaci a^n b^n, nie uzywamy arytmetyki

slowo(S) :- odwroc(S, R), sprawdz(S, R, a).

sprawdz([a|L1], [b|L2], a) :- sprawdz(L1, L2, a).

sprawdz(L1, L2, a) :- sprawdz(L1, L2, b).

sprawdz([b|L1], [a|L2], b) :- sprawdz(L1, L2, b).

sprawdz([], [], b).




% zly generator, który daje dodatkowy sukces na pozycji "omega" w porządku sukcesów

lista([]).
lista([_|L]) :- lista(L).

lista(omega).












 
