Zdroj


/* Rozdílové seznamy: S-K kde K je proměnná
	unifikovaná s koncem seznamu S (K místo []).
	Například: [1,2,3|K]-K
	Naprogramujte zretězení (append/3). */
% append(+S1, +S2, -Zřetězení)
%append(S1-K1, S2-K2, S1-K2) :- K1=S2.
append(A-B, B-C, A-C).

% empty(+RozdílovýSeznam)
empty(A-B) :- var(A), A==B.

% lengthRS(+RozdílovýSeznam, -Délka)
lengthRS(L, 0) :- empty(L).
lengthRS(L, N) :- \+ empty(L), L = [_|T]-E,
	lengthRS(T-E, NT), N is NT + 1.
	% ``\+ Pred`` uspěje právě když Pred neuspěje

% lengthRSA(+RozdílovýSeznam, -Délka)
lengthRSA(L, N) :- lengthRSA(L, 0, N).
lengthRSA(L, A, A) :- empty(L).
lengthRSA(L, A, N) :- \+ empty(L), L = [_|T]-E, AT is A + 1,
	lengthRSA(T-E, AT, N).


/* Prefixová notace výrazu je prostý seznam operátorů a čísel:
	operátor ++ notace L. argumentu ++ notace P. argumentu
	Pro jednoduchost: binární -, * a čísla (number/1).
	Příklad: (5-2)*(7-3)  <->  [*, -, 5, 2, -, 7, 3]  */
% Převeďte prologovský výraz do prefixové notace v lineárním čase.
% vyr2pref(+Výraz, -PrefixSeznam)
vyr2pref(E, [E|T]-T) :- number(E).
vyr2pref(L-P, O) :- vyr2pref(L, LH-LT), vyr2pref(P, PP),
	append([-|LH]-LT, PP, O).
vyr2pref(L+P, O) :- vyr2pref(L, LH-LT), vyr2pref(P, PP),
	append([+|LH]-LT, PP, O).


% A opačný směr, případně obousměrně?
% pref2vyr(+PrefixSeznam, -Výraz)
% Můžete si zkusit sami, není to komplikovanější.

Dotazy


?- lengthRSA([1,2,3|K]-K, L).
L = 3 ;
false.