% prikaz help/1 vyvola napovedu

% flatten(L,Lflat) - Lflat je zplostely (jednoduchy seznam) L
flatten([H|T],Lf):-flatten(H,Hf),flatten(T,Tf),append(Hf,Tf,Lf).
flatten([],[]).
flatten(X,[X]):-X\=[_];X\=[_|_].
% pri backtracovani se to chova divne


compress([],[]).
compress([X],[X]).
compress([X,X|Xs],Zs) :- compress([X|Xs],Zs).
compress([X,Y|Ys],[X|Zs]) :- X \= Y, compress([Y|Ys],Zs).



drop(L1,Ln,L2) :- drop(L1,Ln,L2,Ln).

% drop(L1,Ln,L2,Li) - seznam L2 vznikne ze seznamu L1 tak, ze odstranime kazdy nty prvek. Nemame aritmetiku, takze odcitame pocmoci odrezavani seznamu. Li je aktualni seznam, Ln pouzivame pro resetovani citace
drop([],_,[],_).
drop([_|Xs],N,Ys,1) :- drop(Xs,N,Ys,N).
drop([X|Xs],N,[X|Ys],K) :- K > 1, K1 is K - 1, drop(Xs,N,Ys,K1).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% priklady na praci s mnozinami
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


% sjedn(A,B,C) - C je sjednocenim A a B
sjedn([],B,B).
sjedn(A,[],A):-A\=[].
sjedn([X|A],B,[X|C]):-smaz2(X,B,B1),sjedn(A,B1,C).
% co tady prohodit smaz2 a sjedn?


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% unarni aritmetika
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% secti(A,B,C) - C=A+B
secti(0,B,B).
secti(s(A),B,s(C)):-secti(A,B,C).

% vynasob(+A,+B,-C) - C=A*B
vynasob(0,_,0).  % proc je tohle lepsi varianta, nez vynasob(s(0),B,B).
vynasob(s(A),B,C):-vynasob(A,B,C1),secti(C1,B,C).
% co to provede, pokud to pouzijeme jako deleni?

% vetsi(A,B) - uspeje, pokud A > B
vetsi(s(_),0).
vetsi(s(A),s(B)):-vetsi(A,B).

%DU: napiste predikat je_prvocislo(X), ktery uspeje, pokud X je prvocislo (v unarni aritmetice)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% aritmetika
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% prikaz is,  relace =:= , =\= , ‹ , › , ‹= , ›=
% is dava prologu prikaz, aby vyraz vycislil. 
% Pozor! nefunugje jako prirazovatko: X is X +2 - tohle vrati no 
% ma i float cisla, piseme je s teckou namisto carky (carka oddeluje argumenty)
% preddefinovane mat. fce a konstanty - sin, cos, log, exp, pi,e
% zajimave preddefinove fce pro praci s cisly- random, floor, ceiling, integer
% delkaseznamu(L,N) - N je delka seznamu L
delkaseznamu([],0).
delkaseznamu([_|L],N):-delkaseznamu(L,N1),N is N1+1.
% proc funguje:
delkaseznamu2([],0).
delkaseznamu2([_|L],N):-delkaseznamu2(L,N1),N = N1+1.
% toto je dokonce tail rekurive (ale o tom az u Haskellu)
delkaseznamu3([],0).
delkaseznamu3([_|L],N):-N = N1+1,delkaseznamu3(L,N1).

% gcd(A,B,C) - C je gcd A a B
gcd(A, 0, A). % dno rekurze
gcd(A, B, D):-(A>B),(B>0),R is A mod B,gcd(B,R,D). % pokud to jde, modulime
gcd(A, B, D):-(A<B), gcd(B,A,D). % tady by to slo provadet obdobne, jak o radek vyse.
% jde i varianta s odcitanim, ale je pomalejsi
   

perf(X,X,0).
perf(X,Souc,I):-I>0,X mod I =:=0,Souc1 is Souc + I,
                I1 is I-1, 
                perf(X,Souc1,I1). 
perf(X,Souc,I):-I>0,X mod I =\=0,Souc1 is Souc,
                I1 is I-1,
                perf(X,Souc1,I1).

perfekt(X):-I is X-1,perf(X,0,I).