I Lean, når vi arbejder med algebraiske strukturer som grupper eller ringer, er en central opgave at registrere, hvordan Lean skal finde og bruge de nødvendige oplysninger for at udføre beregninger og bevise sætninger. I et simpelt eksempel som en gruppe, kan vi registrere denne information ved at bruge to væsentlige ændringer i den måde, vi definerer strukturer på. Først skal vi i stedet for at bruge kommandoen structure til at definere en gruppe, bruge nøgleordet class for at angive, at det er et kandidatobjekt til klasseinferens. Dernæst, i stedet for at definere bestemte instanser med def, bruger vi nøgleordet instance for at registrere instansen hos Lean.

Et eksempel på dette kan ses i definitionen af en gruppe i Lean. Vi definerer først en klasse Group2 for et objekt α af typen Type*, hvor vi angiver de nødvendige egenskaber for en gruppe som multiplikation (mul), neutral element (one), og inverse elementer (inv). Når vi registrerer en konkret instans af denne klasse for typen Equiv.Perm α, bruger vi kommandoen instance og angiver, hvordan multiplikationen, identitetsoperatoren og inverse funktioner skal udføres for denne type. Lean er nu i stand til automatisk at finde og anvende denne struktur til enhver funktion, der kræver en gruppe.

For eksempel kan vi definere en funktion som mySquare, der tager et element fra gruppen og multiplicerer det med sig selv. Ved at bruge implicitte argumenter kan Lean automatisk finde den rette gruppe og dens operationer, hvilket gør det lettere at arbejde med generelle algebraiske strukturer uden at specificere detaljer manuelt hver gang.

Dette mekanisme for klasseinferens giver os mulighed for at bruge notation som + og * for at betegne binære operationer på enhver type, der er blevet registreret med de relevante algebraiske strukturer. For eksempel kan vi definere en ny instans af en ring i Lean, og vi behøver ikke at definere operatorerne + og * fra bunden, da Lean allerede kender disse for enhver ring.

Det er dog vigtigt at forstå, at denne automatiserede søgning kan føre til tvetydighed, især når forskellige algebraiske strukturer overlapper hinanden. For eksempel kan Lean finde både en instans af en gruppe og en instans af en ring for en given type, hvilket kan skabe usikkerhed om, hvilken struktur der skal anvendes i en given situation. Lean prioriterer som regel de nyeste erklæringer af instanser, medmindre der gives specifik prioritet.

En anden nyttig funktion er brugen af extends-nøgleordet. Dette bruges til at angive, at én struktur er en instans af en anden. For eksempel kan man bruge extends til at sige, at enhver kommutativ ring også er en ring. Det er dog vigtigt at være opmærksom på, at det i almindelighed ikke er en god idé at redefinere operatorer, som allerede er defineret i Lean’s biblioteker, da det kan føre til forvirring og potentielt fejl.

Class inference er et kraftfuldt værktøj, men det kræver omhyggelig brug. Det er den mekanisme, der muliggør algebraisk ræsonnering i Lean, og dens anvendelse gør det lettere at arbejde med matematiske objekter på et højere niveau af abstraktion. Når man arbejder med algebraiske strukturer i Lean, er det essentielt at forstå, hvordan denne automatiserede inferens fungerer, så man kan udnytte dens styrker og undgå fejltagelser.

Når man definerer nye typer, som f.eks. Gaussian integers, kan man også bruge disse mekanismer. I Lean kan vi bygge Gaussian integers som en struktur bestående af to heltal, hvor vi repræsenterer den reelle og den imaginære del. Når vi har defineret denne struktur, kan vi vise, at de opfylder de nødvendige egenskaber for at være en ring, ved at definere addition og multiplikation på en måde, der svarer til de algebraiske operationer på komplekse tal.

Det er vigtigt at bemærke, at selvom Lean gør det muligt at arbejde med meget generelle algebraiske strukturer, er det også nødvendigt at forstå, hvordan instanser og noterede operationer er relateret til hinanden. Dette giver ikke kun større fleksibilitet i arbejdet med forskellige typer og operationer, men sikrer også, at systemet ikke bliver forvirret, når flere muligheder er til stede.

I praksis er det altså ikke kun muligt at arbejde med standard algebraiske strukturer som grupper og ringer, men man kan også bygge sine egne strukturer og notere operationer, som passer til ens behov. Lean’s system af klasseinferens gør det muligt at abstrahere væk fra de konkrete detaljer og koncentrere sig om de matematiske relationer mellem objekterne, hvilket er en af styrkerne ved denne tilgang.

Hvordan arbejder man med Gaussiske heltal i matematikken?

Når vi arbejder med Gaussiske heltal, som er komplekse tal af formen a+bia + bi, hvor både aa og bb er heltal, stammer meget af arbejdet fra fundamentale begreber som normer, konjugater og division. Dette viser sig at være et utroligt kraftfuldt værktøj, især når man formulerer og beviser resultater inden for algebra og talteori. Det følgende gennemgår nogle af de vigtigste aspekter ved at arbejde med Gaussiske heltal, som det ses i den matematiske teori, samt hvordan man kan håndtere divisionen af disse tal i en formel sammenhæng.

For at forstå hvordan Gaussiske heltal fungerer, kan vi starte med at se på en typisk udtryk, som vi ønsker at manipulere. Antag, at vi har q=u+viq = u + vi og r=(c+di)(u+vi)r = (c + di)(u' + v'i), så vi får udtrykket:

a+bi=(c+di)q+ra + bi = (c + di)q + r

Vores mål er nu at finde en øvre grænse for normen af rr. Hvis vi antager, at normen af rr, N(r)N(r), er mindre end normen af c+dic + di, kan vi gøre brug af følgende ulighed:

N(r)=N(c+di)N(u+vi)N(c+di)12<N(c+di)N(r) = N(c + di)N(u' + v'i) \leq N(c + di) \cdot \frac{1}{2} < N(c + di)

Denne beregning kræver, at vi ser de Gaussiske heltal som en undergruppe af de komplekse tal. En måde at gøre dette på i formel matematik er at embedde de Gaussiske heltal i de komplekse tal og bruge de eksisterende begreber til at arbejde med division og modulering på en effektiv måde.

I den specifikke implementering, som er blevet beskrevet i Lean-biblioteket (Mathlib), behandles de Gaussiske heltal som en speciel form for kvadratiske heltal. Denne tilgang involverer en grundig forståelse af, hvordan man håndterer kvotienter og rester, mens man arbejder med tal, der ikke nødvendigvis er heltallige.

Når vi kommer til praktisk anvendelse, står man ofte over for et valg: enten skal man udvide sine begreber for at kunne håndtere situationen, eller skal man forsøge at tilpasse argumenterne til eksisterende begreber? I de fleste tilfælde er det en god idé at udvide teorien, især hvis de nye begreber kan anvendes på tværs af flere kontekster. Dog kan det nogle gange være mere effektivt at finde en mere elementær løsning, som er tilstrækkelig for det pågældende problem.

Der er en variation af den sædvanlige kvotient-rest-sætning for heltal, som vi bruger i denne sammenhæng. Normalt siger den, at for ethvert aa og et ikke-nul bb, findes der qq og rr, således at:

a=bq+rog0r<ba = bq + r \quad \text{og} \quad 0 \leq r < b

Her anvender vi en variation, der siger, at der findes qq' og rr', sådan at:

a=bq+rogrb2a = bq' + r' \quad \text{og} \quad |r'| \leq \frac{b}{2}

Denne variation er specielt nyttig, når vi skal forfine divisionen af komplekse tal. Hvis rr i den oprindelige sætning opfylder betingelsen rb2r \leq \frac{b}{2}, kan vi tage q=qq' = q og r=rr' = r. Hvis ikke, justerer vi værdierne til q=q+1q' = q + 1 og r=rbr' = r - b.

I denne sammenhæng kan vi definere funktionerne div’\text{div'} og mod’\text{mod'}, som begge spiller en central rolle i den præcise håndtering af division og modulus for de Gaussiske heltal. Funktionen div’\text{div'} giver os kvotienten af divisionen, mens mod’\text{mod'} giver resten, og begge funktioner skal opfylde visse egenskaber for at kunne anvendes korrekt i beregningerne.

En vigtig egenskab ved Gaussiske heltal er, at deres norm er defineret som N(x)=xre2+xim2N(x) = x_{\text{re}}^2 + x_{\text{im}}^2, hvor xrex_{\text{re}} og ximx_{\text{im}} er de reelle og imaginære dele af tallet xx. Denne funktion er vigtig for at forstå, hvordan tal som xx og yy relaterer sig til hinanden, når man arbejder med division og modulus.

En anden central funktion er konjugatet af et Gaussisk heltal, som er defineret som:

conj(x)=xre,xim\text{conj}(x) = \langle x_{\text{re}}, -x_{\text{im}} \rangle

Dette konjugat spiller en stor rolle i divisionen af Gaussiske heltal, da vi bruger det til at beregne kvotienten ved at multiplicere med konjugatet af nævneren. Dette leder til den ønskede kvotient og rest, som vi kan bruge til at definere divisionen og modulus for Gaussiske heltal på en korrekt og effektiv måde.

Endelig er en vigtig egenskab ved divisionen af Gaussiske heltal, at kvotienten x/yx / y og resten x%yx \% y skal have den egenskab, at normen af resten er mindre end normen af nævneren, hvilket kan udtrykkes som:

norm(x%y)<norm(y)\text{norm}(x \% y) < \text{norm}(y)

Dette krav sikrer, at divisionen er korrekt og giver os et håndterbart resultat, som vi kan bruge til at udføre yderligere beregninger.

Det er også vigtigt at bemærke, at når man arbejder med normer og division i denne sammenhæng, anvendes det velkendte begreb om "naturlige tal" og "absolut værdi", som kan hjælpe med at sikre, at de opnåede resultater er af de rette typer og kan anvendes korrekt i matematiske beviser og anvendelser.