%Aufgabe 1 a)
map(P,[],[]).
map(P,[X|XS],[Y|YS]):-call(P,X,Y),map(P,XS,YS).

%Aufgabe 1 b)
ntimes(P,0,X,X).
ntimes(P,N,X,Z):-call(P,X,Y),M is N-1,ntimes(P,M,Y,Z). 

%Aufgabe 2

prove2(I,G,_):- I<0,!,fail. 
prove2(I,true,0) :- !.
prove2(I,(G1,G2),K) :- !, prove2(I,G1,N),J is I-N,prove2(J,G2,M),K is N+M.
prove2(I,G,K) :- clause(G,B), J1 is I-1,prove2(J1,B,K1),K is K1+1.

prove(I,G):-prove2(I,G,K),write(G),nl,fail.
prove(I,G).

% zum Testen von prove
split(XS,[],XS).
split([X|XS],[X|YS],ZS):-split(XS,YS,ZS).

perm([],[]).
perm(XS,[Z|AS]):-split(XS,YS,[Z|ZS]),append(YS,ZS,PXS),perm(PXS,AS).


%Aufgabe 3
start   :- write('Steuerdatei:'),read(X), getFile(X),write('Laenge:'),read(L),nl, list(L),nl, killall, !.

killall :- retract(extern(X)), killall.
killall. 

getFile(X) :- see(X), readFile, seen.

readFile :- read(X), X \= end_of_file, assert(extern(X)), readFile.
readFile.

writeList([]).
writeList([X|XS]):-write(X),writeList(XS).

list(L):- wort(VS,L),writeList(VS),nl,fail.
list(L). 

erkenne([],Q,L):- L>=0, extern(ende(Q)).
erkenne([V|VS],Q,L) :- L>=0,K is L-1,extern(kante(Q,V,NQ)),erkenne(VS,NQ,K).
erkenne(VS,Q,L) :- L>=0,extern(epsilonkante(Q,NQ)), erkenne(VS,NQ,L).

wort(VS,L):-extern(start(Q)),erkenne(VS,Q,L).

