I matematik, når vi taler om funktioner og deres inverser, stødder vi ofte på nødvendigheden af at vælge et bestemt element ud af en uendelig mængde af muligheder. I teorien om funktioner betyder dette, at vi nogle gange skal bruge en metode til at vælge et element, når vi ikke har en naturlig måde at gøre det på. I sådanne tilfælde henviser vi til det matematiske "valgaxiom", som giver os ret til at vælge et element fra en mængde, uden nødvendigvis at kunne angive, hvordan dette valg skal foretages. Dette kan ske med brugen af klassisk logik, og Lean – et bevisværktøj og matematikprogrammeringssprog – gør det muligt at arbejde med sådanne koncepter ved hjælp af værktøjer som "Classical.choose".
Lad os tage et eksempel, hvor vi arbejder med en funktion . Målet er at definere en funktion, der fungerer som den inverse af , dvs. en funktion, der "vende tilbage" et element , så , for en given . Men hvordan kan vi finde et sådant , hvis vi kun kender ? Hvis det er muligt, skal vi kunne vælge et element , så .
Lean håndterer dette gennem brug af det klassiske valgoperator, som kan anvendes, når vi ved, at der eksisterer et sådant , men ikke nødvendigvis kan udtrykke det konkret. Vi kan definere den inverse funktion som følger:
I denne definition er en funktion, der tager et element og returnerer et , sådan at , hvis et sådant findes. Hvis der ikke findes et sådant , returnerer funktionen et "default" element af , som er et vilkårligt element fra mængden.
For at sikre, at dette fungerer som ønsket, skal vi også bevise, at den inverse funktion faktisk opfylder den korrekte egenskab. Det betyder, at hvis er et element af , der kan opnås ved at anvende på et element , skal det gælde, at .
Teoremet siger, at hvis der eksisterer et sådan at , så vil anvendt på den inverse funktion returnere , som vi forventer.
I Lean bliver vi i mange tilfælde nødt til at erklære, at de definitioner og funktioner, vi arbejder med, ikke nødvendigvis er beregnelige – hvilket betyder, at de ikke nødvendigvis kan udtrykkes som eksplitte funktioner, men kun som teoretiske konstruktioner, der fungerer under de rette betingelser. Derfor bruger vi annotationen noncomputable section i vores kode.
Et vigtigt aspekt af denne tilgang er forståelsen af de logiske operationer bag funktionerne og deres beviser. F.eks. er det, at funktionen "inverse" kun er korrekt defineret, hvis den faktisk kan vælge et passende element ud fra de givne betingelser. Hvis ikke, returneres et standardelement, som ikke nødvendigvis er "rigtigt", men blot et element, der opfylder kravene i det klassiske valgaxiom.
En anden væsentlig komponent er forståelsen af "left inverse" og "right inverse". En funktion har en venstre inverse funktion , hvis for alle . En højre inverse funktion opfylder for alle . I praksis betyder det, at en funktion er injektiv (enten venstre invers eller højre invers), hvis den kan vendes uden at miste information.
Så hvad betyder det, når vi siger, at en funktion har en "invers"? En invers funktion er, hvad vi kan bruge til at "annullere" virkningen af den oprindelige funktion, dvs. at hvis vi først anvender og derefter anvender , skal vi ende med det oprindelige input. Denne egenskab er fundamentalt for mange områder af matematikken og er tæt forbundet med begreberne injektivitet (en funktion der "ikke mister" information) og surjektivitet (en funktion der dækker hele mængden).
Når vi arbejder med begreber som injektivitet og surjektivitet i Lean, kan vi bruge de relevante definitioner, som er implementeret i systemet, og kontrollere om de gælder i et konkret tilfælde. For eksempel:
I disse sætninger søger vi at vise, at en funktion er injektiv, hvis og kun hvis dens inverse funktion er en venstre invers, og at den er surjektiv, hvis og kun hvis dens inverse funktion er en højre invers. Bevisene kan være tricky, men de kan relativt let opbygges med Lean, når man forstår, hvordan de logiske konstruktioner fungerer.
Afslutningsvis skal vi nævne Cantors berømte sætning om, at der ikke eksisterer en surjektiv funktion fra et sæt til dets potensæt. Dette er et klassisk resultat i mængdeteorien, og det kan bevises ved at antage, at en sådan surjektiv funktion eksisterer, og derefter finde en kontradiktion. Formaliseringen af dette resultat i Lean kræver nogle avancerede teknikker, men den giver os et klart billede af, hvordan man arbejder med uendelige mængder og deres strukturer.
Hvordan bygget man de Gaussiske heltall?
For at forstå den fundamentale egenskab ved normfunktionen på en euklidisk domæne, skal vi først se på et konkret eksempel. Vi starter med at definere et centralt resultat om den euklidiske norm, og på baggrund af dette kan vi udlede flere interessante egenskaber om de Gaussiske heltall.
Teoremet "not_norm_mul_left_lt_norm" viser, at når man multiplicerer to elementer i de Gaussiske heltall, vil den resulterende norm altid være større eller lig med normen af det første element. Med andre ord, for to GaussInt og , hvor , gælder det, at normen af produktet aldrig vil være mindre end normen af . Denne egenskab er fundamental, når man arbejder med de Gaussiske heltall, da den understøtter den naturlige orden i de euklidiske domæner.
Når vi anvender dette, kan vi vise, at de Gaussiske heltall er et eksempel på et euklidisk domæne. I et euklidisk domæne defineres kvotient og rest som funktioner, og i dette tilfælde er de kvotienter og rester, som vi kender fra divisionen af naturlige tal. Mathlibs definition af et euklidisk domæne er dog mere generel end vores umiddelbare eksempel, da den giver os mulighed for at vise, at resten i en division falder i henhold til en velordnet måling, og det er netop normfunktionen, der giver os denne måling.
For at definere et euklidisk domæne for de Gaussiske heltall, definerer vi kvotienten og resten som divisionen og modulooperationen. Det kræver, at vi beviser, at disse operationer opfylder de nødvendige egenskaber, herunder, at normen af resten er mindre end normen af det oprindelige tal. Ved at definere de nødvendige egenskaber som teoremene "natAbs_norm_mod_lt" og "not_norm_mul_left_lt_norm", kan vi etablere, at de Gaussiske heltall faktisk udgør et euklidisk domæne.
Når vi først har bekræftet, at de Gaussiske heltall udgør et euklidisk domæne, får vi en umiddelbar fordel: vi kan nu sige, at begreberne primtall og irreducibilitet er ækvivalente for de Gaussiske heltall. Dette betyder, at et tal er primt, hvis og kun hvis det er irreducibelt, hvilket forenkler arbejdet med faktorisering i de Gaussiske heltall betydeligt.
Det er vigtigt at bemærke, at den euklidiske egenskab, der gør det muligt at definere normer og beregne divisioner og rester, ikke kun gælder for de Gaussiske heltall, men også for andre algebraiske strukturer, som kan have en normfunktion. Denne tilgang gør det muligt at analysere flere typer domæner i algebraen, ikke kun de Gaussiske heltall.
Ud over de rent tekniske aspekter af normberegning og division, er det væsentligt at forstå, hvordan disse matematiske strukturer kan anvendes til at udføre faktorisering i andre algebraiske systemer, især når vi bevæger os fra de Gaussiske heltall til mere generelle domæner som hele tal, polynomier eller endda mere komplekse algebraiske strukturer. Dette giver os mulighed for at udvide vores forståelse af normer og faktorisering til et bredt spektrum af matematiske områder.
Den euklidiske struktur er en nøglekomponent i mange algebraiske teorier, og dens egenskaber er centrale for at forstå både de Gaussiske heltall og andre relaterede strukturer. Det er derfor essentielt at arbejde grundigt med normer, division og restfunktioner, så man får en dybdegående forståelse af de matematiske principper bag dem.
Hvordan opbygger man algebraiske strukturer i Lean?
I Lean kan man definere algebraiske strukturer ved hjælp af den omfattende typeklassessystem og arvefunktionalitet, som gør det muligt at kombinere eksisterende strukturer på en effektiv og elegant måde. Dette åbner døren for at definere komplekse matematiske strukturer som semigrupper, monoider, grupper og ringe, ved at udnytte et hierarki af typeklasser.
En grundlæggende struktur i Lean er semigrupper, som er defineret med en operation, der er associativ. Denne operation kan kaldes for "diamanter" i nogle tilfælde, hvilket refererer til en binær operation, der opfylder den associative lov. For at definere en semigruppe i Lean anvendes følgende syntaks:
I denne definition udvider Semigroup2 den grundlæggende struktur Dia1 α, hvor den associativitetsegenskab for operationen er angivet med dia_assoc. Ved at udvide eksisterende klasser kan man gradvist bygge mere komplekse strukturer. Et eksempel på dette er en monoid, der udvider både semigruppe-strukturen og en enhedsoperation, der sikrer, at der findes et neutralt element for operationen.
Når man arbejder med sådanne strukturer, kan man nemt få en symmetri mellem de udvidede klasser, selvom man kombinerer flere strukturer. For eksempel kan en monoid defineres ved at udvide både Semigroup1 og DiaOneClass1:
Denne tilgang skaber en symmetri, der forhindrer problemer som duplikering af operationer, der ellers kunne opstå, hvis man definerede en monoid manuelt ved at inkludere to uafhængige instanser af en diamantoperation. En vigtig funktion ved extends syntaksen i Lean er, at den automatisk løser dette problem, og dermed forenkler arbejdet med algebraiske strukturer.
En vigtig del af arbejdet med algebraiske strukturer i Lean er at forstå, hvordan man håndterer disse udvidelser uden at skabe redundante eller konfliktfyldte definitioner. Når man definerer grupper, kan man for eksempel tilføje et felt, der definerer den inverse operation for hvert element i gruppen. Dette gøres ved at introducere en ny datatype for inversion:
Med denne struktur kan man definere grupper, som inkluderer en monoid-operation samt en invers operation, og man kan derefter udnytte eksisterende resultater og lemmer i Lean for at udvikle yderligere beviser om gruppens egenskaber. Et eksempel på en gruppe kan defineres som:
Når man arbejder med grupper i Lean, er det også muligt at optimere genbrug af beviser ved hjælp af eksportkommandoer. Dette gør det muligt at importere beviser fra andre strukturer og dermed reducere behovet for at gentage hele argumentationen. For eksempel kan man eksportere lemmer og definere nye versioner af eksisterende lemmer med den nødvendige notation.
Den tekniske udfordring ved at definere ringe i Lean er, at en ringstruktur kræver både en additiv gruppe og en multiplicativ monoid, hvilket betyder, at man skal kunne håndtere to forskellige typer af operationer på en konsistent måde. Lean håndterer dette problem ved at duplicere definitionerne af operationerne for både additive og multiplikative teorier og linker dem med en to_additive attribut. Dette sikrer, at både de additive og multiplicative versioner af strukturerne og deres beviser bliver korrekt genereret.
I praksis er det muligt at definere kommutative semigrupper, monoider og grupper, og senere udvide dem til ringe. For eksempel kan en kommutativ semigruppe defineres som:
Når disse strukturer er defineret, kan de bruges som byggeklodser til at definere endnu mere komplekse algebraiske objekter som ringe og deres egenskaber. Dette system gør det muligt at arbejde med abstrakte algebraiske strukturer på en effektiv måde, samtidig med at man bevarer fleksibiliteten og genbrugbarheden af de enkelte komponenter.
I sidste ende giver Lean et stærkt værktøj til at bygge algebraiske strukturer ved hjælp af typeklasser og inheritance. Det gør det muligt at definere komplekse strukturer som semigrupper, monoider, grupper og ringe på en ren og systematisk måde, hvilket letter både konstruktionen og bevisføringen af matematiske resultater.

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский