« Home

Notes [notes]

MILKY☆SUBWAY [TDJD]

In Defense of Inefficiency [29QD]

Я - extremely composable embeddable programming language [software-000A]

Extremely composable embeddable programming language

可以先從這些截圖感受一下這什麼程式語言xd

witr - Why is this running? [software-0009]

系統上執行的某個程式或服務 - 無論是 process、service 或綁定到連接埠的程式。都必然有其原因,但這些原因通常間接、不易察覺,或是跨越多個層級,例如監控程式、容器、服務或 shell。而 witr 的用途就是一次展示這些資訊。

OCaml formatter online configurator [programming-0006]

看不懂 OCaml formatter 要怎麼設定?這個專案把排版選項、原始碼跟結果都展示出來,讓人直覺的做出選擇。

Definition. Covering spaces in HoTT [ag-000L]

From Zero to QED [lean-0000]

Eliminator [ag-000K]

{-# OPTIONS --safe --without-K #-}
module ag-000K where

open import MLTT.Spartan
open import Naturals.Properties

Eliminator of

ℕ-elim :  (P :   𝓤 ̇)  P 0  (∀ (n : )  P n  P (succ n))  (∀ (n : )  P n)
ℕ-elim P P0 Ps zero = P0
ℕ-elim P P0 Ps (succ n) = Ps n (ℕ-elim P P0 Ps n)

Define with pattern matching

plus :     
plus zero b = b
plus (succ a) b = succ (plus a b)

mul :     
mul zero c = zero
mul (succ a) b = plus b (mul a b)

exp :     
exp x zero = 1
exp x (succ k) = mul x (exp x k)

Now use the eliminator to define them

plus' :     
plus' x = ℕ-elim  _    )  z  z)  x' plus-x'  λ y  succ (plus-x' y)) x

t5 : plus' 1 1  2
t5 = refl

p1 : (a b : )  plus a b  plus' a b
p1 zero b = refl
p1 (succ a) b =
  succ (plus a b)  =⟨ ap succ (p1 a b) 
  succ (plus' a b) =⟨by-definition⟩
  succ (ℕ-elim  _    )  z  z)  x' plus-x'  λ y  succ (plus-x' y)) a b)
    =⟨by-definition⟩
  plus' (succ a) b 

mul' :     
mul' x = ℕ-elim  _    )  z  zero)  x' mul-x'  λ y  plus' y (mul-x' y)) x

t7 : mul' 0 1  0
t7 = refl
t8 : mul' 1 1  1
t8 = refl
t9 : mul' 2 2  4
t9 = refl

p2 : (a b : )  mul a b  mul' a b
p2 zero b = refl
p2 (succ a) zero = p2 a 0
p2 (succ a) (succ b) =
  plus (succ b) (mul a (succ b))   =⟨ p1 (succ b) (mul a (succ b)) 
  plus' (succ b) (mul a (succ b))  =⟨ ap (plus' (succ b)) (p2 a (succ b)) 
  plus' (succ b) (mul' a (succ b)) =⟨by-definition⟩
  mul' (succ a) (succ b) 

exp' :     
exp' x y = ℕ-elim  _    )  x  1)  y' exp-y'  λ x  mul' x (exp-y' x)) y x

t10 : exp' 2 0  1
t10 = refl
t11 : exp' 2 10  1024
t11 = refl

p3 : (a b : )  exp a b  exp' a b
p3 a zero = refl
p3 zero (succ b) = refl
p3 (succ a) (succ b) =
  exp (succ a) (succ b)           =⟨by-definition⟩
  mul (succ a) (exp (succ a) b)   =⟨ p2 (succ a) (exp (succ a) b) 
  mul' (succ a) (exp (succ a) b)  =⟨ ap (mul' (succ a)) (p3 (succ a) b) 
  mul' (succ a) (exp' (succ a) b) =⟨by-definition⟩
  exp' (succ a) (succ b) 

Plus commutative yoga

C : commutative plus
C zero zero = refl
C zero (succ b) =
  succ b =⟨ ap succ (C 0 b) 
  succ (plus b zero) 
C (succ a) zero =
  succ (plus a 0) =⟨ ap succ (C a 0) 
  succ (plus 0 a) =⟨ refl 
  plus 0 (succ a) 
C (succ a) (succ b) =
  succ (plus a (succ b)) =⟨ ap succ (C a (succ b)) 
  succ (plus (succ b) a) =⟨ ap succ refl 
  succ (succ (plus b a)) =⟨ ap  x  succ (succ x)) (C b a) 
  succ (succ (plus a b)) =⟨ ap succ refl 
  succ (plus (succ a) b) =⟨ ap succ (C (succ a) b) 
  succ (plus b (succ a)) 

Remind

add1 :   
add1 = ℕ-elim  _  ) (succ zero) λ _ n  succ n

t1 : add1 0  1
t1 = refl

double' :   
double' = ℕ-elim  _  ) zero λ _ mn  succ (succ mn)

t2 : double' 0  0
t2 = refl
t3 : double' 1  2
t3 = refl
t4 : double' 2  4
t4 = refl

M-type (the type of non-well-founded, labelled trees) [ag-000J]

{-# OPTIONS --cubical --guardedness --two-level --no-level-universe #-}
module ag-000J where

open import Cubical.Foundations.Prelude
open import Cubical.Data.Sum
open import Cubical.Data.Nat

data 𝟘 : Type where
data 𝟙 : Type where
   : 𝟙
data Maybe (X : Type) : Type where
  none : Maybe X
  some : X  Maybe X
record ℕ∞ : Type where
  coinductive
  field
    pred∞ : Maybe ℕ∞

M-type 是 non-well-formed, labelled trees 的型別,有可能有有限也可能有無限長的 path。 M 是 strictly positive coinductive types 的 universal type。

record M (S : Type) (P : S  Type) : Type where
  coinductive
  field
    shape : S
    pos : P shape  M S P

M S P 代表了 conatural number

module conatural-number where
  open ℕ∞
  open M

  S = 𝟙  𝟙

  P : S  Type
  P (inl _) = 𝟘
  P (inr _) = 𝟙

  N∞ = M S P

  inf : ℕ∞
  pred∞ inf = none
  inf' : ℕ∞
  pred∞ inf' = some inf

  i : N∞
  shape i = inl 
  pos i = λ ()

  i' : N∞
  shape i' = inr 
  pos i' = λ x  i

W-type (the type of well-founded, labelled trees) [ag-000I]

{-# OPTIONS --cubical --guardedness --two-level --no-level-universe #-}
module ag-000I where

open import Cubical.Foundations.Prelude
open import Cubical.Data.Sum
open import Cubical.Data.Nat

data 𝟘 : Type where
data 𝟙 : Type where
   : 𝟙

W-type (due to Martin-Löf) 是 well-founded, labelled trees 的型別。每棵 W-type 的樹都可以有無限多分支,但 path 都是有限長。W 有兩個參數

  1. S : Type 表示 shape
  2. P : S → Type 表示有 (P s)-many positions

W 是 strictly positive inductive types 的 universal type。

data W (S : Type) (P : S  Type) : Type where
  sup-W : (s : S)  (P s  W S P)  W S P

Example: 自然數

module natural-number where
  S = 𝟙  𝟙

  P : S  Type
  P (inl _) = 𝟘 -- therefore, in this direction cannot go further
  P (inr _) = 𝟙 -- this direction has one continuation

  N = W S P

  z : N
  z = sup-W (inl ) λ ()
  s : N  N
  s n = sup-W (inr ) λ   n

  α :   N
  α zero = z
  α (suc n) = s (α n)
  β : N  
  β (sup-W (inl ) x) = zero
  β (sup-W (inr ) f) = suc (β (f ))

  main : (n : )  β (α n)  n
  main zero =
    β (α zero) ≡⟨ refl 
    β z ≡⟨ refl 
    zero 
  main (suc n) = cong suc (main n)

  main⁻¹ : (n : N)  α (β n)  n
  main⁻¹ (sup-W (inl ) f) =
    α (β (sup-W (inl ) f)) ≡⟨ refl 
    z                       ≡⟨ refl 
    sup-W (inl )  ())    ≡⟨ cong (sup-W (inl )) (sym (funExt λ ())) 
    sup-W (inl ) f 
  main⁻¹ (sup-W (inr ) f) =
    α (β (sup-W (inr ) f))           ≡⟨ refl 
    α (suc (β (f )))                 ≡⟨ refl 
    s (α (β (f )))                   ≡⟨ refl 
    sup-W (inr )  _  α (β (f ))) ≡⟨ cong (sup-W (inr )) (funExt t) 
    sup-W (inr ) f 
    where
    t : (x : 𝟙)  α (β (f ))  f x
    t  = main⁻¹ (f )

Simplex category 與 face maps [math-001I]

根據定義,每個 simplicial set SS 都是 simplex category Δ\Delta 的一個 presheaf

Definition. Simplex Category [local-0]

  1. Ob: 每個 object 都是 [n]:={0,,n}[n] := \{0, \dots, n\} 並帶有整數的 order 結構(其中 nn 是非負整數)
  2. Hom: 每個 morphism 都是嚴格遞增函數 Δ([m],[n]):={ϕ:[m][n]x>y    ϕ(x)>ϕ(y)}\Delta([m], [n]) := \{ \phi : [m] \to [n] \mid x > y \implies \phi(x) > \phi(y) \}

這些 morphism 可以用一類特殊的 maps 組出來,叫做 face maps,舉例來說

δi:[n1][n]x{x,x<ix+1,xi\delta_i : [n-1] \to [n] \\ x \mapsto \begin{align*}\begin{cases} x, \quad &x < i \\ x + 1, \quad &x \ge i \\ \end{cases}\end{align*}

這個定義乍一看實在沒辦法理解這在定義什麼,所以要實際看看幾個案例:從 [0][0][1][1] 可以畫成

[1][1][2][2] 可以畫成

事實上,如果畫成 simplex 的幾何表示 Simpn\text{Simp}_n 就更明顯了:

標準 nn -simplex Simpn\text{Simp}_n 可以定義成:

Simpn:={(x0,,xn)[0,1]nixi=1}\text{Simp}_n := \{ (x_0,\dots,x_n) \in [0,1]^n \mid \sum_i x_i = 1 \}

所以 face maps 就是在表示 [n1][n-1] 表示 [n][n] 的哪一個邊界,線的邊界是兩個點,面的邊界是三條線。

沒有內接矩形的平面曲線 [math-001H]

在看過

之後的一點嘗試。

就我的認知,有限多的 singular points 無法破壞這裡的拓墣特性,所以討論非碎形曲線的時候,頂多討論能夠減少內接矩形到什麼程度。所以我真正有興趣的是局部構成沒有內接矩形時,如何重複這個構成還是保持特性。

然而一次跨出這步太超出我目前所知了,所以只能先考慮相關的變形問題:首先,開放的曲線可能沒有內接矩形,比如下圖由兩個有界直線構成(箭頭表示無限延伸方向)

  1. 如果選擇了頂點與其中一邊的點,那麼法向只能再跟此圖交於一點,無法構成矩形。另一邊因為對稱性所以一樣。
  2. 如果選擇一邊的兩點,那法向接觸到另一邊的長度不同,自然也不是矩形。
  3. 如果一邊各自選一點,因為這條邊往任意一邊移動都會改變長度,也沒辦法構成矩形。

但這張圖如果稍作修改,比如加一個直線拉回來變成三角形,就會再次有內接矩形。

另一種值得考慮的基本構造是圓,因為可以說圓的內接矩形有無限多個,但也可以說某種程度上只有一個內接矩形。所以如果考慮取半圓形,另一半則是想辦法破壞對稱性,比如我考慮過的其中一種形狀是

想法就是一直取一半直徑的半圓去填右半部。這個旋轉一下就可以弄成方程組,所以要驗證這個圖形可以嘗試看看方程組中出現矩形要怎麼驗證。

Formal Topology in UF [math-001G]

Reading https://github.com/ayberkt/formal-topology-in-UF and use TypeTopology to understand

Definition. Poset [ag-000F]

{-# OPTIONS --safe --without-K #-}
module ag-000F where

open import MLTT.Spartan
open import UF.Sets
open import UF.SubtypeClassifier

Order is a binary relation .

order-structure : 𝓤 ̇   𝓤  ̇
order-structure {𝓤} A = A  A  Ω 𝓤

A poset A is a pair (A,  ≤ )

  1. x ≤ x for all x ∈ A
  2. x ≤ y and y ≤ z implies x ≤ z for all x, y, z ∈ A
  3. x ≤ y and y ≤ x implies x = y for all x, y ∈ A
poset-axioms : (A : 𝓤 ̇ )  order-structure A  𝓤 ̇
poset-axioms A _≤_ = is-set A
                    × ((x : A)  (x  x) holds)
                    × ((x y z : A)  (x  y) holds  (y  z) holds  (x  z) holds)
                    × ((x y : A)  (x  y) holds  (y  x) holds  x  y)

Poset-structure : 𝓤 ̇   𝓤  ̇
Poset-structure A = Σ _≤_  order-structure A , (poset-axioms A _≤_)

Poset : (𝓤 : Universe)  𝓤  ̇
Poset 𝓤 = Σ A  𝓤 ̇ , Poset-structure A

We can add a helper to extract underlying set

⟨_⟩ : {S : 𝓤 ̇  𝓥 ̇ }  Σ S  𝓤 ̇
 X , s  = X

order-of : (P : Poset 𝓤)   P    P   Ω 𝓤
order-of (X , _≤_ , _) x y = x  y

syntax order-of P x y = x ≤⟨ P  y

posets-are-sets : (P : Poset 𝓤)  is-set  P 
posets-are-sets (X , _≤_ , i , rfl , trans , ir) = i

A hom from a poset to another, is a map that preserves the order

is-hom : (P : Poset 𝓤) (Q : Poset 𝓥)  ( P    Q )  𝓤  𝓥 ̇
is-hom P Q f =  {x y}  (x ≤⟨ P  y) holds  (f x ≤⟨ Q  f y) holds

Identity map is a hom

id-is-hom : (P : Poset 𝓤)  is-hom P P id
id-is-hom P x≤y = x≤y

The composition of homs is a hom

∘-is-hom : (P : Poset 𝓤) (Q : Poset 𝓥) (R : Poset 𝓦)
            (f :  P    Q ) (g :  Q    R )
           is-hom P Q f  is-hom Q R g  is-hom P R (g  f)
∘-is-hom P Q R f g f-is-hom g-is-hom x≤y = g-is-hom (f-is-hom x≤y)

Definition. Frame [ag-000G]

{-# OPTIONS --safe --without-K #-}
module ag-000G where

open import MLTT.Spartan
open import UF.SubtypeClassifier
open import ag-000F

To build frame, we must be able to talk about arbitrary subsets of underlying set X

Fam : 𝓤 ̇   𝓤  ̇
Fam {𝓤} A = Σ I  𝓤 ̇ , (I  A)

module JoinStntax {A : 𝓤 ̇ } (join : Fam A  A) where
  join-of : {I : 𝓤 ̇ }  (I  A)  A
  join-of {I} f = join (I , f)

  syntax join-of  i  e) = ∨⟨ i  e

index : {X : 𝓤 ̇ }  Fam X  𝓤 ̇
index (I , _) = I

_$_ : {X : 𝓤 ̇ }  (F : Fam X)  index F  X
_$_ (_ , f) = f
infixl 40 _$_

_∈_ : {X : 𝓤 ̇ }  X  Fam X  𝓤 ̇
x  (_ , f) = fiber f x

Beside poset axioms, frame axioms are

  1. There is a top element , every element x ≤ ⊤
  2. Binary meet x ∧ y is smaller than x and y, and it is a limit
  3. Each arbitrary subset U has a join U, such that each element of it smaller than the join
  4. Binary meets must distribute over arbitrary joins
frame-axioms : (X : 𝓤 ̇ )  order-structure X  X  (X  X  X)  (Fam X  X)  𝓤  ̇
frame-axioms X _≤_  _∧_  =
  ((x : X)  (x  ) holds)
  × ((x y : X)  ((x  y)  x) holds × ((x  y)  y) holds)
  × ((x y z : X)  (z  x) holds  (z  y) holds  (z  (x  y)) holds)
  × ((U : Fam X)  (x : X)  x  U  (x   U) holds)
  × ((U : Fam X)  (x : X)  ((y : X)  y  U  (y  x) holds)  ( U  x) holds)
  × distrib
  where
  open JoinStntax 
  distrib = ((U : Fam X)  (x : X)  x  ( U)  ∨⟨ i  (x  U $ i))

Frame-structure : 𝓤 ̇   𝓤  ̇
Frame-structure X =
  Σ _≤_  order-structure X ,
  Σ   X ,
  Σ _∧_  (X  X  X) ,
  Σ   (Fam X  X) ,
  (poset-axioms X _≤_) × (frame-axioms X _≤_  _∧_ )

Frame : (𝓤 : Universe)  𝓤  ̇
Frame 𝓤 = Σ X  𝓤 ̇ , Frame-structure X

Properties of frames [ag-000H]

{-# OPTIONS --safe --without-K #-}
module ag-000H where

open import MLTT.Spartan
open import UF.SubtypeClassifier
open import ag-000F
open import ag-000G

In frames, meet is commutative, hence no difference between x ∧ y and y ∧ x

meet-is-comm : (F : Frame 𝓤)  (x y :  F )  𝓤 ̇
meet-is-comm (X , _≤_ ,  , _∧_ , _ ) x y = x  y  y  x

prove-meet-is-comm : (F : Frame 𝓤)  (x y :  F )  meet-is-comm F x y
prove-meet-is-comm (X , _≤_ ,  , _∧_ ,  , (_ , _ , _ , split) , (_ , meet , lim , _ , _) ) x y = split (x  y) (y  x) I II
  where
  I : ((x  y)  (y  x)) holds
  I = lim y x (x  y) (meet x y .pr₂) (meet x y .pr₁)
  II : ((y  x)  (x  y)) holds
  II = lim x y (y  x) (meet y x .pr₂) (meet y x .pr₁)

Matrix representation of complex numbers [math-001F]

To see why

Rθ=[cosθsinθsinθcosθ]R_\theta = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}

behave same as the complex numbers zθ=cosθ+isinθz_\theta = \cos\theta + i\sin\theta is to write RθR_\theta as a linear combination:

Rθ=cosθ[1001]+sinθ[0110]R_\theta = \cos\theta \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} + \sin\theta \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix}

and hence we are wondering, what if we define

1=[1001]andi=[0110]\bold{1} = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} \quad \text{and} \quad \bold{i} = \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix}

and multiplication as matrix multiplication, addition as matrix addition? Are these behave same as complex numbers? Since 1\bold{1} is the identity matrix, we simply get followings

  1. 12=1\bold{1}^2 = \bold{1}
  2. 1i=i1=i\bold{1}\bold{i} = \bold{i}\bold{1} = \bold{i}

we would like to know if i2=1\bold{i}^2 = -\bold{1} :

i2=[0110][0110]=[1001]=[1001]=1\bold{i}^2 = \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix} \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix} = \begin{bmatrix} -1 & 0 \\ 0 & -1 \end{bmatrix} = - \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} = -\bold{1}

as desired. Then we also know linear combinations based on 1\bold{1} and i\bold{i} maps to complex numbers bijectively:

[abba]=a1+bia+bi\begin{bmatrix} a & -b \\ b & a \end{bmatrix} = a\bold{1} + b\bold{i} \simeq a + bi

so now we can see this indeed is a representation of complex numbers.

旋轉矩陣的 product 是給定角度的相加 [ag-000E]

{-# OPTIONS --without-K #-}
module ag-000E where

open import MLTT.Spartan hiding (_+_; _×_)
open import MLTT.Fin

因為不想引入太多其餘結構,把實數跟三角函數的一些性質直接公理化來用

module _ ( : 𝓤₀ ̇) where
  variable
    a b : 
  postulate
    cos :   
    sin :   
    -_  :   
    _+_ :     
    _×_ :     

    tri1 : cos (a + b)  cos a × cos b + - (sin a × sin b)
    tri2 : sin (a + b)  sin a × cos b + sin b × cos a

    ℝ-neg-1 : a × - b  - (a × b)
    ℝ-neg-add : - a + - b  - (a + b)
    ℝ-+-comm : a + b  b + a
    ℝ-×-comm : a × b  b × a
  infixl 60 -_
  infixl 40 _+_
  infixl 50 _×_
  ℝ-neg-2 : - a × b  - (a × b)
  ℝ-neg-2 {a}{b} =
    - a × b   =⟨ ℝ-×-comm 
    b × - a   =⟨ ℝ-neg-1 
    - (b × a) =⟨ ap -_ ℝ-×-comm 
    - (a × b) 

矩陣可以看成由兩個索引指向某其 Field K 的元素的型別

  Matrix : (m n : )  (K : 𝓤 ̇)  𝓤 ̇
  Matrix m n K = Fin m  Fin n  K

只定義 2 × 2 的矩陣乘法

  _⊗_ : Matrix 2 2   Matrix 2 2   Matrix 2 2 
  _⊗_ m n 𝟎 𝟎 = m 𝟎 𝟎 × n 𝟎 𝟎 + m 𝟎 𝟏 × n 𝟏 𝟎
  _⊗_ m n 𝟎 𝟏 = m 𝟎 𝟎 × n 𝟎 𝟏 + m 𝟎 𝟏 × n 𝟏 𝟏
  _⊗_ m n 𝟏 𝟎 = m 𝟏 𝟎 × n 𝟎 𝟎 + m 𝟏 𝟏 × n 𝟏 𝟎
  _⊗_ m n 𝟏 𝟏 = m 𝟏 𝟎 × n 𝟎 𝟏 + m 𝟏 𝟏 × n 𝟏 𝟏
  infixl 30 _⊗_

旋轉矩陣它本人,這個用來表示 Rθ,其中 θ ∈ ℝ 是角度的值

  R :   Matrix 2 2 
  R θ 𝟎 𝟎 = cos θ
  R θ 𝟎 𝟏 = sin θ
  R θ 𝟏 𝟎 = - sin θ
  R θ 𝟏 𝟏 = cos θ

證明目標:RθRφ = Rθ + φ

證明方式就是按 component 去證明等式成立。

  thm : {θ φ : } (i j : Fin 2)  (R θ  R φ) i j  R (θ + φ) i j
  thm {θ}{φ} 𝟎 𝟎 =
    (R θ  R φ) 𝟎 𝟎                   =⟨by-definition⟩
    cos θ × cos φ + sin θ × (- sin φ) =⟨ ap (cos θ × cos φ +_) ℝ-neg-1 
    cos θ × cos φ + - (sin θ × sin φ) =⟨ tri1 ⁻¹ 
    cos (θ + φ)                       =⟨by-definition⟩
    R (θ + φ) 𝟎 𝟎 
  thm {θ}{φ} 𝟎 𝟏 =
    (R θ  R φ) 𝟎 𝟏               =⟨by-definition⟩
    cos θ × sin φ + sin θ × cos φ =⟨ ℝ-+-comm 
    sin θ × cos φ + cos θ × sin φ =⟨ ap (sin θ × cos φ +_) ℝ-×-comm 
    sin θ × cos φ + sin φ × cos θ =⟨ tri2 ⁻¹ 
    sin (θ + φ)                   =⟨by-definition⟩
    R (θ + φ) 𝟎 𝟏 
  thm {θ}{φ} 𝟏 𝟎 =
    (R θ  R φ) 𝟏 𝟎                       =⟨by-definition⟩
    (- sin θ) × cos φ + cos θ × (- sin φ) =⟨ ap (_+ cos θ × - sin φ) ℝ-neg-2 
    - (sin θ × cos φ) + cos θ × (- sin φ) =⟨ ap (- (sin θ × cos φ) +_) ℝ-neg-1 
    - (sin θ × cos φ) + - (cos θ × sin φ) =⟨ ℝ-neg-add 
    - (sin θ × cos φ + cos θ × sin φ)     =⟨ ap -_ (ap (sin θ × cos φ +_) ℝ-×-comm) 
    - (sin θ × cos φ + sin φ × cos θ)     =⟨ ap -_ (tri2 ⁻¹) 
    - sin (θ + φ)                         =⟨by-definition⟩
    R (θ + φ) 𝟏 𝟎 
  thm {θ}{φ} 𝟏 𝟏 =
    (R θ  R φ) 𝟏 𝟏                   =⟨by-definition⟩
    - sin θ × sin φ + cos θ × cos φ   =⟨ ℝ-+-comm 
    cos θ × cos φ + - sin θ × sin φ   =⟨ ap (cos θ × cos φ +_) ℝ-neg-2 
    cos θ × cos φ + - (sin θ × sin φ) =⟨ tri1 ⁻¹ 
    R (θ + φ) 𝟏 𝟏 

  addition : {θ φ : } (i j : Fin 2)  (R θ  R φ) i j  (R φ  R θ) i j
  addition {θ} {φ} i j =
    (R θ  R φ) i j =⟨ thm i j 
    R (θ + φ) i j   =⟨ ap  x  R x i j) ℝ-+-comm 
    R (φ + θ) i j   =⟨ thm i j ⁻¹ 
    (R φ  R θ) i j 

Streams and finite observations [ag-000D]

From Topology via logic
{-# OPTIONS --safe --without-K --guardedness --no-exact-split #-}
module ag-000D where

open import MLTT.Spartan
open import MLTT.List

Stream can be defined as a coinductive record.

record Stream (A : 𝓤 ̇ ) : 𝓤 ̇ where
  coinductive
  constructor _∷_
  field
    head : A
    tail : Stream A

open Stream

For example a stream of all zero.

zeros : Stream 𝟚
head zeros = 
tail zeros = zeros

s ⊨starts o defines a relation that a stream can be realized by a finite observation.

_⊨starts_ : Stream 𝟚  List 𝟚  𝓤₀ ̇
s ⊨starts [] =   
s ⊨starts (x  xs) = (x  head s) × (tail s ⊨starts xs)

For example, the first bit zeros produces is .

first-bit : zeros ⊨starts [  ]
first-bit = refl , refl

Every stream can be realized by “no” observation.

realize-by-no-observation : (s : Stream 𝟚)  s ⊨starts []
realize-by-no-observation s = refl

We can define order relation for these finite observations.

_⊇_ : List 𝟚  List 𝟚  𝓤₀ ̇
_  [] =   
[]  _ = 𝟘
(x  l)  (x₁  l2) = (x  x₁) × (l  l2)

This order has antisymmetric

eq-condition : (l1 l2 : List 𝟚)  l1  l2  l2  l1  l1  l2
eq-condition [] [] p q = refl
eq-condition (x  l1) (y  l2) (ph , pt) (qh , qt) =
  x  l1 =⟨ ap (_∷ l1) ph 
  y  l1 =⟨ ap (y ∷_) (eq-condition l1 l2 pt qt) 
  y  l2 

, in fact total, which means a boring order. The order induces refinement of observations: if a observation is subsequence of another observation that realise the stream, then the stream also be realized by this subsequence.

refine-observation : {s : Stream 𝟚}  (l l2 : List 𝟚)  s ⊨starts l  l  l2  s ⊨starts l2
refine-observation l2 [] _ _ = refl
refine-observation (x  l) (y  l2) (x=head , tail) (x=y , rest) =
  (x=y ⁻¹  x=head) , refine-observation l l2 tail rest

Dependent equality in dependent type theory [ag-000C]

這是從 https://mathstodon.xyz/@MartinEscardo/114751426538568913 學到的技巧。

{-# OPTIONS --safe --without-K #-}
module ag-000C where

open import Agda.Primitive
  renaming (Set to Type; Setω to Typeω)
open import Agda.Builtin.Equality
open import Agda.Builtin.Nat

假設我們有

  1. a type X : Type
  2. a family of types A : X → Type indexed by X

那我們常常會遇到有

  1. x y : X
  2. a : A x
  3. b : A y
  4. p : x = y

是 MLTT 的 identity type,p 是一個 x = y 的證明,這時候如果我們問 a = b 是沒有答案的,因為根據 MLTT,ab 的類型壓根兒就不一樣,這導致問題連寫都寫不下來,那怎麼辦?

方法是定義高階等式(又稱為 dependent equality 或是 PathOver 或是 path transport),在該依賴項等價的情況下把問題變成新的等式來讓 dependent type 語言表達等式

用案例來說就是如果有個 equality 是「類型不同」的(出於依賴項的不透明性,比如這裡 vector length 輸入的 associative 不同)

先定義一些下面案例會用到的輔助程式:

cong : {X Y : Type} (f : X  Y) {x₀ x₁ : X}  x₀  x₁  f x₀  f x₁
cong {X} {Y} f refl = refl

+-assoc :  l m n  (l + m) + n  l + (m + n)
+-assoc zero     m n = refl
+-assoc (suc l) m n = cong suc (+-assoc l m n)

具體案例 vector ++ 的 associativity

data Vec (A : Type) : Nat  Type where
  [] : Vec A 0
  _::_ : ∀{n}  A  Vec A n  Vec A (suc n)
infixl 40 _::_

_++_ : {Y : Type} {l m : Nat}  (xs : Vec Y l)  (ys : Vec Y m)  Vec Y (l + m)
[]        ++ ys = ys
(x :: xs) ++ ys = x :: (xs ++ ys)
infixl 30 _++_

基於 x₀ ≡ x₁ 定義一個更高階的 equality

higher-equality : {X : Type} (A : X  Type) {x₀ x₁ : X}  A x₀  x₀  x₁  A x₁  Type
higher-equality A a₀ refl a₁ = a₀  a₁

但可以根據案例定義比較簡單的版本

_≡[_]_ : {X : Type} {x₀ x₁ : Nat}  Vec X x₀  x₀  x₁  Vec X x₁  Type
a₀ ≡[ refl ] a₁ = a₀  a₁

命題 (xs ++ ys) ++ zs ≡ xs ++ (ys ++ zs) 無法寫下,因為(meta-level 的)型別不同。 所以需要用高階等式描述

cong-cons : {X : Type} {m n : Nat} {xs : Vec X m} {ys : Vec X n}
  (x : X) (p : m  n)
   xs ≡[ p ] ys  x :: xs ≡[ cong suc p ] x :: ys
cong-cons {X}{A} x refl refl = refl

++-assoc : {X : Type} (l m n : Nat)
  (xs : Vec X l) (ys : Vec X m) (zs : Vec X n)
   (xs ++ ys) ++ zs ≡[ +-assoc l m n ] xs ++ (ys ++ zs)
++-assoc {X} zero     m n []       ys zs = refl
++-assoc {X} (suc l) m n (x :: xs) ys zs = I
  where
  I : x :: (xs ++ ys) ++ zs ≡[ cong suc (+-assoc l m n) ] x :: (xs ++ (ys ++ zs))
  I = cong-cons x (+-assoc l m n) (++-assoc l m n xs ys zs)

Second-Order Generalised Algebraic Theories: Signatures and First-Order Semantics [tt-000U]

NOTE about Second-Order Generalised Algebraic Theories: Signatures and First-Order Semantics

這篇文章主要在探討程式語法的表示方式,並展示如何結合代數方法跟 HOAS。作者說他們跟隨 Uemura 把語言定義成 second-order generalised algebraic theories (SOGATs),通過一系列案例揭示 non-substructural languages 可以自然的定義成 SOGATs

  1. SOGAT 的形式定義 (using the syntax of a particular SOGAT)
  2. 定義兩種 SOGAT signatures 到 GAT signatures (signatures for quotient inductive-inductive types) 的轉換,分別基於同時替換(parallel substitution)與單一替換(single substitution)

按代數抽象程度區分 [local-0]

從具體到抽象可以把語法表示看成

語法表示 能力
abstract syntax trees (AST) 把程式原文 parse 後直接儲存用的一系列資料結構
well-scoped syntax tree λx.xλy.y 在這類表示法裡面無法區分,也就是說綁定使用的具體名稱不再重要
intrinsic well-typed terms 這種表示把語法跟 typing relation 整合,所以 non well-typed 的程式甚至無法表達
well-typed, quotiented by the conversion relation (GAT) 加上更多 well-formness relation 的推廣代數理論,下面介紹
SOGAT GAT 推到 second-order,下面介紹

在 well-typed terms 上再加上 conversion relation 就變成廣義代數理論(generalised algebraic theory,簡稱 GAT),GAT 用來處理 dependently typed languages 時特別方便,因為 typing 依賴了 conversion relation。在 GAT 上只能定義保留了 conversion relation 的函數,因此連印出函數都無法定義,但 normalisation(正規化)、typechecking(型別檢查)跟 parametricity 這些函數保留 conversion 因此可定義。

對任何 GAT 來說,syntax 可以定義成 initial model,因此沒有區分語法跟語意的必要,某種意義上來說,一個程式語言就是一個 GAT。

HOAS 方法:按對 bindings/variables 的處理方式區分 [local-1]

HOAS 觀點關心 bindings 跟 variables 的處理方式,比如 De Bruijn indices 使名稱選擇與語意無關,但這也表示替換必須是語法的一部分,舉例來說 form of a category with families。

Logical frameworks 跟 higher-order abstract syntax (HOAS) 提供了另一種實現 bindings 跟 variables 的方式:使用 metatheory 的函數空間。 舉例來說,pure lambda calculus 的 lambda operation 的 type 是二階函數空間 (Tm → Tm) → Tm。這在理論上的解釋是 type-theoretic internal language of presheaves over the category of contexts and syntactic substitutions,在這個 topos 的 internal language 裡,lambda 的類型就長那樣。

Internal language 的觀點可以用來定義程式語言是什麼:有綁定的語言不是一個 GAT,而是一個二階的廣義代數理論(second-order generalised algebraic theory,簡稱 SOGAT),這種理論可以有二階操作(但不是任意高階)。

Untyped 或是 Simply typed 都有被定義成二階理論過,但 Uemura 是第一個用 SOGATs 定義有綁定的語言的人。這個理論真的很厲害,一個語言的 SOGAT 定義比 well-typed quotiented 定義還要抽象:SOGAT 連 contexts 跟 substitutions 都不用提到,這些會自動生成。但這不是一個 well-behaved 的代數理論,比如 second-order models 之間沒有有意義的 homomorphism。

為了描述 SOGAT 的一階模型、homomorphisms 或是 syntax 的 notion,作者把它轉成一個 GAT。這個過程中引入新的 sorts 給 contexts 跟 substitutions,然後把每個操作都用其 context index,second-order 的函數空間也由 context indexing 轉換成 first-order。因此得到一個有 some “correctness by construction” properties 的 GAT,比如每個操作都自動保留替換。這對複雜的理論來說,如果不是從 SOGAT 出發而是直接用其 GAT 表示,那這種屬性並不 trivial。

Cubical type theory 跟有 internal parametricity 的 type theory 都可以定義成 SOGATs,這些方法已經用來證明型別論的屬性。

Substructural (像是 linear or modal) type theories 無法用這篇論文說的方法用 SOGATs 定義,但有時候 presheaves over a substructural theory 提供的 substructural internal language 可以用來描述理論,像是 multi-modal type theory。

簡單的代數理論可以用 signatures 和方程式來表示,也可以 presentation independently 為 Lawvere theories。

GATs 的 syntactic signatures 可以用 preterms 跟 well-formedness relations 定義,也可以 presentation-independent 為 contextual categories 或 categories with families (CwFs) 或 clans。

GATs 的 theory of signatures (ToS) 方法落在 syntactic 跟 presentation-independent 方法中間:signatures 用某個 GAT 語法定義,這是一種設計來專用於定義簽名的類型理論。簽名跟我們在 Agda 裡寫下的 inductive datatype 定義一模一樣:A list (telescope) of the curried types of sorts and constructors。ToS 裡一個 signature 是一個理論的具體表示,但在 well-typed quotiented syntax 這層抽象上給出。這讓我們得到優雅的語意構造,又還是能用 signatures 工作。

SOGATs 同樣可以定義成 syntactically 或 presentation-independently(用 representable map categories 或是 CwFs with locally representable types)

這篇論文貢獻了 ToS 風格的 SOGATs 定義。SOGAT signatures 的理論本身也是 SOGAT,所以這個理論可以描述自己。

避免了循環論證,因為我們首先將 SOGAT 簽名定義為 GAT,從而引導 SOGAT 簽名理論,而 GAT 簽名理論(即 GAT 的語法)本身可以使用 Church 編碼進行引導。

Contributions [local-2]

The main takeaway of this paper is that structural languages are SOGATs.

We justify this claim through several examples. Our technical contributions are the following:

  • The theory of SOGAT signatures (ToS+), a domain-specific type theory in which every closed type is a SOGAT signature. As it is a structural type theory, it can be defined as a SOGAT itself. Signatures can be formalised in ToS+ without encoding overhead.
  • A translation from SOGAT signatures to GAT signatures based on a parallel substitution calculus. Thus, for every SOGAT, we obtain all of the semantics of GATs: a category of models with an initial object, (co)free models, notions of displayed models and sections, the fact that induction is equivalent to initiality, and so on. The GAT descriptions that we obtain are readable, do not contain occurrences of Yoneda as in usual presheaf function spaces. Correctness of the translation is showed by proving that internally to presheaves over a model of the GAT, a second-order model of the SOGAT is available.
  • We define an alternative translation producing a single substitution calculus.

作者開始展示如何把各種 logic 或程式語言定義成代數理論。這邊我寫下每個代數理論的 agda 版本

Schönfinkel's combinator calculus (Algebraic Theories) [ag-0003]

{-# OPTIONS --safe --without-K #-}
module ag-0003 where

open import MLTT.Spartan

Combinator calculus 可以看成一個代數理論,這時候它有

  1. 一個 sort of terms
  2. 一個 binary
  3. 兩個 nullary operations
  4. 兩個等式
record combinator-calculus : 𝓤₁ ̇ where
  field
    Tm : 𝓤₀ ̇

    _·_ : Tm  Tm  Tm

    K : Tm
    S : Tm

     : {u f : Tm}  K · u · f  u
     : {f g u : Tm}  S · f · g · u  f · u · (g · u)

  infixl 30 _·_
  1. 從這個符號可以明顯看出代數/模型的概念
  2. Combinator calculus 的 quotiented syntax 是初始模型,它總是存在。
  3. Notions of homomorphism, displayed/dependent model, induction, products and coproducts of models, free models, and so on, are derivable from the signature, as described in any book on universal algebra
  4. Algebraic Theory 的 initial algebra 叫做 quotient inductive type

其他 single-sorted algebraic theories 著名案例:

  1. 邏輯:經典(或直覺主義)命題邏輯,定義為布林代數(或海廷代數)理論
  2. 代數:monoids、群、環、lattices 等等

Generalised algebraic theories (GATs) [local-3]

Generalised algebraic theories (GATs) 的 sort 可以 indexed by 其他 sort。案例有 typed combinator calculus、propositional logic with Hilbert-style proof theory、theories of graphs、preorders、categories 等等

Typed combinator calculus (Generalised algebraic theories) [ag-0004]

module ag-0004 where

open import MLTT.Spartan
record typed-combinator-calculus : 𝓤₁ ̇ where
  field

給 types 的 sort

    Ty : 𝓤₀ ̇

每個 type 對應(index)一個 term 用的 sort

    Tm : Ty  𝓤₀ ̇

    ι : Ty
    _⇒_ : Ty  Ty  Ty

    _·_ : {A B : Ty}  Tm (A  B)  Tm A  Tm B

    K : {A B : Ty}  Tm (A  B  A)
    S : {A B C : Ty}  Tm ((A  B  C)  (A  B)  A  C)

     : {A B : Ty} {u : Tm A} {f : Tm B}  K · u · f  u
     : {A B C : Ty}
      {f : Tm (A  B  C)}
      {g : Tm (A  B)}
      {u : Tm A}
       S · f · g · u  f · u · (g · u)

  infixl 40 _·_
  infixr 30 _⇒_

上述 Algebraic Theory 的通用代數特徵可以推廣到 GAT。具體來說,每個 GAT 都具有由 quotient inductive-inductive type 給出的語法,我們有 free 模型和 cofree 模型。

Second-order algebraic theories (SOATs) [local-4]

如果一個語言有變數或是綁定,就被定義成一個二階理論。

Lambda calculus (Second-order algebraic theories) [ag-0005]

module ag-0005 where

open import MLTT.Spartan
record lambda-calculus : 𝓤₁ ̇ where
  field
    Tm : 𝓤₀ ̇

lam 的(metatheory)型別不是一階的(not strictly positive)

    lam : (Tm  Tm)  Tm
    _·_ : Tm  Tm  Tm

    β : {f : Tm  Tm} {u : Tm}  lam f · u  f u

  infixl 30 _·_

By the syntax of lambda calculus, we mean the syntax for the GAT of Definition 4. However, we still prefer to define lambda calculus as a SOGAT: it is a shorter definition, does not include boilerplate, and ensures that once translated to its first-order version, all operations respect substitution by construction.

此外,我們可以像邏輯框架一樣,使用二階表示來進行程式設計。這意味著,使用二階表示,我們可以定義 derivable operation 並證明 derivable 等式,而不是像證明 admissible 那樣需要歸納法。

舉例來說 Y combinator 是 derivable operation。可以證明它是 fixpoint combinator:

  Y : Tm
  Y = lam  f  (lam  x  f · (x · x))) · (lam  x  f · (x · x))))

  Y-is-fixed-point : {f : Tm}  Y · f  f · (Y · f)
  Y-is-fixed-point {f} =
    Y · f                                                                 =⟨by-definition⟩
    lam  f  (lam  x  f · (x · x))) · (lam  x  f · (x · x)))) · f =⟨ β 
     f  (lam  x  f · (x · x))) · (lam  x  f · (x · x)))) f       =⟨ refl 
    (lam  x  f · (x · x))) · (lam  x  f · (x · x)))                 =⟨ β 
    f · ((lam  x  f · (x · x))) · (lam  x  f · (x · x))))           =⟨ refl 
    f · ((λ f  (lam  x  f · (x · x))) · (lam  x  f · (x · x)))) f) =⟨ ap (f ·_) (β ⁻¹) 
    f · (Y · f) 

這種推理對任何 second-order model 都有效,而且任何 first-order model 都可以在 internal language of presheaves over first-order model 裡被升級成 second-order model。

但注意沒有可用的 SOAT models MMNN 之間的同態概念。為了討論同態或語法,我們將 SOAT 轉換為一階 GAT:加上上下文、替換、索引 Tm 以及所有基於上下文的操作,然後 lam 就變成了一個以擴展上下文中的項作為輸入的一階函數。轉換出來的 GAT 就是

Lambda calculus (GAT) [ag-0006]

module ag-0006 where

open import MLTT.Spartan hiding (_∘_; id)

作者這邊開始解釋從二階理論得出一階理論(GAT)的標準過程

record first-order-lambda-calculus : 𝓤₁ ̇  where
  field
    Con : 𝓤₀ ̇
    Sub : Con  Con  𝓤₀ ̇

有 terminal object 的 category

    _∘_ : {Δ Γ Θ : Con}  Sub Δ Γ  Sub Θ Δ  Sub Θ Γ
    assoc : {A B C D : Con} {γ : Sub C D} {δ : Sub B C} {θ : Sub A B}
       (γ  δ)  θ  γ  (δ  θ)
    id : {Γ : Con}  Sub Γ Γ
    id-left : {A B : Con} {γ : Sub A B}  id  γ  γ
    id-right : {A B : Con} {γ : Sub A B}  γ  id  γ
    -- empty context: zero
     : Con
    ε : {Γ : Con}  Sub Γ 
    -- terminal
    ◇η : {Γ : Con}  (σ : Sub Γ )  σ  ε

sort Tm 現在 indexed by Con 且有一個 instantiation operation,這個 operation 是 functorial ([◦], [id]).

    Tm : Con  𝓤₀ ̇
    _[_] : {Γ Δ : Con}  Tm Γ  Sub Δ Γ  Tm Δ
    [id] : {Γ : Con} {t : Tm Γ}  t [ id ]  t
    [∘] : {Θ Γ Δ : Con} {t : Tm Γ} {γ : Sub Δ Γ} {δ : Sub Θ Δ}  t [ γ  δ ]  t [ γ ] [ δ ]

context extension 讓 contexts 是 natural number algebra

    _▹ : Con  Con

substitutions 是一串 terms,由組成元件表達

    _,,_ : {Δ Γ : Con}  Sub Δ Γ  Tm Δ  Sub Δ (Γ )

有了 contexts 跟 substitutions,變數就可以定義成 De Bruijn indices:

  1. 0 = q
  2. 1 = q[p]
  3. 2 = q[p] [p],以此類推
    p : {Γ : Con}  Sub (Γ ) Γ
    q : {Γ : Con}  Tm (Γ )

應該滿足的等式規則

    ▹β₁ : {Δ Γ : Con} {γ : Sub Δ Γ} {t : Tm Δ}
       p  (γ ,, t)  γ
    ▹β₂ : {Δ Γ : Con} {γ : Sub Δ Γ} {t : Tm Δ}
       q [ γ ,, t ]  t
    ▹η : {Δ Γ : Con} {σ : Sub Δ (Γ )}  σ  (p  σ ,, q [ σ ])

    lam : {Γ : Con}  Tm (Γ )  Tm Γ
    lam[] : {Δ Γ : Con} {γ : Sub Δ Γ} {t : Tm (Γ )}  (lam t)[ γ ]  lam (t [ γ  p ,, q ])

    _·_ : {Γ : Con}  Tm Γ  Tm Γ  Tm Γ
    ·[] : {Δ Γ : Con} {γ : Sub Δ Γ} {t u : Tm Γ}  (t · u)[ γ ]  t [ γ ] · (u [ γ ])

    β : {Δ Γ : Con} {γ : Sub Δ Γ} {t : Tm (Γ )} {u : Tm Γ}
       lam t · u  t [ id ,, u ]

  infixl 40 _∘_
  infixl 30 _,,_
  infixl 40 _·_
  infixl 50 _[_]

Second-order generalised algebraic theories (SOGATs) [local-5]

SOGATs combine the two previous classes: sorts can be indexed over previous sorts and second-order operations are allowed.

Simply typed lambda calculus [ag-0007]

module ag-0007 where

open import MLTT.Spartan
open import UF.Equiv
record simply-typed-lambda-calculus : 𝓤₁ ̇  where
  field
    Ty : 𝓤₀ ̇
    _⇒_ : Ty  Ty  Ty

generalised 的部分是因為 index Tm by Ty

    Tm : Ty  𝓤₀ ̇

綁定的部分

    lam : {A B : Ty}  (Tm A  Tm B)  Tm (A  B)
    _·_ : {A B : Ty}  Tm (A  B)  (Tm A  Tm B)

    stlc-cong : {A B : Ty}  Tm (A  B)  (Tm A  Tm B)

一樣參照 first-order lambda calculus 的過程,加上 contexts、加上 substitutions,相應的 first-order 等式跟改寫,就會得到 simply-typed-lambda-calculus 的 GAT。

Minimal intuitionistic first-order logic (SOGAT) [ag-0008]

module ag-0008 where

open import MLTT.Spartan
open import UF.Subsingletons
record minimal-intuitionistic-first-order-logic : 𝓤₁ ̇  where
  field
    For : 𝓤₀ ̇
    Tm : 𝓤₀ ̇
    _⊃_ : For  For  For
    All : (Tm  For)  For
    Eq : Tm  Tm  For

    Pf : For  𝓤₀ ̇
    Pf-is-prop : (A : For)  is-prop (Pf A)

    intro⊃ : {A B : For}  (Pf A  Pf B)  Pf (A  B)
    elim⊃ : {A B : For}  Pf (A  B)  (Pf A  Pf B)

    intro∀ : {A : Tm  For}  ((𝑡 : Tm)  Pf (A 𝑡))  Pf (All A)
    elim∀ : {A : Tm  For}  Pf (All A)  ((𝑡 : Tm)  Pf (A 𝑡))

    introEq : {t : Tm}  Pf (Eq t t)
    elimEq : {t t' : Tm}  (A : Tm  For)  Pf (Eq t t')  Pf (A t)  Pf (A t')

一樣參照 first-order lambda calculus 的過程,加上 contexts、加上 substitutions,相應的 first-order 等式跟改寫。

Polymorphic lambda calculus (SOGAT) [ag-0009]

module ag-0009 where

open import MLTT.Spartan
record polymorphic-lambda-calculus : 𝓤₁ ̇  where
  field
    Ty : 𝓤₀ ̇
    Tm : Ty  𝓤₀ ̇
    _⇒_ : Ty  Ty  Ty
    lam : {𝐴 𝐵 : Ty}  (Tm 𝐴  Tm 𝐵)  Tm (𝐴  𝐵)
    _·_ : {𝐴 𝐵 : Ty}  Tm (𝐴  𝐵)  (Tm 𝐴  Tm 𝐵)
    All : (Ty  Ty)  Ty
    Lam : {𝐴 : Ty  Ty}  ((𝑋 : Ty)  Tm (𝐴 𝑋))  Tm (All 𝐴)
    _•_ : {𝐴 : Ty  Ty}  Tm (All 𝐴)  ((𝑋 : Ty)  Tm (𝐴 𝑋))

一樣參照 first-order lambda calculus 的過程,加上 contexts、加上 substitutions,相應的 first-order 等式跟改寫。

System Fω (SOGAT) [ag-000A]

module ag-000A where

open import MLTT.Spartan
record system-F-ω : 𝓤₁ ̇  where
  field
     : 𝓤₀ ̇
    Ty :   𝓤₀ ̇

    _⇛_ :     
    LAM : {K L : }  (Ty K  Ty L)  Ty (K  L)
    _●_ : {K L : }  Ty (K  L)  (Ty K  Ty L)

     : 
    Tm : Ty   𝓤₀ ̇

    All : {K : }  (Ty K  Ty )  Ty 
    Lam : {K : }{A : Ty K  Ty }  ((X : Ty K)  Tm (A X))  Tm (All A)
    _•_ : {K : }{A : Ty K  Ty }  Tm (All A)  ((X : Ty K)  Tm (A X))

    _⇒_ : Ty   Ty   Ty 
    lam : {A B : Ty }  (Tm A  Tm B)  Tm (A  B)
    _·_ : {A B : Ty }  Tm (A  B)  (Tm A  Tm B)

System Fω 轉換後有

  1. 3 個 operations 綁定 Ty-variables
  2. 1 個 operation 綁定 term-variable

Minimal Martin-Löf type theory (SOGAT) [ag-000B]

module ag-000B where

open import MLTT.Spartan
open import MLTT.NaturalNumbers
variable
  𝑖 : 

record minimal-martin-lof-type-theory : 𝓤₁ ̇  where
  field
    Ty :   𝓤₀ ̇
    U : (𝑖 : )  Ty (succ 𝑖)
    Tm : Ty 𝑖  𝓤₀ ̇

    c : Ty 𝑖  Tm (U 𝑖)
    El : Tm (U 𝑖)  Ty 𝑖

    PI : (A : Ty 𝑖)  (Tm A  Ty 𝑖)  Ty 𝑖
    Lift : Ty 𝑖  Ty (succ 𝑖)

    lam : {𝐴 : Ty 𝑖}{𝐵 : Tm 𝐴  Ty 𝑖}  ((𝑎 : Tm 𝐴)  Tm (𝐵 𝑎))  Tm (PI 𝐴 𝐵)
    _·_ : {𝐴 : Ty 𝑖}{𝐵 : Tm 𝐴  Ty 𝑖}  Tm (PI 𝐴 𝐵)  ((𝑎 : Tm 𝐴)  Tm (𝐵 𝑎))

    mk : {𝐴 : Ty 𝑖}  Tm 𝐴  Tm (Lift 𝐴)
    un : {𝐴 : Ty 𝑖}  Tm (Lift 𝐴)  Tm 𝐴

這個理論的對應 GAT 得到一個具有族的範疇(CwF),更準確地說,是一個具有 N 個 families 的範疇,這些族配備了 familywise Π-types、宇宙以及族之間的一步向上提升。 這些類型是 Ty : Con → N → SetTm : (Γ : Con) → Ty Γ 𝑖 → Set,其中 𝑖 論證隱含在後者中。

後面幾節

  1. 第三節 Theories of signatures as SOGATs,開始把 signatures 理論也寫成 SOGAT 來討論
  2. 第四節 Naive semantics of SOGAT signatures,討論 for any SOGAT signature 的 a notion of first-order model.
  3. 第五節 Direct semantics of SOGAT signatures,用一個更小心版本的 presheaf model 定義 first-order models of SOGATs
  4. 第六節 GAT signature semantics of SOGAT signatures,把 SOGAT signatures 轉成 GAT signatures 的方法

Intrinsically typed term [ag-0002]

{-# OPTIONS --safe --without-K #-}
module ag-0002 where

open import MLTT.Spartan hiding (Type)
open import MLTT.List

Type 在 STLC 還只需要是一個簡單的 formation

data Type : 𝓤₀  ̇ where
  bool : Type
  _⇒_ : Type  Type  Type
infixr 50 _⇒_

variable
  S T : Type

Context 通常會自訂,比如 MLTT 需要兩種綁定時自訂就會更方便一些

Ctx = List Type
_▷_ : Ctx  Type  Ctx
Γ  T = T  Γ
infix 40 _▷_

variable Γ : Ctx

Intrinsically-scoped de Brujin indices

基本上變數都長這樣

data _∋_ : Ctx  Type  𝓤₀  ̇ where
  here  : Γ  T  T
  there : Γ  T  Γ  S  T
infix 20 _∋_

variable x : Γ  T

Intrinsically-typed terms

確保 term 是類型良好的一種方式就是從一開始就跟 context 一起構造,讓 terms 必須是 well-typed

data _⊢_ : Ctx  Type  𝓤₀  ̇ where
  true false : Γ  bool
  var : Γ  T  Γ  T
  lam : Γ  S  T  Γ  S  T
  _·_ : Γ  S  T  Γ  S  Γ  T
  if_then_else_ : Γ  bool  Γ  T  Γ  T  Γ  T
infix 30 _⊢_

Video. Why You Can't Bring Checkerboards to Math Exams [math-001E]

A cool way to do multiply, divide and root!

Definition. Diffeological space [math-001D]

A diffeological space is a pair (X,DX)(X, \mathcal{D}_X) consists of a given set XX and a diffeology DX\mathcal{D}_X consists of a collection of parameterizations p:UXp : U \to X satisfying the following conditions:

  1. All parameterizations with domain R0\mathbb{R}^0 belong to DX\mathcal{D}_X , namely all the points of XX
  2. If p:VXp : V \to X is a parameterization, and f:UVf : U \to V is a smooth map between cartesian spaces, then pfp \circ f belongs to DX\mathcal{D}_X
  3. If p:UXp : U \to X is a parameterization, an open cover (Ui)iI(U_i)_{i\in I} of UU that each restriction pUiDXp \mid_{U_i} \in \mathcal{D}_X , then pDXp \in \mathcal{D}_X

If DX\mathcal{D}_X is a diffeology, then we call a parameterization pp that belongs to it a plot.

Lemma. Presheaves are colimits of representables [math-001B]

The presheaf XA^X \in\widehat{A} is the colimit of the functor φX:=hπX\varphi_X := h \circ \pi_X ,

πX:XAπX(a,s):=a\pi_X : \int X \to A \\ \pi_X(a, s) := a

where hh is the yoneda embedding, X\int X is the category of elements of XX . For morphism φX(u):=u\varphi_X(u) := u .

Proof. [local-0]

We first show that XX is a cocone, for each object (a,s)X(a, s) \in \int X , there is a morphism

hasX h_a \xrightarrow{s} X
here abuse notation that sXas \in X_a has a corresponding haXh_a \to X in A^\widehat{A} because the Yoneda lemma.

and for each (a,s)u(b,t)(a,s)\xrightarrow{u}(b,t) , the following diagram commutes

figure tex1633

hence XX is a cocone. Given any other cocone YY , which means a collection of sections

fs:haYf_s : h_a \to Y

where u(ft)=fsu^*(f_t) = f_s for each u:(a,s)(b,t)u : (a,s) \to (b,t) by definition. The point is if we define a natural transformation

ηa:XaYaηa(s):=fs\eta_a : X_a \to Y_a \\ \eta_a(s) := f_s

naturality follows because X(u)(t)=sX(u)(t) = s implies Y(u)(ft)=fsY(u)(f_t) = f_s . It is clear that η\eta is the unique natural transformation under φX\varphi_X , showing that XX is the colimit.

Presheaves, Yoneda embedding, and Yoneda lemma [math-001A]

Definition. Presheaf [local-0]

Let AA be a category. A presheaf over AA is a functor of the form

X:AopSetX : A^{op} \to Set

For each object aAa \in A , we will denote by

Xa:=X(a)SetX_a := X(a) \in Set

the evaluation of XX at aa . The set XaX_a will sometimes be called the fibre of the presheaf XX at aa , and the elements of XaX_a thus deserve the name of sections of XX over aa .

For morphism auba \xrightarrow{u} b , the induced map from XbXaX_b \to X_a denotes u:=X(u)u^* := X(u) .

The category of presheaves over AA denotes A^\widehat{A} .

Definition. Yoneda embedding [local-1]

h:AA^ha:=HomA(,a)h : A \to \widehat{A} \\ h_a := \text{Hom}_A(-,a)

Lemma. Yoneda [local-3]

For any presheaf XX over AA , there is a natural bijection of the form

θ:HomA^(ha,X)Xaθ(α):=αa(1a)\begin{aligned} &\theta &&: \text{Hom}_{\widehat{A}}(h_a,X) \xrightarrow{\sim} X_a \\ &\theta(\alpha) &&:= \alpha_a(1_a) \end{aligned}

Proof. [local-2]

We first define inverse map τ:XaHomA^(ha,X)\tau : X_a \to \text{Hom}_{\widehat{A}}(h_a,X) , given a section ss of XX over aa , i.e. sXas \in X_a , we have

τ(s)b:HomA(b,a)Xbτ(s)b(f):=f(s)\begin{aligned} \tau(s)_b &: \text{Hom}_A(b,a) \to X_b \\ \tau(s)_b(f) &:= f^*(s) \end{aligned}

for each morphism bfab \xrightarrow{f} a . This indeed defines a morphism haτ(s)Xh_a \xrightarrow{\tau(s)} X in A^\widehat{A} .

Now check θ\theta and τ\tau indeed are inverse of each other. First: given sXas \in X_a , we have

θ(τ(s))=τ(s)a(1a)=1a(s)=X(1a)(s)=s\theta(\tau(s)) = \tau(s)_a(1_a) = 1_a^*(s) = X(1_a)(s) = s

Another direction: given α:haX\alpha : h_a \to X , we have

τ(θ(α))b(f)=τ(αa(1a))b(f)=f(αa(1a))by definition of τ=X(f)(αa(1a))=αb(HomA(f,a)(1a))by naturality=αb(1af)=αb(f)\begin{aligned} \tau(\theta(\alpha))_b(f) &= \tau(\alpha_a(1_a))_b(f) \\ &= f^*(\alpha_a(1_a)) \quad \text{by definition of } \tau \\ &= X(f)(\alpha_a(1_a)) \\ &= \alpha_b(\text{Hom}_A(f, a)(1_a)) \quad \text{by naturality} \\ &= \alpha_b(1_a \circ f) \\ &= \alpha_b(f) \end{aligned}

for each f:baf : b \to a . Naturality is obvious, hence they form a natural bijection.

隱式編程:coherence 與 stability 屬性 [tt-000T]

這篇是 COCHIS: Stable and coherent implicits 的筆記

隱式編程機制是指,使用型別指導的推導能力,在使用者不提供完整資訊的情況下給出程式語意的技術。比如 Haskell 的 type class、Rust 的 trait 等。合成的過程叫做 resolution。

Haskell 的 type class 的一個重要特徵是給定的類型只會有一個 instance 符合。coherence 在這個意義下指的是,給出的程式語意是唯一的,也就是說對某段合法程式碼,不會合成出超過一個語意。

比如説 Haskell 會拒絕 show (read "3") == "3" 這段程式碼,因為根據 type class resolution 有很多種可能性(show : α -> Stringread : String -> α

  1. 選了 α := Float 那結果是 False,因為 show (read "3") == "3.0"
  2. 選了 α := Int 那結果是 True
  3. 選了 α := Char 那結果是 True

所以這種會導致有多種語意出現的程式就需要被拒絕。

Haskell 的 overlapping instances 技術是對上述問題的一種推廣(使我們可以接受更多程式),比如說

class Trans α where trans :: α → α
instance Trans α where trans x = x
instance Trans Int where trans x = x + 1

對於程式 trans 3 應該要決定出什麼結果?Overlapping 的決定是,因為 α := Int 比沒有決定更特定,因此選 instance Trans Int。然而,也有 overlapping 策略也無法決定的情況,比如下面比較刻意的

class C α β where
  m :: α → β → Bool
instance C Bool α where
  mx y = x
instance C α Bool where
  mx y = y

對程式 m True False 兩個 instances 都一樣特定,沒辦法決定,因此這段程式碼也必須被拒絕。

Stability 是跟 coherence 高度相關的屬性。不正式的說,stable 是指 type variables 的實例化與否不影響 resolution 的結果。但 overlapping 技術會影響這個結果,比如

bad :: α → α
bad x = trans x

就是一個 unstable 的定義。如果寫成 Trans α => α → α 就不一樣了,這表示 α 交由呼叫 bad 的地方決定,但這裡則是必須在定義處馬上決定,如果 Haskell 接受這段定義,那可能會選擇第一個 instance Trans,導致 bad 33trans 34。雖然 bad x := trans x 是定義等價。

也可以參考 https://blog.ezyang.com/2014/07/type-classes-confluence-coherence-global-uniqueness/ 的案例跟論點。

Definition. 流形上的微分式 [math-0019]

(xi)(x^i) 為 differentiable manifold MnM^n 的局部座標,可以把微分式定義為 1,.n\partial_1, \dots. \partial_n 的對偶基底,記為 dx1,,dxndx^1, \dots, dx^n 。亦即

dxi(i)=δjidx^i (\partial_i) = \delta^i_j

一階微分式的整體記為 Ω(M)\Omega(M)

任何給定的微分式 ω\omega 可以寫成向量形式 ω=aidxi\omega = a_i dx^i

對一個 fC(M)f \in C^\infty(M) ,什麼是 dfdf ?用向量微積分的觀點,是函數 ff 的一階變化量

df(X)=DXf:=limt0f(p+tX)f(p)tdf(X) = D_X f := \lim_{t\to0} \frac{f(p + tX) - f(p)}{t}

因此其類型是 df:TpMRdf : T_pM \to \R 的線性函數,通過空間對偶可知這就是 TpMT_p^*M 的元素。

性質一

df=fxidxidf = \frac{\partial f}{\partial x^i} dx^i

證明如下:設 df=bjdxjdf = b_j dx^j

df(i)=bjdxj(i)=bjδij=bidf(\partial_i) = b_j dx^j(\partial_i) = b_j \delta^j_i = b_i

又有

df(i)=Dif=fxidf(\partial_i) = D_{\partial_i} f = \frac{\partial f}{\partial x^i}

因此

df=fxidxidf = \frac{\partial f}{\partial x^i} dx^i
然而要注意到,並不是每個 ωΩ(M)\omega \in \Omega(M) 都可以表示成某個 ff 的微分 dfdf

性質二

而且,對於每個具體的 iixix^i 顯然是一種 C(M)C^\infty(M) 的特例,因此也可以定義

dxi(X):=DXxidx^i(X) := D_X x^i

驗證

DXxi=DXjjxi=XjDjxi=Xjxixj=Xi\begin{aligned} D_X x^i &= D_{X^j \partial_j} x^i \\ &= X^j D_{\partial_j} x^i \\ &= X^j \frac{\partial x^i}{\partial x^j} \\ &= X^i \end{aligned}

可見如此定義的 dxidx^i 跟取對偶基底的結果相同。

Definition. 切向量場沿曲線平行 (parallel) [math-0018]

γ(t)\gamma(t) 為一 CC^\infty -affine manifold (Mn,)(M^n, \nabla) 上一 CC^\infty -曲線。ZZγ\gamma 上有意義的切向量場(i.e. 對所有 tt ,可以對 tt 可微的指定一個 ZTγ(t)MZ\in T_{\gamma(t)} M

dγdtZ=0\nabla_{\frac{d\gamma}{dt}}Z=0

ZZ 沿 γ\gamma 為平行。

若適當的局部座標為 (xi)(x^i) ,則

γ(t)=(xi(t))Z=Zii\gamma(t) = (x^i(t)) \\ Z=Z^i\partial_i

X=dγdtX = \frac{d\gamma}{dt} (即速度向量),則

dγdtf=dfγdt=df(xi(t))dt=fxidxidt=dxidtif\frac{d\gamma}{dt} f = \frac{d f\circ\gamma}{dt} = \frac{d f(x^i(t))}{dt} = \frac{\partial f}{\partial x^i} \frac{d x^i}{dt} = \frac{d x^i}{dt} \partial_i f

因此

X=dxidtiX = \frac{d x^i}{dt} \partial_i

因此

dγdtZ=X(Zjj)=dxidti(Zjj)=dxidt((iZj)j+Zjij)by Leibniz=dxidt((iZj)j+ZkΓikjj)by Christoffel=dxidt((iZj)+ZkΓikj)j=(dxidt(iZj)+dxidtZkΓikj)j=(ddtZj+dxidtZkΓikj)j=(dZjdt+dxidtΓikjZk)j\begin{aligned} \nabla_{\frac{d\gamma}{dt}}Z &= \nabla_{X} (Z^j \partial_j) = \frac{d x^i}{dt} \nabla_{\partial_i}(Z^j \partial_j) \\ &= \frac{d x^i}{dt} ((\partial_i Z^j) \partial_j + Z^j \nabla_{\partial_i}\partial_j) \quad \text{by Leibniz} \\ &= \frac{d x^i}{dt} ((\partial_i Z^j) \partial_j + Z^k \Gamma^j_{ik} \partial_j) \quad \text{by Christoffel} \\ &= \frac{d x^i}{dt} ((\partial_i Z^j) + Z^k \Gamma^j_{ik}) \partial_j \\ &= (\frac{d x^i}{dt}(\partial_i Z^j) + \frac{d x^i}{dt}Z^k \Gamma^j_{ik}) \partial_j \\ &= (\frac{d}{dt}Z^j + \frac{d x^i}{dt}Z^k \Gamma^j_{ik}) \partial_j \\ &= (\frac{d Z^j}{dt} + \frac{d x^i}{dt}\Gamma^j_{ik} Z^k) \partial_j \end{aligned}

ZZ 沿 γ\gamma 平行的充要條件為滿足一階線性方程組

dZjdt+dxidtΓikjZk,j=1,,n\frac{d Z^j}{dt} + \frac{d x^i}{dt}\Gamma^j_{ik} Z^k, \forall j = 1,\dots,n

測地線方程組推導 [math-0017]

γ(t)\gamma(t) 為一 CC^\infty -affine manifold (Mn,)(M^n, \nabla) 上一 CC^\infty -曲線,我們定義當

dγdtdγdt=0\nabla_{\frac{d\gamma}{dt}} \frac{d\gamma}{dt}=0

對所有 tt 成立時,γ\gamma 為一測地線。只要參考切向量場沿著某一曲線如何被視為平行定義的推廣就可以直觀的看出測地線的幾何意義。

藉由座標 γ(t)=(xi(t))\gamma(t) = (x^i(t)) ,可將 γ\gamma 表達為

dγdt=dxidtxi\frac{d\gamma}{dt} = \frac{d x^i}{dt} \frac{\partial}{\partial x^i}

故推導當 γ\gamma 為一測地線時,有方程式

0=dxidtidxjdtxj=dxidtidxjdtjby linear=dxidt((idxjdt)j+dxjdtij)by Leibniz=dxidt(idxjdt)j+dxidtdxjdtij=dxidtdxjdtij+dxidt(idxjdt)j=dxidtdxjdtij+ddt(dxjdt)jby chain rule=dxidtdxjdtij+d2xjdt2j=dxidtdxjdtij+d2xkdt2k=dxidtdxjdtΓijkk+d2xkdt2kby ij=Γijkk=(dxidtdxjdtΓijk+d2xkdt2)k\begin{aligned} 0 &= \nabla_{\frac{d x^i}{dt} \partial_i}{\frac{d x^j}{dt} \partial x_j} \\ &= \frac{d x^i}{dt} \textcolor{red}{\nabla_{\partial_i}{\frac{d x^j}{dt} \partial_j}} \quad\quad\quad \text{by linear} \\ &= \frac{d x^i}{dt} (\textcolor{red}{(\partial_i \frac{d x^j}{dt}) \partial_j + \frac{d x^j}{dt} \nabla_{\partial_i}{\partial_j}}) \quad \text{by Leibniz} \\ &= \frac{d x^i}{dt}(\partial_i \frac{d x^j}{dt}) \partial_j + \textcolor{blue}{\frac{d x^i}{dt}\frac{d x^j}{dt} \nabla_{\partial_i}{\partial_j}} \\ &= \textcolor{blue}{\frac{d x^i}{dt}\frac{d x^j}{dt} \nabla_{\partial_i}{\partial_j}} + \textcolor{green}{\frac{d x^i}{dt}}(\textcolor{green}{\partial_i} \frac{d x^j}{dt}) \partial_j \\ &= \frac{d x^i}{dt}\frac{d x^j}{dt} \nabla_{\partial_i}{\partial_j} + \textcolor{green}{\frac{d}{dt}}(\frac{d x^j}{dt}) \partial_j \quad \text{by chain rule} \\ &= \frac{d x^i}{dt}\frac{d x^j}{dt} \nabla_{\partial_i}{\partial_j} + \frac{d^2 x^{\textcolor{red}{j}}}{dt^2} \partial_{\textcolor{red}{j}} \\ &= \frac{d x^i}{dt}\frac{d x^j}{dt} \nabla_{\partial_i}{\partial_j} + \frac{d^2 x^k}{dt^2} \partial_k \\ &= \frac{d x^i}{dt}\frac{d x^j}{dt} \Gamma^k_{ij}\textcolor{red}{\partial_k} + \frac{d^2 x^k}{dt^2} \textcolor{red}{\partial_k} \quad \text{by } \nabla_{\partial_i}\partial_j = \Gamma^k_{ij}\partial_k \\ &= (\frac{d x^i}{dt}\frac{d x^j}{dt} \Gamma^k_{ij} + \frac{d^2 x^k}{dt^2}) \textcolor{red}{\partial_k} \end{aligned}

因此測地線方程組就是指

d2xkdt2+dxidtdxjdtΓijk=0,k=1,,n\frac{d^2 x^k}{dt^2} + \frac{d x^i}{dt}\frac{d x^j}{dt} \Gamma^k_{ij} = 0, \quad \forall k=1,\dots,n

The Basel problem with trigonometric Fourier series [math-0016]

An idea is define f(x)=x2f(x) = x^2 on [π,π][-\pi, \pi] . Its trigonometric Fourier series was:

a02+n=1(ancos(nx)+bnsin(nx))\frac{a_0}{2} + \sum_{n=1}^{\infty}(a_n \cos(nx)+b_n \sin(nx))

which is periodic and converges to f(x)f(x) in [π,π][-\pi,\pi] .

Observing that f(x)f(x) is even, hence

bn=1πππf(x)sin(nx)dx=0b_n = \frac{1}{\pi} \int_{-\pi}^{\pi} f(x)\sin(nx)\,dx = 0

for all n=1,2,3,n = 1,2,3,\dots . Now compute a0a_0

a0=1πππx2dx=2π0πx2dx=2π[x33]0π=2ππ33=2π23\begin{aligned} a_0 &= \frac{1}{\pi} \int_{-\pi}^{\pi} x^2\,dx = \frac{2}{\pi}\int_{0}^{\pi} x^2\,dx \\ &= \frac{2}{\pi} \left[\frac{x^3}{3}\right]_0^\pi \\ &= \frac{2}{\pi} \frac{\pi^3}{3} = \frac{2\pi^2}{3} \end{aligned}

and each ana_n is

an=1πππx2cos(nx)dx=2π0πx2cos(nx)dx\begin{aligned} a_n &= \frac{1}{\pi} \int_{-\pi}^{\pi} x^2\cos(nx)\,dx \\ &= \frac{2}{\pi} \textcolor{red}{\int_{0}^{\pi} x^2\cos(nx)\,dx} \end{aligned}

Now let's focus on integral by part

x2cos(nx)dx=x2(cos(nx)dx)2x(cos(nx)dx)dx=x2sin(nx)n2xsin(nx)ndx\begin{aligned} \textcolor{red}{\int x^2\cos(nx)\,dx} &= x^2(\int \cos(nx)\,dx) - \int 2x (\int \cos(nx)\,dx)\,dx \\ &= x^2 \frac{\sin(nx)}{n} - 2 \textcolor{blue}{\int x \frac{\sin(nx)}{n}\,dx} \end{aligned}

and again

xsin(nx)ndx=xsin(nx)ndx1(sin(nx)ndx)dx=xcos(nx)n2cos(nx)n2dx=xcos(nx)n2sin(nx)n3\begin{aligned} \textcolor{blue}{\int x \frac{\sin(nx)}{n}\,dx} &= x \int\frac{\sin(nx)}{n}\,dx - \int 1 (\int\frac{\sin(nx)}{n}\,dx)\,dx \\ &= x \frac{-\cos(nx)}{n^2} - \int \frac{-\cos(nx)}{n^2}\,dx \\ &= x \frac{-\cos(nx)}{n^2} - \frac{-\sin(nx)}{n^3} \end{aligned}

It seems complicated, but in fact we have sin(nπ)=0\sin(n\pi) = 0 , hence we can ignore them in this definite integral

an=2π[2xcos(nx)n2]0π=2π2πcos(nπ)n2=4cos(nπ)n2=4(1)nn2=(1)n4n2\begin{aligned} a_n &= \frac{2}{\pi} \left[ \frac{2 x \cos(nx)}{n^2} \right]_0^\pi \\ &= \frac{2}{\pi} \frac{2 \pi \cos(n \pi)}{n^2} \\ &= \frac{4 \cos(n \pi)}{n^2} \\ &= \frac{4 (-1)^n}{n^2} = (-1)^n \frac{4}{n^2} \end{aligned}

Therefore, if we compute f(π)f(\pi) can get

f(π)=π2=π23+n=1((1)n4n2cos(nπ))=π23+n=1((1)n(1)n4n2)=π23+n=1((1)2n4n2)=π23+n=1(4n2)=π23+4n=1(1n2)\begin{aligned} f(\pi) &= \pi^2 \\ &= \frac{\pi^2}{3} + \sum_{n=1}^\infty ((-1)^n \frac{4}{n^2} \cos(n\pi)) \\ &= \frac{\pi^2}{3} + \sum_{n=1}^\infty ((-1)^n (-1)^n \frac{4}{n^2}) \\ &= \frac{\pi^2}{3} + \sum_{n=1}^\infty ((-1)^{2n} \frac{4}{n^2}) \\ &= \frac{\pi^2}{3} + \sum_{n=1}^\infty (\frac{4}{n^2}) \\ &= \frac{\pi^2}{3} + 4 \sum_{n=1}^\infty (\frac{1}{n^2}) \end{aligned}

Hence

2π23=4n=1(1n2)π26=n=1(1n2)\frac{2\pi^2}{3} = 4 \sum_{n=1}^\infty (\frac{1}{n^2}) \\ \frac{\pi^2}{6} = \sum_{n=1}^\infty (\frac{1}{n^2})

RP1\R P^1 is diffeomorphic to S1S^1 [math-0015]

Construction

  1. Ua=S1(0,1)U_a = S^1 - (0,1) and φa(u,v)=u1v\varphi_a(u,v) = \frac{u}{1-v}
  2. Ub=S1(0,1)U_b = S^1 - (0,-1) and φb(u,v)=u1+v\varphi_b(u,v) = \frac{u}{1+v}

and RP1\R P^1 use

  1. U1={[x:y]x0}U_1 = \{[x:y] \mid x\ne0\} and φ1([x:y])=yx\varphi_1([x:y]) = \frac{y}{x}
  2. U2={[x:y]y0}U_2 = \{[x:y] \mid y\ne0\} and φ1([x:y])=xy\varphi_1([x:y]) = \frac{x}{y}

The diffeomorphism ψ:RP1S1\psi : \R P^1 \to S^1 defined as

ψ(p=[x:y])={φa1φ1 if pU1φb1φ2 if pU2\psi(p=[x:y]) = \begin{cases} \varphi_a^{-1} \circ \varphi_1 \text{ if } p\in U_1 \\ \varphi_b^{-1} \circ \varphi_2 \text{ if } p\in U_2 \end{cases}

Given [x:y][x:y] we have a ratio k=y/xk = y/x , we want to recover a point (u,v)(u,v) on S1S^1 , how to get this inverse map? The idea is

k=u1v    k(1v)=u    k2(1v)2=u2    k2(1v)2+v2=1    k2(12v+v2)+v2=1    (k2+1)v22k2v+k2=1    (k2+1)v22k2v+(k21)=0k = \frac{u}{1-v} \implies k(1-v)=u \\ \implies k^2(1-v)^2=u^2 \\ \implies k^2(1-v)^2 + v^2=1 \\ \implies k^2(1-2v+v^2) + v^2=1 \\ \implies (k^2+1) v^2 - 2k^2v + k^2=1 \\ \implies (k^2+1) v^2 - 2k^2v + (k^2-1)=0

Now we can use quadratic formula to solve vv (and remind that v1v \ne 1 ):

v=2k2±4k44(k2+1)(k21)2(k2+1)=2k2±2k4(k2+1)(k21)2(k2+1)=k2±k4(k2+1)(k21)k2+1=k2±k4(k41)k2+1=k2±1k2+1v = \frac{ 2k^2 \pm \sqrt{4k^4 - 4(k^2+1)(k^2-1)} }{2(k^2+1)} = \frac{2k^2\pm2\sqrt{k^4-(k^2+1)(k^2-1)}}{2(k^2+1)} \\ = \frac{k^2\pm\sqrt{k^4-(k^2+1)(k^2-1)}}{k^2+1} \\ = \frac{k^2\pm\sqrt{k^4-(k^4-1)}}{k^2+1} = \frac{k^2\pm1}{k^2+1}

However, v1v \ne 1 hence

v=k21k2+1v = \frac{k^2-1}{k^2+1}

By this we can see

u=2kk2+1u = \frac{2k}{k^2+1}

Therefore, φa1\varphi_a^{-1} is

φa1(k)=(2kk2+1k21k2+1)\varphi_a^{-1}(k) = \begin{pmatrix} \frac{2k}{k^2+1}\\ \frac{k^2-1}{k^2+1} \end{pmatrix}

The similiar reasoning can show

φb1(k)=(2kk2+11k2k2+1)\varphi_b^{-1}(k) = \begin{pmatrix} \frac{2k}{k^2+1}\\ \frac{1-k^2}{k^2+1} \end{pmatrix}

Hence, for U1U2U_1 \cap U_2 (i.e. x0y0x \ne 0 \land y \ne 0 ) we have

φa1φ1=φb1φ2\varphi_a^{-1} \circ \varphi_1 = \varphi_b^{-1} \circ \varphi_2

By component, first check uu :

2y/xy2/x2+1=2y/x(x2+y2)/x2=2yx2(x2+y2)x=2xyx2+y2and2x/yx2/y2+1=2x/y(x2+y2)/y2=2xy2(x2+y2)y=2xyx2+y2\frac{2 y/x}{y^2/x^2 + 1} = \frac{2 y/x}{(x^2+y^2)/x^2} = \frac{2 y x^2}{(x^2+y^2)x} = \frac{2 xy}{x^2+y^2} \\ \text{and} \\ \frac{2 x/y}{x^2/y^2 + 1} = \frac{2 x/y}{(x^2+y^2)/y^2} = \frac{2 xy^2}{(x^2+y^2)y} = \frac{2 xy}{x^2+y^2}

Then check vv :

(y/x)21(y/x)2+1=y2x2y2+x2and1(x/y)2(x/y)2+1=y2x2x2+y2\frac{(y/x)^2-1}{(y/x)^2+1} = \frac{y^2-x^2}{y^2+x^2} \\ \text{and} \\ \frac{1-(x/y)^2}{(x/y)^2+1} = \frac{y^2-x^2}{x^2+y^2}

So ψ\psi is indeed well defined, and smooth on it domain, the inverse defined as

ψ1(p=(u,v))={φ11φa if pUaφ21φb if pUb\psi^{-1}(p=(u,v)) = \begin{cases} \varphi_1^{-1} \circ \varphi_a \text{ if } p\in U_a \\ \varphi_2^{-1} \circ \varphi_b \text{ if } p\in U_b \end{cases}

where φ11(a)=[1:a]\varphi_1^{-1}(a) = [1 : a] and φ21(b)=[b:1]\varphi_2^{-1}(b) = [b : 1] because the equivalence. These maps are smooth on u,vu,v and agree each other (inverse the ratio because the position) when meet hence well defined. Hence ψ\psi is a diffeomorphism.

Definition. Jacobian matrix [math-0014]

Let f:URnRmf : U \subset \R^n \to \R^m be a map, hence we can view each mm component is a function RnR\R^n \to \R :

f(x1,x2,,xn)=(f1(x1,,xn)f2(x1,,xn)fm(x1,,xn))f(x^1, x^2, \dots, x^n) = \begin{pmatrix}f_1\left(x^1,\ldots,x^{n}\right)\\ f_2\left(x^1,\ldots,x^{n}\right)\\ \vdots\\ f_{m}\left(x^1,\ldots,x^{n}\right) \end{pmatrix}

with respect to standard bases, and aRna \in \R^n , DfaDf\left|_{a}\right. is given by the m×nm \times n matrix of partial derivatives (the Jacobian matrix) in the following sense

Dfav=(f1x1(a)f1x2(a)f1xn(a)f2x1(a)f2x2(a)f2xn(a)fmx1(a)fmx2(a)fmxn(a))n()}m(v1v2vn)Df\left|_{a}\right.v=\overbrace{\begin{pmatrix}\frac{\partial f_1}{\partial x^1}\left(a\right) & \frac{\partial f_1}{\partial x^2}\left(a\right) & \cdots & \frac{\partial f_1}{\partial x^{n}}\left(a\right)\\ \frac{\partial f_2}{\partial x^1}\left(a\right) & \frac{\partial f_2}{\partial x^2}\left(a\right) & \cdots & \frac{\partial f_2}{\partial x^{n}}\left(a\right)\\ \vdots & \vdots & \ddots & \vdots\\ \frac{\partial f_{m}}{\partial x^1}\left(a\right) & \frac{\partial f_m}{\partial x^2}\left(a\right) & \cdots & \frac{\partial f_m}{\partial x^{n}}\left(a\right)\end{pmatrix}}^{n}\left.\vphantom{ \begin{pmatrix} \\ \\ \\ \\ \end{pmatrix} }\right\rbrace m\begin{pmatrix}v^1\\ v^2\\ \vdots\\ v^{n}\end{pmatrix}

Or using the index notation, so ω=Df(a)v\omega=Df\left(a\right)v can be expressed as:

ωi=jfixj(a)vj\omega^{i}=\sum_{j}\frac{\partial f_{i}}{\partial x^{j}}\left(a\right)v_{}^{j}

Type system 的 Soundness 與 Completeness [tt-000S]

  1. 我們說型別系統 sound 的時候,意思是如果一隻程式的型別不正確,系統就不會接受這隻程式。這蘊含了如果程式被系統接受 (type-checked),那就一定是沒有類型錯誤的程式。

  2. 我們說型別系統 complete 的時候,意思是如果一隻程式的型別正確,就一定會被系統接受。

我們通常更偏好滿足 soundness,因為有型別錯誤卻被接受的程式,因為比起有幾個需要改寫幾隻程式的麻煩,unsound 往往能造成更大的問題。

Definition. Predicative [tt-000R]

Definition. Injectivity [tt-000Q]

Counterexamples in Type Systems

如果我們說一個型別建構子 FF 是 Injective,那麼意思是如果 F[A]=F[B]F[A] = F[B]A=BA = B

一個程式語言的各個參數化型別不必然都具有這個特性。

Definition. maximal ideal [math-0013]

A maximal ideal AA of a commutative ring RR is a proper ideal of RR such that, whenever BB is an ideal of RR and ABRA \subset B \subset R , then B=AB = A or B=RB = R .

An equivalent condition is R/AR / A is a field if and only if AA is maximal.

Definition. prime ideal [math-0012]

Let AA be a ring and II be an ideal, the followings are equivalent conditions to say that II is prime

  1. II is prime if abIab \in I than aIa \in I or bIb \in I for all a,bAa,b \in A
  2. II is prime if A/IA / I is an integral domain

Proof

Backward

Let A/IA / I be an integral domain, that's say if x,yA/Ix, y \in A / I and xy=0xy = 0 , then x=0x = 0 or y=0y = 0 . Let (a+I)(b+I)(a + I)(b + I) be the zero element of II (i.e. (0A)+I(0 \in A) + I ), then ab+I=Iab + I = I . Hence a+I=Ia + I = I or b+I=Ib + I = I , implies aIa \in I or bIb \in I .

Forward

Let II be a prime ideal, let

(a+I)(b+I)=0+I=I(a+I)(b+I)=0+I = I

then abIab \in I and therefore, aIa \in I or bIb \in I . Hence a+Ia + I or b+Ib + I is the zero coset in A/IA / I .

Algorithm. 君主選舉 [cs-000I]

前提

  1. 每個節點入場的時候都分配到一個代數(generation),這個數字是唯一的
  2. 第一個啟動節點直接當選

當原始的領導者掛了(一段時間無回應),注意到這點的節點就開始問比自己老的所有節點是不是還活著

  1. 收到 alive 回應,或是得到其他更高優先順序的候選節點資訊。
  2. 從中選出最老(代數數字最小)的節點告知它當選了,當選節點會廣播自己當選的消息。

問題

  1. 注意到領導者無回應而發起投票的節點可以超過一個
  2. 兩個發起投票的節點有連線的節點當然可能不同

比如 5 6 都注意到 1 死亡,發起投票。3 4 跟 5 有連線於是選出 2;2 3 跟 6 有連線於是選出 3。這時候 2 3 就都覺得自己是領導者了,而且 5 對 6 的通知還是更不正確的結果。

當然補上當選節點廣播之後,較年輕的當選者會自己去除這個屬性也是可以,但這中間會有一小段時間可能發生(以資料庫而言)雙重寫入而遺失資料。

而且要注意到實際上當然可以比這麻煩的多,比如通訊密集時,更容易讓 leader 過載;同時 90% 的節點都發現這點並發起投票,那麼消除腦分裂前的混亂就會特別嚴重。

Internal language 之用 [math-0011]

這是 An informal introduction to topos theory 的閱讀筆記,Leinster 在這裡說 generalized elements 可以說是 Category 的 internal language。而 set theoretic 裡面使用 element 的論證多半都能改用這樣的語言進行,甚至,不使用 LEM 與 AC 的構造式證明,可以在任意 topos 中使用。

除了在 Generalized element 已經討論過的 product (x,y)(x, y) ,topos 還有 exponentials YXY^X ,equalizer 也可以記為

{xXfx=gx}\{ x \in X \mid f x = g x \}

表示 XYX \rightrightarrows Y

這樣就無需使用大量的 diagram,而是採用數學家已經熟悉的集合式的論證即可。

Definition. Generalized element [math-0010]

Let E\mathcal{E} be a category, and let AA be an object of E\mathcal{E} . A generalized element of AA is simply a map in E\mathcal{E} with codomain AA .

A generalized element x:SAx : S \to A is shape SS or SS -element of AA .

When S=1S = 1 (the terminal) then SS -elements are called global elements.

Global elements can be very boring, for example in the category of groups.

The language of generalized elements is the internal language of the category. For example, let E\mathcal{E} be a category with finite products. An SS -element of X×YX \times Y consists of two component x:SX,y:SYx : S \to X, y : S \to Y and is denoted by (x,y)(x,y) , hence extended the notation of set-theoretic Cartesian product of global elements.

Definition. Immersion, embedding, and submanifold [math-000Z]

Let M,NM, N be differentiable manifolds (dimensions are mm and nn respectively). A differentiable map φ:MN\varphi : M \to N is said to be an immersion if

dφp:TpMTφ(p)Nd \varphi_p : T_pM \to T_{\varphi(p)} N

is injective for all pMp \in M .

If in addition, φ\varphi is a homeomorphism onto φ(M)N\varphi(M) \subset N , where φ(M)\varphi(M) has the subspace topology induced from NN , then φ\varphi is an embedding.

If MNM \subset N and the inclusion MNM \subset N is an embedding, then MM is a submanifold of NN .

Proposition. Right adjoint fully faithful <=> counit is isomorphism [math-000Y]

Suppose FGF \dashv G is an adjunction, and G:BAG : B \to A is fully faithful, then counit ε:FG1B\varepsilon : FG \to 1_B is an isomorphism

Proof

Forward direction

To prove counit εB:FG(B)B\varepsilon_B : FG(B) \to B is an isomorphism, we need to find an inverse ε1\varepsilon^{-1} and show pre and post composition of them are identity. Let ε1:=G1η\varepsilon^{-1} := G^{-1}\eta , then we have two targets

  1. ε1ε=idX\varepsilon^{-1} \gg \varepsilon = id_X

    Apply GG to get

    GG1η=Gε1Gε=idG(X)\boxed{G G^{-1} \eta = G \varepsilon^{-1}} \gg G \varepsilon = id_{G(X)}

    hence the target is ηGε=idG(X)\eta \gg G \varepsilon = id_{G(X)} , right triangle fills the target.

  2. εε1=idFG(X)\varepsilon \gg \varepsilon^{-1} = id_{FG(X)}

    Use counit naturality on ε1\varepsilon^{-1} to get

    FηεFG(B)=εBε1=G1ηF \eta \gg \varepsilon_{FG(B)} = \varepsilon_B \gg \boxed{\varepsilon^{-1} = G^{-1}\eta}

    Therefore, we have target FηεFG(B)=idFG(X)F \eta \gg \varepsilon_{FG(B)} = id_{FG(X)} , left triangle fills the target.

Backward direction

For GG is faithful, we want to know if Gf=GgGf = Gg then f=gf = g . We first obtain two equations via naturality of counit:

FGfεY=εXfFGgεY=εXg\begin{align*}FGf \gg \varepsilon_Y = \varepsilon_X \gg f \\ FGg \gg \varepsilon_Y = \varepsilon_X \gg g\end{align*}

Replace GfGf with GgGg then we have εXf=εXg\varepsilon_X \gg f = \varepsilon_X \gg g , counit is an isomorphism and hence left-cancellable, f=gf = g .

For GG is full, we want to show every ff there is a aa such that Ga=fG a = f . Let a=εX1φ1fa = \varepsilon_X^{-1} \gg \varphi^{-1} f (where φ\varphi is the hom-set equivalence of adjunction), this is same as asking

G(εX1)=ηGXG(\varepsilon_X^{-1}) = \eta_{GX}

because isomorphism property, we have

G(εX1)= G(εX1εX)= G(εX1)G(εX)= ηGXG(εX)\begin{align*}&G(\varepsilon_X^{-1}) \\ =\ &G(\varepsilon_X^{-1} \gg \varepsilon_X) \\ =\ &G(\varepsilon_X^{-1}) \gg G(\varepsilon_X) \\ =\ &\eta_{GX} \gg G(\varepsilon_X)\end{align*}

now we use isomorphism to cancel right, so G(εX1)=ηGXG(\varepsilon_X^{-1}) = \eta_{GX} .

Counterexample. pp no need to be identity when pf=fp \gg f = f [math-000X]

The counterexample in the category of sets is

p:22p=notf:21f(b)=\begin{align*} &p : 2 \to 2 \\ &p = not \\ &f : 2 \to 1 \\ &f(b) = \star \end{align*}

We have f(p(x))=f(x)f(p(x)) = f(x) for all x:2x : 2 , but pp is not identity. Where 1,21, 2 represent the set with 11 and 22 elements, respectively.

tr-notes transclude 的發展 [tr-0007]

tr 最開始我的想法是讓每一張卡片自己都輸出一個 HTML 網頁,然後就想到「哎糟糕,被嵌入 (transclude 概念) 的網頁會有重複的共用元素」就放棄了,當時認為所以必須像 forester 那樣用 XML 才行

好久以後我再次考慮(2025/05)實現一個 forester fork 時才想到,只要每張卡生成一個 a.index.html 一個 a.embed.html 就可以避免重複元素了

順著這個想法我用 iframe 嵌入來實現功能,直到我實在解不開 JS 的工作空間問題,這逼我思考其他方案。結果過了幾天我想到其實根本不用這麼麻煩xd,transclude 直接讀 embed 的內容就好了(並且 escape 排版確保不破壞 pre tag 等對排版敏感的內容)

現在剩下的問題就是其實 index 其實也沒必要再用 racket 生成一次,而是應該把 header, footer 等內容插入,讀取自己的 embed 檔案,但目前耦合比較多(依靠 generate-index? 判斷是否生成這些區塊),需要重新思考怎麼編排這些程式

魔物獵人荒野 充能斧 操作筆記 [game-0000]

基本操作

  • : 劍 牽制斬
  • △ + O: 劍 突進斬
  • O 長按: 劍 蓄力上撈斬
  • R2 + △: 劍 變形斬
  • R2 + O: 劍 充能

強化瓶系統

最有效率的集氣連技是: O 長按 → △

但魔物太靈活時這樣可能會一直落空,不一定要堅持這樣打

充能模式

1. 充能盾牌(紅盾)

架盾操作:
  1. R2 + O 之後保持 O 不放開
  2. △ + O 三次接 R2
    • 突進斬
    • 盾突刺
    • 高解
    • 屬性強化迴旋斬

2. 充能劍(紅劍)

操作流程:
  • R2 + O 後按住 △ 進行蓄力
  • 放開後打出「劍:高壓屬性斬」

3. 充能斧(紅斧)

觸發條件有三種(任何一個達成就會觸發紅斧模式):
  1. L2 瞄準用 R1 集中攻擊打到傷口(必須命中才會觸發)
  2. 精準防禦之後按 △
  3. 騎乘打出處決後觸發

出紅斧是為了能長按攻擊鍵 △ 或是 O 時,斧會持續輸出而不是只有一次輸出

Naturality cannot be given by a family of isomorphisms [math-000S]

This is came from when I'm formalizing lemma 1.3.11 of Basic Category Theory, I miss a precondition (HH below must be a natural transformation in the lemma) and try to prove an impossible thing.

Let F,G:CDF, G : \mathcal{C} \to \mathcal{D} be functors, and a family

H:(X:C)FXGXH : (X : C) \mapsto F X \cong G X

Does HH must be natural?

Counterexample. [math-000T]

The result is HH can be not natural.

This counterexample is given by Zhixuan Yang:

Let C\mathcal{C} be the two-object one-arrow category, and D\mathcal{D} be SetSet , and

F,G:012id2F, G : 0 \to 1 \mapsto 2 \xrightarrow{id} 2

where 22 is the two elements set. For 00 we choice H(0)=idH(0) = id and H(1)=notH(1) = \text{not} , then HH is not natural.

Definition. exterior algebra [math-000R]

The exterior algebra of vector space VV is defined as a Z\mathbb{Z} -graded algebra:

ΛV:=r0ΛrV\Lambda^\bullet V := \bigoplus_{r \ge 0} \Lambda^r V

Definition. Homotopy extension property (HEP) [math-000O]

A map i:AXi : A \to X of spaces has the homotopy extension property for a space YY if

  1. for each homotopy H:A×IYH : A \times I \to Y
  2. and for each map f:XYf : X \to Y with f(i(a))=H(a,0)f(i(a)) = H(a, 0) for all aAa \in A

there is a homotopy H:X×IYH' : X \times I \to Y such that

H(i(a),t)=H(a,t)H(x,0)=f(x)\begin{align*} &H'(i(a), t) &= &H(a, t) \\ &H'(x, 0) &= &f(x) \end{align*}

for all aAa \in A , xXx \in X and tIt \in I . The idea can be expressed in the following commutative diagram:

figure tex1633

The homotopy HH' is called the extension of HH with initial condition ff .

Definition. Natural Transformation [math-000N]

Let C\mathcal{C} and D\mathcal{D} be categories, let F,G:CDF, G : \mathcal{C} \to \mathcal{D} be functors. A natural transformation α:FG\alpha : F \Rightarrow G is a function consists of

  1. For each XCX \in \mathcal{C} , there is a morphism αX:F(X)G(X)\alpha_X : F(X) \to G(X) in D\mathcal{D} , called the XX -component of α\alpha
  2. For every morphism f:XYf : X \to Y in C\mathcal{C} , there is a commute diagram
    figure tex1633

常青筆記的困難 [note-0001]

Sterlinghttps://www.forester-notes.org/QHXX/index.xml 精確的描述了常青筆記可能遭遇的困難,關鍵在於,常青筆記對於不停變化的目標,如數學、電腦程式框架等存在,本體論的目標並不統一。用數學為例,我們傳統上接受 ZFC 作為「集合論」的本體,但 topos theory 的發展給出另一套定義 ETCS https://en.wikipedia.org/wiki/Elementary_Theory_of_the_Category_of_Sets!ETCS 說我們覺得集合論是「由 sets 與 functions 構成的 well-pointed topos,有自然數 object 與 Epics split」。

這個定義並沒有循環定義(但使用了短語簡化說法),因為 sets 跟 functions 的公理可以直接給出,ETCS 並沒有比 ZFC 不穩固。

事實上我們甚至知道 ETCS 跟 ZFC 的差異,ETCS + replacement(https://en.wikipedia.org/wiki/Axiom_schema_of_replacement)等價於 ZFC 的推理能力。ZFC 中的某部份等價於 ETCS(參考 Sheaves in Geometry and Logic: A First Introduction to Topos Theory VI. 10)

重點是,既然沒辦法保證討論主題的永久不變,那就應該紀錄當下對主題的洞見,因而在未來仍可從思想中復原出結構。

Definition. Pfaffian [math-000P]

Let AA be a skew-symmetric endomorphism of a vector space VV (hence AA can also be view as a tensor: AΛ2VA \in \Lambda^2 V ) and N=dimVN = \dim{V} is even, the Pfaffian of AA is the number Pf A\text{Pf}\ A defined as the constant factor in the tensor equality:

(Pf A)e1eN=1(N/2)!AAN/2 times(\text{Pf}\ {A}) e_1 \wedge \dots \wedge e_N = \frac{1}{(N/2)!} \underbrace{A \wedge \dots \wedge A}_{N/2\ times}

where {e1,,eN}\set{e_1,\dots,e_N} is an orthonormal basis of VV .

The sign of Pfaffian depends on the orientation of the orthonormal basis.

An Agda Framework for Synthetic Mathematics [math-000K]

Theorem. Borsuk–Ulam [math-000L]

If f:SnRnf : S^n \to \R^n is continuous then there exists a point xSnx \in S^n such that f(x)=f(x)f(x) = f(-x) .

Lemma. [math-000M]

If f:SnRnf : S^n \to \R^n is continuous and antipode-preserving, then there exists a point xSnx \in S^n such that f(x)=0f(x) = 0 .

Proof

Use standard stereographic projection, we can see NN and SS charts gives exactly the same coordinate system at equator (i.e. where its embedding coordinate (x1,,xn+1)(x_1, \dots, x_{n+1}) with xn+1=0x_{n+1} = 0 ). This also tells the equator is a Sn1S^{n-1} in Rn\R^n because x12++xn2=1x_1^2 + \dots + x_n^2 = 1 .

By continuous and antipode-preserving, ff preserves such an equator (we denote EE ) to Sn1S^{n-1} (with any deformation that still an antipode shape) and f(E)f(E) must bound a set contains 0Rn0 \in \R^n .

By continuous, both of two open sets of SnS^n , complement of EE , needs to be mapped to cover the subset of Rn\R^n which bounded by f(E)f(E) , so there exists a point xSnx \in S^n such that f(x)=0f(x) = 0 .

Proof

Define g(x)=f(x)f(x)g(x) = f(x) - f(-x) , gg is continuous.

By

g(x)=f(x)f(x)=(f(x)f(x))=g(x)g(x) = f(x) - f(-x) = -(f(x) - f(-x)) = -g(-x)

gg is antipode-preserving.

By the lemma, there is a point xSnx \in S^n such that g(x)=0g(x) = 0 , so f(x)f(x)=0f(x) - f(-x) = 0 then f(x)=f(x)f(x) = f(-x) .

Determinant of Skew-Symmetric Matrices [math-000V]

This problem arose from studying the book Lectures on the Geometry of Manifolds: Suppose VV is a real vector space, and ω:V×VR\omega : V \times V \to \mathbb{R} is a symplectic duality, then VV has even dimension.

I can make some concrete computation on dimension 2 and 3 and roughly understand the reason, but I have no general proof.

After a month, I found a solution:

Proof. Using the properties of matrix column operations [math-000W]

Since the multiplication factor of a matrix column can be extracted as a basis, flip the column 1 (i.e. the whole column multiply 1-1 ) we have

det(A)=1det(Aflip1)\det(A) = -1 \cdot \det(A_{\text{flip1}})

Following this pattern, flipping column 2 gives us:

det(A)=(1)(1)det(Aflip1,flip2)\det(A) = (-1) \cdot (-1) \cdot \det(A_{\text{flip1,flip2}})

Let AA be an n×nn \times n skew-symmetric matrix. After flipping all nn columns, we obtain A-A , therefore

det(A)=(1)ndet(A)\det(A) = (-1)^n \cdot \det(-A)

By definition, skew-symmetric means A=AT-A = A^T , so

det(A)=(1)ndet(AT)\det(A) = (-1)^n \cdot \det(A^T)

When nn is odd, this gives us

det(A)=det(AT)=det(A)\det(A) = -\det(A^T) = -\det(A)

Therefore det(A)\det(A) must be 0.

After formalize this statement https://github.com/dannypsnl/blackboard/commit/2c0de90a98c24ae57bd30bc47ed8c3b6a75f2664, I found this need the field is charateristic 0, sure R\mathbb{R} indeed satisfies that, this point to me is that Lean can help me refine my ideas.

If AA represents a duality, then det(A)0\det(A) \neq 0 . Therefore nn cannot be odd—it must be even.

What I Wish I Knew When Learning HoTT [tt-000P]

Dependent Pattern Matching [ag-0001]

Lecture. Domain Theory [dt-0000]

Course. CS208 Logic & Algorithms [MSP-cs208]

Tool. agda 的開發工具 [agda-0001]

我使用的編輯器工具是 Agda Mode on VS Code,也可以用 emacs 之類的。常用操作有

  • ctrl+c, ctrl+l 會編譯檢查檔案,假設程式中有 ?,會被替換成所謂的 hole {! !},其實就是待寫的程式

  • ctrl+c, ctrl+, 可以窺看 hole 的目標類型,與當前 context 有哪些 term 可用

  • ctrl+c, ctrl+r 會把 hole 中你打的程式碼往前提取,當然前提是類型是正確的

  • ctrl+c, ctrl+m 會把 hole 中你打的程式碼直接當成結果,一樣類型要是正確的

  • 一般來說一個 agda 定義如下

    hello : A → B
    hello a = {! !}

    ctrl+c, ctrl+c 會問你要把哪個變數用構造子分開,回答 a,假設有 a1a2 兩個構造子,程式就會變成

    hello : A → B
    hello a1 = {! !}
    hello a2 = {! !}
使用 Linux 的使用者可以更改預設的 copy/cut 指令以免衝突。

已完成的軟體 [software-0007]

已完成的軟體這種概念,是指一個軟體的功能已經沒有大幅度更動的必要,可以長期使用在產品上,而軟體本身只會進行必要的安全與移植性更新。我在 https://josem.co/the-beauty-of-finished-software/ 讀到這個想法。對應到筆記軟體上,我不希望軟體一直更新,尤其是當我一打開工具需要寫筆記時,上面的更新按鈕非常的讓人煩躁。同時,這個想法也是一種解放我們原先對軟體想像的開端,比起軟體如何如何,更重要的是真的去做,外部連結裡面也談到冰與火之歌正是用這樣的軟體寫出。

git send-email setup with Protonmail [software-0006]

In the original setup I already explain the configuration, to do the same with Protonmail will need to install Proton Mail Bridge(https://proton.me/mail/bridge), then with configuration as below.

[sendemail]
  smtpEncryption = STARTTLS
  smtpServer = 127.0.0.1
  smtpUser = <your id>@protonmail.com
  smtpServerPort = 1025
  smtpPass = <your password>

Definition. point-surjective [math-000A]

A morphism AϕBA \xrightarrow{\phi} B is point-surjective iff for every point 1qB1 \xrightarrow{q} B , there exists a point 1pA1 \xrightarrow{p} A that lifts qq (satisfy ϕp=q\phi \circ p = q ).

git send-email 的設定 [software-0004]

I use gmail, and hence, I need to get a Google app password. After having the password, one has to setup ~/.gitconfig with content:

[sendemail]
  smtpEncryption = tls
  smtpServer = smtp.gmail.com
  smtpUser = <your id>@gmail.com
  smtpServerPort = 587
  smtpPass = <your password>

Then you are able to use git send-email command:

git switch -c branch-patch
git format-patch main
git send-email 0001-***********.patch

prompt will ask some questions, an important one is which mailing list is your target? After command success, your patch are sent.

For certain git repository you're working on, can config local repository via git config --edit, and add below to omit email list in command line.

[sendemail]
  to = <target email list>

Mastodon 私訊相比於一般通訊軟體 e.g. LINE, Telegram [software-0003]

好處

  1. 可以有效分類特定話題,例如一個串是講約去哪裡吃飯、另一個串講專業內容
  2. 可以用僅限提及的人,限制可見性,所以可以形成一定程度的群組概念

壞處

  1. 兩方站點的站長都能看到內容
  2. 客戶端不支援把一群提及名單固定成群組,這或許是一個可行的客戶端新功能

壞處的可能解法:公佈自己的 public key 讓對方加密訊息再傳,配上專用客戶軟體或許可以做的更方便

let Racket GC manage your FFI object [software-0005]

All you need are deallocator and allocator from ffi/unsafe/alloc.

(require ffi/unsafe
         ffi/unsafe/define
         ffi/unsafe/alloc)

(define-ffi-definer define-xxx
  (ffi-lib "" '(#f)))

(define-xxx free-yyy (_fun _YyyRef -> _void)
  #:c-id yyy_delete
  #:wrap (deallocator))
(define-xxx make-yyy (_fun -> _YyyRef)
  #:c-id yyy_new
  #:wrap (allocator free-yyy))

Tool. ngrok [software-0002]

Sometimes we didn't have public ip, but temporary wants to test website, ngrok can help in this situation.

# expose localhost:8080 by HTTP
$ ngrok http 8080
# expose localhost:8080 by TCP
$ ngrok tcp 8080

XDP [software-0001]

XDP is eXpress Data Path, it's a technology about putting a BPF code virtual machine on the NIC(network interface controller) driver before kernel network stack so that we can filter the packet before kernel, it would make processing speed greater.

We can do following things on the packet:

  1. XDP_PASS: allow the packet to pass through
  2. XDP_DROP: drop the packet
  3. XDP_TX: bounce the packet back on the same interface
  4. XDP_REDIRECT: redirects the packet to another interface

Here is an example of counting how many IPv4/6 packets be dropped.

package main

import (
    "fmt"
    "os"
    "os/signal"

    bpf "github.com/iovisor/gobpf/bcc"
)

// bcc is from iovisor/bcc this project
/*
#cgo CFLAGS: -I/usr/include/bcc/compat
#cgo LDFLAGS: -lbcc
#include 
#include 
void perf_reader_free(void *ptr);
*/
import "C"

const source string = `
#define KBUILD_MODNAME "foo"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
BPF_TABLE("array", int, long, dropcnt, 256);
static inline int parse_ipv4(void *data, u64 nh_off, void *data_end) {
    struct iphdr *iph = data + nh_off;
    if ((void*)&iph[1] > data_end)
        return 0;
    return iph->protocol;
}
static inline int parse_ipv6(void *data, u64 nh_off, void *data_end) {
    struct ipv6hdr *ip6h = data + nh_off;
    if ((void*)&ip6h[1] > data_end)
        return 0;
    return ip6h->nexthdr;
}
int xdp_prog1(struct xdp_md *ctx) {
    void* data_end = (void*)(long)ctx->data_end;
    void* data = (void*)(long)ctx->data;
    struct ethhdr *eth = data;

    uint64_t nh_off = sizeof(*eth);
    if (data + nh_off  > data_end)
        return XDP_DROP;
    uint16_t h_proto = eth->h_proto;
    if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) {
        struct vlan_hdr *vhdr;
        vhdr = data + nh_off;
        nh_off += sizeof(struct vlan_hdr);
        if (data + nh_off > data_end)
            return XDP_DROP;
            h_proto = vhdr->h_vlan_encapsulated_proto;
    }
    if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) {
        struct vlan_hdr *vhdr;
        vhdr = data + nh_off;
        nh_off += sizeof(struct vlan_hdr);
        if (data + nh_off > data_end)
            return XDP_DROP;
            h_proto = vhdr->h_vlan_encapsulated_proto;
    }
    int index;
    if (h_proto == htons(ETH_P_IP))
        index = parse_ipv4(data, nh_off, data_end);
    else if (h_proto == htons(ETH_P_IPV6))
        index = parse_ipv6(data, nh_off, data_end);
    else
        index = 0;
    long *value;
    value = dropcnt.lookup(&index);
    if (value) lock_xadd(value, 1);
    return XDP_DROP;
}
`

func usage() {
    fmt.Printf("Usage: %v \n", os.Args[0])
    fmt.Printf("e.g.: %v eth0\n", os.Args[0])
    os.Exit(1)
}

func main() {
    if len(os.Args) != 2 {
        usage()
    }
    module := bpf.NewModule(source, []string{
        "-w",
    })
    defer module.Close()

    fn, err := module.Load("xdp_prog1", C.BPF_PROG_TYPE_XDP, 1, 65536)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Failed to load xdp prog: %v\n", err)
        os.Exit(1)
    }

    device := os.Args[1]
    if err := module.AttachXDP(device, fn); err != nil {
        fmt.Fprintf(os.Stderr, "Failed to attach xdp prog: %v\n", err)
        os.Exit(1)
    }

    defer func() {
        if err := module.RemoveXDP(device); err != nil {
            fmt.Fprintf(os.Stderr, "Failed to remove XDP from %s: %v\n", device, err)
        }
    }()

    fmt.Println("Dropping packets, hit CTRL+C to stop")
    sig := make(chan os.Signal, 1)
    signal.Notify(sig, os.Interrupt, os.Kill)

    dropcnt := bpf.NewTable(module.TableId("dropcnt"), module)

    <-sig

    fmt.Println("\n{IP protocol-number}: {total dropped pkts}")
    for it := dropcnt.Iter(); it.Next(); {
        key := bpf.GetHostByteOrder().Uint32(it.Key())
        value := bpf.GetHostByteOrder().Uint64(it.Leaf())

        if value > 0 {
            fmt.Printf("%v: %v pkts\n", key, value)
        }
    }
}

Algorithm. Mark sweep GC [cs-0008]

Mark-Sweep is a classic GC algorithm, it's combined with two parts, mark and sweep.

mark(root):
  if not marked?(root):
    mark(root)
  for obj in knowns(root):
    mark(obj)
sweep(heap):
  for obj in heap:
    if marked?(obj):
      unmark(obj)
    else:
      release(obj)

If we run collection (mark-sweep), then since each object is reachable from root, so no one would be released.

figure tex1633

After do some executions, obj1 don't need obj3 anymore, so it became:

figure tex1634

Now when we run collection, obj3 is unreachable from root, so it won't be marked! When running to sweep, it will be dropped.