
/* PROGRAMM lib.pl */

/* Das einstellige Praedikat "nit(Q)" ist genau dann erfuellbar,
   also wahr, wenn Q nicht erfuellbar, also falsch ist           */

nit(Q):- Q,!,fail.
nit(_).


/* Das zweistellige Praedikat "in_list(X,L)" ist genau dann 
   wahr, wenn X ein Element der Liste L ist                      */

in_list(_,[]):- !,fail. 
in_list(X,L):- L=[X|_].
in_list(X,L):- L=[_|Rest], in_list(X,Rest). 


/* Das zweistellige Praedikat "length_list(L,N)" ist genau 
   dann wahr, wenn N die Laenge der Liste L ist                  */

length_list([],0):- !.
length_list(L,N):- L=[_|Rest], length_list(Rest,M), N is M+1.


/* Das dreistellige Praedikat "append_list(L1,L2,L)" ist genau
   dann wahr, wenn L die Liste ist die entsteht, wenn man die 
   Liste L2 an die Liste L1 anhaengt                             */ 

append_list(L,[],L):- !.
append_list([],L,L):- !.
append_list(L1,L2,L):- L1=[X|Rest1], L=[X|RestL], 
                       append_list(Rest1,L2,RestL).


/* Das zweistellig Praedikat "reverse_list(L,R)" ist genau 
   dann wahr, wenn die Liste R die Umkehrung der Liste L ist     */

reverse_list([],[]).
reverse_list(L,R):- nonvar(L), reverse_list(L,[],R).
reverse_list([Head|Tail],Stack,R):- 
                  reverse_list(Tail,[Head|Stack],R).
reverse_list([],R,R).


/* Die beiden dreistelligen Praedikate "min(N1,N2,M)" und
   "max(N1,N2,M)" sind genau dann wahr, wenn M das Minimum 
   bzw. das Maximum der beiden Zahlen N1 und N2 ist              */                                  

min(N1,N2,M):- N1 >= N2, M is N2.
min(N1,N2,M):- N1 < N2, M is N1.

max(N1,N2,M):- N1 >= N2, M is N1.
max(N1,N2,M):- N1 < N2, M is N2.


/* Das dreistellige Praedikat "power(B,E,P)" ist genau dann
   wahr, wenn P=B^E ist (nur fuer ganzzahlige E mit E>=0 )       */

power(_,0,1):- !.
power(B,E,P):- integer(E), E>0, or(integer(B),float(B)), 
               powercalc(B,E,P).
powercalc(B,E,P):- EE is E-1, power(B,EE,PP),
                   P is (PP*B).


/* Das zweistellige Praedikat "or(Q1,Q2)" ist das logische "or"  */

or(Q,_):- nonvar(Q),Q.
or(_,Q):- nonvar(Q),Q.


/* Mit "all_of(Q)" erhaelt man alle wahren Instanziierungen 
   von Q                                                         */

all_of(Q):- nonvar(Q),Q,fail.
all_of(_):- nl,write('that''s all'),nl.
 
/* End of lib.pl */