Author SHA1 Message Date
aziis98 40a466859c versione finale 2025-07-13 23:30:21 +02:00
aziis98 c359bc007c fiwjpfewjpifew 2025-07-13 16:09:32 +02:00
aziis98 9ed3bfdf0d fewjfewipjfwe 2025-07-13 01:47:48 +02:00
aziis98 69baada6d5 fewjfewipjfwe 2025-07-12 23:56:36 +02:00
aziis98 21b33e74a6 fewjfewipjfwe 2025-07-12 20:30:46 +02:00
aziis98 52e2278f4d maybe fixed dim 2025-07-12 02:24:40 +02:00
aziis98 19c6be7357 fewjfipewjfw 2025-07-11 01:05:33 +02:00
aziis98 4436f141eb fewifewp 2025-07-11 01:04:39 +02:00
aziis98 d498205e42 presentation prototype with llm 2025-07-11 01:03:54 +02:00
aziis98 b74be29ee6 fwejifjewpfep 2025-07-09 23:00:30 +02:00
aziis98 61e1d39248 fewofw 2025-07-09 21:26:24 +02:00
aziis98 841ea6cdc2 almost finished 2025-07-09 21:01:05 +02:00
aziis98 34f9f921b2 more work 2025-07-09 13:12:34 +02:00
aziis98 ff05f7996a more work 2025-07-09 01:46:25 +02:00
aziis98 91834e7164 categorical proof with diagrams and crossings 2025-07-08 20:08:52 +02:00
aziis98 b1a604e91c preventivamente post esplosione 2025-07-08 13:42:55 +02:00
aziis98 e5fb9835f4 fixed minor typos 2025-07-06 21:38:22 +02:00
aziis98 edbabac625 finished first part of chapter 3 2025-07-06 20:59:46 +02:00
aziis98 a38c3754aa finished first part 2025-07-06 20:58:52 +02:00
aziis98 60567ce745 almost finished first part of chapter 3 2025-07-06 16:29:28 +02:00
aziis98 0a13243240 fixed a proof 2025-07-06 12:45:51 +02:00
aziis98 26fc1f769e completed first complete draft 2025-07-06 02:00:49 +02:00
aziis98 65c2506188 almost end of proof 2025-07-05 20:14:29 +02:00
aziis98 52087756d9 finita dimostrazione lemma con tante sommatorie e switch 2025-07-05 15:26:19 +02:00
aziis98 d855a22c7b many sums 2025-07-05 12:52:12 +02:00
aziis98 b9434226bb more work 2025-07-03 15:09:59 +02:00
aziis98 f101b49738 snapshot per versione finale capitolo 2 2025-06-27 18:10:42 +02:00
aziis98 40b028c8cb ultimato capitolo 2 2025-06-27 17:21:53 +02:00
aziis98 c3e479bc78 more work, chapter 2 almost done 2025-06-27 00:28:42 +02:00
aziis98 d7c6309425 removed old pdf 2025-06-24 00:56:36 +02:00
aziis98 edd05f4502 almost finished chapter 2 2025-06-24 00:56:11 +02:00
56 changed files with 2436 additions and 700 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

+1479 -434
View File
File diff suppressed because it is too large Load Diff
+62 -60
View File
@@ -25,39 +25,39 @@
// })
// }
#let definition(body, name: none) = {
#let definition(body, name: none, numbered: false) = {
// show figure: statement-style(name, numbered: false)
figure(
//
body,
kind: "definition",
supplement: {
[Definizione]
if name != none {
[ -- ]
name
}
supplement: if name != none {
[#name]
},
numbering: if numbered {
"1"
},
)
}
#let fact(body, name: none) = {
#let fact(body, numbered: false, name: none) = {
// show figure: statement-style(name, numbered: false)
figure(
body,
kind: "fact",
supplement: {
[Fatto]
if name != none {
[ -- ]
name
}
},
)
figure(body, kind: "fact", supplement: {
[Fatto]
if name != none {
[ -- ]
name
}
}, numbering: if numbered { "1" })
}
#let observation(body) = {
// show figure: statement-style(name, numbered: false)
figure(body, kind: "observation", supplement: [Osservazione], numbering: "1")
}
#let proposition(body, numbered: true) = {
// show figure: statement-style(name, numbered: numbered)
return figure(
body,
// kind: "proposition",
@@ -80,17 +80,12 @@
#let theorem(body, name: none, numbered: true) = {
// show figure: statement-style(name, numbered: numbered)
figure(
body,
kind: "theorem",
supplement: {
[Teorema]
if name != none {
[ (#name)]
}
},
numbering: if numbered { "1" },
)
figure(body, kind: "theorem", supplement: {
[Teorema]
if name != none {
[ (#name) ]
}
}, numbering: if numbered { "1" })
}
#let proof(body) = block({
@@ -125,34 +120,41 @@
}
#let todo-color = color.mix((red, 10%), (yellow, 90%))
#let todo(content) = block(
breakable: false,
grid(
rows: 2,
align: left,
block(
fill: todo-color.desaturate(60%),
inset: (x: 0.5em, y: 0.35em),
radius: (top: 0.25em),
{
set text(fill: black.transparentize(15%), size: 8pt, font: "Open Sans")
[*TODO*]
},
),
block(
width: 100%,
fill: todo-color.desaturate(75%),
inset: (x: 0.5em, y: 0.5em),
radius: (bottom: 0.25em, top-right: 0.25em),
{
set text(fill: black.transparentize(15%), size: 9pt, font: "Open Sans")
content
},
),
#let todo(content) = block(breakable: false, grid(
rows: 2,
align: left,
block(fill: todo-color.desaturate(60%), inset: (x: 0.5em, y: 0.35em), radius: (top: 0.25em), {
set text(fill: black.transparentize(15%), size: 8pt, font: "Open Sans")
[*TODO*]
}),
block(
width: 100%,
fill: todo-color.desaturate(75%),
inset: (x: 0.5em, y: 0.5em),
radius: (bottom: 0.25em, top-right: 0.25em),
{
set text(fill: black.transparentize(15%), size: 9pt, font: "Open Sans")
content
},
),
)
))
#let scr(it) = text(
features: ("ss01",),
box($cal(it)$),
)
#let scr(it) = text(features: ("ss01",), box($cal(it)$))
#let blank = {
$#h(0.125em) #{
rect(width: 0.8em * 1.41, height: 0.8em, stroke: 0.5pt, place(dx: -0.2em, dy: -0.55em, {
set text(size: 10pt)
$dots$
}))
} #h(0.125em)$
}
#let marker(content) = metadata(("marker", content))
#let qquad = h(2em)
#let diff-add(body) = block(fill: green.mix(white), outset: (x: 2pt, y: 3pt), radius: 2pt, body)
#let diff-del(body) = block(fill: red.mix(white), outset: (x: 2pt, y: 3pt), radius: 2pt, body)
+418
View File
@@ -0,0 +1,418 @@
#import "@preview/touying:0.6.1": *
#import "./presentation/theme.typ": *
#import "@preview/cetz:0.3.2"
#import "@preview/fletcher:0.5.4" as fletcher: node, edge
#import "@preview/numbly:0.1.0": numbly
#import "@preview/theorion:0.3.2": *
#show: show-theorion
// cetz and fletcher bindings for touying
#let cetz-canvas = touying-reducer.with(reduce: cetz.canvas, cover: cetz.draw.hide.with(bounds: true))
#let fletcher-diagram = touying-reducer.with(reduce: fletcher.diagram, cover: fletcher.hide)
#show: dm-unipi-theme.with(aspect-ratio: "16-9", config-common(frozen-counters: (theorem-counter,)), config-info(
title: [Il Polinomio di Kauffman: Un Invariante di Isotopia Regolare],
subtitle: [Tesi di Laurea Triennale],
author: [Antonio De Lucreziis],
date: [18 Luglio 2025],
institution: [Dipartimento di Matematica \ Università di Pisa],
logo: image("assets/dm-unipi-logo-bianco.png"),
))
// #set text(font: "Source Sans Pro", weight: 500, size: 20pt)
#set text(font: "Open Sans", weight: 400, size: 17pt)
#set strong(delta: 100)
#set par(leading: 1em)
#set list(spacing: 1em)
#title-slide()
= Introduzione e Motivazione
== Motivazione
#slide[
Come distinguere matematicamente due nodi?
#pause
- I nodi possono apparire diversi ma essere topologicamente equivalenti
- Abbiamo bisogno di *invarianti*: proprietà che non cambiano sotto deformazioni ammesse
- Gli invarianti polinomiali sono strumenti potenti e computabili
#pause
#align(center)[
#text(size: 1.2em, weight: "bold")[
Obiettivo: costruire un invariante polinomiale robusto
]
]
]
== Nodi e Diagrammi
#slide[
*Definizione:* Un *nodo tame* è un sottoinsieme $K subset bb(R)^3$ per cui esiste un embedding $f : bb(S)^1 arrow.hook bb(R)^3$ localmente piatto con $K = f(bb(S)^1)$.
#pause
*Problema:* Lavorare direttamente con embedding in $bb(R)^3$ è complesso
#pause
*Soluzione:* Proiezioni su un piano
- Proiettiamo il nodo su un piano
- Aggiungiamo informazione *sopra/sotto* ad ogni incrocio
- Otteniamo un *diagramma* del nodo
#pause
#align(center)[
I diagrammi sono l'interfaccia computazionale per studiare i nodi
]
]
== Equivalenze tra Nodi
#slide[
*Isotopia Ambiente:* Deformare un nodo senza tagliarlo o incollarlo
Due nodi $K_0, K_1 subset bb(R)^3$ sono *equivalenti* se esiste un'*isotopia ambiente* $H : bb(R)^3 times [0,1] arrow bb(R)^3$
#pause
*Teorema di Reidemeister:* Due diagrammi rappresentano nodi equivalenti se e solo se sono collegati da mosse I, II, III
#pause
*Isotopia Regolare:* Equivalenza generata solo da mosse II e III (ignoriamo la mossa I)
#pause
#align(center)[
L'isotopia regolare "vede" i riccioli (curls)
]
]
= Teoria e Costruzione
== Il Writhe: Un Primo Invariante
#slide[
*Definizione del segno di un incrocio:*
$epsilon(+) = +1 quad quad epsilon(-) = -1$
#pause
*Il writhe:* $w(K) := sum_("incroci " c) epsilon(c)$
#pause
*Proprietà:*
- Invariante per mosse II e III ✓
- NON invariante per mossa I ✗
#pause
*Formula di correzione:* Se $L_K$ è invariante per isotopia regolare con
$L(#text("sopra-ricciolo")) = a L(#text("filo"))$, $L(#text("sotto-ricciolo")) = a^(-1) L(#text("filo"))$
Allora: $F_K := a^(-w(K)) L_K$ è invariante per isotopia ambiente!
]
== Il Polinomio di Kauffman: Definizione
#slide[
Il protagonista: $L_K (a,z) in bb(Z)[a, a^(-1), z, z^(-1)]$
*Assiomi:*
1. Se $K$, $K'$ sono equivalenti a meno di isotopia regolare, allora $L_K = L_K'$
#pause
2. Relazioni skein:
- $L(#text("sopra")) + L(#text("sotto")) = z(L(#text("h-splice")) + L(#text("v-splice")))$
- $L(#text("nodo banale")) = 1$
- $L(#text("sopra-ricciolo")) = a L(#text("filo"))$, $L(#text("sotto-ricciolo")) = a^(-1) L(#text("filo"))$
#pause
*Domanda:* Gli assiomi definiscono univocamente $L_K$?
]
== Esempio: Link di Hopf
#slide[
Applichiamo la relazione skein:
$L[#text("Hopf")] + L[#text("versione scambiata")] = z(L[#text("due cerchi")] + L[#text("due fili")])$
#pause
Sapendo che:
- $L[#text("due cerchi")] = delta = (a + a^(-1))/z - 1$
- $L[#text("due fili")] = a + a^(-1)$
#pause
Otteniamo:
$L[#text("Hopf")] = -(a + a^(-1))z^(-1) + 1 + (a + a^(-1))z$
#pause
Questi calcoli suggeriscono che $L_K$ esiste, ma serve una dimostrazione rigorosa!
]
== La Sfida della Buona Definizione
#slide[
*Problema centrale:* Gli assiomi definiscono $L_K$ in modo unico?
#pause
*Sfide:*
1. Gli assiomi sono *impliciti* (relazioni, non formule)
2. Come garantire che esista una soluzione?
3. Come garantire l'unicità?
4. Come verificare l'indipendenza dalle scelte computazionali?
#pause
*Scelte che potrebbero influenzare il risultato:*
- Scelta del punto base $p$ su ogni componente
- Direzione del punto base (orario vs antiorario)
- Ordine delle operazioni nelle sequenze
#pause
#align(center)[
#box(fill: red.lighten(80%), inset: 1em, radius: 5pt)[
*Senza questa dimostrazione, $L_K$ non sarebbe ben definito!*
]
]
]
== Ingredienti per la Costruzione
#slide[
*Concetti chiave necessari:*
1. *Nodo banale standard*: $hat(K)(cal(U), p)$
- Percorrere l'ombra planare da un punto base $p$
- Primo passaggio su ogni incrocio = sopra-incrocio
#pause
2. *Operazioni sui diagrammi*:
- $S_i K$: scambia l'incrocio $i$
- $E_i K$, $e_i K$: splice orizzontale e verticale
#pause
3. *Sequenze di scambi*: $lambda = (lambda_n, dots, lambda_0)$
- Trasformano $K$ in $hat(K)(lambda)$
#pause
*Proprietà fondamentale:* $L[hat(K)] = a^(w(hat(K)))$
]
== La Formula Ricorsiva
#slide[
*Idea*: Esprimere $L_K$ in termini di diagrammi "più semplici"
Applicando le relazioni skein incrementalmente:
$
L[K] + L[S_0 K] &= z(L[E_0 K] + L[e_0 K]) \
L[S_0 K] + L[S_1 S_0 K] &= z(L[E_1 S_0 K] + L[e_1 S_0 K]) \
&dots.v \
L[S_(n-1) dots S_0 K] + L[hat(K)] &= z(L[E_n S_(n-1) dots S_0 K] + L[e_n S_(n-1) dots S_0 K])
$
#pause
Sommando e sottraendo membro a membro, i termini intermedi si cancellano!
#pause
*Formula finale:*
$L_K = (-1)^(n+1) L_(hat(K)) + z sum_(i=0)^n (-1)^i (L[A_i^lambda K] + L[B_i^lambda K])$
]
== Definizione Induttiva Completa
#slide[
*Caso 1:* $K = hat(K)$ (nodo banale standard)
$L_K = a^(w(K))$
#pause
*Caso 2:* $K = K_1 union K_2$ con $K_1$ sovrastante $K_2$
$L_K = delta L_(K_1) L_(K_2)$ dove $delta = (a + a^(-1))/z - 1$
#pause
*Caso 3:* Uso della formula ricorsiva:
$L_K = 1/2 [sum_(q = p, overline(p)) ((-1)^(abs(lambda(q))+1) L_(hat(K)(q)) + z sum_K (lambda(q)))]$
#pause
*Proprietà cruciale:* Ogni termine a destra ha meno incroci o è "più vicino" al caso base
]
== Strategia della Dimostrazione
#slide[
*Ipotesi induttiva* (per diagrammi con $< N$ incroci):
1. $L_K$ è ben definito (indipendente dalle scelte)
2. $L_K$ verifica tutte le relazioni skein
3. $L_K$ è invariante per mosse II e III che non aumentano gli incroci
#pause
*Lemmi tecnici fondamentali:*
- *Lemma delle Rotazioni*: L'ordine ciclico degli scambi non influenza il risultato
- *Invarianza del punto base*: La definizione non dipende dal punto base scelto
- *Identità per nodi banali*: $L[hat(K)(p)] + L[hat(K)(q)] = z(L[E_i hat(K)] + L[e_i hat(K)])$
#pause
*Metodo:* Spostando il punto base di un incrocio per volta, si dimostra l'invarianza completa
]
== Verifica degli Assiomi e Invarianza
#slide[
*Teorema*: La definizione induttiva soddisfa tutti gli assiomi di Kauffman
#pause
*Dimostrazione per le relazioni skein*:
1. Scegli il punto base in modo che l'incrocio sia il primo nella sequenza
2. La relazione skein emerge naturalmente dalla formula ricorsiva
3. Gli altri termini si cancellano per simmetria
#pause
*Invarianza per isotopia regolare*:
- *Mossa II*: scegli punti base che evitano gli incroci coinvolti
- *Mossa III*: usa equivalenze locali e induzione
#pause
#align(center)[
La costruzione induttiva "conosce automaticamente" tutte le proprietà necessarie!
]
]
= Risultati e Applicazioni
== Il Risultato Principale
#slide[
*Teorema*: Esiste ed è unico un invariante $L_K (a,z)$ che soddisfa gli assiomi di Kauffman.
#pause
*Dimostrazione completa*:
1. *Esistenza*: La costruzione induttiva fornisce una definizione esplicita
2. *Buona definizione*: Indipendenza dalle scelte arbitrarie
3. *Verifica assiomi*: La definizione soddisfa tutte le relazioni richieste
4. *Unicità*: Gli assiomi determinano univocamente i valori
#pause
*Conseguenza*: Il polinomio di Kauffman è un invariante completo e computabile per l'isotopia regolare
#pause
#align(center)[
#box(fill: green.lighten(80%), inset: 1em, radius: 5pt)[
*La teoria è ora su basi solide!*
]
]
]
== Dal Regolare all'Ambiente: Il Polinomio $F_K$
#slide[
Usando la formula di correzione:
$F_K = a^(-w(K)) L_K$
#pause
*Teorema*: $F_K (a,z)$ è un invariante di isotopia ambiente.
#pause
*Significato*:
- Partendo da un invariante regolare ($L_K$)
- Aggiungiamo la correzione del writhe
- Otteniamo un vero invariante di nodi!
#pause
*Proprietà*:
- $F_(m(K))(a,z) = F_K(1/a, z)$ (comportamento rispetto al mirror)
- $F[K_1 hash K_2] = F[K_1] F[K_2]$ (moltiplicatività per somma connessa)
- $F_K$ distingue nodi che $L_K$ non può distinguere
]
== Implementazione e Verifica
#slide[
*Progetto Computazionale:*
- *Implementazione in Python*: Algoritmo basato sulle relazioni skein
- *Calcolo automatico* di $L_K$ e $F_K$ per diagrammi di nodi
- *Interfaccia user-friendly* per l'inserimento di diagrammi
#pause
*Verifica sperimentale:*
- Confronto con il database *KnotInfo*
- Verifica su centinaia di nodi noti
- Test di coerenza con valori pubblicati
#pause
*Scoperta interessante:* Trovato un *errore* nel valore pubblicato per il nodo $10_125$!
#pause
#align(center)[
La teoria e l'implementazione si confermano a vicenda
]
]
== Conclusioni
#slide[
*Percorso compiuto:*
1. Dal concetto geometrico di nodo alla formalizzazione tramite diagrammi
2. Definizione dell'isotopia regolare e degli invarianti
3. Costruzione rigorosa del polinomio di Kauffman
4. Dimostrazione della buona definizione
5. Estensione agli invarianti di isotopia ambiente
#pause
*Risultati principali:*
- *Dimostrazione* della buona definizione di $L_K$
- *Costruzione* di $F_K$ come invariante ambiente
- *Verifica computazionale* e scoperta di errori nella letteratura
#pause
#align(center)[
#text(size: 1.2em, weight: "bold")[
Grazie per l'attenzione!
]
]
*Domande?*
]
+273
View File
@@ -0,0 +1,273 @@
#import "@preview/touying:0.6.1": *
#let _tblock(self: none, title: none, it) = {
grid(columns: 1, row-gutter: 0pt, block(
fill: self.colors.primary-dark,
width: 100%,
radius: (top: 6pt),
inset: (top: 0.4em, bottom: 0.3em, left: 0.5em, right: 0.5em),
text(fill: self.colors.neutral-lightest, weight: "bold", title),
), rect(
fill: gradient.linear(self.colors.primary-dark, self.colors.primary.lighten(90%), angle: 90deg),
width: 100%,
height: 4pt,
), block(
fill: self.colors.primary.lighten(90%),
width: 100%,
radius: (bottom: 6pt),
inset: (top: 0.4em, bottom: 0.5em, left: 0.5em, right: 0.5em),
it,
))
}
#let tblock(title: none, it) = touying-fn-wrapper(_tblock.with(title: title, it))
#let slide(
title: auto,
header: auto,
footer: auto,
align: auto,
config: (:),
repeat: auto,
setting: body => body,
composer: auto,
..bodies,
) = touying-slide-wrapper(self => {
if align != auto {
self.store.align = align
}
if title != auto {
self.store.title = title
}
if header != auto {
self.store.header = header
}
if footer != auto {
self.store.footer = footer
}
let new-setting = body => {
show: std.align.with(self.store.align)
show: setting
body
}
touying-slide(self: self, config: config, repeat: repeat, setting: new-setting, composer: composer, ..bodies)
})
#let title-slide(config: (:), ..args) = touying-slide-wrapper(self => {
self = utils.merge-dicts(self, config)
self.store.title = none
let info = self.info + args.named()
info.authors = {
let authors = if "authors" in info {
info.authors
} else {
info.author
}
if type(authors) == array {
authors
} else {
(authors,)
}
}
let body = {
show: std.align.with(center + horizon)
block(fill: self.colors.primary, inset: 1.5em, radius: 0.5em, breakable: false, {
text(size: 1.2em, fill: self.colors.neutral-lightest, weight: "bold", info.title)
if info.subtitle != none {
parbreak()
text(size: 1.0em, fill: self.colors.neutral-lightest, weight: "bold", info.subtitle)
}
})
// authors
grid(
columns: (1fr,) * calc.min(info.authors.len(), 3),
column-gutter: 1em,
row-gutter: 1em,
..info.authors.map(author => text(fill: black, author)),
)
v(0.5em)
// institution
if info.institution != none {
parbreak()
text(size: 0.7em, info.institution)
}
// date
if info.date != none {
parbreak()
text(size: 1.0em, utils.display-info-date(self))
}
}
touying-slide(self: self, body)
})
#let outline-slide(config: (:), title: utils.i18n-outline-title, numbered: true, level: none, ..args) = touying-slide-wrapper(self => {
self.store.title = title
touying-slide(self: self, config: config, std.align(self.store.align, components.adaptive-columns({
text(fill: self.colors.primary, weight: 600, components.custom-progressive-outline(
level: level,
alpha: self.store.alpha,
indent: (0em, 1em),
vspace: (.4em,),
numbered: (numbered,),
depth: 1,
..args.named(),
))
}) + args.pos().sum(default: none)))
})
#let new-section-slide(config: (:), title: utils.i18n-outline-title, level: 1, numbered: true, ..args, body) = outline-slide(config: config, title: title, level: level, numbered: numbered, ..args, body)
#let focus-slide(config: (:), align: horizon + center, body) = touying-slide-wrapper(self => {
self = utils.merge-dicts(
self,
config-common(freeze-slide-counter: true),
config-page(fill: self.colors.primary, margin: 2em, header: none, footer: none),
)
set text(fill: self.colors.neutral-lightest, weight: "bold", size: 1.5em)
touying-slide(self: self, config: config, std.align(align, body))
})
#let ending-slide(config: (:), title: none, body) = touying-slide-wrapper(self => {
let content = {
set std.align(center + horizon)
if title != none {
block(
fill: self.colors.tertiary,
inset: (top: 0.7em, bottom: 0.7em, left: 3em, right: 3em),
radius: 0.5em,
text(size: 1.5em, fill: self.colors.neutral-lightest, title),
)
}
body
}
touying-slide(self: self, config: config, content)
})
#let dm-unipi-theme(
aspect-ratio: "16-9",
align: horizon,
alpha: 20%,
title: self => utils.display-current-heading(depth: self.slide-level),
header-right: self => self.info.logo,
progress-bar: true,
footer-columns: (25%, 1fr, 5em),
footer-a: self => self.info.author,
footer-c: self => if self.info.short-title == auto {
self.info.title
} else {
self.info.short-title
},
footer-d: context utils.slide-counter.display() + " / " + utils.last-slide-number,
..args,
body,
) = {
let header(self) = {
set std.align(top)
grid(
rows: (auto, auto),
utils.call-or-display(self, self.store.navigation),
utils.call-or-display(self, self.store.header),
)
}
let footer(self) = {
set text(size: .5em)
set std.align(center + bottom)
grid(
rows: (auto, auto),
utils.call-or-display(self, self.store.footer),
if self.store.progress-bar {
utils.call-or-display(self, components.progress-bar(height: 2pt, self.colors.primary, self.colors.neutral-lightest))
},
)
}
show: touying-slides.with(
config-page(
paper: "presentation-" + aspect-ratio,
header: header,
footer: footer,
header-ascent: 0em,
footer-descent: 0em,
margin: (top: 3.5em, bottom: 2.5em, x: 2.5em),
),
config-common(slide-fn: slide, new-section-slide-fn: new-section-slide),
config-methods(init: (self: none, body) => {
set text(size: 18pt, font: "Open Sans")
set par(leading: 0.75em)
set list(marker: {
place(top + left, dy: 0.2em, circle(fill: self.colors.primary, radius: 3pt))
h(0.25em)
})
show figure.caption: set text(size: 0.6em)
show footnote.entry: set text(size: 0.6em)
show heading: set text(fill: self.colors.primary)
show link: it => if type(it.dest) == str {
set text(fill: self.colors.primary)
it
} else {
it
}
show figure.where(kind: table): set figure.caption(position: top)
body
}, alert: utils.alert-with-primary-color, tblock: _tblock),
config-colors(
primary: rgb("#003c71"),
primary-dark: rgb("#005baa"),
secondary: rgb("#ffffff"),
neutral-lightest: rgb("#ffffff"),
neutral-darkest: rgb("#001c35"),
),
config-store(
align: align,
alpha: alpha,
title: title,
header-right: header-right,
progress-bar: progress-bar,
footer-columns: footer-columns,
footer-a: footer-a,
footer-c: footer-c,
footer-d: footer-d,
navigation: self => components.simple-navigation(
self: self,
primary: white,
secondary: gray,
background: self.colors.neutral-darkest,
logo: utils.call-or-display(self, self.store.header-right),
),
header: self => if self.store.title != none {
block(
width: 100%,
height: 2em,
fill: self.colors.primary,
place(
left + horizon,
text(fill: self.colors.neutral-lightest, weight: 600, size: 1.2em, utils.call-or-display(self, self.store.title)),
dx: 1.5em,
),
)
},
footer: self => {
let cell(fill: none, it) = rect(
width: 100%,
height: 100%,
inset: 1mm,
outset: 0mm,
fill: fill,
stroke: none,
std.align(horizon, text(fill: self.colors.neutral-lightest, it)),
)
grid(
columns: self.store.footer-columns,
rows: (1.5em, auto),
cell(fill: self.colors.neutral-darkest, utils.call-or-display(self, self.store.footer-a)),
cell(fill: self.colors.primary, utils.call-or-display(self, self.store.footer-c)),
cell(fill: self.colors.primary, utils.call-or-display(self, self.store.footer-d)),
)
},
),
..args,
)
body
}
+11 -2
View File
@@ -40,8 +40,17 @@
author = {Crowell, R.H. and Fox, R.H.},
isbn = {9783540902720},
lccn = {77022776},
series = {Ecological Studies},
url = {https://books.google.it/books?id=_1HvAAAAMAAJ},
series = {Graduate Text in Mathematics},
year = {1977},
publisher = {Springer New York}
}
@book{lickorish1997introduction,
title = {An Introduction to Knot Theory},
author = {Lickorish, W.B.R.},
isbn = {9780387982540},
lccn = {97016660},
series = {Graduate Texts in Mathematics},
year = {1997},
publisher = {Springer New York}
}
+2
View File
@@ -23,6 +23,8 @@ for i in $(seq 0 3); do
X_OFFSET=$(( i * TILE_WIDTH ))
TEMP_FILE="_temp_${i}.png"
OUTPUT_FILE=$(printf "$OUTPUT_TEMPLATE" "$i")
echo "Generating tile $i: $OUTPUT_FILE"
magick "$INPUT_IMAGE" -crop "${TILE_WIDTH}x${TILE_HEIGHT}+${X_OFFSET}+0" +repage "$TEMP_FILE"
+57 -31
View File
@@ -1,36 +1,24 @@
#import "@preview/cetz:0.3.4"
#let draw-strand(polyline, style: (:)) = {
#let draw-strand(polyline, size-factor: 1.0, style: (:)) = {
import cetz.draw: *
set-style(
..cetz.styles.resolve(
(stroke: (paint: white, thickness: 0.75pt * 8, cap: "butt")),
base: style,
),
)
polyline
set-style(
..cetz.styles.resolve(
style,
base: (stroke: (paint: black, thickness: 0.75pt, cap: "round")),
),
)
// draw the white outline
set-style(..cetz.styles.resolve((stroke: (paint: white, thickness: size-factor * 0.75pt * 8, cap: "butt")), base: style))
polyline
set-style(stroke: (paint: black, thickness: 0.75pt, cap: "round"))
// draw the black line
set-style(..cetz.styles.resolve(style, base: (stroke: (paint: black, thickness: size-factor * 0.75pt, cap: "round"))))
polyline
// set-style(stroke: (paint: black, thickness: thickness, cap: "round"))
}
#let skein-canvas = body => cetz.canvas(
length: 0.25cm,
padding: 0.25,
{
import cetz.draw: *
rect((-1, -1), (1, 1), fill: white, stroke: none)
#let skein-canvas = (body, size-factor: 1.0) => cetz.canvas(length: size-factor * 0.25cm, padding: 0.25, {
import cetz.draw: *
rect((-1, -1), (1, 1), fill: white, stroke: none)
body
},
)
body
})
#let arrow-size = 0.35
@@ -48,6 +36,9 @@
}
}
#let medium-scale-factor = 0.8
#let small-scale-factor = 0.125cm / 0.25cm
#let skein = (
unit: skein-canvas({
import cetz.draw: *
@@ -89,15 +80,50 @@
draw-strand({ hobby((-1.5, +1), (-1, +1), (0.5, 0), (0.1, -1), (0, -1)) })
draw-strand({ hobby((1.5, +1), (1, +1), (-0.5, 0), (-0.1, -1), (0, -1)) })
}),
//
// Medium
//
unit-medium: skein-canvas(size-factor: medium-scale-factor, {
import cetz.draw: *
circle((0, 0), radius: 1, stroke: (paint: black, thickness: 0.75pt))
}),
strand-medium: skein-canvas(size-factor: medium-scale-factor, {
import cetz.draw: *
rect((-1, -1), (1, 1), fill: white, stroke: none)
draw-strand(size-factor: medium-scale-factor, { hobby((-1, 0), (0, 0.25), (1, 0), omega: 1) })
}),
over-twist-medium: skein-canvas(size-factor: medium-scale-factor, {
import cetz.draw: *
draw-strand(size-factor: medium-scale-factor, { hobby((1.5, +1), (1, +1), (-0.5, 0), (-0.1, -1), (0, -1)) })
draw-strand(size-factor: medium-scale-factor, { hobby((-1.5, +1), (-1, +1), (0.5, 0), (0.1, -1), (0, -1)) })
}),
under-twist-medium: skein-canvas(size-factor: medium-scale-factor, {
import cetz.draw: *
draw-strand(size-factor: small-scale-factor, { hobby((-1.5, +1), (-1, +1), (0.5, 0), (0.1, -1), (0, -1)) })
draw-strand(size-factor: small-scale-factor, { hobby((1.5, +1), (1, +1), (-0.5, 0), (-0.1, -1), (0, -1)) })
}),
//
// Small
//
strand-small: skein-canvas(size-factor: small-scale-factor, {
import cetz.draw: *
rect((-1, -1), (1, 1), fill: white, stroke: none)
draw-strand(size-factor: small-scale-factor, { hobby((-1, 0), (0, 0.25), (1, 0), omega: 1) })
}),
over-twist-small: skein-canvas(size-factor: small-scale-factor, {
import cetz.draw: *
draw-strand(size-factor: small-scale-factor, { hobby((1.5, +1), (1, +1), (-0.5, 0), (-0.1, -1), (0, -1)) })
draw-strand(size-factor: small-scale-factor, { hobby((-1.5, +1), (-1, +1), (0.5, 0), (0.1, -1), (0, -1)) })
}),
under-twist-small: skein-canvas(size-factor: small-scale-factor, {
import cetz.draw: *
draw-strand(size-factor: small-scale-factor, { hobby((-1.5, +1), (-1, +1), (0.5, 0), (0.1, -1), (0, -1)) })
draw-strand(size-factor: small-scale-factor, { hobby((1.5, +1), (1, +1), (-0.5, 0), (-0.1, -1), (0, -1)) })
}),
)
#let skein-generic(
kind: "over",
direction: (+1, +1),
arrows: (true, true),
styles: ((:), (:)),
) = {
#let skein-generic(kind: "over", direction: (+1, +1), arrows: (true, true), styles: ((:), (:))) = {
skein-canvas({
import cetz.draw: *
if kind == "over" {
+134 -173
View File
@@ -60,7 +60,6 @@
// top: 4.5cm,
// bottom: 3.5cm,
),
header-ascent: 1cm,
header: context {
let i = counter(page).get().first()
@@ -68,14 +67,10 @@
set text(size: script-size)
align(center, upper(page-title))
},
footer-descent: 1cm,
footer: context {
let i = counter(page).get().first()
align(
center,
[#i],
)
align(center, [#i])
},
)
@@ -90,19 +85,8 @@
let heading-size = heading-level-size(it.level)
set text(
size: heading-size,
fill: luma(10%),
weight: 600,
top-edge: "bounds",
bottom-edge: "baseline",
)
set par(
spacing: 0pt,
hanging-indent: 0pt,
first-line-indent: 0pt,
)
set text(size: heading-size, fill: luma(10%), weight: 600, top-edge: "bounds", bottom-edge: "baseline")
set par(spacing: 0pt, hanging-indent: 0pt, first-line-indent: 0pt)
if it.level == 1 {
if counter(heading).get() != (0,) {
@@ -111,20 +95,14 @@
stack(
dir: ttb,
..(
if counter(heading).get() != (0,) {
(
layout(size => v(size.height * 25%)),
{
set text(size: heading-level-size(3))
[Capitolo ]
set text(size: heading-level-size(2))
counter(heading).display("1")
},
v(heading-size * 0.61),
)
}
),
..(if counter(heading).get() != (0,) {
(layout(size => v(size.height * 25%)), {
set text(size: heading-level-size(3))
[Capitolo ]
set text(size: heading-level-size(2))
counter(heading).display("1")
}, v(heading-size * 0.61),)
}),
line(length: 100%),
v(heading-size * 0.61),
align(right, it.body),
@@ -169,10 +147,7 @@
show math.equation: set block(below: normal-size * 1.5, above: normal-size * 1.5)
show math.equation: set text(weight: 400)
set math.equation(
numbering: "(1)",
supplement: none,
)
set math.equation(numbering: "(1)", supplement: none)
show math.equation: it => {
if it.block and not it.has("label") [
@@ -194,44 +169,31 @@
show raw.where(block: false): it => {
set text(size: 7.25pt, fill: luma(7%))
box(
outset: (x: 2pt, y: 3pt),
fill: luma(92%),
radius: 3pt,
it,
)
box(outset: (x: 2pt, y: 3pt), fill: luma(92%), radius: 3pt, it)
}
show raw.where(block: true): it => block(
outset: (x: 2pt, y: 3pt),
fill: luma(92%),
radius: 4pt,
inset: 4pt,
it,
)
show raw.where(block: true): it => block(outset: (x: 2pt, y: 3pt), fill: luma(92%), radius: 4pt, inset: 4pt, it)
set std.bibliography(
style: "ieee",
title: none,
)
set std.bibliography(style: "ieee", title: none, full: true)
set figure(gap: 17pt)
set figure(gap: 1em)
show figure: set block(above: 1.5em, below: 1.5em)
show figure: it => {
// Customize the figure's caption.
show figure.caption: caption => {
set text(size: small-size)
smallcaps(caption.supplement)
show figure.caption: caption => block(inset: (x: 1.4em), {
set align(left)
set text(size: 10.5pt)
smallcaps([Figura])
if caption.numbering != none {
[ ]
numbering(caption.numbering, ..caption.counter.at(it.location()))
}
[. ]
caption.body
}
})
// We want a bit of space around tables and images.
show selector.or(table, image): pad.with(x: 23pt)
show selector.or(table, image): pad.with(x: 2em)
// Display the figure's body and caption.
it
@@ -261,7 +223,20 @@
block({
strong({
it.supplement
[Definizione]
if it.numbering != none {
[ #(
..counter(heading).get().slice(0, 1).map(it => str(it)),
numbering(it.numbering, ..it.counter.at(it.location())),
).join(".") ]
}
if it.supplement != none {
[ -- ]
it.supplement
}
[.]
})
[ ]
@@ -274,12 +249,42 @@
block({
strong({
it.supplement
if it.numbering != none {
[ ]
// current chapter and section
[#(
..counter(heading).get().slice(0, 1).map(it => str(it)),
numbering(it.numbering, ..it.counter.at(it.location())),
).join(".")]
}
[.]
})
it.body
})
}
show figure.where(kind: "observation"): it => {
set align(start)
block({
strong({
it.supplement
if it.numbering != none {
[ ]
// current chapter and section
[#(
..counter(heading).get().slice(0, 1).map(it => str(it)),
numbering(it.numbering, ..it.counter.at(it.location())),
).join(".")]
}
[.]
})
[ ]
it.body
})
}
show figure.where(kind: "proposition"): it => {
set align(start)
block({
@@ -346,102 +351,75 @@
show ref: it => {
if it.element != none {
let el = it.element
if el == figure {
if el.kind == "proposition" or el.kind == "lemma" or el.kind == "theorem" {
link(
el.location(),
{
if it.supplement != auto { it.supplement } else { el.supplement }
[ ]
(
..counter(heading).at(el.location()).slice(0, 1).map(it => str(it)),
numbering(el.numbering, ..el.counter.at(el.location())),
).join(".")
},
)
}
if el.func() == figure {
link(el.location(), {
if it.supplement != auto {
it.supplement
} else {
if el.kind == "definition" {
[Definizione]
} else {
el.supplement
}
}
[ ]
(
..counter(heading).at(el.location()).slice(0, 1).map(it => str(it)),
numbering(el.numbering, ..el.counter.at(el.location())),
).join(".")
})
} else if el.func() == metadata and type(el.value) == array and el.value.at(0) == "marker" {
link(el.location(), el.value.at(1))
} else {
it
repr(it)
}
} else if it.citation != none {
it
}
}
// Highlight ref
// show ref: it => {
// set text(fill: red.mix(black))
// box(fill: red.mix(white), outset: (y: 0.5em), it)
// }
// First thesis page
context {
set align(center + horizon)
set text(size: 14pt)
set page(
margin: 0pt,
header: none,
footer: none,
)
set page(margin: 0pt, header: none, footer: none)
// show text: it => box(stroke: 1pt + red, it)
// show grid: it => box(stroke: 1pt + red, it)
grid(
columns: 1,
image("assets/unipi.svg", width: 5cm),
v(2em),
{
set text(size: 18pt)
smallcaps[Università di Pisa]
},
grid(columns: 1, image("assets/unipi.svg", width: 5cm), v(2em), {
set text(size: 18pt)
smallcaps[Università di Pisa]
}, v(1em), {
line(length: 5.25cm)
}, v(1em), [
*Dipartimento di Matematica \ Corso di Laurea Triennale in Matematica*
], v(6em), {
[Tesi di Laurea]
}, v(1em), {
set text(size: 18pt)
strong(page-title)
}, v(15em), {
block(width: 12cm, grid(columns: (1fr, 1fr), {
set align(left)
v(1em),
{
line(length: 5.25cm)
},
[Relatore: \ *Prof. Paolo Lisca*]
}, {
set align(right)
v(1em),
[
*Dipartimento di Matematica \ Corso di Laurea Triennale in Matematica*
],
v(6em),
{
[Tesi di Laurea]
},
v(1em),
{
set text(size: 18pt)
strong(page-title)
},
v(15em),
{
block(
width: 12cm,
grid(
columns: (1fr, 1fr),
{
set align(left)
[Relatore: \ *Prof. Paolo Lisca*]
},
{
set align(right)
[Candidato: \ *Antonio De Lucreziis*]
},
),
)
},
v(6em),
{
line(length: 6cm)
},
v(1em),
[
*Anno Accademico 2024/2025*
],
)
[Candidato: \ *Antonio De Lucreziis*]
}))
}, v(6em), {
line(length: 6cm)
}, v(1em), [
*Anno Accademico 2024/2025*
])
pagebreak()
}
@@ -459,43 +437,26 @@
// },
// )
grid(rows: (auto, 1fr, 2fr), align: center + horizon, v(2em), {
if abstract != none {
pad(x: 2em, grid(columns: 1, {
set text(size: 16pt)
grid(
rows: (auto, 1fr, 2fr),
align: center + horizon,
v(2em),
{
if abstract != none {
pad(
x: 2em,
grid(
columns: 1,
{
set text(size: 16pt)
[*Abstract*]
}, v(1em), {
set align(start)
abstract
}))
}
}, {
set text(size: 16pt)
[*Indice*]
[*Abstract*]
},
v(1em),
{
set align(start)
abstract
},
),
)
}
},
{
set text(size: 16pt)
[*Indice*]
v(0.25em)
set text(size: 12pt)
outline(title: none, depth: 2, indent: 1em)
},
)
v(0.25em)
set text(size: 12pt)
outline(title: none, depth: 2, indent: 1em)
})
context { counter("fact").update(2) }