% SWI-Prolog-Programm zur Erzeugung der Multiplikationstabellen modulo N
% für alle Reste modulo N sowie für die Einheitengruppe, für N=2,...,22.

:- initialization(main).

main:-
    write('\\section*{Das Rechnen mit Resten modulo $n$ '),
    write('für Zahlen $n$ zwischen 2 und 22}\n\n'),
    write('\\subsection*{'),
    write('Verknüpfungstafeln für Addition $\\oplus_n$ modulo $n$}\n\n'),
    forall(between(2,22,N), schreib_Additionstabelle(N)),
    write('\n\\newpage\n\n'),
    write('\\subsection*{'),
    write('Verknüpfungstafeln für Multiplikation $\\otimes_n$ modulo $n$\n'),
    write('für alle Reste modulo $n$\\\\\n'),
    write('sowie eingeschränkt auf die zu $n$ teilerfremden Reste\n'),
    write('(Verknüpfungstafel der Einheitengruppe modulo $n$)}'),
    nl, nl,
    forall(between(2,22,N), schreib_Multiplikationstabellen(N)).

% schreib_Additionstabelle(+N) schreibt den LaTeX-Code für eine
%    Additionstabelle der Reste modulo N.
schreib_Additionstabelle(N):-
    N1 is N-1,
    findall(A, between(0,N1,A), L),
    write('\\begin{tikzpicture}\n'),
    format('  \\linksoben{$\\oplus_{~w}$}~n',[N]),
    forall(nth1(I,L,A), format('  \\rand{~w}{~w}~n',[I,A])),
    forall((nth1(I,L,A),nth1(J,L,B)),
	   (C is (A+B) mod N, format('  \\feld{~w}{~w}{~w}~n',[I,J,C]))),
    write('  \\useasboundingbox (0,2);\n'),
    write('\\end{tikzpicture}\n'),
    write('\\quad\n').


% schreib_Multiplikationstabellen(+N)  schreibt den LaTeX-Code
% für die Multiplikationstabelle für alle Reste modulo N
% sowie die Multiplikationstabelle für die Einheiten.
schreib_Multiplikationstabellen(N):-
    N1 is N-1,
    findall(A, between(0,N1,A), Alle),
    schreib_Multiplikationstabelle(Alle,N),
    write('\\quad\n'),
    findall(E, einheit(E,N), Einheiten),
    schreib_Multiplikationstabelle(Einheiten,N),
    nl.

% schreib_Multiplikationstabelle(+L,+N) schreibt den LaTeX-Code für eine
%    Multiplikationstabelle der Zahlen aus der Zahlenliste L modulo N.
schreib_Multiplikationstabelle(L,N):-
    write('\\begin{tikzpicture}\n'),
    format('  \\linksoben{$\\otimes_{~w}$}~n',[N]),
    forall(nth1(I,L,A), format('  \\rand{~w}{~w}~n',[I,A])),
    forall((nth1(I,L,A),nth1(J,L,B)),
	   (C is A*B mod N, format('  \\feld{~w}{~w}{~w}~n',[I,J,C]))),
    write('  \\useasboundingbox (0,2);\n'),
    write('\\end{tikzpicture}\n').

% ggT(+A,+B,-D)  D=ggT(A,B).
ggT(A,0,D):- !, D=A.
ggT(A,B,D):- C is A mod B, ggT(B,C,D).

% einheit(-E,+N)  E ist eine Einheit modulo N.
einheit(E,N):- N1 is N-1, between(1,N1,E), ggT(E,N,1).
