mult(X,Y,Z) :- Z is X * Y.
add(X, Y, Z) :- Z is X + Y.

fold(_, [], _) :- fail. 
fold(_, [X], X).
fold(F, [H1,H2|T], Y) :- call(F,H1,H2,H3),
	fold(F,[H3|T], Y).

%vyrobi ze stromu seznam v traverzacnim poradi
projdi(null,[]).
projdi(t(L,H,P),R) :- projdi(L,Vys),projdi(P,Vys2),
		append(Vys,[H|Vys2],R).

% vyrobi vyvazeny strom ze seznamu
vyrobstrom([],null).
vyrobstrom(S, t(T1,Stred,T2)) :- halve(S, P1, [Stred|P2]),
		   vyrobstrom(P1, T1),
		   vyrobstrom(P2, T2).

% puvodni verze rozdeleni seznamu vejpul ze cviceni
rozdelnapul(S, R1, R2) :- rh(S,S,R2), append(R1,R2,S).

rh(S1,[],S1).
rh(S1,[_],S1).
rh([_|S1],[_,_|S2],V) :- rh(S1,S2,V).

% trochu lepsi verze predchoziho; opravdu jednopruchodova a s akumulatorem:
halve(S,L,R) :- halve(S,S,L,R). %prevod na 2 pointery
halve([],B,[],B).
halve([_],B,[],B):-!. %rez tady zabrani zbytecnemu backtracku.
halve([_,_|A],[X|B],[X|L],R) :- halve(A,B,L,R).

% demo: jak secist vsechny hodnoty ve strome:
sectistrom(T,S) :- projdi(T,L), fold(add, L, S).

% demo: jak zjistit ze strom je vyhledavaci (tj. serazeny)
mensirovno(A,B,B) :- A =< B.
jeBVS(T) :- projdi(T,L), fold(mensirovno, L, _).
