% element_at(X,[a,b,c,d,e],3).
/*
P03    (*) Find the K'th element of a list.
The first element in the list is number 1.
    Example:
    ?- element_at(X,[a,b,c,d,e],3).
      X = c



P08    (**) Eliminate consecutive duplicates of list elements.         If a list contains repeated elements they should be replaced     with a single copy of the element. The order of the elements should     not be changed.

    Example:
    ?- compress([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).
    X = [a,b,c,a,d,e]


P10    (*) Run-length encoding of a list.
Consecutive duplicates of elements are encoded as terms [N,E] where N is the number     of duplicates of the element E.

    Example:
    ?- encode([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).
    X = [[4,a],[1,b],[2,c],[2,a],[1,d][4,e]]

P19    (**) Rotate a list N places to the left.     Examples:
    ?- rotate([a,b,c,d,e,f,g,h],3,X).
    X = [d,e,f,g,h,a,b,c]

    ?- rotate([a,b,c,d,e,f,g,h],-2,X).
    X = [g,h,a,b,c,d,e,f]
 */
 
% element_at/3
% element_at(X,[a,b,c,d,e],3).
% X = c

element_at(X,[X|_T],1):-!.

element_at(X,[_|T],N):-
     N1 is N-1,
     element_at(X,T,N1).
     


% compress([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).
% X = [a,b,c,a,d,e]

compress([H|L],[H|X]):-
   compress(L,H,X).

compress([],_,[]).

compress([H|T],Acc,X):-
   H == Acc,
   compress(T,Acc,X).
   
compress([H|T],Acc,[H|X]):-
   H \== Acc,
   compress(T,H,X).

% encode([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).
% X = [[4,a],[1,b],[2,c],[2,a],[1,d][4,e]]

encode([H|T],X):-
   encode(T,1,H,X).

encode([],Z,E,[[Z,E]]).

encode([H|T],Z,E,X):-
   H == E,
   Z1 is Z+1,
   encode(T,Z1,E,X).

encode([H|T],Z,E,[[Z,E]|X]):-
   H \== E,
   encode(T,1,H,X).



% rotate1([a,b,c,d],[b,c,d,a]).

rotate1([H|T],X):-
    append(T,[H],X).


% rotate/3
% rotate([a,b,c,d,e,f,g,h],3,X).
%    X = [d,e,f,g,h,a,b,c]

rotate(L,0,L):-!.

rotate(L,Z,X):-
   Z > 0,
   Z1 is Z - 1,
   rotate1(L,L1),
   rotate(L1,Z1,X).
   
   
Link zu weiteren Aufgaben mit Lösungen nur die einfachen machen und nur die zu Listen:
https://www.ic.unicamp.br/~meidanis/courses/mc336/2009s2/prolog/problemas/

:- dynamic fak/2.

fak(0,1):-!.
fak(N,R):-
    N1 is N-1,
    fak(N1,R1),
    R is R1*N,
    asserta(fak(N,R):-!).





findall((X, Y, Z), (species(X, Y), age(X, Z)), L).





------- allgemein interessante Lösung aber ohne assert und retract
max(List, Max) :-
    member(Max, List),
    \+ (member(Y, List), Y > Max).



------- Lösung mit assert und retract aber nur für positive Zahlen 

:- dynamic max/1.
max(0).

% only for positive numbers

max([],Max):-
    max(Max).

max([H|T],Max):-
    max(Y),
    H > Y,
    retract(max(_)),
    assert(max(H)),
    max(T,Max).

max([H|T],Max):-
    max(Y),
    H =< Y,
    max(T,Max).


--- Musterlösung

:- dynamic max/1.

% positive and negative numbers

max([H|T],Max):-
    assert(max(H)),
    max1(T,Max).


max1([],Max):-
    max(Max).

max1([H|T],Max):-
    max(Y),
    H > Y,
    retract(max(_)),
    assert(max(H)),
    max1(T,Max).

max1([H|T],Max):-
    max(Y),
    H =< Y,
    max1(T,Max).





















% Grammtikregeln:
s --> simple_s.
s --> simple_s, conj, s.
simple_s --> npsg, vpsg.
simple_s --> nppl, vppl.
np --> nppl.
np --> npsg.
npsg --> pn.
npsg --> detsg, adjsSG, nsg.
nppl --> detpl, adjsPL, npl.
vpsg --> vsg,np.
vppl --> vpl,np.


adjsSG --> [].
adjsSG --> adjSG, adjsSG.
adjsPL --> [].
adjsPL --> adjPL, adjsPL.



% Lexikon:
detsg --> [eine].
%detsg -->[die].
%detsg -->[keine].
detpl --> [die].
%detpl --> [keine].
nsg -->[katze].
%nsg --> [maus].
%npl --> [mäuse].
npl --> [katzen].
vsg --> [jagt].
%vsg --> [klaut].
vpl --> [jagen].
%vpl --> [klauen].
adjSG --> [kleine].
%adjSG --> [schnelle].
adjPL --> [kleinen].
%adjPL --> [schnellen].
conj --> [und].
%conj --> [oder].
pn --> [otto].



lex(der, det, (nom,sg,mas)). 
lex(den, det, (akk,sg,mas)). 
lex(die, det, (_,sg,fem)).
lex(das, det, (_,sg,neu)).
lex(die, det, (_,pl,_)).
lex(_, det, (_,pl,_)).
lex(maus, n, (_,sg,fem)).
lex(maeuse, n, (_,pl,_)).
lex(katze, n, (_,sg,fem)).
lex(katzen, n, (_,pl,_)).
lex(hund, n, (_,sg,mas)).
lex(hunde, n, (_,pl,mas)).
lex(pferd, n, (_,sg,neu)).
lex(pferde, n, (_,pl,neu)).
lex(jagt, v, (sg)).
lex(jagen, v(pl)).