Compare commits

24 Commits

Author SHA1 Message Date
Zheyuan Wu
461135ee9d updates
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-27 13:51:39 -05:00
Zheyuan Wu
0e0ca39f0a updates 2026-03-27 11:50:01 -05:00
Zheyuan Wu
87a5182ac6 update
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-25 20:18:14 -05:00
Zheyuan Wu
b94eef4848 Merge branch 'main' of https://git.trance-0.com/Trance-0/NoteNextra-origin 2026-03-25 18:35:23 -05:00
Zheyuan Wu
37707302bb update 2026-03-25 11:49:59 -05:00
Zheyuan Wu
dbdc8f528b Update Math4202_L23.md
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-24 15:47:02 -05:00
Zheyuan Wu
04cda8c4ca updates 2026-03-24 15:28:40 -05:00
Zheyuan Wu
a7640075cb Merge branch 'main' of https://git.trance-0.com/Trance-0/NoteNextra-origin
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-24 12:18:22 -05:00
Zheyuan Wu
31139ae077 updates 2026-03-24 12:18:11 -05:00
Zheyuan Wu
604b48ca70 updates
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-23 13:50:46 -05:00
Zheyuan Wu
1577e5e731 updates 2026-03-23 11:50:31 -05:00
Zheyuan Wu
3f4479157b updates
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-20 16:59:05 -05:00
Zheyuan Wu
cd8705ad9e update mcp
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-20 01:58:49 -05:00
Zheyuan Wu
24153a40b4 mcp addded by codex 2026-03-19 23:46:00 -05:00
Zheyuan Wu
d5e1774aad updates
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-18 20:28:39 -05:00
Zheyuan Wu
cbca8c0233 Merge branch 'main' of https://git.trance-0.com/Trance-0/NoteNextra-origin 2026-03-18 13:01:50 -05:00
Zheyuan Wu
2e0a28b28d updates 2026-03-18 11:51:38 -05:00
Zheyuan Wu
e1ed310a2e Update CSE4303_L14.md
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-17 13:30:41 -05:00
Zheyuan Wu
f37253b471 updates 2026-03-17 12:36:05 -05:00
Zheyuan Wu
4823eefff6 updates
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-16 13:48:46 -05:00
Zheyuan Wu
94bfe0b0f1 Merge branch 'main' of https://git.trance-0.com/Trance-0/NoteNextra-origin
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-08 12:11:01 -05:00
Zheyuan Wu
2f33f6a9a3 updates 2026-03-08 12:10:49 -05:00
Zheyuan Wu
c663850ee2 Create Math4302_L22.md
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-07 11:19:20 -06:00
Zheyuan Wu
9c506ec0c1 updates
Some checks failed
Sync from Gitea (main→main, keep workflow) / mirror (push) Has been cancelled
2026-03-06 11:55:42 -06:00
37 changed files with 2840 additions and 211 deletions

3
.gitignore vendored
View File

@@ -147,3 +147,6 @@ public/sitemap.xml
# npm package lock file for different platforms
package-lock.json
# generated
mcp-worker/generated

View File

@@ -36,3 +36,18 @@ Update dependencies
```bash
npx npm-check-updates -u
```
### MCP access to notes
This repository includes a minimal MCP server that exposes the existing `content/` notes as a knowledge base for AI tools over stdio.
```bash
npm install
npm run mcp:notes
```
The server exposes:
- `list_notes`
- `read_note`
- `search_notes`

View File

@@ -0,0 +1,156 @@
# CSE4303 Introduction to Computer Security (Lecture 14)
## Cryptography applications
### Crypto summary
- Cryptographic goals
- Confidentiality
- Symmetric-key ciphers
- Block ciphers
- Stream ciphers
- Public-key ciphers
- Data integrity
- Arbitrary length hash functions
- Message Authentication Codes (MACs)
- Digital signatures
- Authentication
- Entity authentication
- Authentication primitives
- Message authentication
- MACs
- Digital signatures
- Non-repudiation
- Digital signatures
### Overview
- Digital certificates
- PKI
- Intentional MITMs
- Other uses
- Authentication (...of users, not data)
- SSH keys
- Time-based One-Time Password (TOTP)
- Ransomware
- Post-Quantum (PQ) crypto
- Zero-Knowledge (ZK) proofs
- Homomorphic encryption
### Recall: key-exchange challenge
- No matter the cipher, **algorithm** is known but **key** must remain secret
- (Security principle: open design)
- Symmetric-key system: entire key remains secret
- Public-key scheme: private keys remain secret
- Q: before secure channel established, how to **reliably exchange** symmetric keys? How to reliably exchange public keys?
- Symmetric keys: via public/private keys
- Public keys: web of trust (e.g. GPG), what else?
As presented, the protocol is insecure against active attacks
MiTM can insert and create 2 separate secure sessions
### Public-key distribution: digital certificates
- Common public-key object
- Goal: bind identity to public key
- Contents:
- ID/key tuple
- Digital signature of some trusted signing authority: provides integrity/authenticity "guarantees" (under proper assumptions)
- Implementation:
- Can be chained: e.g. certificate for key of interest signed by Certificate Authority $CA_N$, cert for $CA_N$'s key signed by $CA_{N-1}$, ..., certificate for $CA_2$'s key signed by $CA_1$ (root CA), root CA's key pre-loaded in OS
- Allows for a hierarchy
- Requires entity to gain trust of signing authority and obtain certificate
### Defeating MITM using Digital Certificates
- Alice goes to a **trusted party** to get a certificate.
- After verifying Alice's identity, the trusted party issues a certificate **signed by them** with Alice's name and her public key.
- Alice sends the entire certificate to Bob.
- Bob verifies the certificate using the trusted party's public key (i.e. he checks the **signature** on the cert).
- Bob now knows the **true owner** of a public key.
### Public key infrastructure
- Certificate Authority (CA): a trusted party responsible for verifying the identity of users and binding the verified identity to public keys by issuing signed certificates to them
- Digital Certificate: a document certifying that the public key included inside does belong to the identity described in the document (signed by CA)
- Standard governing certs: X.509
### HTTPS layers of trust
- Data
- Trust data b/c it's encrypted by session key
- Session Key
- Trust session key b/c it was exchanged via public-key scheme
- Public Key
- Trust public key b/c it's in a certificate
- Certificate
- Trust certificate b/c it's signed by chain of CAs, ending with root CA
- Certificate Authorities
- Trust root CA's sig b/c it's embedded in browser/OS
- Browser/OS ...
- Trust browser/OS b/c
- we trust whoever installed the browser/OS
- and we trust the hardware that runs the OS
- (note: mechanisms for justifying these trusts exist too)
- Hardware
#### Application: PKI for public-key distribution
- Q: How are encrypted communications usually sent across a network? (e.g. https traffic)
- A: Multi-part strategy
- 1. Use symmetric-key cipher for encrypting traffic (speed advantage)
- 2. Use public-key cipher for exchanging symmetric key values (authenticity, consistency)
- 3. Use public-key infrastructure (PKI) to certify public keys (using certificates)
- Full details and data traces: First Few Milliseconds of a TLS 1.2 Connection (2017)
- [demo: ciphers currently used to encrypt session in Firefox, Chrome]
- [demo: root CAs currently trusted]
- How to mitigate attacks?
- Revocation cert
- Real attacks
- DigiNotar attacked 2011: issued fraudulent certs for, e.g., google.com
- WoSign 2016: issued certs to domains rather than subdomains
#### Legitimate (?) MITMs in PKI: private root certs
- Recent trend: entity (company/ISP/govt) installs root cert on user's system (as requirement for access), and possibly accompanying app
- Entity intercepts all secure sessions from user and MITMs them using root cert
- Entity then has access to all user's traffic
- Possibly legitimate uses:
- Enforce web usage policies: e.g. no gaming/social networking during work
- Enhance security: scan traffic for malware, phishing, etc. and respond
- Possibly illegitimate uses:
- Record user's traffic, browsing habits, personal data
- Sell data to third party
- Censor content
- More info:
- How to tell whether your https session is being MITM'ed
- Certificate hash lookup page
- Kazakhstan's ongoing MITM saga
#### Related privacy question: visibility
- Question: should govt agencies (including law enforcement) have access to encrypted communications?
- One "yes" argument: helps catch criminals, prevent terrorist attacks, etc.
- One "no" argument: invades privacy, gives too much eavesdropping power
- Relevant history / case studies:
- Munitions restrictions on crypto circa late 1990's: DES
- Phil Zimmerman and PGP: e-mail encryption, govt attempts to suppress
- Edward Snowden revelations 2013: fears of privacy abuse are well-founded
- RSA Sec's use of NIST-recommended PRNG w/ECC: was apparently an NSA backdoor
- Syed Farook ("San Bernardino shooter") case 2015: FBI pressure on Apple to unlock user's iPhone
- Apple resisted
- Never resolved legally: FBI found 3rd party to grant access
- GCHQ "ghost protocol" proposal 2018
- Don't weaken encryption, but secretly add government to encrypted conversation at will
- Add extra private key to encrypted convos; suppress notifications about new user being added to convo
- Condemned by big tech companies June 2019
- Question: should private companies have access to encrypted communications, or just metadata, or neither?
- Relevant history / case studies:
- Zoom end-to-end encryption [Dec 2022 status]
- Note: without E2EE, Zoom holds keys but never decrypts conversations
- Facebook/WhatsApp terms of service update 2021 [Wired mag article]
- Note: WhatsApp still has E2EE for messages, but shares metadata

View File

@@ -0,0 +1,72 @@
# CSE4303 Introduction to Computer Security (Lecture 15)
## Cryptography applications
### Authentication (...of users, not data)
- Traditional authentication: password-based, single-factor
- Disadvantage: convenience often chosen over security
- Weak passwords
- Password re-use: one password compromised ==> many accounts compromised
- Attack: "credential stuffing" (testing single stolen password against many accounts)
#### SSH keys
- Idea: relieve burden of secure passwords
- Use public/private-key auth instead (can be automated!)
- Use secure password once to exchange public key
- Protocol: challenge/response to verify possession of keys
#### Case Study: SSH
- SSH can use public-key based authentication to authenticate users
- Generate a pair of public and private keys: `ssh-keygen -t rsa`
- private key: `/home/seed/.ssh/id_rsa`
- public key: `/home/seed/.ssh/id_rsa.pub`
- Register public key with server:
- Send the public key file to the remote server using a secure channel
- Add public key to the authorization file `~/.ssh/authorized_keys`
- Server can use key to authenticate clients
#### Time-based One-Time Password (TOTP)
- Goal: provide secure 2nd factor for authentication
- Idea:
- Generate one-time (single-use) password for each login attempt
- Compute one-time password using secure HMAC with current time as a parameter
- Key used for HMAC: exchanged once at setup
- Protocol: open standard published by OATH, IETF
- HMAC-based One-Time Password (HOTP)
- e.g. $TOTP(k) = HOTP(k, C_t)$, where $C_t$ is absolute measure of current time interval
- Num digits taken from output: 6 to 10
### Ransomware
- Idea: attacker encrypts victim's data with symmetric cipher, requires ransom payment to decrypt (or provide key)
- System model: any data store (company database, municipal database, user's hard drive, etc.)
- Threat model: attacker who has already compromised victim's system
- Vuln: lack of backups (or prohibitive time to restore); whatever vuln allowed attacker into system
- Surface: exposed data, and surface of original compromise
- Vector: encrypt data store and erase or replace original data store
- Mitigation/defense: keep up-to-date backups (possibly "air-gapped") in separate location; practice restoring from backups
- Enabler: anonymity of Bitcoin payments
- Recent-ish examples:
- Baltimore 2019 (didn't pay, est. $18 million to fix)
- Atlanta 2018 (~$9 million to fix)
- Lake City & Riviera City, Florida 2019 (did pay, $500,000+ apiece)
- Many others since these
- One of the top projected trends in cybersecurity in 2021 (e.g. by CSO online)
### Post-Quantum (PQ) crypto
- Fundamentally different computation paradigm than "classical" von Neumann or dataflow models
- Relies on properties of quantum physics to solve problems efficiently
- Superposition: state of quantum bit ("qubit") expressed by probability model over continuous range of values (vs. classic bit: 0 or 1 only)
- Like being able to operate on all possible bit combos of a register simultaneously, instead of operating on only one among all possibilities
- Entanglement: operating on one qubit affects others
### Zero-Knowledge (ZK) proofs
### Homomorphic encryption

View File

@@ -0,0 +1,160 @@
# CSE4303 Introduction to Computer Security (Lecture 16)
## System security
- Why system security / platform security?
- All code runs on some physical machine!
- The cloud is not a cloud
- Web pages are just data and code copied from a server that also manages the transfer
- Why Linux?
- Majority of web servers run Linux (esp. Cloud); popular in embedded, mobile devices
### Operating system background
Context: computing stack
| Layer | Description |
| --- | --- |
| Application | Web browser, user apps, DNS |
| OS:libs | Memory allocations, compiler/linker|
| OS:kernel | Process control, networking, file system, access control|
| OS:drivers | Manage hardware|
| (Firmware) | Minimal hardware management (if no full OS)|
|Hardware | Processor, cahce, RAM, disk, USB ports|
#### Operating systems
- Operating System:
- Provides easier to use and high level **abstractions** for resources such as address space for memory and files for disk blocks.
- Provides **controlled access** to hardware resources.
- Provides **isolation** between different processes and between the processes running untrusted/application code and the trusted operating system.
- Need for trusting an operating system
- Why do we need to trust the operating system? (AKA a Trusted Computing Base or TCB)
- What requirements must it meet to be trusted?
- TCB Requirements:
- 1. Tamper-proof
- 2. Complete mediation (reference monitor)
- 3. Correct
Isolating OS from Untrusted User Code
- How do we meet the first requirement of a TCB (e.g., isolation or tamper-proofness)?
- Hardware support for memory protection
- Processor execution modes (system AND user modes, execution rings)
- Privileged instructions which can only be executed in system mode
- System calls used to transfer control between user and system code
System Calls: Going from User to OS Code
- System calls used to transfer control between user and system code
- Such calls come through "call gates" and return back to user code.
- The processor execution mode or privilege ring changes when call and return happen.
- x86 `sysenter` / `sysexit` instructions
Isolating User Processes from Each Other
- How do we meet the user/user isolation and separation?
- OS uses hardware support for memory protection to ensure this.
Virtualization
- OS is large and complex, even different operating systems may be desired by different customers
- Compromise of an OS impacts all applications
Complete Mediation: The TCB
- Make sure that no protected resource (e.g., memory page or file) could be accessed without going through the TCB
- TCB acts as a reference monitor that cannot be bypassed
- Privileged instructions
Limiting the Damage oa a Hacked OS
Use: Hypervisor, virtual machines, guest OS and applications
Compromise of OS in VM1 only impacts applications running on VM1
### Secure boot and Root of Trust (RoT)
Goal: create chain of trust back to hardware-stored cryptographic keys
#### Secure enclave: overview (Intel SGX)
![Intel SGX](https://notenextra.com/CSE4303/Intel_SGX.png)
Goal: keep sensitive data within hardware-isolated encrypted environment
### Access control
Controlling Accesses to Resources
- TCB (reference monitor) sees a request for a resource, how does it decide whether it should be granted?
- Example: Should John's process making a request to read a certain file be allowed to do so?
- Authentication establishes the source of a request (e.g., John's UID)
- Authorization (or access control) answers the question if a certain source of a request (User ID) is allowed to read the file
- Subject who owns a resource (creates it) should be able to control access to it (sometimes this is not true)
- Access control
- Basically, it is about who is allowed to access what.
- Two parts
- Part I - Policy: decide who should have access to certain resources (access control policy)
- Part II - Enforcement: only accesses defined by the access control policy are granted.
- Complete mediation is essential for successful enforcement
Discretionary Access Control
- In discretionary access control (DAC), owner of a resource decides how it can be shared
- Owner can choose to give read or write access to other users
- Two problems with DAC:
- You cannot control if someone you share a file with will not further share the data contained in it
- Cannot control "information flow"
- In many organizations, a user does not get to decide how certain type of data can be shared
- Typically the employer may mandate how to share various types of sensitive data
- Mandatory Access Control (MAC) helps address these problems
Mandatory Access Control (MAC) Models
- User works in a company and the company decides how data should be shared
- Hospital owns patient records and limits their sharing
- Regulatory requirements may limit sharing
- HIPAA for health information
#### Example: Linux system controls
Unix file access control list
- Each file has owner and group
- Permissions set by owner
- Read, write, execute
- Owner, group, other
- Represented by vector of four octal values
- Only owner, root can change permissions
- This privilege cannot be delegated or shared
- Setid bits -- Discuss in a few slides
Process effective user id (EUID)
- Each process has three IDs (+ more under Linux)
- Real user ID (RUID)
- Same as the user ID of parent (unless changed)
- Used to determine which user started the process
- Effective user ID (EUID)
- From set user ID bit on the file being executed, or sys call
- Determines the permissions for process
- File access and port binding
- Saved user ID (SUID)
- So previous EUID can be restored
- Real group ID, effective group ID used similarly
#### Weaknesses in Unix isolation, privileges
- Shared resources
- Since any process can create files in `/tmp` directory, an untrusted process may create files that are used by arbitrary system processes
- Time-of-Check-to-Time-of-Use (TOCTTOU), i.e. race conditions
- Typically, a root process uses system call to determine if initiating user has permission to a particular file, e.g. `/tmp/X`.
- After access is authorized and before the file open, user may change the file `/tmp/X` to a symbolic link to a target file `/etc/shadow`.
### Hazard: race conditions

View File

@@ -18,4 +18,7 @@ export default {
CSE4303_L11: "Introduction to Computer Security (Lecture 11)",
CSE4303_L12: "Introduction to Computer Security (Lecture 12)",
CSE4303_L13: "Introduction to Computer Security (Lecture 13)",
CSE4303_L14: "Introduction to Computer Security (Lecture 14)",
CSE4303_L15: "Introduction to Computer Security (Lecture 15)",
CSE4303_L16: "Introduction to Computer Security (Lecture 16)"
}

View File

@@ -163,9 +163,9 @@ Define the product $f*g$ of $f$ and $g$ to be the map $h:[0,1]\to X$.
#### Definition for equivalent classes of paths
$\Pi_1(X,x)$ is the equivalent classes of paths starting and ending at $x$.
$pi_1(X,x)$ is the equivalent classes of paths starting and ending at $x$.
On $\Pi_1(X,x)$,, we define $\forall [f],[g],[f]*[g]=[f*g]$.
On $pi_1(X,x)$,, we define $\forall [f],[g],[f]*[g]=[f*g]$.
$$
[f]\coloneqq \{f_i:[0,1]\to X|f_0(0)=f(0),f_i(1)=f(1)\}
@@ -191,6 +191,12 @@ $$
### Covering space
#### Definition of partition into slice
Let $p:E\to B$ be a continuous surjective map. The open set $U\subseteq B$ is said to be evenly covered by $p$ if it's inverse image $p^{-1}(U)$ can be written as the union of **disjoint open sets** $V_\alpha$ in $E$. Such that for each $\alpha$, the restriction of $p$ to $V_\alpha$ is a homeomorphism of $V_\alpha$ onto $U$.
The collection of $\{V_\alpha\}$ is called a **partition** $p^{-1}(U)$ into slice.
#### Definition of covering space
Let $p:E\to B$ be a continuous surjective map.
@@ -225,3 +231,7 @@ Recall from previous lecture, we have unique lift for covering map.
Let $p: E\to B$ be a covering map, and $e_0\in E$ and $p(e_0)=b_0$. Any path $f:I\to B$ beginning at $b_0$, has a unique lifting to a path starting at $e_0$.
Back to the circle example, it means that there exists a unique correspondence between a loop starting at $(1,0)$ in $S^1$ and a path in $\mathbb{R}$ starting at $0$, ending in $\mathbb{Z}$.
#### Theorem for induced homotopy for fundamental groups
Suppose $f,g$ are two paths in $B$, and suppose $f$ and $g$ are path homotopy ($f(0)=g(0)=b_0$, and $f(1)=g(1)=b_1$, $b_0,b_1\in B$), then $\hat{f}:\pi_1(B,b_0)\to \pi_1(B,b_1)$ and $\hat{g}:\pi_1(B,b_0)\to \pi_1(B,b_1)$ are path homotopic.

View File

@@ -88,12 +88,12 @@ $\bar{f}_t=\bar{f}(1-ts)$ $s\in[\frac{1}{2},1]$.
> [!CAUTION]
>
> Homeomorphism does not implies homotopy automatically.
> Homeomorphism does not implies homotopy automatically. Homeomorphism doesnt force a homotopy between that map and the identity (or between two given homeomorphisms).
#### Definition for the fundamental group
The fundamental group of $X$ at $x$ is defined to be
$$
(\Pi_1(X,x),*)
(pi_1(X,x),*)
$$

View File

@@ -8,9 +8,9 @@ The $*$ operation has the following properties:
#### Properties for the path product operation
Let $[f],[g]\in \Pi_1(X)$, for $[f]\in \Pi_1(X)$, let $s:\Pi_1(X)\to X, [f]\mapsto f(0)$ and $t:\Pi_1(X)\to X, [f]\mapsto f(1)$.
Let $[f],[g]\in pi_1(X)$, for $[f]\in pi_1(X)$, let $s:pi_1(X)\to X, [f]\mapsto f(0)$ and $t:pi_1(X)\to X, [f]\mapsto f(1)$.
Note that $t([f])=s([g])$, $[f]*[g]=[f*g]\in \Pi_1(X)$.
Note that $t([f])=s([g])$, $[f]*[g]=[f*g]\in pi_1(X)$.
This also satisfies the associativity. $([f]*[g])*[h]=[f]*([g]*[h])$.
@@ -51,33 +51,33 @@ Let $x_0\in X$. A path starting and ending at $x_0$ is called a loop based at $x
The fundamental group of $X$ at $x$ is defined to be
$$
(\Pi_1(X,x),*)
(pi_1(X,x),*)
$$
where $*$ is the product operation, and $\Pi_1(X,x)$ is the set o homotopy classes of loops in $X$ based at $x$.
where $*$ is the product operation, and $pi_1(X,x)$ is the set o homotopy classes of loops in $X$ based at $x$.
<details>
<summary>Example of fundamental group</summary>
Consider $X=[0,1]$, with subspace topology from standard topology in $\mathbb{R}$.
$\Pi_1(X,0)=\{e\}$, (constant function at $0$) since we can build homotopy for all loops based at $0$ as follows $H(s,t)=(1-t)f(s)+t$.
$pi_1(X,0)=\{e\}$, (constant function at $0$) since we can build homotopy for all loops based at $0$ as follows $H(s,t)=(1-t)f(s)+t$.
And $\Pi_1(X,1)=\{e\}$, (constant function at $1$.)
And $pi_1(X,1)=\{e\}$, (constant function at $1$.)
---
Let $X=\{1,2\}$ with discrete topology.
$\Pi_1(X,1)=\{e\}$, (constant function at $1$.)
$pi_1(X,1)=\{e\}$, (constant function at $1$.)
$\Pi_1(X,2)=\{e\}$, (constant function at $2$.)
$pi_1(X,2)=\{e\}$, (constant function at $2$.)
---
Let $X=S^1$ be the circle.
$\Pi_1(X,1)=\mathbb{Z}$ (related to winding numbers, prove next week).
$pi_1(X,1)=\mathbb{Z}$ (related to winding numbers, prove next week).
</details>
@@ -85,7 +85,7 @@ A natural question is, will the fundamental group depends on the base point $x$?
#### Definition for $\hat{\alpha}$
Let $\alpha$ be a path in $X$ from $x_0$ to $x_1$. $\alpha:[0,1]\to X$ such that $\alpha(0)=x_0$ and $\alpha(1)=x_1$. Define $\hat{\alpha}:\Pi_1(X,x_0)\to \Pi_1(X,x_1)$ as follows:
Let $\alpha$ be a path in $X$ from $x_0$ to $x_1$. $\alpha:[0,1]\to X$ such that $\alpha(0)=x_0$ and $\alpha(1)=x_1$. Define $\hat{\alpha}:pi_1(X,x_0)\to pi_1(X,x_1)$ as follows:
$$
\hat{\alpha}(\beta)=[\bar{\alpha}]*[f]*[\alpha]
@@ -93,12 +93,12 @@ $$
#### $\hat{\alpha}$ is a group homomorphism
$\hat{\alpha}$ is a group homomorphism between $(\Pi_1(X,x_0),*)$ and $(\Pi_1(X,x_1),*)$
$\hat{\alpha}$ is a group homomorphism between $(pi_1(X,x_0),*)$ and $(pi_1(X,x_1),*)$
<details>
<summary>Proof</summary>
Let $f,g\in \Pi_1(X,x_0)$, then $\hat{\alpha}(f*g)=\hat{\alpha}(f)\hat{\alpha}(g)$
Let $f,g\in pi_1(X,x_0)$, then $\hat{\alpha}(f*g)=\hat{\alpha}(f)\hat{\alpha}(g)$
$$
\begin{aligned}
@@ -129,4 +129,4 @@ The other case is the same
#### Corollary of fundamental group
If $X$ is path-connected and $x_0,x_1\in X$, then $\Pi_1(X,x_0)$ is isomorphic to $\Pi_1(X,x_1)$.
If $X$ is path-connected and $x_0,x_1\in X$, then $pi_1(X,x_0)$ is isomorphic to $pi_1(X,x_1)$.

View File

@@ -4,18 +4,18 @@
### Fundamental group
Recall from last lecture, the $(\Pi_1(X,x_0),*)$ is a group, and for any two points $x_0,x_1\in X$, the group $(\Pi_1(X,x_0),*)$ is isomorphic to $(\Pi_1(X,x_1),*)$ if $x_0,x_1$ is path connected.
Recall from last lecture, the $(pi_1(X,x_0),*)$ is a group, and for any two points $x_0,x_1\in X$, the group $(pi_1(X,x_0),*)$ is isomorphic to $(pi_1(X,x_1),*)$ if $x_0,x_1$ is path connected.
> [!TIP]
>
> How does the $\hat{\alpha}$ (isomorphism between $(\Pi_1(X,x_0),*)$ and $(\Pi_1(X,x_1),*)$) depend on the choice of $\alpha$ (path) we choose?
> How does the $\hat{\alpha}$ (isomorphism between $(pi_1(X,x_0),*)$ and $(pi_1(X,x_1),*)$) depend on the choice of $\alpha$ (path) we choose?
#### Definition of simply connected
A space $X$ is simply connected if
- $X$ is [path-connected](https://notenextra.trance-0.com/Math4201/Math4201_L23/#definition-of-path-connected-space) ($\forall x_0,x_1\in X$, there exists a continuous function $\alpha:[0,1]\to X$ such that $\alpha(0)=x_0$ and $\alpha(1)=x_1$)
- $\Pi_1(X,x_0)$ is the trivial group for some $x_0\in X$
- $pi_1(X,x_0)$ is the trivial group for some $x_0\in X$
<details>
<summary>Example of simply connected space</summary>
@@ -59,7 +59,7 @@ $$
#### Definition of group homomorphism induced by continuous map
Let $h:(X,x_0)\to (Y,y_0)$ be a continuous map, define $h_*:\Pi_1(X,x_0)\to \Pi_1(Y,y_0)$ where $h(x_0)=y_0$. by $h_*([f])=[h\circ f]$.
Let $h:(X,x_0)\to (Y,y_0)$ be a continuous map, define $h_*:pi_1(X,x_0)\to pi_1(Y,y_0)$ where $h(x_0)=y_0$. by $h_*([f])=[h\circ f]$.
$h_*$ is called the group homomorphism induced by $h$ relative to $x_0$.
@@ -80,7 +80,7 @@ $$
#### Theorem composite of group homomorphism
If $h:(X,x_0)\to (Y,y_0)$ and $k:(Y,y_0)\to (Z,z_0)$ are continuous maps, then $k_* \circ h_*:\Pi_1(X,x_0)\to \Pi_1(Z,z_0)$ where $h_*:\Pi_1(X,x_0)\to \Pi_1(Y,y_0)$, $k_*:\Pi_1(Y,y_0)\to \Pi_1(Z,z_0)$,is a group homomorphism.
If $h:(X,x_0)\to (Y,y_0)$ and $k:(Y,y_0)\to (Z,z_0)$ are continuous maps, then $k_* \circ h_*:pi_1(X,x_0)\to pi_1(Z,z_0)$ where $h_*:pi_1(X,x_0)\to pi_1(Y,y_0)$, $k_*:pi_1(Y,y_0)\to pi_1(Z,z_0)$,is a group homomorphism.
<details>
<summary>Proof</summary>
@@ -100,7 +100,7 @@ $$
#### Corollary of composite of group homomorphism
Let $\operatorname{id}:(X,x_0)\to (X,x_0)$ be the identity map. This induces $(\operatorname{id})_*:\Pi_1(X,x_0)\to \Pi_1(X,x_0)$.
Let $\operatorname{id}:(X,x_0)\to (X,x_0)$ be the identity map. This induces $(\operatorname{id})_*:pi_1(X,x_0)\to pi_1(X,x_0)$.
If $h$ is a homeomorphism with the inverse $k$, with
@@ -108,7 +108,7 @@ $$
k_*\circ h_*=(k\circ h)_*=(\operatorname{id})_*=I=(\operatorname{id})_*=(h\circ k)_*
$$
This induced $h_*: \Pi_1(X,x_0)\to \Pi_1(Y,y_0)$ is an isomorphism.
This induced $h_*: pi_1(X,x_0)\to pi_1(Y,y_0)$ is an isomorphism.
#### Corollary for homotopy and group homomorphism

View File

@@ -0,0 +1,67 @@
# Math4202 Topology II (Lecture 21)
## Algebraic Topology
### Application of fundamental groups
Recall from last Friday, $j:S^1\to \mathbb{R}^2-\{0\}$ is not null homotopic
#### Hairy ball theorem
Given a non-vanishing vector field on $B^2=\{(x,y)\in\mathbb{R}^2:x^2+y^2\leq 1\}$, ($v:B^2\to \mathbb{R}^2$ continuous and $v(x,y)\neq 0$ for all $(x,y)\in B^2$) there exists a point of $S^1$ where the vector field points directly outward, and a point of $S^1$ where the vector field points directly inward.
<details>
<summary>Proof</summary>
By our assumption, then $v:B^2\to \mathbb{R}^2-\{0\}$ is a continuous vector field on $B^2$.
$v|_{S^1}:S^1\to \mathbb{R}^2-\{0\}$ is null homotopic.
We prove by contradiction.
Suppose $v:B^2\to \mathbb{R}^2-\{0\}$ and $v|_{S^1}:S^1\to \mathbb{R}^2-\{0\}$ is everywhere outward. (for everywhere inward, consider $-v$ must be everywhere outward)
Because $v|_{S^1}$ extends continuously to $B^2$, then $v|_{S^1}:B^2\to \mathbb{R}^2-\{0\}$ is null homotopic.
We construct a homotopy for functions between $v|_{S^1}$ and $j$. (Recall $j:S^1\to \mathbb{R}^2-\{0\}$ is not null homotopic)
Define $H:S^1\times I\to \mathbb{R}^2-\{0\}$ by affine combination
$$
H((x,y),t)=(1-t)v(x,y)+tj(x,y)
$$
we also need to show that $H$ is non zero.
Since $v$ is everywhere outward, $v(x,y)\cdot j(x,y)$ is positive for all $(x,y)\in S^1$.
$H((x,y),t)\cdot j(x,y)=(1-t)v(x,y)\cdot j(x,y)+tj(x,y)\cdot j(x,y)=(1-t)(v(x,y)\cdot j(x,y))+t$
which is positive for all $t\in I$, therefore $H$ is non zero.
So $H$ is a homotopy between $v|_{S^1}$ and $j$.
</details>
#### Corollary of the hairy ball theorem
$\forall v:B^2\to \mathbb{R}^2$, if on $S^1$, $v$ is everywhere outward/inward, there is $(x,y)\in B^2$ such that $v(x,y)=0$.
#### Brouwer's fixed point theorem
If $f:B^2\to B^2$ is continuous, then there exists a point $x\in B^2$ such that $f(x)=x$.
<details>
<summary>Proof</summary>
We proceed by contradiction again.
Suppose $f$ has no fixed point, $f(x)-x\neq 0$ for all $x\in B^2$.
Now we consider the map $v:B^2\to \mathbb{R}^2$ defined by $v(x,y)=f(x)-x$, this function is continuous since $f$ is continuous.
$forall x\in S^1$, $v(x)\cdot x=f(x)\cdot x-x\cdot x=f(x)\cdot x-1$.
Recall the cauchy schwartz theorem, $|f(x)\cdot x|\leq \|f(x)\|\cdot\|x\|\leq 1$, note that $f(x)\neq 0$ for all $x\in B^2$, $v(x)\cdot x<0$. This means that all $v(x)$ points inward.
This is a contradiction to the hairy ball theorem, so $f$ has a fixed point.
</details>

View File

@@ -0,0 +1,45 @@
# Math4202 Topology II (Lecture 22)
## Final reading, report, presentation
- Mar 30: Reading topic send email or discuss in OH.
- Apr 3: Finalize the plan.
- Apr 22,24: Last two lectures: 10 minutes to present.
- Final: type a short report, 2-5 pages.
## Algebraic topology
### Fundamental theorem of Algebra
For arbitrary polynomial $f(z)=\sum_{i=0}^n a_i x^i$. Are there roots in $\mathbb{C}$?
Consider $f(z)=a_nx^n+a_{n-1}x^{n-1}+a_{n-2}x^{n-2}+\cdots+a_0$ is a continuous map from $\mathbb{C}\to\mathbb{C}$.
If $f(z_0)=0$, then $z_0$ is a root.
By contradiction, Then $f:\mathbb{C}\to\mathbb{C}-\{0\}\cong \mathbb{R}^2-\{(0,0)\}$.
#### Theorem for existence of n roots
A polynomial equation $x^n+a_{n-1}x^{n-1}+a_{n-2}x^{n-2}+\cdots+a_0=0$ of degree $>0$ with complex coefficients has at least one complex root.
There are $n$ roots by induction.
#### Lemma
If $g:S^1\to \mathbb{R}^2-\{(0,0)\}$ is the map $g(z)=z^n$, then $g$ is not nulhomotopic. $n\neq 0$, $n\in \mathbb{Z}$.
> Recall that we proved that $g(z)=z$ is not nulhomotopic.
Consider $k:S^1\to S^1$ by $k(z)=z^n$. $k$ is continuous, $k_*:\pi_1(S^1,1)\to \pi_1(S^1,1)$.
Where $\pi_1(S^1,1)\cong \mathbb{Z}$.
$k_*(n)=nk_*(1)$.
Recall that the path in the loop $p:I\to S^1$ where $p:t\mapsto e^{2\pi it}$.
$k_*(p)=[k(p(t))]$, where $n=\tilde{k\circ p}(1)$.
$k_*$ is injective.

View File

@@ -0,0 +1,142 @@
# Math4202 Topology II (Lecture 23)
## Algebraic Topology
### Fundamental Theorem of Algebra
Recall the lemma $g:S^1\to \mathbb{R}-\{0\}$ is not nulhomotopic.
$g=h\circ k$ where $k:S^1\to S^1$ by $z\mapsto z^n$, $k_*:\pi_1(S^1)\to \pi_1(S^1)$ is injective. (consider the multiplication of integer is injective)
and $h:S^1\to \mathbb{R}-\{0\}$ where $z\mapsto z$. $h_*:\pi_1(S^1)\to \pi_1(\mathbb{R}-\{0\})$ is injective. (inclusion map is injective)
Therefore $g_*:\pi_1(S^1)\to \pi_1(\mathbb{R}-\{0\})$ is injective, therefore $g$ cannot be nulhomotopic. (nulhomotopic cannot be injective)
#### Theorem
Consider $x^n+a_{n-1}x^{n-1}+a_{n-2}x^{n-2}+\cdots+a_0=0$ of degree $>0$.
<details>
<summary>Proof: part 1</summary>
Step 1: if $|a_{n-1}|+|a_{n-2}|+\cdots+|a_0|<1$, then $x^n+a_{n-1}x^{n-1}+a_{n-2}x^{n-2}+\cdots+a_0=0$ has a root in the unit disk $B^2$.
We proceed by contradiction, suppose there is no root in $B^2$.
Consider $f(x)=x^n+a_{n-1}x^{n-1}+a_{n-2}x^{n-2}+\cdots+a_0$.
$f|_{B^2}$ is a continuous map from $B^2\to \mathbb{R}^2-\{0\}$.
$f|_{S^1=\partial B^2}:S^1\to \mathbb{R}-\{0\}$ **is nulhomotopic**.
> Recall that: Any map $g:S^1\to Y$ is nulhomotopic whenever it extends to a continuous map $G:B^2\to Y$.
Construct a homotopy between $f|_{S^1}$ and $g$
$$
H(x,t):S^1\to \mathbb{R}-\{0\}\quad x^n+t(a_{n-1}x^{n-1}+a_{n-2}x^{n-2}+\cdots+a_0)
$$
Observer on $S^1$, $\|x^n\|=1,\forall n\in \mathbb{N}$.
$$
\begin{aligned}
\|t(a_{n-1}x^{n-1}+a_{n-2}x^{n-2}+\cdots+a_0)\|&=t\|a_{n-1}x^{n-1}+a_{n-2}x^{n-2}+\cdots+a_0\|\\
&\leq 1(\|a_{n-1}x^{n-1}\|+\|a_{n-2}x^{n-2}\|+\cdots+\|a_0\|)\\
&=\|a_{n-1}\|+\|a_{n-2}\|+\cdots+\|a_0\|\\
&<1
\end{aligned}
$$
Therefore $H(s,t)>0\forall 0<t<1$. is a well-defined homotopy between $f|_{S^1}$ and $g$.
Therefore $f_*=g_*$ is injective, $f$ is not nulhomotopic. This contradicts our previous assumption that $f$ is nulhomotopic.
Therefore $f$ must have a root in $B^2$.
</details>
<details>
<summary>Proof: part 2</summary>
If $\|a_{n-1}\|+\|a_{n-2}\|+\cdots+\|a_0\|< R$ has a root in the disk $B^2_R$. (and $R\geq 1$, otherwise follows part 1)
Consider $\tilde{f}(x)=f(Rx)$.
$$
\begin{aligned}
\tilde{f}(x)
=f(Rx)&=(Rx)^n+a_{n-1}(Rx)^{n-1}+a_{n-2}(Rx)^{n-2}+\cdots+a_0\\
&=R^n\left(x^n+\frac{a_{n-1}}{R}x^{n-1}+\frac{a_{n-2}}{R^2}x^{n-2}+\cdots+\frac{a_0}{R^n}\right)
\end{aligned}
$$
$$
\begin{aligned}
\left\|\frac{a_{n-1}}{R}\right\|+\left\|\frac{a_{n-2}}{R^2}\right\|+\cdots+\left\|\frac{a_0}{R^n}\right\|&=\frac{1}{R}\|a_{n-1}\|+\frac{1}{R^2}\|a_{n-2}\|+\cdots+\frac{1}{R^n}\|a_0\|\\
&<\frac{1}{R}\left(\|a_{n-1}\|+\|a_{n-2}\|+\cdots+\|a_0\|\right)\\
&<\frac{1}{R}<1
\end{aligned}
$$
By Step 1, $\tilde{f}$ must have a root $z_0$ inside the unit disk.
$f(Rz_0)=\tilde{f}(z_0)=0$.
So $f$ has a root $Rz_0$ in $B^2_R$.
</details>
### Deformation Retracts and Homotopy Type
Recall previous section, $h:S^1\to \mathbb{R}-\{0\}$ gives $h_*:\pi_1(S^1,1)\to \pi_1(\mathbb{R}-\{0\},0)$ is injective.
For this section, we will show that $h_*$ is an isomorphism.
#### Lemma for equality of homomorphism
Let $h,k: (X,x_0)\to (Y,y_0)$ be continuous maps. If $h$ and $k$ are homotopic, and if **the image of $x_0$ under the homotopy remains $y_0$**. The homomorphism $h_*$ and $k_*$ from $\pi_1(X,x_0)$ to $\pi_1(Y,y_0)$ are equal.
<details>
<summary>Proof</summary>
Let $H:X\times I\to Y$ be a homotopy from $h$ to $k$ such that
$$
H(x,0)=h(x), \qquad H(x,1)=k(x), \qquad H(x_0,t)=y_0 \text{ for all } t\in I.
$$
To show $h_*=k_*$, let $[f]\in \pi_1(X,x_0)$ be arbitrary, where
$f:I\to X$ is a loop based at $x_0$, so $f(0)=f(1)=x_0$.
Define
$$
F:I\times I\to Y,\qquad F(s,t)=H(f(s),t).
$$
Since $H$ and $f$ are continuous, $F$ is continuous. For each fixed $t\in I$, the map
$$
s\mapsto F(s,t)=H(f(s),t)
$$
is a loop based at $y_0$, because
$$
F(0,t)=H(f(0),t)=H(x_0,t)=y_0
\quad\text{and}\quad
F(1,t)=H(f(1),t)=H(x_0,t)=y_0.
$$
Thus $F$ is a based homotopy between the loops $h\circ f$ and $k\circ f$, since
$$
F(s,0)=H(f(s),0)=h(f(s))=(h\circ f)(s),
$$
and
$$
F(s,1)=H(f(s),1)=k(f(s))=(k\circ f)(s).
$$
Therefore $h\circ f$ and $k\circ f$ represent the same element of $\pi_1(Y,y_0)$, so
$$
[h\circ f]=[k\circ f].
$$
Hence
$$
h_*([f])=[h\circ f]=[k\circ f]=k_*([f]).
$$
Since $[f]$ was arbitrary, it follows that $h_*=k_*$.
</details>

View File

@@ -0,0 +1,84 @@
# Math4202 Topology II (Lecture 24)
## Algebraic Topology
### Deformation Retracts and Homotopy Type
Recall from last lecture, let $h,k:(X,x_0)\to (Y,y_0)$ be continuous maps. If there exists a homotopy of $h,y$ such that $H:X\times I\to Y$ that $H(x_0,t)=y_0$.
Then $h_*=k_*:\pi_1(X,x_0)\to \pi_1(Y,y_0)$.
We can prove this by showing that all the loop $f:I\to X$ based at $x_0$, $h_*([f])=k_*([f])$.
That is $[h\circ f]=[k\circ f]$.
This is a function $I\times I \to Y$ by $(s,t)\mapsto H(f(s),t)$.
We need to show that this is a homotopy between $h\circ f$ and $k\circ f$.
#### Theorem
The Inclusion map $j:S^n\to \mathbb{R}^n-\{0\}$ induces on isomorphism of fundamental groups
$$
j_*:\pi_1(S^n)\to \pi_1(\mathbb{R}^n-\{0\})
$$
The function is injective.
> Recall we showed that $S^1\to \mathbb{R}-\{0\}$ is injective by $x\mapsto \frac{x}{|x|}$.
We want to show that $j_*\circ r_*=id_{\pi_1(S^n)}\quad r_*\circ j_*=id_{\pi_1(\mathbb{R}^n-\{0\})}$, then $r_*$, $j_*$ are isomorphism.
<details>
<summary>Proof</summary>
**Homotopy is well defined**.
Consider $H:(\mathbb{R}^n-\{0\})\times I\to \mathbb{R}^n-\{0\}$.
Given $(x,t)\mapsto tx+(1-t)\frac{x}{\|x\|}$.
Note that $(t-\frac{1-t}{\|x\|})x=0\implies t=0\land t=1$.
So this map is well defined.
**Base point is fixed**.
On point $(1,0)$ (or anything on the sphere), $H(x,0)=x$.
</details>
#### Definition of deformation retract
Let $A$ be a subspace of $X$, we say that $A$ is a deformation retract of $X$ if the identity map of $X$ is homotopic to a map that carries all $X$ to $A$ such that each point of $A$ remains fixed during the homotopy.
Equivalently, there exists a homotopy $H:X\times I\to X$ such that:
- $H(x,0)=x$ forall $x\in X$
- $H(a,t)=a$ for all $a\in A$, $t\in I$
- $H(x,1)\in A$ for all $x\in X$
Equivalently,
$r:H(x,1):X\to A$ is a retract.
If we let $j:A\to X$ be the inclusion map, then $r\circ j=id_A$, and $j\circ r\sim id_X$ (with $A$ fixed.)
<details>
<summary>Example of deformation retract</summary>
$S^1$ is a deformation retract of $\mathbb{R}^2-\{0\}$
---
Consider $\mathbb{R}^2-p=q$, the doubly punctured plane. "The figure 8" space is the deformation retract.
![Retraction of doubly punctured plane](https://notenextra.trance-0.com/Math4202/Retraction_of_doubly_punctured_plane.jpg)
</details>
#### Theorem for Deformation Retract
If $A$ is a deformation retract of $X$, then $A$ and $X$ have the same fundamental group.

View File

@@ -0,0 +1,89 @@
# Math4202 Topology II (Lecture 25)
## Algebraic Topology
### Deformation Retracts and Homotopy Type
Recall from last lecture, Let $A\subseteq X$, if there exists a continuous map (deformation retraction) $H:X\times I\to X$ such that
- $H(x,0)=x$ for all $x\in X$
- $H(x,1)\in A$ for all $x\in X$
- $H(a,t)=a$ for all $a\in A$, $t\in I$
then the inclusion map$\pi_1(A,a)\to \pi_1(X,a)$ is an isomorphism.
<details>
<summary>Example for more deformation retract</summary>
Let $X=\mathbb{R}^3-\{0,(0,0,1)\}$.
Then the two sphere with one point intersect is a deformation retract of $X$.
---
Let $X$ be $\mathbb{R}^3-\{(t,0,0)\mid t\in \mathbb{R}\}$, then the cyclinder is a deformation retract of $X$.
</details>
#### Definition of homotopy equivalence
Let $f:X\to Y$ and $g:Y\to X$ be a continuous maps.
Suppose
- the map $g\circ f:X\to X$ is homotopic to the identity map $\operatorname{id}_X$.
- the map $f\circ g:Y\to Y$ is homotopic to the identity map $\operatorname{id}_Y$.
Then $f$ and $g$ are **homotopy equivalences**, and each is said to be the **homotopy inverse** of the other.
$X$ and $Y$ are said to be **homotopy equivalent**.
<details>
<summary>Example</summary>
Consider the punctured torus $X=S^1\times S^1-\{(0,0)\}$.
Then we can do deformation retract of the glued square space to boundary of the square.
After glueing, we left with the figure 8 space.
Then $X$ is homotopy equivalent to the figure 8 space.
</details>
Recall the lemma, [Lemma for equality of homomorphism](https://notenextra.trance-0.com/Math4202/Math4202_L23/#lemma-for-equality-of-homomorphism)
Let $f:X\to Y$ and $g:X\to Y$, with homotopy $H:X\times I\to Y$, such that
- $H(x,0)=f(x)$ for all $x\in X$
- $H(x,1)=g(x)$ for all $x\in X$
- $H(x,t)=y_0$ for all $t\in I$, and $y_0\in Y$ is fixed.
Then $f_*=g_*:\pi_1(X,x_0)\to \pi_1(Y,y_0)$ is an isomorphism.
We wan to know if it is safe to remove the assumption that $y_0$ is fixed.
<details>
<summary>Idea of Proof</summary>
Let $k$ be any loop in $\pi_1(X,x_0)$.
We can correlate the two fundamental group $f\cric k$ by the function $\alpha:I\to Y$, and $\hat{\alpha}:\pi_1(Y,y_0)\to \pi_1(Y,y_1)$. (suppose $f(x_0)=y_0, g(x_0)=y_1$), it is sufficient to show that
$$
f\circ k\simeq \alpha *(g\circ k)*\bar{\alpha}
$$
</details>
#### Lemma of homotopy equivalence
Let $f,g:X\to Y$ be continuous maps. let $f(x_0)=y_0$ and $g(x_0)=y_1$. If $f$ and $g$ are homotopic, then there is a path $\alpha:I\to Y$ such that $\alpha(0)=y_0$ and $\alpha(1)=y_1$.
Defined as the restriction of the homotopy to $\{x_0\}\times I$, satisfying $\hat{\alpha}\circ f_*=g_*$.
Imagine a triangle here:
- $\pi_1(X,x_0)\to \pi_1(Y,y_0)$ by $f_*$
- $\pi_1(Y,y_0)\to \pi_1(Y,y_1)$ by $\hat{\alpha}$
- $\pi_1(Y,y_1)\to \pi_1(X,x_0)$ by $g_*$

View File

@@ -0,0 +1,90 @@
# Math4202 Topology II (Lecture 26)
## Algebraic Topology
### Deformation Retracts and Homotopy Type
#### Lemma of homotopy equivalence
Let $f,g:X\to Y$ be continuous maps. let
$$
f_*=\pi_1(X,f(x_0))\quad\text{and}\quad g_*=\pi_1(Y,g(x_0))
$$
And $H:X\times I\to Y$ is a homotopy from $f$ to $g$ with a path $H(x_0,t)=\alpha(t)$ for all $t\in I$.
Then $\hat{\alpha}\circ f_*=[\bar{\alpha}*(f\circ \gamma)*\alpha]=[g\circ \gamma]=g_*$. where $\gamma$ is a loop in $X$ based at $x_0$.
<details>
<summary>Proof</summary>
$I\times I\xrightarrow{\gamma_{id}} X\times I\xrightarrow{H} Y$
- $I\times \{0\}\mapsto f\circ\gamma$
- $I\times \{1\}\mapsto g\circ\gamma$
- $\{0\}\times I\mapsto \alpha$
- $\{1\}\times I\mapsto \alpha$
As $I\times I$ is convex, $I\times \{0\}\simeq (\{0\}\times I)*(I\times \{1\})*(\{1\}\times I)$.
</details>
#### Corollary for homotopic continuous maps
Let $h,k$ be homotopic continuous maps. And let $h(x_0)=y_0,k(x_0)=y_1$. If $h_*:\pi_1(X,x_0)\to \pi_1(Y,y_0)$ is injective, then $k_*:\pi_1(X,x_0)\to \pi_1(Y,y_1)$ is injective.
<details>
<summary>Proof</summary>
$\hat{\alpha}$ is an isomorphism of $\pi_1(Y,y_0)$ to $\pi_1(Y,y_1)$.
</details>
#### Corollary for nulhomotopic maps
Let $h:X\to Y$ be nulhomotopic. Then $h_*:\pi_1(X,x_0)\to \pi_1(Y,h(x_0))$ is a trivial group homomorphism (mapping to the constant map on $h(x_0)$).
#### Theorem for fundamental group isomorphism by homotopy equivalence
Let $f:X\to Y$ be a continuous map. Let $f(x_0)=y_0$. If $f$ is a [homotopy equivalence](https://notenextra.trance-0.com/Math4202/Math4202_L25/#definition-of-homotopy-equivalence) ($\exists g:Y\to X$ such that $fg\simeq id_X$, $gf\simeq id_Y$), then
$$
f_*:\pi_1(X,x_0)\to \pi_1(Y,y_0)
$$
is an isomorphism.
<details>
<summary>Proof</summary>
Let $g:Y\to X$ be the homotopy inverse of $f$.
Then,
$f_*\circ g_*=\alpha \circ id_{\pi_1(Y,y_0)}=\alpha$
And $g_*\circ f_*=\bar{\alpha}\circ id_{\pi_1(X,x_0)}=\bar{\alpha}$
So $f_*\circ (g_*\circ \hat{\alpha}^-1)=id_{\pi_1(X,x_0)}$
And $g_*\circ (f_*\circ \hat{\alpha}^-1)=id_{\pi_1(Y,y_0)}$
So $f_*$ is an isomorphism (have left and right inverse).
</details>
### Fundamental group of higher dimensional sphere
$\pi_1(S^n,x_0)=\{e\}$ for $n\geq 2$.
We can decompose the sphere to the union of two hemisphere and compute $\pi_1(S^n_+,x_0)=\pi_1(S^n_-,x_0)=\{e\}$
But for $n\geq 2$, $S^n_+\cap S^n_-=S^{n-1}$, where $S^1_+\cap S^1_-$ is two disjoint points.
#### Theorem for "gluing" fundamental group
Suppose $X=U\cup V$, where $U$ and $V$ are open subsets of $X$. Suppose that $U\cap V$ is path connected, and $x\in U\cap V$. Let $i,j$ be the inclusion maps of $U$ and $V$ into $X$, the images of the induced homomorphisms
$$
i_*:\pi_1(U,x_0)\to \pi_1(X,x_0)\quad j_*:\pi_1(V,x_0)\to \pi_1(X,x_0)
$$
The image of the two map generate $\pi_1(X,x_0)$.

View File

@@ -0,0 +1,69 @@
# Math4202 Topology II (Lecture 27)
## Algebraic Topology
### Fundamental Groups for Higher Dimensional Sphere
#### Theorem for "gluing" fundamental group
Suppose $X=U\cup V$, where $U$ and $V$ are open subsets of $X$. Suppose that $U\cap V$ is path connected, and $x\in U\cap V$. Let $i,j$ be the inclusion maps of $U$ and $V$ into $X$, the images of the induced homomorphisms
$$
i_*:\pi_1(U,x_0)\to \pi_1(X,x_0)\quad j_*:\pi_1(V,x_0)\to \pi_1(X,x_0)
$$
The image of the two map generate $\pi_1(X,x_0)$.
$G$ is a group, and let $S\subseteq G$, where $G$ is generated by $S$, if $\forall g\in G$, $\exists s_1,s_2,\ldots,s_n\in S$ such that $g=s_1s_2\ldots s_n\in G$. (We can write $G$ as a word of elements in $S$.)
<details>
<summary>Proof</summary>
Let $f$ be a loop in $X$, $f\simeq g_1*g_2*\ldots*g_n$, where $g_i$ is a loop in $U$ or $V$.
For example, consider the function, $f=f_1*f_2*f_3*f_4$, where $f_1\in S_+$, $f_2\in S_-$, $f_3\in S_+$, $f_4\in S_-$.
Take the functions $\bar{\alpha_1}*\alpha_1\simeq e_{x_1}$ where $x_1$ is the intersecting point on $f_1$ and $f_2$.
Therefore,
$$
\begin{aligned}
f&=f_1*f_2*f_3*f_4\\
&(f_1*\bar{\alpha})*(\alpha_1*f_2*\bar{\alpha_2})*(\alpha_2*f_3*\bar{\alpha_3})*(\alpha_4*f_4)
\end{aligned}
$$
This decompose $f$ into a word of elements in either $S_+$ or $S_-$.
---
Note that $f$ is a continuous function $I\to X$, for $t\in I$, $\exists I_t$ being a small neighborhood of $t$ such that $f(I_t)\subseteq U$ or $f(I_t)\subseteq V$.
Since $U_{t\in I}I_t=I$, then $\{I_t\}_{t\in I}$ is an open cover of $I$.
By compactness of $I$, there is a finite subcover $\{I_{t_1},\ldots,I_{t_n}\}$.
Therefore, we can create a partition of $I$ into $[s_i,s_{i+1}]\subseteq I_{t_k}$ for some $k$.
Then with the definition of $I_{t_k}$, $f([s_i,s_{i+1}])\subseteq U$ or $V$.
Then we can connect $x_0$ to $f(s_i)$ with a path $\alpha_i\subseteq U\cap V$.
$$
\begin{aligned}
f&=f|_{[s_0,s_1]}*f|_{[s_1,s_2]}*\ldots**f|_{[s_{n-1},s_n]}\\
&\simeq f|_{[s_0,s_1]}*(\bar{\alpha_1}*\alpha_1)*f|_{[s_1,s_2]}*(\bar{\alpha_2}*\alpha_2)*\ldots*f|_{[s_{n-1},s_n]}*(\bar{\alpha_n}*\alpha_n
)\\
&=(f|_{[s_0,s_1]}*\bar{\alpha_1})*(\alpha_1*f|_{[s_1,s_2]}*\bar{\alpha_2})*\ldots*(\alpha_{n-1}*f|_{[s_{n-1},s_n]}*\bar{\alpha_n})\\
&=g_1*g_2*\ldots*g_n
\end{aligned}
$$
</details>
#### Corollary in higher dimensional sphere
Since $S^n_+$ and $S^n_-$ are homeomorphic to open balls $B^n$, then $\pi_1(S^n_+,x_0)=\pi_1(S^n_-,x_0)=\pi_1(B^n,x_0)=\{e\}$ for $n\geq 2$.
> Preview: Van Kampen Theorem

View File

@@ -17,6 +17,7 @@ An $m$-dimensional **manifold** is a topological space $X$ that is
> Try to find some example that satisfies some of the properties above but not a manifold.
1. Non-Hausdorff
- Real line with two origin, as discussed in homework problem
2. Non-countable basis
- Consider $\mathbb{R}^\delta$ where the set is $\mathbb{R}$ with discrete topology. The basis must include all singleton sets in $\mathbb{R}$ therefore $\mathbb{R}^\delta$ is not second countable.
3. Non-local euclidean

View File

@@ -7,7 +7,7 @@
Consider the space of paths up to homotopy equivalence.
$$
\operatorname{Path}/\simeq_p(X) =\Pi_1(X)
\operatorname{Path}/\simeq_p(X) =pi_1(X)
$$
We want to impose some group structure on $\operatorname{Path}/\simeq_p(X)$.
@@ -33,9 +33,9 @@ Define the product $f*g$ of $f$ and $g$ to be the map $h:[0,1]\to X$.
#### Definition for equivalent classes of paths
$\Pi_1(X,x)$ is the equivalent classes of paths starting and ending at $x$.
$pi_1(X,x)$ is the equivalent classes of paths starting and ending at $x$.
On $\Pi_1(X,x)$,, we define $\forall [f],[g],[f]*[g]=[f*g]$.
On $pi_1(X,x)$,, we define $\forall [f],[g],[f]*[g]=[f*g]$.
$$
[f]\coloneqq \{f_i:[0,1]\to X|f_0(0)=f(0),f_i(1)=f(1)\}
@@ -141,5 +141,5 @@ Continue next time.
The fundamental group of $X$ at $x$ is defined to be
$$
(\Pi_1(X,x),*)
(pi_1(X,x),*)
$$

View File

@@ -1,3 +1,5 @@
import { MathJax } from "nextra/components";
export default {
index: "Course Description",
"---":{
@@ -24,4 +26,11 @@ export default {
Math4202_L18: "Topology II (Lecture 18)",
Math4202_L19: "Topology II (Lecture 19)",
Math4202_L20: "Topology II (Lecture 20)",
Math4202_L21: "Topology II (Lecture 21)",
Math4202_L22: "Topology II (Lecture 22)",
Math4202_L23: "Topology II (Lecture 23)",
Math4202_L24: "Topology II (Lecture 24)",
Math4202_L25: "Topology II (Lecture 25)",
Math4202_L26: "Topology II (Lecture 26)",
Math4202_L27: "Topology II (Lecture 27)",
}

View File

@@ -0,0 +1,109 @@
# Math4302 Modern Algebra (Lecture 22)
## Groups
### Group acting on a set
Let $X$ be a $G$-set, recall that the orbit of $x\in X$ is $\{g\cdot x|g\in G\}$.
#### The orbit-stabilizer theorem
For any $x\in X$, ,$G_x=\{g\in G|g\cdot x=x\}\leq G$.
Let $(G:G_x)$ denote the index of $G_x$ in $G$, then $(G:G_x)=\frac{|G|}{|G_x|}$, which equals to the number of left cosets of $G_x$ in $G$.
<details>
<summary>Proof</summary>
Define $\alpha:gG_x\mapsto g\cdot x$.
$\alpha$ is well-defined and injective.
$$
gG_x=g'G_x\iff g^{-1}g'\in G_x\iff (g^{-1}g')\cdot x=x\iff g^{-1}\cdot(g'\cdot x)=x\iff g'\cdot x=g\cdot x
$$
$\alpha$ is surjective, therefore $\alpha$ is a bijection.
</details>
<details>
<summary>Example</summary>
Number of elements in the orbit of $x$ is $1$ if and only if $g\cdot x=x$ for all $g\in G$.
if and only if $G_x=G$.
</details>
#### Theorem for orbit with prime power groups
Suppose $X$ is a $G$-set, and $|G|=p^n$ for some prime $p$. Let $X_G$ be the set of all elements in $X$ whose orbit has size $1$. (Recall the orbit divides $X$ into disjoint partitions.) Then $|X|\equiv |X_G|\mod p$.
<details>
<summary>Examples</summary>
Let $G=D_4$ acting on $\{1,2,3,4\}=X$.
$X_G=\emptyset$ since there is no element whose orbit has size $1$.
---
Let $G=\mathbb{Z}_{11}$ acting on a set with $|X|=20$ if the action is not trivial, then what is $|X_G|$?
Using the theorem we have $|X_G|\equiv 20\mod 11=9$. Therefore $|X_G|=9$ or $20$, but the action is not trivial, $|X_G|=9$.
An instance for such $X=\mathbb{Z}_{11}\sqcup\{x_1,x_2,\ldots,x_9\}$, where $\mathbb{Z}_{11}$ acts on $\{x_1,x_2,\ldots,x_9\}$ trivially. and $\mathbb{Z}_{11}$ acts on $x_1$ with addition.
</details>
<details>
<summary>Proof</summary>
If $x\in X$ such that $|Gx|\geq 2$, then $\frac{|G|}{|G_x|}=|Gx|\geq 2$.
So $|G|=|G_x||Gx|\implies |Gx|$ divides $|G|$.
So $|Gx|=p^m$ for some $m\geq 1$.
Note that $X$ is the union of subset of elements with orbit of size $1$, and distinct orbits of sizes $\geq 2$. (each of them has size positive power of $p$)
So $p|(|X|-|X_G|)$.
this implies that $|X_G|\equiv |X_G|\mod p$.
</details>
#### Corollary: Cauchy's theorem
If $p$ is prime and $p|(|G|)$, then $G$ has a subgroup of order $p$.
> This does not hold when $p$ is not prime.
>
> Consider $A_4$ with order $12$, and $A_4$ has no subgroup of order $6$.
<details>
<summary>Proof</summary>
It is enough to show, there is $a\in G$ which has order $p$: $\{e,a,a^2,\ldots,a^{p-1}\}\leq G$.
Let $X=\{(g_1,g_2,\ldots,g_p)|g_i\in G,g_1g_2g_3\ldots g_p=e\}$.
Then $|X|=|G|^{p-1}$ since $g_p$ is determined uniquely by $g_p=(g_1,g_2,\ldots,g_{p-1})^{-1}$.
Therefore we can define $\mathbb{Z}_p$ acts on $X$ by shifting.
$i\in \mathbb{Z}_p$ $i\cdot (g_1,g_2,\ldots,g_p)=(g_{i+1},g_2,\ldots,g_p,g_1,\ldots,g_i)$.
$X$ is a $\mathbb{Z}_p$-set.
- $0\cdot (g_1,g_2,\ldots,g_p)=(g_1,g_2,\ldots,g_p)$.
- $j\cdot (i\cdot (g_1,g_2,\ldots,g_p))=(i+j)\cdot (g_1,g_2,\ldots,g_p)$.
By the previous theorem, $|X|\equiv |X_G|\mod p$.
Since $p$ divides $|G|^{p-1}$, $p$ also divides $|X_G|$. Therefore $(e,e,e,\ldots,e)\in X_G$. Therefore $|X_G|\geq 1$.
So $|X_G|\geq 2$, we have $(a,a,\ldots,a)\in X_G$, $a\neq e$, but $a^p=e$, so $ord(a)=p$.
</details>

View File

@@ -0,0 +1,133 @@
# Math4302 Modern Algebra (Lecture 23)
## Group
### Group acting on a set
#### Theorem for the orbit of a set with prime power group
Suppose $X$ is a $G$-set, and $|G|=p^n$ where $p$ is prime, then $|X_G|\equiv |X|\mod p$.
Where $X_G=\{x\in X|g\cdot x=x\text{ for all }g\in G\}=\{x\in X|\text{orbit of }x\text{ is trivial}\}$
#### Corollary: Cauchy's theorem
If $p$, where $p$ is a prime, divides $|G|$, then $G$ has a subgroup of order $p$. (equivalently, $g$ has an element of order $p$)
> This does not hold when $p$ is not prime.
>
> Consider $A_4$ with order $12$, and $A_4$ has no subgroup of order $6$.
#### Corollary: Center of prime power group is non-trivial
If $|G|=p^m$, then $Z(G)$ is non-trivial. ($Z(G)\neq \{e\}$)
<details>
<summary>Proof</summary>
Let $G$ act on $G$ via conjugation, then $g\cdot h=ghg^{-1}$. This makes $G$ to a $G$-set.
Apply the theorem, the set of elements with trivial orbit is; Let $X=G$, then $X_G=\{h\in G|g\cdot h=h\text{ for all }g\in G\}=\{h\in G|ghg^{-1}=h\text{ for all }g\in G\}=Z(G)$.
Therefore $|Z(G)|\equiv |G|\mod p$.
So $p$ divides $|Z(G)|$, so $|Z(G)|\neq 1$, therefore $Z(G)$ is non-trivial.
</details>
#### Proposition: Prime square group is abelian
If $|G|=p^2$, where $p$ is a prime, then $G$ is abelian.
<details>
<summary>Proof</summary>
Since $Z(G)$ is a subgroup of $G$, $|Z(G)|$ divides $p^2$ so $|Z(G)|=1, p$ or $p^2$.
By corollary center of prime power group is non-trivial, $Z(G)\neq 1$.
If $|Z(G)|=p$. If $|Z(G)|=p$, then consider the group $G/Z(G)$ (Note that $Z(G)\trianglelefteq G$). We have $|G/Z(G)|=p$ so $G/Z(G)$ is cyclic (by problem 13.39), therefore $G$ is abelian.
If $|Z(G)|=p^2$, then $G$ is abelian.
</details>
### Classification of small order
Let $G$ be a group
- $|G|=1$
- $G=\{e\}$
- $|G|=2$
- $G\simeq\mathbb{Z}_2$ (prime order)
- $|G|=3$
- $G\simeq\mathbb{Z}_3$ (prime order)
- $|G|=4$
- $G\simeq\mathbb{Z}_2\times \mathbb{Z}_2$
- $G\simeq\mathbb{Z}_4$
- $|G|=5$
- $G\simeq\mathbb{Z}_5$ (prime order)
- $|G|=6$
- $G\simeq S_3$
- $G\simeq\mathbb{Z}_3\times \mathbb{Z}_2\simeq \mathbb{Z}_6$
<details>
<summary>Proof</summary>
$|G|$ has an element of order $2$, namely $b$, and an element of order $3$, namely $a$.
So $e,a,a^2,b,ba,ba^2$ are distinct.
Therefore, there are only two possibilities for value of $ab$. ($a,a^2$ are inverse of each other, $b$ is inverse of itself.)
If $ab=ba$, then $G$ is abelian, then $G\simeq \mathbb{Z}_2\times \mathbb{Z}_3$.
If $ab=ba^2$, then $G\simeq S_3$.
</details>
- $|G|=7$
- $G\simeq\mathbb{Z}_7$ (prime order)
- $|G|=8$
- $G\simeq\mathbb{Z}_2\times \mathbb{Z}_2\times \mathbb{Z}_2$
- $G\simeq\mathbb{Z}_4\times \mathbb{Z}_2$
- $G\simeq\mathbb{Z}_8$
- $G\simeq D_4$
- $G\simeq$ quaternion group $\{e,i,j,k,-1,-i,-j,-k\}$ where $i^2=j^2=k^2=-1$, $(-1)^2=1$. $ij=l$, $jk=i$, $ki=j$, $ji=-k$, $kj=-i$, $ik=-j$.
- $|G|=9$
- $G\simeq\mathbb{Z}_3\times \mathbb{Z}_3$
- $G\simeq\mathbb{Z}_9$ (apply the corollary, $9=3^2$, these are all the possible cases)
- $|G|=10$
- $G\simeq\mathbb{Z}_5\times \mathbb{Z}_2\simeq \mathbb{Z}_{10}$
- $G\simeq D_5$
- $|G|=11$
- $G\simeq\mathbb{Z}_11$ (prime order)
- $|G|=12$
- $G\simeq\mathbb{Z}_3\times \mathbb{Z}_4$
- $G\simeq\mathbb{Z}_2\times \mathbb{Z}_2\times \mathbb{Z}_3$
- $A_4$
- $D_6\simeq S_3\times \mathbb{Z}_2$
- ??? One more
- $|G|=13$
- $G\simeq\mathbb{Z}_{13}$ (prime order)
- $|G|=14$
- $G\simeq\mathbb{Z}_2\times \mathbb{Z}_7$
- $G\simeq D_7$
#### Lemma for group of order $2p$ where $p$ is prime
If $p$ is prime, $p\neq 2$, and $|G|=2p$, then $G$ is either abelian $\simeq \mathbb{Z}_2\times \mathbb{Z}_p$ or $G\simeq D_p$
<details>
<summary>Proof</summary>
We know $G$ has an element of order 2, namely $b$, and an element of order $p$, namely $a$.
So $e,a,a^2,\dots ,a^{p-1},ba,ba^2,\dots,ba^{p-1}$ are distinct elements of $G$.
Consider $ab$, if $ab=ba$, then $G$ is abelian, then $G\simeq \mathbb{Z}_2\times \mathbb{Z}_p$.
If $ab=ba^{p-1}$, then $G\simeq D_p$.
$ab$ cannot be inverse of other elements, if $ab=ba^t$, where $2\leq t\leq p-2$, then $bab=a^t$, then $(bab)^t=a^{t^2}$, then $ba^tb=a^{t^2}$, therefore $a=a^{t^2}$, then $a^{t^2-1}=e$, so $p|(t^2-1)$, therefore $p|t-1$ or $p|t+1$.
This is not possible since $2\leq t\leq p-2$.
</details>

View File

@@ -0,0 +1,147 @@
# Math4302 Modern Algebra (Lecture 24)
## Rings
### Definition of ring
A ring is a set $R$ with binary operation $+$ and $\cdot$ such that:
- $(R,+)$ is an abelian group.
- Multiplication is associative: $(a\cdot b)\cdot c=a\cdot (b\cdot c)$.
- Distribution property: $a\cdot (b+c)=a\cdot b+a\cdot c$, $(b+c)\cdot a=b\cdot a+c\cdot a$. (Note that $\cdot$ may not be abelian, may not even be a group, therefore we need to distribute on both sides.)
> [!NOTE]
>
> $a\cdot b=ab$ will be used for the rest of the sections.
<details>
<summary>Examples of rings</summary>
$(\mathbb{Z},+,*)$, $(\mathbb{R},+,*)$ are rings.
---
$(2\mathbb{Z},+,\cdot)$ is a ring.
---
$(M_n(\mathbb{R}),+,\cdot)$ is a ring.
---
$(\mathbb{Z}_n,+,\cdot)$ is a ring, where $a\cdot b=a*b\mod n$.
e.g. in $\mathbb{Z}_{12}, 4\cdot 8=8$.
</details>
> [!TIP]
>
> If $(R+,\cdot)$ is a ring, then $(R,\cdot)$ may not be necessarily a group.
#### Properties of rings
Let $0$ denote the identity of addition of $R$. $-a$ denote the additive inverse of $a$.
- $0\cdot a=a\cdot 0=0$
- $(-a)b=a(-b)=-(ab)$, $\forall a,b\in R$
- $(-a)(-b)=ab$, $\forall a,b\in R$
<details>
<summary>Proof</summary>
1) $0\cdot a=(0+0)\cdot a=0\cdot a+0\cdot a$, by cancellation, $0\cdot a=0$.
Similarly, $a\cdot 0=0\cdot a=0$.
2) $(a+(-a))\cdot b=0\cdot b=0$ by (1), So $a\cdot b +(-a)\cdot b=0$, $(-a)\cdot b=-(ab)$. Similarly, $a\cdot (-b)=-(ab)$.
3) $(-a)(-b)=(a(-b))$ by (2), apply (2) again, $-(-(ab))=ab$.
</details>
#### Definition of commutative ring
A ring $(R,+,\cdot)$ is commutative if $a\cdot b=b\cdot a$, $\forall a,b\in R$.
<details>
<summary>Example of non commutative ring</summary>
$(M_n(\mathbb{R}),+,\cdot)$ is not commutative.
</details>
#### Definition of unity element
A ring $R$ has unity element if there is an element $1\in R$ such that $a\cdot 1=1\cdot a=a$, $\forall a\in R$.
> [!NOTE]
>
> Unity element is unique.
>
> Suppose $1,1'$ are unity elements, then $1\cdot 1'=1'\cdot 1=1$, $1=1'$.
<details>
<summary>Example of field have no unity element</summary>
$(2\mathbb{Z},+,\cdot)$ does not have unity element.
</details>
#### Definition of unit
Suppose $R$ is a ring with unity element. An element $a\in R$ is called a unit if there is $b\in R$ such that $a\cdot b=b\cdot a=1$.
In this case $b$ is called the inverse of $a$.
> [!TIP]
>
> If $a$ is a unit, then its inverse is unique. If $b,b'$ are inverses of $a$, then $b'=1b'=bab'=b1=b$.
We use $a^{-1}$ or $\frac{1}{a}$ to represent the inverse of $a$.
Let $R$ be a ring with unity, then $0$ is not a unit. (identity of addition has no multiplicative inverse)
If $0b=b0=1$, then $\forall a\in R$, $a=1a=0a=0$.
#### Definition of division ring
If every $a\neq 0$ in $R$ has a multiplicative inverse (is a unit), then $R$ is called a division ring.
#### Definition of field
A commutative division ring is called a field.
<details>
<summary>Example of field</summary>
$(\mathbb{R},+,\cdot)$ is a field.
---
$(\mathbb{Z}_p,+,\cdot)$ is a field, where $p$ is a prime number.
</details>
#### Lemma $\mathbb{Z}_p$ is a field
$\mathbb{Z}_p$ is a field if and only if $p$ is prime.
<details>
<summary>Proof</summary>
If $\mathbb{Z}_n$ is a field, then $n$ is prime.
<!-- This is equivalent to the statement that: If $\mathbb{Z}_p$ is a field and $1\leq m\leq n-1$, then $\operatorname{gcd}(m,n)=1$.
We $\operatorname{gcd}(m,n)=d>1$, -->
We proceed by contradiction. Suppose $n$ is not a prime, then $d|n$ for some $2\leq d\leq n-1$, then $[d]$ does not have inverse.
If $[d][x]=[1]$, then $dx\equiv 1\mod n$, so $dx-1=ny$ for some $y\in \mathbb{Z}$, but $d|dx$, and $d|ny$, so $d|1$ which is impossible.
Therefore, $n$ is prime.
---
If $p$ is prime, then $\mathbb{Z}_p$ is a field.
Since $p$ is a prime, then $\operatorname{gcd}(m,n)=1$ for $1\leq m\leq n-1$. So $1=mx+ny$ for some $x,y\in \mathbb{Z}_p$. Then $[x]$ (the remainder of $x$ when divided by $p$) is the multiplicative inverse of $[m]$. $[m][x]=[mx]=[1-ny]=[1]$.
</details>

View File

@@ -0,0 +1,141 @@
# Math4302 Modern Algebra (Lecture 25)
Midterm next, next Wednesday
## Rings
### Definitions
- commutative ring: elements $a\cdot b=b\cdot a$, $\forall a,b\in R$
- ring with unity: elements $a\cdot 1=1\cdot a=a$, $\forall a\in R$
- units: elements such that there is $a\cdot b=1$ for some $b\in R$.
- division ring: every element $a\neq 0$ has a multiplicative inverse $a^{-1}$ such that $a\cdot a^{-1}=1$.
- field: division ring that is commutative
<details>
<summary>Examples of division ring that is not a field</summary>
Quaternions
Let $i^2=-1$, $j^2=-1$, $k^2=-1$, with $ij=k$, $jk=i$, $ki=j$.
$R=\{a+bi+ci+dj\mid a,b,c,d\in \mathbb{R}\}$
$R$ is not commutative since $ij\neq ji$, but $R$ is a division ring.
Let $x=a+bi+cj+dk$ be none zero, then $\bar{x}=a-bi-cj-dk$, $x^{-1}=\frac{\bar{x}}{a^2+b^2+c^2+d^2}$ is also non zero and $xx^{-1}=1$.
</details>
Recall from last time $\mathbb{Z}_n$ is a field if and only if $n$ is prime.
#### Units in $\mathbb{Z}_n$ is coprime to $n$
More generally, $[m]\in \mathbb{Z}_n$ is a unit if and only if $\operatorname{gcd}(m,n)=1$.
<details>
<summary>Proof</summary>
Let $d=\operatorname{gcd}(m,n)$ and $[m]$ is a unit, then $\exists [x]\in \mathbb{Z}_n$ with $[m][z]=[1]$, so $mz\equiv 1\mod n$. so $mz-1=nt$ for some $t\in \mathbb{Z}$, but $d|m$, $d|t$, so $d|1$ implies $d=1$.
If $d=1$, so $1=mr+ns$ for some $r,s\in \mathbb{Z}_n$. If $x=r\mod n$, then $[x]$ is the inverse of $[m]$. $mr\equiv 1\mod n\implies [m][x]=[1]$.
</details>
### Integral Domains
#### Definition of zero divisors
If $a,b\in R$ with $a,b\neq 0$ and $ab=0$, then $a,b$ are called zero divisors.
<details>
<summary>Example of zero divisors</summary>
Consider $\mathbb{Z}_6$, then $2\cdot 3=0$, so $2$ and $3$ are zero divisors.
And $4\cdot 3=0$, so $4$ and $3$ are zero divisors.
> If $a$ is a unit, then $a$ is not a zero divisor.
$ab=0\implies a^{-1}ab=0\implies 1b=0\implies b=0$.
</details>
> [!NOTE]
>
> If an element is not unit, it may not be a zero divisor.
>
> Consider $R=\mathbb{Z}$ and $2$ is not a unit, but $2$ is not a zero divisor.
#### Zero divisors in $\mathbb{Z}_n$
$[m]\in \mathbb{Z}_n$ is a zero divisor if and only if $\operatorname{gcd}(m,n)>1$ ($m$ is not a unit).
<details>
<summary>Proof</summary>
If $d=\operatorname{gcd}(m,n)=1$, then $[m]$ is a unit, so $[m]$ is not a zero divisor.
Therefore $[m]$ is a zero divisor if $\operatorname{gcd}(m,n)>1$.
---
If $d=\operatorname{gcd}(m,n)>1$, then $n=n_1d,m=m_1d, 1\leq n_1<n$.
Then $mn_1=m_1dn_1=m_1n$, $n|mn_1$ $[m][n_1]=[0]$, $n_1\neq 0$, $[m]$ is a zero divisor.
</details>
#### Definition of integral domain
A commutative ring with unity is called a integral domain (or just a domain) if it has no zero divisors.
<details>
<summary>Example of integral domain</summary>
$\mathbb{Z}$ is a integral domain.
---
Any field is a integral domain.
</details>
#### Corollaries of integral domain
If $R$ is a integral domain, then we have cancellation property $ab=ac,a\neq 0\implies b=c$.
#### Units with multiplication forms a group
If $R$ is a ring with unity, then the units in $R$ forms a group under multiplication.
<details>
<summary>Proof</summary>
if $a,b$ are units, then $ab$ is a unit $(ab)^{-1}=b^{-1}a^{-1}$.
</details>
In particular, non-zero elements of any field form an abelian group under multiplication.
<details>
<summary>Example</summary>
Consider $\mathbb{Z}_p$ field, then $(\{1,2,\cdots,p-1\},\cdot)$ forms an abelian group of size $p-1$.
---
Consider $\mathbb{Z}_5$, then we have a group of size $4$ under multiplication.
- $1$ has order 1
- $2$ has order 4 $2,4,3,1$.
- $3$ has order 4 $3,4,2,1$.
- $4$ has order 2 $4,1$.
Therefore $\mathbb{Z}_5\simeq \mathbb{Z}_4$.
---
Therefore in $R=\mathbb{Z}_p$, $\mathbb{Z}_p^*=\{[1],[2],\cdots,[p-1]\}$ is a group of order $p-1$.
Therefore, for every $a\in \mathbb{Z}_p$, $[a]^{p-1}=[1]$, then $a^{p-1}\equiv 1\mod p$ (Fermat's little theorem).
</details>

View File

@@ -0,0 +1,111 @@
# Math4302 Modern Algebra (Lecture 26)
## Rings
### Fermats and Eulers Theorems
Recall from last lecture, we consider $\mathbb{Z}_p$ and $\mathbb{Z}_p^*$ denote the group of units in $\mathbb{Z}_p$ with multiplication.
$$
\mathbb{Z}_p^* = \{1,2,\cdots,p-1\}, \quad |\mathbb{Z}_p^*| = p-1
$$
Let $[a]\in \mathbb{Z}_p^*$, then $[a]^{p-1}=[1]$, this implies that $a^{p-1}\mod p=1$.
Now if $m\in \mathbb{Z}$ and $a=$ remainder of $m$ by $p$, $[a]\in \mathbb{Z}_p$, implies $m\equiv a\mod p$.
Then $m^{p-1}\equiv a^{p-1}\mod p$.
So
#### Fermats little theorem
If $p$ is not a divisor of $m$, then $m^{p-1}\equiv 1\mod p$.
#### Corollary of Fermats little theorem
If $m\in \mathbb{Z}$, then $m^p\equiv m\mod p$.
<details>
<summary>Proof</summary>
If $p|m$, then $m^{p-1}\equiv 0\equiv m\mod p$.
If $p\not|m$, then by Fermats little theorem, $m^{p-1}\equiv 1\equiv m\mod p$, so $m^p\equiv m\mod p$.
</details>
<details>
<summary>Example</summary>
Find the remainder of $40^{100}$ by $19$.
$40^{100}\equiv 2^{100}\mod 19$
$2^{100}\equiv 2^{10}\mod 19$ (Fermats little theorem $2^18\equiv 1\mod 19, 2^{90}\equiv 1\mod 19$)
$2^10\equiv (-6)^2\mod 19\equiv 36\mod 19\equiv 17\mod 19$
---
For every integer $n$, $15|(n^{33}-n)$.
$15=3\cdot 5$, therefore enough to show that $3|(n^{33}-n)$ and $5|(n^{33}-n)$.
Apply the corollary of Fermats little theorem to $p=3$: $n^3\equiv n\mod 3$, $(n^3)^11\equiv n^{11}\equiv (n^3)^3 n^2=n^3 n^2\equiv n^3\mod 3\equiv n\mod 3$.
Therefore $3|(n^{33}-n)$.
Apply the corollary of Fermats little theorem to $p=5$: $n^5\equiv n\mod 5$, $n^30 n^3\equiv (n^5)^6 n^3\equiv n^6 n^3\equiv n^5\mod 5\equiv n\mod 5$.
Therefore $5|(n^{33}-n)$.
</details>
#### Eulers totient function
Consider $\mathbb{Z}_6$, by definition for the group of units, $\mathbb{Z}_6^*=\{1,5\}$.
$$
\phi(n)=|\mathbb{Z}_n^*|=|\{1\leq x\leq n:gcd(x,n)=1\}|
$$
<details>
<summary>Example</summary>
$\phi(8)=|\{1,3,5,7\}|=4$
</details>
If $[a]\in \mathbb{Z}_n^*$, then $[a]^{\phi(n)}=[1]$. So $a^{\phi(n)}\equiv 1\mod n$.
#### Theorem
If $m\in \mathbb{Z}$, and $gcd(m,n)=1$, then $m^{\phi(n)}\equiv 1\mod n$.
<details>
<summary>Proof</summary>
If $a$ is the remainder of $m$ by $n$, then $m\equiv a\mod n$, and $\operatorname{gcd}(a,n)=1$, so $m^{\phi(n)}\equiv a^{\phi(n)}\equiv 1\mod n$.
</details>
#### Applications on solving modular equations
Solving equations of the form $ax\equiv b\mod n$.
Not always have solution, $2x\equiv 1\mod 4$ has no solution since $1$ is odd.
Solution for $2x\equiv 1\mod 3$
- $x\equiv 0\implies 2x\equiv 0\mod 3$
- $x\equiv 1\implies 2x\equiv 2\mod 3$
- $x\equiv 2\implies 2x\equiv 1\mod 3$
So solution for $2x\equiv 1\mod 3$ is $\{3k+2|k\in \mathbb{Z}\}$.
#### Theorem for exsistence of solution of modular equations
$ax\equiv b\mod n$ has a solution if and only if $\operatorname{gcd}(a,n)|b$ and in that case the equation has $d$ solutions in $\mathbb{Z}_n$.
Proof on next lecture.

View File

@@ -0,0 +1,126 @@
# Math4302 Modern Algebra (Lecture 27)
## Rings
### Fermats and Eulers Theorems
Recall from last lecture, $ax\equiv b \mod n$, if $x\equiv y\mod n$, then $x$ is a solution if and only if $y$ is a solution.
#### Theorem for existence of solution of modular equations
$ax\equiv b\mod n$ has a solution if and only if $d=\operatorname{gcd}(a,n)|b$ And if there is a solution, then there are exactly $d$ solutions in $\mathbb{Z}_n$.
<details>
<summary>Proof</summary>
For the forward direction, we proved if $ax\equiv b\mod n$ then $ax-b=ny$, $y\in\mathbb{Z}$.
then $b=ax-ny$, $d|(ax-ny)$ implies that $d|b$.
---
For the backward direction, assume $d=\operatorname{gcd}(a,n)=1$. Then we need to show, there is exactly $1$ solution between $0$ and $n-1$.
If $ax\equiv b\mod n$, then in $\mathbb{Z}_n$, $[a][x]=[b]$. (where $[a]$ denotes the remainder of $a$ by $n$ and $[b]$ denotes the remainder of $b$ by $n$)
Since $\operatorname{gcd}(a,n)=1$, then $[a]$ is a unit in $\mathbb{Z}_n$, so we can multiply the above equation by the inverse of $[a]$. and get $[x]=[a]^{-1}[b]$.
Now assume $d=\operatorname{gcd}(a,n)$ where $n$ is arbitrary. Then $a=a'd$, then $n=n'd$, with $\operatorname{gcd}(a',n')=1$.
Also $d|b$ so $b=b'd$. So
$$
\begin{aligned}
ax\equiv b \mod n&\iff n|(ax-b)\\
&\iff n'd|(a'dx-b'd)\\
&\iff n'|(a'x-b')\\
&\iff a'x\equiv b'\mod n'
\end{aligned}
$$.
Since $\operatorname{gcd}(a',n')=1$, there is a unique solution $x_0\in \mathbb{Z}_{n'}$. $0\leq x_0\leq n'+1$. Other solution in $\mathbb{Z}$ are of the form $x_0+kn'$ for $k\in \mathbb{Z}$.
And there will be $d$ solutions in $\mathbb{Z}_n$,
</details>
<details>
<summary>Examples</summary>
Solve $12x\equiv 25\mod 7$.
$12\equiv 5\mod 7$, $25\equiv 4\mod 7$. So the equation becomes $5x\equiv 4\mod 7$.
$[5]^{-1}=3\in \mathbb{Z}_7$, so $[5][x]\equiv [4]$ implies $[x]\equiv [3][4]\equiv [5]\mod 7$.
So solution in $\mathbb{Z}$ is $\{5+7k:k\in \mathbb{Z}\}$.
---
Solve $6x\equiv 32\mod 20$.
$\operatorname{gcd}(6,20)=2$, so $6x\equiv 12\mod 20$ if and only if $3x\equiv 6\mod 10$.
$[3]^{-1}=[7]\in \mathbb{Z}_{10}$, so $[3][x]\equiv [6]$ implies $[x]\equiv [7][6]\equiv [2]\mod 10$.
So solution in $\mathbb{Z}_{20}$ is $[2]$ and $[12]$
So solution in $\mathbb{Z}$ is $\{2+10k:k\in \mathbb{Z}\}$
</details>
### Ring homomorphisms
#### Definition of ring homomorphism
Let $R,S$ be two rings, $f:R\to S$ is a ring homomorphism if $\forall a,b\in R$,
- $f(a+b)=f(a)+f(b)\implies f(0)=0, f(-a)=-f(a)$
- $f(ab)=f(a)f(b)$
#### Definition of ring isomorphism
If $f$ is a ring homomorphism and a bijection, then $f$ is called a ring isomorphism.
<details>
<summary>Example</summary>
Let $f:(\mathbb{Z},+,\times)\to(2\mathbb{Z},+,\times)$ by $f(a)=2a$.
Is not a ring homomorphism since $f(ab)\neq f(a)f(b)$ in general.
---
Let $f:(\mathbb{Z},+,\times)\to(\mathbb{Z}_n,+,\times)$ by $f(a)=a\mod n$
Is a ring homomorphism.
</details>
### Integral domains and their file fo fractions.
Let $R$ be an integral domain: (i.e. $R$ is commutative with unity and no zero divisors).
#### Definition of field of fractions
If $R$ is an integral domain, we can construct a field containing $R$ called the field of fractions (or called field of quotients) of $R$.
$$
S=\{(a,b)|a,b\in R, b\neq 0\}
$$
a relation on $S$ is defined as follows:
$(a,b)\sim (c,d)$ if and only if $ad=bc$.
<details>
<summary>This equivalence relation is well defined</summary>
- Reflectivity: $(a,b)\sim (a,b)$ $ab=ab$
- Symmetry: $(a,b)\sim (c,d)\Rightarrow (c,d)\sim (a,b)$
- Transitivity: $(a,b)\sim (c,d)$ and $(c,d)\sim (e,f)\Rightarrow (a,b)\sim (e,f)$
- $ad=bc$, and $cf=ed$, we want to conclude that $af=be$. since $ad=bc$, then $adf=bcf$, since $cf=ed$, then $cfb=edb$, therefore $adf=edb$.
- Then $d(af-be)=0$ since $d\neq 0$ then $af=be$.
</details>
Then $S/\sim$ is a field.

View File

@@ -0,0 +1,153 @@
# Math4302 Modern Algebra (Lecture 28)
## Rings
### Field of quotients
Let $R$ be an integral domain ($R$ has unity and commutative with no zero divisors).
Consider the pair $S=\{(a,b)|a,b\in R, b\neq 0\}$.
And define the equivalence relation on $S$ as follows:
$(a,b)\sim (c,d)$ if and only if $ad=bc$.
We denote $[(a,b)]$ as set of all elements in $S$ equivalent to $(a,b)$.
Let $F$ be the set of all equivalent classes. We define addition and multiplication on $F$ as follows:
$$
[(a,b)]+[(c,d)]=[(ad+bc,bd)]
$$
$$
[(a,b)]\cdot[(c,d)]=[(ac,bd)]
$$
<details>
<summary>The multiplication and addition is well defined </summary>
Addition:
If $(a,b)\sim (a',b')$, and $(c,d)\sim (c',d')$, then we want to show that $(ad+bc,bd)\sim (a'd+c'd,b'd)$.
Since $(a,b)\sim (a',b')$, then $ab'=a'b$; $(c,d)\sim (c',d')$, then $cd'=dc'$,
So $ab'dd'=a'bdd'$, and $cd'bb'=dc'bb'$.
$adb'd'+bcb'd'=a'd'bd+b'c'bd$, therefore $(ad+bc,bd)\sim (a'd+c'd,b'd)$.
---
Multiplication:
If $(a,b)\sim (a',b')$, and $(c,d)\sim (c',d')$, then we want to show that $(ac,bd)\sim (a'c',b'd')$.
Since $(a,b)\sim (a',b')$, then $ab'=a'b$; $(c,d)\sim (c',d')$, then $cd'=dc'$, so $(ac,bd)\sim (a'c',b'd')$
</details>
#### Claim (F,+,*) is a field
- additive identity: $(0,1)\in F$
- additive inverse: $(a,b)\in F$, then $(-a,b)\in F$ and $(-a,b)+(a,b)=(0,1)\in F$
- additive associativity: bit long.
- multiplicative identity: $(1,1)\in F$
- multiplicative inverse: $[(a,b)]$ is non zero if and only if $a\neq 0$, then $a^{-1}=[(b,a)]\in F$.
- multiplicative associativity: bit long
- distributivity: skip, too long.
Such field is called a quotient field of $R$.
And $F$ contains $R$ by $\phi:R\to F$, $\phi(a)=[(a,1)]$.
This is a ring homomorphism.
- $\phi(a+b)=[(a+b,1)]=[(a,1)][(b,1)]\phi(a)+\phi(b)$
- $\phi(ab)=[(ab,1)]=[(a,1)][(b,1)]\phi(a)\phi(b)$
and $\phi$ is injective.
If $\phi(a)=\phi(b)$, then $a=b$.
<details>
<summary>Example</summary>
Let $D\subset \mathbb R$ and
$$
\mathbb Z \subset D\coloneqq \{a+b\sqrt{2}:a,b\in \mathbb Z\}
$$
Then $D$ is a subring of $\mathbb R$, and integral domain, with usual addition and multiplication.
$$
(a+b\sqrt{2})(c+d\sqrt{2})=(ac+2bd)+(ad+bc)\sqrt{2}
$$
$$
-(a+b\sqrt{2})=(-a)+(-b)\sqrt{2})
$$
...
$D$ is a integral domain since $\mathbb R$ has no zero divisors, therefore $D$ has no zero divisors.
Consider the field of quotients of $D$. $[(a+b\sqrt{2},c+d\sqrt{2})]$. This is isomorphic to $\mathbb Q(\sqrt2)=\{r+s\sqrt{2}:r,s\in \mathbb Q\}$
$$
m+n\sqrt{2}=\frac{m}{n}+\frac{m'}{n'}\sqrt{2}\mapsto [(mn'+nm'\sqrt{2},nn')]
$$
And use rationalization on the forward direction.
</details>
#### Polynomial rings
Let $R$ be a ring, a polynomial with coefficients in $R$ is a sum
$$
a_0+a_1x+\cdots+a_nx^n
$$
where $a_i\in R$. $x$ is indeterminate, $a_0,a_1,\cdots,a_n$ are called coefficients. $a_0$ is the constant term.
If $f$ is a non-zero polynomial, then the degree of $f$ is defined as the largest $n$ such that $a_n\neq 0$.
<details>
<summary>Example</summary>
Let $f=1+2x+0x^2-1x^3+0x^4$, then $deg f=3$
</details>
If $R$ has a unity $1$, then we write $x^m$ instead of $1x^m$.
Let $R[x]$ denote the set of all polynomials with coefficients in $R$.
We define multiplication and addition on $R[x]$.
$f:a_0+a_1x+\cdots+a_nx^n$
$g:b_0+b_1x+\cdots+b_mx^m$
Define,
$$
f+g=a_0+b_0+a_1x+b_1x+\cdots+a_nx^n+b_mx^m
$$
$$
fg=(a_0b_0)+(a_1b_0)x+\cdots+(a_nb_m)x^m
$$
In general, the coefficient of $x^m=\sum_{i=0}^{m}a_ix^{m-i}$.
> [!CAUTION]
>
> The field $R$ may not be commutative, follow the order of computation matters.
We will show that this is a ring and explore additional properties.

View File

@@ -24,4 +24,11 @@ export default {
Math4302_L19: "Modern Algebra (Lecture 19)",
Math4302_L20: "Modern Algebra (Lecture 20)",
Math4302_L21: "Modern Algebra (Lecture 21)",
Math4302_L22: "Modern Algebra (Lecture 22)",
Math4302_L23: "Modern Algebra (Lecture 23)",
Math4302_L24: "Modern Algebra (Lecture 24)",
Math4302_L25: "Modern Algebra (Lecture 25)",
Math4302_L26: "Modern Algebra (Lecture 26)",
Math4302_L27: "Modern Algebra (Lecture 27)",
Math4302_L28: "Modern Algebra (Lecture 28)",
}

207
mcp-server.mjs Normal file
View File

@@ -0,0 +1,207 @@
import fs from 'node:fs/promises'
import path from 'node:path'
import process from 'node:process'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import {
CallToolRequestSchema,
ListToolsRequestSchema
} from '@modelcontextprotocol/sdk/types.js'
const CONTENT_ROOT = path.join(process.cwd(), 'content')
const NOTE_EXTENSIONS = new Set(['.md', '.mdx'])
const MAX_SEARCH_RESULTS = 10
const SNIPPET_RADIUS = 220
async function walkNotes(dir = CONTENT_ROOT) {
const entries = await fs.readdir(dir, { withFileTypes: true })
const notes = await Promise.all(entries.map(async (entry) => {
const fullPath = path.join(dir, entry.name)
if (entry.isDirectory()) {
return walkNotes(fullPath)
}
if (!entry.isFile() || !NOTE_EXTENSIONS.has(path.extname(entry.name))) {
return []
}
const relativePath = path.relative(CONTENT_ROOT, fullPath).replaceAll('\\', '/')
const slug = relativePath.replace(/\.(md|mdx)$/i, '')
return [{
fullPath,
relativePath,
slug,
title: path.basename(slug)
}]
}))
return notes.flat().sort((a, b) => a.relativePath.localeCompare(b.relativePath))
}
function normalizeNoteId(noteId = '') {
const normalized = String(noteId).trim().replaceAll('\\', '/').replace(/^\/+|\/+$/g, '')
if (!normalized || normalized.includes('..')) {
return null
}
return normalized
}
async function resolveNote(noteId) {
const normalized = normalizeNoteId(noteId)
if (!normalized) {
return null
}
const notes = await walkNotes()
return notes.find((note) =>
note.slug === normalized ||
note.relativePath === normalized ||
note.relativePath.replace(/\.(md|mdx)$/i, '') === normalized
) ?? null
}
function buildSnippet(content, index, query) {
const start = Math.max(0, index - SNIPPET_RADIUS)
const end = Math.min(content.length, index + query.length + SNIPPET_RADIUS)
return content
.slice(start, end)
.replace(/\s+/g, ' ')
.trim()
}
function textResponse(text) {
return {
content: [{ type: 'text', text }]
}
}
const server = new Server(
{
name: 'notenextra-notes',
version: '1.0.0'
},
{
capabilities: {
tools: {}
}
}
)
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'list_notes',
description: 'List available notes from the Next.js content directory.',
inputSchema: {
type: 'object',
properties: {
course: {
type: 'string',
description: 'Optional course or directory prefix, for example CSE442T or Math4201.'
}
}
}
},
{
name: 'read_note',
description: 'Read a note by slug or relative path, for example CSE442T/CSE442T_L1.',
inputSchema: {
type: 'object',
properties: {
noteId: {
type: 'string',
description: 'Note slug or relative path inside content/.'
}
},
required: ['noteId']
}
},
{
name: 'search_notes',
description: 'Search the notes knowledge base using a simple text match over all markdown content.',
inputSchema: {
type: 'object',
properties: {
query: {
type: 'string',
description: 'Search term or phrase.'
},
limit: {
type: 'number',
description: `Maximum results to return, capped at ${MAX_SEARCH_RESULTS}.`
}
},
required: ['query']
}
}
]
}))
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args = {} } = request.params
if (name === 'list_notes') {
const notes = await walkNotes()
const course = typeof args.course === 'string'
? args.course.trim().toLowerCase()
: ''
const filtered = course
? notes.filter((note) => note.relativePath.toLowerCase().startsWith(`${course}/`))
: notes
return textResponse(filtered.map((note) => note.slug).join('\n') || 'No notes found.')
}
if (name === 'read_note') {
const note = await resolveNote(args.noteId)
if (!note) {
return textResponse('Note not found.')
}
const content = await fs.readFile(note.fullPath, 'utf8')
return textResponse(`# ${note.slug}\n\n${content}`)
}
if (name === 'search_notes') {
const query = typeof args.query === 'string' ? args.query.trim() : ''
if (!query) {
return textResponse('Query must be a non-empty string.')
}
const limit = Math.max(1, Math.min(Number(args.limit) || 5, MAX_SEARCH_RESULTS))
const queryLower = query.toLowerCase()
const notes = await walkNotes()
const matches = []
for (const note of notes) {
const content = await fs.readFile(note.fullPath, 'utf8')
const haystack = `${note.slug}\n${content}`
const index = haystack.toLowerCase().indexOf(queryLower)
if (index === -1) {
continue
}
matches.push({
note,
index,
snippet: buildSnippet(haystack, index, query)
})
}
matches.sort((a, b) => a.index - b.index || a.note.slug.localeCompare(b.note.slug))
return textResponse(
matches
.slice(0, limit)
.map(({ note, snippet }) => `- ${note.slug}\n${snippet}`)
.join('\n\n') || 'No matches found.'
)
}
throw new Error(`Unknown tool: ${name}`)
})
const transport = new StdioServerTransport()
await server.connect(transport)

227
mcp-worker/src/index.mjs Normal file
View File

@@ -0,0 +1,227 @@
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js'
import {
CallToolRequestSchema,
ListToolsRequestSchema
} from '@modelcontextprotocol/sdk/types.js'
import { notesData } from '../generated/notes-data.mjs'
const MAX_SEARCH_RESULTS = 10
const SNIPPET_RADIUS = 220
const transports = new Map()
function normalizeNoteId(noteId = '') {
const normalized = String(noteId).trim().replaceAll('\\', '/').replace(/^\/+|\/+$/g, '')
if (!normalized || normalized.includes('..')) {
return null
}
return normalized
}
function resolveNote(noteId) {
const normalized = normalizeNoteId(noteId)
if (!normalized) {
return null
}
return notesData.find((note) =>
note.slug === normalized ||
note.relativePath === normalized ||
note.relativePath.replace(/\.(md|mdx)$/i, '') === normalized
) ?? null
}
function buildSnippet(content, index, query) {
const start = Math.max(0, index - SNIPPET_RADIUS)
const end = Math.min(content.length, index + query.length + SNIPPET_RADIUS)
return content
.slice(start, end)
.replace(/\s+/g, ' ')
.trim()
}
function textResponse(text) {
return {
content: [{ type: 'text', text }]
}
}
function createServer() {
const server = new Server(
{
name: 'notenextra-notes-worker',
version: '1.0.0'
},
{
capabilities: {
tools: {}
}
}
)
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'list_notes',
description: 'List available notes from the generated notes knowledge base.',
inputSchema: {
type: 'object',
properties: {
course: {
type: 'string',
description: 'Optional course or directory prefix, for example CSE442T or Math4201.'
}
}
}
},
{
name: 'read_note',
description: 'Read a note by slug or relative path, for example CSE442T/CSE442T_L1.',
inputSchema: {
type: 'object',
properties: {
noteId: {
type: 'string',
description: 'Note slug or relative path inside content/.'
}
},
required: ['noteId']
}
},
{
name: 'search_notes',
description: 'Search the notes knowledge base using a simple text match over all markdown content.',
inputSchema: {
type: 'object',
properties: {
query: {
type: 'string',
description: 'Search term or phrase.'
},
limit: {
type: 'number',
description: `Maximum results to return, capped at ${MAX_SEARCH_RESULTS}.`
}
},
required: ['query']
}
}
]
}))
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args = {} } = request.params
if (name === 'list_notes') {
const course = typeof args.course === 'string'
? args.course.trim().toLowerCase()
: ''
const filtered = course
? notesData.filter((note) => note.relativePath.toLowerCase().startsWith(`${course}/`))
: notesData
return textResponse(filtered.map((note) => note.slug).join('\n') || 'No notes found.')
}
if (name === 'read_note') {
const note = resolveNote(args.noteId)
if (!note) {
return textResponse('Note not found.')
}
return textResponse(`# ${note.slug}\n\n${note.content}`)
}
if (name === 'search_notes') {
const query = typeof args.query === 'string' ? args.query.trim() : ''
if (!query) {
return textResponse('Query must be a non-empty string.')
}
const limit = Math.max(1, Math.min(Number(args.limit) || 5, MAX_SEARCH_RESULTS))
const queryLower = query.toLowerCase()
const matches = []
for (const note of notesData) {
const haystack = `${note.slug}\n${note.content}`
const index = haystack.toLowerCase().indexOf(queryLower)
if (index === -1) {
continue
}
matches.push({
note,
index,
snippet: buildSnippet(haystack, index, query)
})
}
matches.sort((a, b) => a.index - b.index || a.note.slug.localeCompare(b.note.slug))
return textResponse(
matches
.slice(0, limit)
.map(({ note, snippet }) => `- ${note.slug}\n${snippet}`)
.join('\n\n') || 'No matches found.'
)
}
throw new Error(`Unknown tool: ${name}`)
})
return server
}
async function handleMcpRequest(request) {
const sessionId = request.headers.get('mcp-session-id')
let transport = sessionId ? transports.get(sessionId) : undefined
if (!transport && request.method === 'POST') {
transport = new WebStandardStreamableHTTPServerTransport({
sessionIdGenerator: () => crypto.randomUUID(),
enableJsonResponse: true,
onsessioninitialized: (newSessionId) => {
transports.set(newSessionId, transport)
},
onsessionclosed: (closedSessionId) => {
transports.delete(closedSessionId)
}
})
transport.onclose = () => {
if (transport.sessionId) {
transports.delete(transport.sessionId)
}
}
const server = createServer()
await server.connect(transport)
}
if (!transport) {
return new Response('Invalid or missing MCP session.', { status: 400 })
}
return transport.handleRequest(request)
}
export default {
async fetch(request) {
const url = new URL(request.url)
if (url.pathname === '/health') {
return Response.json({
status: 'ok',
notes: notesData.length
})
}
if (url.pathname === '/mcp') {
return handleMcpRequest(request)
}
return new Response('Not found.', { status: 404 })
}
}

4
mcp-worker/wrangler.toml Normal file
View File

@@ -0,0 +1,4 @@
name = "notenextra-mcp"
main = "src/index.mjs"
compatibility_date = "2025-02-13"
compatibility_flags = ["nodejs_compat"]

View File

@@ -7,9 +7,16 @@
"build:test": "cross-env ANALYZE=true NODE_OPTIONS='--inspect --max-old-space-size=4096' next build",
"build:analyze": "cross-env ANALYZE=true NODE_OPTIONS='--max-old-space-size=16384' next build",
"postbuild": "next-sitemap && pagefind --site .next/server/app --output-path out/_pagefind",
"start": "next start"
"start": "next start",
"mcp:notes": "node ./mcp-server.mjs",
"mcp:worker:build-data": "node ./scripts/generate-mcp-worker-data.mjs",
"mcp:worker:deploy": "npm run mcp:worker:build-data && npx wrangler deploy --config mcp-worker/wrangler.toml",
"mcp:worker:deploy:dry-run": "npm run mcp:worker:build-data && npx wrangler deploy --dry-run --config mcp-worker/wrangler.toml",
"test:mcp": "node ./test/test-mcp-server.mjs",
"test:mcp:worker": "node ./test/test-mcp-worker.mjs"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.18.1",
"@docsearch/css": "^4.3.1",
"@docsearch/react": "^4.3.1",
"@napi-rs/simple-git": "^0.1.22",

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@@ -0,0 +1,47 @@
import fs from 'node:fs/promises'
import path from 'node:path'
import process from 'node:process'
const CONTENT_ROOT = path.join(process.cwd(), 'content')
const OUTPUT_DIR = path.join(process.cwd(), 'mcp-worker', 'generated')
const OUTPUT_FILE = path.join(OUTPUT_DIR, 'notes-data.mjs')
const NOTE_EXTENSIONS = new Set(['.md', '.mdx'])
async function walkNotes(dir = CONTENT_ROOT) {
const entries = await fs.readdir(dir, { withFileTypes: true })
const notes = await Promise.all(entries.map(async (entry) => {
const fullPath = path.join(dir, entry.name)
if (entry.isDirectory()) {
return walkNotes(fullPath)
}
if (!entry.isFile() || !NOTE_EXTENSIONS.has(path.extname(entry.name))) {
return []
}
const relativePath = path.relative(CONTENT_ROOT, fullPath).replaceAll('\\', '/')
const slug = relativePath.replace(/\.(md|mdx)$/i, '')
const content = await fs.readFile(fullPath, 'utf8')
return [{
slug,
relativePath,
title: path.basename(slug),
content
}]
}))
return notes.flat().sort((a, b) => a.relativePath.localeCompare(b.relativePath))
}
const notes = await walkNotes()
await fs.mkdir(OUTPUT_DIR, { recursive: true })
await fs.writeFile(
OUTPUT_FILE,
`export const notesData = ${JSON.stringify(notes, null, 2)};\n`,
'utf8'
)
process.stdout.write(`Generated ${notes.length} notes for MCP worker.\n`)

74
test/test-mcp-server.mjs Normal file
View File

@@ -0,0 +1,74 @@
import assert from 'node:assert/strict'
import path from 'node:path'
import process from 'node:process'
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
const transport = new StdioClientTransport({
command: process.execPath,
args: [path.join(process.cwd(), 'mcp-server.mjs')],
cwd: process.cwd(),
stderr: 'pipe'
})
let stderrOutput = ''
transport.stderr?.setEncoding('utf8')
transport.stderr?.on('data', (chunk) => {
stderrOutput += chunk
})
const client = new Client({
name: 'notenextra-mcp-test',
version: '1.0.0'
})
async function main() {
await client.connect(transport)
const toolListResponse = await client.listTools()
const toolNames = toolListResponse.tools.map((tool) => tool.name).sort()
assert.deepEqual(toolNames, ['list_notes', 'read_note', 'search_notes'])
const listNotesResponse = await client.callTool({
name: 'list_notes',
arguments: {
course: 'CSE442T'
}
})
const listedNotes = listNotesResponse.content[0].text
assert.match(listedNotes, /CSE442T\/CSE442T_L1/, 'list_notes should include CSE442T lecture notes')
const readNoteResponse = await client.callTool({
name: 'read_note',
arguments: {
noteId: 'about'
}
})
const aboutText = readNoteResponse.content[0].text
assert.match(aboutText, /# about/i)
assert.match(aboutText, /This is a static server for me to share my notes/i)
const searchResponse = await client.callTool({
name: 'search_notes',
arguments: {
query: "Kerckhoffs' principle",
limit: 3
}
})
const searchText = searchResponse.content[0].text
assert.match(searchText, /CSE442T\/CSE442T_L1/, 'search_notes should find the cryptography lecture')
assert.match(searchText, /Kerckhoffs/i)
}
try {
await main()
process.stdout.write('MCP server test passed.\n')
} catch (error) {
const suffix = stderrOutput ? `\nServer stderr:\n${stderrOutput}` : ''
process.stderr.write(`${error.stack || error}${suffix}\n`)
process.exitCode = 1
} finally {
await client.close().catch(() => {})
await transport.close().catch(() => {})
}

121
test/test-mcp-worker.mjs Normal file
View File

@@ -0,0 +1,121 @@
import assert from 'node:assert/strict'
import process from 'node:process'
import worker from '../mcp-worker/src/index.mjs'
import { LATEST_PROTOCOL_VERSION } from '@modelcontextprotocol/sdk/types.js'
function makeJsonRequest(url, body, headers = {}) {
return new Request(url, {
method: 'POST',
headers: {
accept: 'application/json, text/event-stream',
'content-type': 'application/json',
...headers
},
body: JSON.stringify(body)
})
}
const baseUrl = 'https://example.com'
const healthResponse = await worker.fetch(new Request(`${baseUrl}/health`))
assert.equal(healthResponse.status, 200)
const healthJson = await healthResponse.json()
assert.equal(healthJson.status, 'ok')
assert.ok(healthJson.notes > 0)
const initializeResponse = await worker.fetch(makeJsonRequest(`${baseUrl}/mcp`, {
jsonrpc: '2.0',
id: 1,
method: 'initialize',
params: {
protocolVersion: LATEST_PROTOCOL_VERSION,
capabilities: {},
clientInfo: {
name: 'notenextra-worker-test',
version: '1.0.0'
}
}
}))
assert.equal(initializeResponse.status, 200)
const sessionId = initializeResponse.headers.get('mcp-session-id')
assert.ok(sessionId, 'initialize should return an MCP session ID')
const protocolVersion = initializeResponse.headers.get('mcp-protocol-version') || LATEST_PROTOCOL_VERSION
const initializeJson = await initializeResponse.json()
assert.ok(initializeJson.result, 'initialize should return a result payload')
const toolListResponse = await worker.fetch(makeJsonRequest(`${baseUrl}/mcp`, {
jsonrpc: '2.0',
id: 2,
method: 'tools/list',
params: {}
}, {
'mcp-protocol-version': protocolVersion,
'mcp-session-id': sessionId
}))
assert.equal(toolListResponse.status, 200)
const toolListJson = await toolListResponse.json()
const toolNames = toolListJson.result.tools.map((tool) => tool.name).sort()
assert.deepEqual(toolNames, ['list_notes', 'read_note', 'search_notes'])
const listNotesResponse = await worker.fetch(makeJsonRequest(`${baseUrl}/mcp`, {
jsonrpc: '2.0',
id: 3,
method: 'tools/call',
params: {
name: 'list_notes',
arguments: {
course: 'CSE442T'
}
}
}, {
'mcp-protocol-version': protocolVersion,
'mcp-session-id': sessionId
}))
assert.equal(listNotesResponse.status, 200)
const listNotesJson = await listNotesResponse.json()
assert.match(listNotesJson.result.content[0].text, /CSE442T\/CSE442T_L1/)
const readNoteResponse = await worker.fetch(makeJsonRequest(`${baseUrl}/mcp`, {
jsonrpc: '2.0',
id: 4,
method: 'tools/call',
params: {
name: 'read_note',
arguments: {
noteId: 'about'
}
}
}, {
'mcp-protocol-version': protocolVersion,
'mcp-session-id': sessionId
}))
assert.equal(readNoteResponse.status, 200)
const readNoteJson = await readNoteResponse.json()
assert.match(readNoteJson.result.content[0].text, /This is a static server for me to share my notes/i)
const searchResponse = await worker.fetch(makeJsonRequest(`${baseUrl}/mcp`, {
jsonrpc: '2.0',
id: 5,
method: 'tools/call',
params: {
name: 'search_notes',
arguments: {
query: "Kerckhoffs' principle",
limit: 3
}
}
}, {
'mcp-protocol-version': protocolVersion,
'mcp-session-id': sessionId
}))
assert.equal(searchResponse.status, 200)
const searchJson = await searchResponse.json()
assert.match(searchJson.result.content[0].text, /CSE442T\/CSE442T_L1/)
process.stdout.write('MCP worker test passed.\n')