%	  Deklaratív Programozás gyakorlat -- megoldások
% 
%				2013.10.31.
%
%---------------------------------------------------------------------------



% 2. feladat

% szorzata(N, A, NA): NA az N nemnegatív egész és az A atom szorzata.
% Nem jobbrekurzív, ezért nem kaphat teljes pontszámot.
szorzata(N, A, NA) :-
	(   N > 0 ->
	    N1 is N-1,
	    szorzata(N1, A, NA1),
	    atom_concat(A, NA1, NA)
	;   NA = ''
	).

szorzata2(N, A, NA) :-
	szorzata2(N, A, '', NA).

% szorzata2(N, A, NA0, NA): Az N nemnegatív egész és az A atom szorzatát
% NA0 elé fűzve kapjuk az NA atomot.
szorzata2(N, A, NA0, NA) :-
	(   N > 0 ->
	    N1 is N-1,
	    atom_concat(A, NA0, NA1),
	    szorzata2(N1, A, NA1, NA)
	;   NA = NA0
	).

:- use_module(library(lists), [append/2]).
:- use_module(library(between), [between/3]).

szorzata3(N, A, NA) :-
	atom_codes(A, ACs),
	findall(ACs, between(1, N, _), NACss),
	append(NACss, NACs),
	atom_codes(NA, NACs).


% 3. feladat

% erteke(OpKif, Ertek): Az OpKif operátoros ábrázolású 
% kifejezés értéke Ertek.
% :- pred erteke(univ::in, atom::out).
erteke(A, E) :-
	atom(A), !, E = A.
erteke(N*Kif, E) :-
	integer(N), !,
	erteke(Kif, A),
	szorzata(N, A, E).
erteke(Kif*N, E) :-
	integer(N), !,
	erteke(Kif, A),
	szorzata(N, A, E).
erteke(Kif1+Kif2, E) :-
	erteke(Kif1, A1),
	erteke(Kif2, A2),
	atom_concat(A1, A2, E).

% 4. feladat

% szimmetrikus(Kif): igaz, ha Kif szimmetrikus.
% :- pred szimmetrikus(univ::in).
szimmetrikus(X) :-
	compound(X), !,
	functor(X, _, N),
	szimmetrikus_argumentumok(1, N, X).
szimmetrikus(_).

% szimmetrikus_argumentumok(I, J, X): Az X struktúra I. és J.,
% I+1. és J-1., ... argumentumai azonosak,
szimmetrikus_argumentumok(I, J, X) :-
	I < J, !,
	arg(I, X, XI),
	arg(J, X, XJ),
	XI == XJ,
	I1 is I+1, J1 is J-1,
	szimmetrikus_argumentumok(I1, J1, X).
szimmetrikus_argumentumok(_, _, _).

szimmetrikus2(X) :-
	compound(X), !,
	X =.. [_|Args],
	reverse(Args, RArgs),
	Args == RArgs.
szimmetrikus2(_).



% 5. feladat

% szimmetrikus_resze(Kif, Resz): Resz a Kif-nek szimmetrikus részkifejezése.
% :- pred szimmetrikus_resze(univ::in, univ::out).
szimmetrikus_resze(Kif, Kif) :-
	szimmetrikus(Kif).
szimmetrikus_resze(Kif, Resz) :-
	compound(Kif),
	Kif =.. [_|As],
	member(A, As),
	szimmetrikus_resze(A, Resz).


% 6. feladat

% elsok(M, Elsok, Maradek): Elsok az M-ben szereplő listák fejeinek,
% Maradek pedig farkainak a listája.
% :- pred elsok(list(list(univ))::in, 
%               list(univ)::out, 
%               list(list(univ))::out).
elsok([], [], []).
elsok([[X|L]|Mx], [X|Xk], [L|Lk]) :-
	elsok(Mx, Xk, Lk).


% 7. feladat
    
% transzponalt(M, TM): TM az M matrix transzponáltja.
% :- pred transzponalt(list(list(univ))::in, list(list(univ))::out).
transzponalt([], TMx) :-
	!, TMx = [].
transzponalt(Mx, TMx) :-
	elsok(Mx, Xk, Mx1), !,
	TMx = [Xk|TMx1],
	transzponalt(Mx1, TMx1).
transzponalt(_, []).

	
