This blog majorly writes about computer science and mathematics, also is my personal public notes. Feel free to point out any good reference of topic you view on the site, I will add them into reference if proper.
elaboration 指的是轉換沒有語意的表面語法(surface syntax 或是說 source code)到有語意的語言表示(language representation)的過程,這樣講可能有點抽象,所以需要一些例子。試問foo(a, b)
這段 Go source code 有語意嗎?事實上是沒有,因為只有在 Go compiler 經過
現在這段程式碼才會在 Go compiler 內部用某種資料結構表示,而 Go compiler 可以相信這段程式碼是滿足 Go 規範的程式,這樣才是有語意的語言。這個觀點一開始對你來說可能蠻怪異的,但我們可以仔細來看這樣定義的好處
雖然 C 的 preprocessor 也被稱為 macro,但跟 LISP、Elixir、Julia 比起來就差很多的原因是
而常見的 LISP macro 過程則是:
TEXT -> S-expression
S-expression -> S-expression
S-expression -> LISP
舉例來說,在 LISP 我至少不能寫出要展開(1 2 3
,因為這連資料語法(S-expression)都沒有滿足。通過巧妙的設計語法,可以用 macro 打造領域語言,而且 S-expression 這種資料結構本身有助於我們寫出更複雜的 macro,比如辨識 subform 或是對內容進行查找運算等等。
elaboration 前對語法樹進行操作的能力就是 LISP 最大的特徵,這使語言使用者可以自行發展他想要的語法,Clojure 做得比傳統 LISP 更好的地方就是這裡它採用的 edn 能表示比 S-expression 更多的資料,如 hashmap。
subroutine 在 C 語言被稱為 function,Fortran 中則分出 function 或是 subroutine,剩下還有一些語言使用 procedure 這個名稱。
Fortran offers two different procedures: function and subroutine. Subroutines are more general and offer the possibility to return multiple values whereas functions only return one value.
我把定義 subroutine 為一個指令語言編寫程式的模式,在組合語言裡面,我們並沒有函數名稱這種東西,相對的,其實只有指令的位址,所以組譯語言通常會提供區塊名稱來標記位址,比如a:
,那你可能已經想到了,如果我跳轉到jump a
是不是就能執行a
的內容了!是,但你要怎麼跳回來呢?所以 subroutine 就被發明了:找個 register 放一下要跳轉回來的位址就好啦!於是一個a
呼叫b
的程式就寫成
a: store ret (here+1) jump b ...b: ... jump ret
(here+1)
是為了跳過jump b
這個指令,而ret
就是一個特殊保留的 register,專門用來讓 subroutine 使用。你會發現,ㄟ這樣是不是沒有傳遞參數?沒錯,所以更完整的故事是,CPU 會乾脆設計一整套傳遞參數應該用哪幾個 registers 跟 stack 偏移的慣例,叫做 calling convention。
這就是所謂的現代 CPU 是為了 compiler 設計。不遵守這些慣例你的程式還是能動,但你的程式就會跟其他 compiler 為這個 CPU 吐出來的程式很難溝通。
在一些非常簡單的作業系統實現裡面,會乾脆讓 user process 自己決定要不要讓出 CPU,怎麼讓?就是把自己當前的 stack pointer address 以及 registers 狀態儲存到記憶體裡面去,通常是 kernel 提供的一個 struct,然後跳轉到另一個 process 去。
這樣的話這是 user process 自己決定讓給誰,一般其實也不是這樣實現的,而是 user process 只有呼叫yield
把自己暫停,下一步轉移給誰交給 kernel 決定。比如 Linux 就有
int sched_yield(void)
這個函數。
但要是 user process 不小心陷入無限迴圈怎麼辦?所以更常出現的是所謂的搶佔式排程,kernel 分配 time slice 並且封裝 process,並且設定計時器硬體中斷來確保自己可以定時查看狀態,這樣 process 在 slice 用光之後(或是它的指令執行完畢)就可以被切斷。
Manifolds and Differential Geometry
Let \(e_1, e_2, \dots , e_n \in V\) be a basis of vector space \(V\), and let \(e^1, \dots , e^n \in V^*\) be a basis of dual space \(V^*\). Now if \(\bar {e}_i = C^k_{\ \ i} e_k\) is another basis of \(V\), then there is an induced basis \(\bar {e}^i = (C^{-1})^i_{\ \ k} e^k\) for dual space \(V^*\).
By Kronecker-delta \(1 = \delta ^i_{\ i}\)
\[1 = \delta ^{i}_{\ i} = \bar {e}_{i} \bar {e}^{i} = C^k_{\ \ i} e_{k} \bar {e}^{i}\]can see that if \(\bar {e}^{i} = e^{k} (C^{-1})^i_k\) then the equality is hold. We can use Penrose notation to show the idea.
Subtype
如何與底下的型別轉換[lean-0003]這是從zulip 上詢問到的做法,假設在 context 中已經有... ↑x ... = ...
這樣的Prop
,並且目標就是... x ... = ...
,那麼使用下列的 tactic 即可
rw [← Subtype.val_inj]; norm_cast
import Mathlib.Data.Real.Basicimport Mathlib.Analysis.SpecialFunctions.Pow.Real
比如我遇到的 proof context 是
c : ℝx y : ℝ>0⊢ (x * y) ^ c = x ^ c * y ^ c
其中ℝ>0
定義是
def VReal := { r : Real // 0 < r } deriving One, CommMonoidnotation "ℝ>0" => VReal
先用
have K := Real.mul_rpow (le_of_lt x.property) (le_of_lt y.property) (z := c)
放置
K : (↑x * ↑y) ^ c = ↑x ^ c * ↑y ^ c
之後用
rw [← Subtype.val_inj]; norm_cast
就搞定了。
變數依然是使用var
函數t = var('t')
,不過要建立依賴t
的函數變數就需要寫
x = function('x')(t)
方程式寫成DE = diff(x, t) + x - 1
\(= \frac {d x}{d t} + x - 1\)。解方程式要用desolve
函數,desolve(DE, [x,t])
\(= e^{-t} (C + e^t)\)
首先,用var
建立變數
x = var('x')
接著就可以按照常見的方式定義函數,比如
f = x^3
有個需要注意的小細節是f(x) = x^3
不等於f = x^3
,兩者的調用方式並不相同
f(1)
f(x=1)
同理,diff(f, x)
的結果也受到f
的定義方式影響
integral
函數)[#296]integral(f, x)
會計算不定積分 \(\int f\ dx\)integral(f, x, a, b)
則會計算定積分 \(\int _a^b f\ dx\)。注意參數缺失會導致錯誤例如integral(x^3,x)
\(= \frac {1}{4} x^4\)
多變數函數還可以求 Jacobian
f = (x*cos((1-z^2)*θ) - y*sin((1-z^2)*θ), x*sin((1-z^2)*θ) + y*cos((1-z^2)*θ), z)jacobian(f, (x,y,z))\[\begin {bmatrix} \cos ((1 - z^2)θ) & -\sin ((1 - z^2)θ) & 2yzθ \cdot \cos ((1 - z^2) θ) + 2xzθ \cdot \sin ((1 - z^2)θ) \\ \sin ((1 - z^2)θ) & \cos ((1 - z^2)θ) & -2xzθ \cdot \cos ((1 - z^2) θ) + 2yzθ \cdot \sin ((1 - z^2)θ) \\ 0 & 0 & 1 \end {bmatrix}\]
這些程式碼都是使用OCaml 實現,並使用了algeff 與asai 程式庫
解析器需要完成的任務就是根據規則把一系列 tokens 變成文法樹,並且回報為何解析失敗,一般大學作業等級的編譯器都會讓學生直接使用解析器生成器,如menhir 這種工具。然而實際上開發真實語言的解析器時,往往會遇到需要錯誤恢復並繼續解析,最後再回報多個錯誤的要求,這時候生成器往往給出很差的結果,甚至乾脆就是做不到的。
然而,手工編寫的解析器通常可維護性相當差劣。一種折衷的方案是所謂的解析器組合子,我過去也曾經介紹過如何利用組合子抽象掉重複的解析規則。但這種方案有個問題,就是回溯必須手動使用try
組合子來在失敗時恢復狀態,但實務上這創造了相當難以理解的各種try
安插,當我意識到這是因為 API 需要是兩階段的問題時,我就發現其實effect handler 正是解決這個問題的好方法。
我本來是直接使用Effect.Deep
的,但後來發現這種情境直接用 algeff 就足夠了,因此改採這個方案。實際程式碼如下
module Tokens = struct type t = Lexer.token Asai.Range.located listendmodule TokenState = Algaeff.State.Make (Tokens)
首先,我假設了Lexer.token
這個型別存在,並且使用者會輸入一個標記過位置的token list
。接著建立一個狀態模組,這個模組的只有三個用法:
let next_token () = match TokenState.get () with | [ eof ] -> eof | tok :: buf -> TokenState.set buf; tok | [] -> raise Impossiblelet shift pos = TokenState.set poslet current_position () = TokenState.get ()
這段程式巧妙的使用了 OCaml 的不可變 list 的特性,也就是持頭就可以保證資料不被回收
並且提供啟動函數
let run (init : Lexer.token Asai.Range.located list) (f : unit -> 'a) : 'a = TokenState.run ~init @@ fun () -> f ()
let catch_parse_error (p : unit -> 'a) : 'a option = let pos = current_position () in Reporter.try_with ~fatal:(fun d -> match d.message with | Parse_error -> shift pos; None | _ -> Reporter.fatal_diagnostic d) (fun () -> Some (p ()))
其中Parse_error
跟Reporter
都是使用者自訂的錯誤回報模組內容,如何定義可以參考 asai 的文件。這段輔助函數之所以出現只是為了讓讀者知道這個函數的存在,這個函數只捕捉解析失敗,讓其他錯誤繼續往上走。
consume
[#237]let consume (predict : Lexer.token) : unit = let tok = next_token () in if tok.value == predict then () else # raise ...
many
[#238]let rec many (p : unit -> 'a) () : 'a list = let x = catch_parse_error p in match x with | None -> [] | Some x -> x :: many p ()
let ( <|> ) (p1 : unit -> 'a) (p2 : unit -> 'a) () : 'a = match catch_parse_error p1 with | None -> p2 () | Some x -> x
此外也有更複雜的錯誤恢復機制
let rec program () = let x = catch_parse_error top in match x with | Some x -> x :: program () | None -> let pos = next_start_token () in shift pos; program ()
程式語言為了讓使用者省略不必要的輸入,必須為使用者推導內容,這種需求催生了合一這種類型的演算法。比如很多程式語言允許泛型,比如下面的 OCaml 程式碼
let id (x : 'a) : 'a = x
Elaboration zoo 這個教學專案,它的程式碼要解決的,是一類更複雜的程式語言,叫做 dependent type 的系統中的合一問題,這類系統最重要的特性,就是類型也只是一種值,值也因此可以出現在類型中,但這就比較不是本篇的重點,有興趣的讀者可以閱讀The Little Typer 來入門。在解釋完它的合一之後,我會介紹它隱式參數的解決方案
假設有程式碼
let id {A : U} (x : A) : A := xlet id2 {B : U} (x : B) : B := id _ x
這裡id _ x
中的底線就是表示「省略的引數」,被稱為 hole,我們並沒有明確的給它B
。在展開這個 hole 時,我們用 meta variable?0
替換它。但 meta variable 必須考慮 contextual variables 的 rigid form,因此進行套用得到?0 B x
這引發問題
答案是,這些是 ?0 能看到且實際內容未知的變數,只能用 rigid form 替代
rigid form 是 dependent type 中即使是 open term 也必須先進行計算而被迫在實作中出現的一種值;由於 meta variable 而被迫出現的值則叫做 flex form
現在我們手上有的 term 是id (?0 B x) x
,現在執行id (?0 B x)
,我們得到型別為
的 term
\[ \lambda x. x \]注意到 \((x\ :\ (?0\ B\ \textcolor {red}{x}))\) 中兩個 \(x\) 來源不同,不可混用,我用顏色表示它們的 scope 其實不同這件事
現在進入到把這個 term 套用到 x 上的環節了,因此觸發 \(x\ :\ B\) 是否是 \(?0\ B\ x\) 的 term 的合一計算,我們概念上紀錄成
\[ ?0\ B\ x \stackrel {?}{=} B \]現在合一演算法必須找出合適的 \(?0\) 來滿足等式。我們知道 \(?0\) 應該是某種 lambda
\[ \lambda 1. \lambda 2. \fbox {?} \],顯然 \(\fbox {?} = 1\) 就會給出我們想要的答案,但這部分要怎麼做到?elaboration zoo 的演算法分成三個階段
這裡的重點是,既然 \(?0\) 已經套用了 \(B\) 與 \(x\),因此就創立關聯它所創立的 lambda 變數到其 contextual variables 的 map
1 -> B2 -> x
現在右手邊的 term 只需要看自己的每個 rigid form 有沒有被指向,只要這個 map 裡面查找到有變數是指向 rigid form 自己即反過來創立 rigid form 指向新名字的 map
因為我們右手邊的 term 是一個 rigid form \(B\),因此 map 是
B -> 1
用第二個 map 去改寫右手邊 term \(B\) 的內容,這樣我們就得到 \(\fbox {?} = 1\)
最後進行 abstraction,就得到了
\[ \lambda 1. \lambda 2. 1 \]在最開始的程式碼
let id {A : U} (x : A) : A := xlet id2 {B : U} (x : B) : B := id _ x
裡面,其實{}
中的綁定叫做隱式參數,這表示我們其實也可以用id x
來調用該函數。但這時候要怎麼知道需要補一個 hole 進去呢?elaboration zoo 作者提出的簡易方案就是區分 implicit \(\Pi \) type 與 implicit application,如此一來,當一個 implicit \(\Pi \) type 被 explicit apply 的時候,我們就知道要安插 hole 了
以id x
而言,如果要明確的用 implicit 調用它,就必須寫成id {B} x
,在語法就進行明確的區分。
這時候跳回去看「contextual variables 是 \(?0\) 能看到且實際內容未知的變數」就更能了解其理由了,因為已經能明確知道其內容的變數,如
let x = t
x
就是指向t
的情況,若右手 term 是x
,其實也會是t
去進行 unify。若右手 term 已經是 rigid form 又可參照,就更不需要成為 contextual variables,因為其 solution 就是把右手 term 原封不動放入,在反轉 map 的時候,只要記得這個 rigid 是非 contextual,就可以為它寫一個 identity mapping。
討論如何用 racket 中的 continuation 實作 effect system 的概念
一個 effect system 大概做了什麼,我們從effekt 語言的案例開始理解
effect yield(v : Int) : Bool
try { ... } with yield { n => ...; resume(n < 10) }
try
區塊中調用的函數f
可以用do yield(k)
來調用 handlerf
執行到do yield(k)
,就會跳轉到with yield
中繼續進行,並且n = k
resume
就會跳回去f
之後的do yield(k)
的續延繼續執行事實上,exception 系統也可以實現成,沒有調用 resume 的 effect handler,讀者或許也已經想出數種使用方法了吧?這正是 effect system 的魅力。racket 擁有比 effect handler 更複雜的機制(continuation with marks),不過 effect handler 機制有保障使用者不容易出錯的好處,因此在 racket 中模擬一套 effect system 就有它的意義,並且是有趣的挑戰。
call/prompt
[racket-0005]call/prompt
的主要功能,就如其名稱,是為被呼叫的函數提示一個標記,這個標記在abort/cc
會被使用。完整的call/prompt
調用是
(call/prompt f tag handler args ...)
f
是被調用的函數,中間的tag
是標記,handler
是處理標記的函數,剩下的都是f
的參數。讀者可以想像成
(with-handler [tag handler] (f args ...))
abort/cc
[racket-0006]abort/cc
的調用是
(abort/cc tag vs ...)
tag
當然就是先前 prompt 寫進去的tag
,而vs ...
會用來呼叫handler
(handler vs ...)
調用(make-continuation-prompt-tag)
產出,這個函數還可以接受一個 symbol 產生可讀的識別碼,並且每次調用這個函數,產生的 tag 都算是不同的 tag,勿必要儲存好這個實體。
要想實現 exception 目前的程式已經完全充分了,只要寫下
(define (f params ...) (abort/cc tag "cannot read file ..."))(call/prompt f tag (λ (err) (printf "got err ~a~n" err)) args ...)
即可。事實上 racket 自身的的 exception 也是這樣實作的,要考慮的問題是,前面我們看過resume
可以跳回去被呼叫的函數!這是如何做到的?
call/cc
[racket-0007]call/cc
這個函數是 call with current continuation 的意思,比如說在下面的程式碼中
(* 2 1)
1
的 continuation 就是把1
挖掉留下的(* 2 hole)
,故下列程式碼
(* 2 (call/cc (λ (k) (k 1))))
的結果是2
。讀者可以想像k = λ (hole) (* 2 hole)
,這在實作上不太正確,但對理解很有幫助。
一般來說,racket 的函數會簡單的寫成
(define (f params ...) stmt1 ... stmtn)
如果我在其中安放一個call/cc
會發生什麼事呢?
(define (f params ...) ... (call/cc (λ (k) ...)) stmtk ...)
答案是k = λ () (begin stmtk ... stmtn)
。由於 racket 自動把
stmt1 ... stmtn
包裝成(begin stmt1 ... stmtn)
,而
(begin stmt1 stmt2 ...)
中stmt1
的 continuation 是(begin stmt2 ...)
,以此類推就很容易理解k
等於什麼了。
我們正是需要使用call/cc
來做出 resume 的效果。
在f
中我們寫下
(define (f params ...) (call/cc (λ (k) (abort/cc tag k ...))))
在call/prompt
的 handler 中新增一個resume
參數,這樣就完成了。讀者可以填補下面的程式中的空白來檢驗結果,也充當練習
(define (f params ...) (call/cc (λ (k) (abort/cc tag k ...))) ...)(call/prompt f tag (λ (resume ...) ... ; 跳回 f 繼續 (resume)) args ...)
到這裡我們已經有了運行的基礎,要改善有幾個方向可以參考
dynamic-wind
)我們下次見。
As I told inintegrate forster site with existed webmentions tools, I will explain how to interact with API ofwebmention.io. Basically, you send a HTTP GET to the link below
https://webmention.io/api/mentions.jf2?domain=<your domain>&token=<your token>
You can get token atsetting page, the result you will get will be like below
{ "type": "feed", "name": "Webmentions", "children": [ ... ]}
each children is
{ "type": "entry", "author": { "type": "card", "name": ..., "photo": ..., "url": ... }, "url": <source>, "published": null, "wm-received": ..., "wm-id": ..., "wm-source": ..., "wm-target": <target>, "wm-protocol": "webmention", "like-of": <target>, "wm-property": "like-of", "wm-private": false}
so you can parse this JSON and produce mention HTML for each target, and if you don't want to pull the whole feed, you can setsince
as below
https://webmention.io/api/mentions.jf2?domain=<your domain>&token=<your token>&since=<time>
time format2017-06-01T10:00:00-0700
. Of course, if you would not like to manage these mentions by hand, you can also consider my projectwebmention_db, which maintains mentions data for you at local.
Discuss how to make webmentions worked for forester.
This is a following post ofthe concept of webmention and forester, show how can you integrate a forester site with existed webmentions tools. To provide webmentions, the document must have a<link>
to provide webmention endopint, you don't have endpoint at this moment, that's why we need webmention.io
Go towebmention.io, there is aWeb Sign-In form, put your<domain>
into it. Then it would load email viaindie auth (you must provide the following content inindex.html
for it)
<head> <link rel="me" href="mailto:your-mail">your-mail</a> <link rel="me" href="your-mastodon">Mastodon</a> <!-- you still haven't have endopint, just remind you once get one, back to here to insert it --> <link rel="webmention" href="<endpoint>" /></head>
then send you a verify mail, after you login and click sites tab you will see a picture like
ClickGet Setup Code, then you will see link like below
https://webmention.io/<domain>/webmention
that's the<endpoint>
for your site. We need to put it intotree.xsl
<head> …… <link rel="webmention" href="<endpoint>" /> ……</head>
If you want to send POST request to webmention.io manually, then here we already complete, but if you want to combine social media, we need to do more.
bridgy is a complex service, it plays several roles, but use it is relatively easy. At home page, you should see
I only use mastodon as example, you click the mastodon button, then get
clickCross-post to a Mastodon account..., unless your site is also a fediverse instance and know what to do. Then it would list your accounts (connected to bridgy) atClick to open an account you're currently logged into, go for one then you would see a formEnter post URL:, that's the place to give it your post link, but no rush, we need to prepare something.
https://domain/xxx.xml
(I openan issue for this)To make ahttps://domain/xxx.html
be a proper document, we must providemicroformat, so you will need to macro
\def\hentry[descrption]{ \<html:div>[class]{h-entry}[hidden]{true}{ \<html:p>[class]{e-content}{ \descrption } }}
and invoke\hentry{describe the tree}
in every tree that you want to provide webmentions.
Now, your tree has proper content, the final step is usingxsltproc
xsltproc default.xsl xxx.xml > xxx.html
to provide html version for post, then cross post html link on bridgy.
If all correct, you will be able to see theDashboard of webmention.io has a list of reactions, which is made by people click like, repost, or reply your toot on mastodon. You might wondering do I missing something here? Yes, we want webmentions because we want to show reactions on our site, we will interact with webmention.io's APIs to collect mentions data, so that we can show them, that will be the next post.
Discuss how can we implement a webmention receiver for forester.
Each post in forester will be a xml (let's use my site as the examplehttps://dannypsnl.me/xxx.xml
), post should provide the following content in<head></head>
<link href="https://dannypsnl.me/webmention-endpoint" rel="webmention" />
According towebmention spec, if someone tries to notify my site that there is a link mentions my post, then she has to do the following:
curl -I https://dannypsnl.me/xxx.xml
to get mywebmention endpoint in thehead
<link>
is the link refers to my postPOST /webmention-endpoint HTTP/1.1Host: dannypsnl.meContent-Type: application/x-www-form-urlencodedsource=<link>target=https://dannypsnl.me/xxx.xml
Therefore, a receiver is aPOST
handler. According to spec, we can
201
withLocation
in header pointing to the status URL202
and asynchronously perform the verification200
and synchronously perform the verification (not recommended), by section 3.2.2Webmention verificationshould be handled asynchronously to prevent DoS (Denial of Service) attacks.
source
andtarget
are valid URLs [URL] and are of schemes that are supported by the receiver. (Most commonly this means checking that thesource
andtarget
schemes are http or https).source
URL is the same as thetarget
URL.target
is a valid resource for which it can accept Webmentions. This checkshould happen synchronously to reject invalid Webmentions before more in-depth verification begins. What a "valid resource" means is up to the receiver. For example, some receivers may accept Webmentions for multiple domains, others may accept Webmentions for only the same domain the endpoint is on.If the receiver is going to use the Webmention in some way, (displaying it as a comment on a post, incrementing alike counter, notifying the author of a post), then itmust perform an HTTP GET request onsource
, following any HTTP redirects (andshould limit the number of redirects it follows) to confirm that it actually mentions the target. The receivershould include an HTTP Accept header indicating its preference of content types that are acceptable.
If the Webmention was not successful because of something the sender did, itmust return a 400 Bad Request status code andmay include a description of the error in the response body.
However, hosting a receiver can be annoying, so the next post I will introduce how to build on the top of some existed tools.
Dockerfile 的內容
FROM ubuntu:oracularRUN apt-get updateRUN apt install -y opamRUN apt install -y build-essentialRUN opam init -yRUN git clone https://git.sr.ht/~jonsterling/ocaml-foresterRUN cd ocaml-forester; opam pin -y .RUN apt install -y curlRUN curl https://sh.rustup.rs -sSf | \ sh -s -- --default-toolchain stable -yENV PATH=/root/.cargo/bin:$PATHENV PATH=/root/.opam/default/bin:$PATHRUN cargo install forest-serverCMD [ "forest", "watch", "1313", "--", "build --dev dev.toml" ]
大致上就是下載opam
、forest-server
等必要工具,然後指定指令監看檔案變化進行 reload。用docker build . -t forest:latest
產出 image。
services: forest: image: "forest:latest" working_dir: "<hostpath/to/your-forest>" ports: - "1313:1313" labels: - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`forest.localhost`)" - "traefik.http.routers.whoami.entrypoints=web" volumes: - "./:<hostpath/to/your-forest>" traefik: image: "traefik:v2.10" container_name: "traefik" command: - "--api.insecure=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" ports: - "80:80" # Web UI - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro"
<hostpath/to/your-forest>
這部分不能省略,因為這樣每篇 tree 中的 edit 按鈕才會是正確的 host 路徑。執行docker compose up -d
啟動 containers。
最後你可以在forest.localhost:1313
存取到 forest,之後就只需要修改跟新增 tree 即可。
自g0v 貼文 改寫
metric 就是在測量長度。不過在歐式空間裡面討論嵌入其中的曲面時,曲面有外部空間切向量,也就是歐式空間的向量可以使用。如果曲面沒有外空間,就需要自己做一個出來,這就引出了Riemann metric 的想法:對可微分流形 \(M\) 的每一點 \(p\) 考慮抽象的切空間 \(T_pM\)(不考慮 \(T_pM\) 到底是什麼),重點是隨點附上內積函數 \(g : T_pM \times T_pM \to R\),因為是模仿內積所以有 bilinearity, positive-definiteness, symmetry 等性質
現在考慮曲線 \(y : [0, 1] \to M\),在每一點度量 \(T_pM\) 向量並積分(加起來)即是曲線長度。又隨著區間 \(t : [0, 1]\) 改變,會有對應變化的 \(p\) 點,因此模仿並定義
\[ \text {length}(y) = \int _0^1 \sqrt {g( \frac {d y}{d t} , \frac {d y}{d t} )} dt \]\(\sqrt {g( \frac {d y}{d t} , \frac {d y}{d t} )}\) 是 norm 的定義,積分因為是跟著 \(t\) 變化,因此依賴 \(y\) 的參數 \(t\) 來定義。如此一來就可以問下一個問題:根據 g 是從 a 到 b 的最短曲線是誰,這就是曲面上的直線的概念(然而,全域與局部最短線,是不一樣的問題,考慮整體將會複雜許多)。
從上次提到之後,我到現在都會斷斷續續的思考這個問題。現在我認為 type pattern matching 在 dependent type 中是一個失敗的想法。或許這個方案只是太過複雜而非不能達成,但我認為目前缺點已經超過這套系統能帶來的好處。下面我會討論一些精簡的推導與相應的結果
U
之外要有一個特殊的 universe,之後會稱其為U-
。A : U-
身為型別與身為值不一樣,這需要一個區分用法的方式,可以考慮極化計算性作為解法,所以到這裡我還沒有停步。然而,有一個特殊的規則是變數不能是U-
,免得出現 stuck value 出現在U-
的計算之中,但這在 type pattern match 的變數 case 中會出現,這裡是我開始認為這套系統沒機會的地方。關於這種情況,我有兩個想法
U- or U
的選擇,讓型別定義可以用U
表示變數的情況,但這又讓型別 universe 更複雜了,我認為這個方向沒什麼機會。U-
的限制,因為這類 inductive types 必然不能被多態函數使用,因此放鬆使用位置之後就能寫出定義時是多態,而使用時必然是單態的新型態函數。這個方向還需要再限制不讓x : U-
是隱式參數,這樣就不可能有 stuck value 出現。此外我沒有想到有什麼錯誤,但這複雜化了實際使用,所以到這裡我就暫時告一段落。
翻杯子遊戲是一個很有名的派對遊戲與典型的奇偶問題。遊戲從 3 個向下的杯子與 2 個向上的杯子開始,每次可以選兩個不同的杯子,被選中的杯子方向會翻轉,問是否有辦法反覆這個動作,得到五個向上的杯子。
在開始閱讀之前,你可以自己先想想看問題的方案。若有辦法達成,提出需要執行什麼步驟;若不可能達成,提出為何無法達成。
正如標題說的,我們想用 agda 來玩這個遊戲,所以需要知道怎麼用這個程式語言。
我使用的編輯器工具是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 中你打的程式碼直接當成結果,一樣類型要是正確的hello : A → B hello a = {! !}ctrl+c, ctrl+c 會問你要把哪個變數用構造子分開,回答
a
,假設有a1
與a2
兩個構造子,程式就會變成hello : A → B hello a1 = {! !} hello a2 = {! !}
使用 Linux 的使用者可以更改預設的 copy/cut 指令以免衝突。
\bN | ℕ |
---|---|
\bP | ℙ |
\:: Vector 類型的串接符號 | ∷ |
\_1 表示下標 1 | ₁ |
\^1 表示上標 1 | ¹ |
\^- 表示上標負號 | ⁻ |
\equiv | ≡ |
\nequiv | ≢ |
\< | ≡⟨⟩ 中的⟨ |
\> | ≡⟨⟩ 中的⟩ |
\r 函數類型的分隔符 | → |
\Gl 匿名函數的開頭 | λ |
由於每次要找兩個杯子做翻轉,而且杯子只有上跟下的分別,因此我們可以考慮用Data.Parity
來表示杯子的狀態,其中_⁻¹
表示可以翻轉杯子,所以引用
open import Data.Parity.Baseopen import Data.Parity.Properties
接著,五個杯子可以用 vector 表示,所以引入模組並定義
open import Data.Natopen import Data.Vecopen import Data.Vec.Properties_Cups : ℕ → Setn Cups = Vec Parity n
現在,我們可以寫下初始狀態與目標狀態
open ParityinitS : 5 CupsinitS = 0ℙ ∷ 0ℙ ∷ 1ℙ ∷ 1ℙ ∷ 0ℙ ∷ []target : 5 Cupstarget = 1ℙ ∷ 1ℙ ∷ 1ℙ ∷ 1ℙ ∷ 1ℙ ∷ []
為了證明從initS
到target
是不可能的
0ℙ ∷ 0ℙ ∷ 1ℙ ∷ 1ℙ ∷ 0ℙ
與0ℙ ∷ 0ℙ ∷ 1ℙ ∷ 0ℙ ∷ 1ℙ
之間的差異於我們無關緊要。由於可能的杯子狀態只有0ℙ
跟1ℙ
,所以可能的選擇有
(0ℙ, 0ℙ)
到(1ℙ, 1ℙ)
(0ℙ, 1ℙ)
到(1ℙ, 0ℙ)
(1ℙ, 0ℙ)
到(0ℙ, 1ℙ)
(1ℙ, 1ℙ)
到(0ℙ, 0ℙ)
中間兩個是 identical 的轉換,由於我們上面討論的第二點,他們不會對狀態造成改變;第一個會把原封不動變成翻轉兩次,最後一個把翻轉兩次變成不動。所以綜合而論就是,若把n Cups
中的Parity
全部直接加起來,就能夠分辨狀態是否有可能互換,據此定義χ
函數。
χ : ∀ {n} → n Cups → Parityχ [] = 0ℙχ (x ∷ cups) = χ cups + x
因此只論遊戲目的,下面的兩個事實就已經證明答案是不可能達成,因為兩者的奇偶性不同,然而我們唯一能做的動作不會改變奇偶性。
lemma₁ : χ initS ≡ 0ℙlemma₁ = refllemma₂ : χ target ≡ 1ℙlemma₂ = refl
但我們還想要知道廣泛的來說,如何將事實表現成定理,並且應用到任意n Cups
上,因此有
theorem : ∀ {n} → (i j : Fin n) → (a : n Cups) ------------------------------------------------ → χ ((a [ i ]%= _⁻¹) [ j ]%= _⁻¹) ≡ χ atheorem i j a = begin χ (updateAt (updateAt a i _⁻¹) j _⁻¹) ≡⟨ lemma j (a [ i ]%= _⁻¹) ⟩ χ (updateAt a i _⁻¹)⁻¹ ≡⟨ ⁻¹-selfInverse (sym (lemma i a)) ⟩ χ a ∎ where open ≡-Reasoning open Lemma
其意義是,對任意有限多個杯子進行兩次翻轉,奇偶性不變。這個定理比實際遊戲進行的行為更廣泛一些,i ≢ j
才是對應現實中的翻杯子行為,因為選擇是先進行的,而翻轉是同時做。但因為對同一杯子翻轉兩次也不會改變奇偶狀態,所以i ≡ j
也行。其中
a [ i ]%= _⁻¹
表示對a
的位置i
套用翻轉函數。x ≡ y
表示要證明x
等於y
。begin
到∎
用來寫出等式替換的過程,程式a ≡⟨ lemma ⟩ b的意義是,根據
lemma
可知a ≡ b
。這些程式要通過引用open import Relation.Binary.PropositionalEquality並使用
open ≡-Reasoning
來存取。Fin n
需要引用open import Data.Fin由於跟
Data.Nat
有名稱衝突,需要用using
跟renaming
控制引用的符號。上面的open Lemma
是一個內部模組,下面留空讓你自行證明
module Lemma where lemma : ∀ {n} → (i : Fin n) → (a : n Cups) ---------------------------------------------------------- → χ (a [ i ]%= _⁻¹) ≡ χ a ⁻¹ lemma i a = {! !}
結論當然還可以再推廣,例如不再是翻兩個而是三個杯子呢?假使奇偶相同,只做某動作就一定能得到某狀態嗎?或是假使動作能改變奇偶性,是否就一定能達成某狀態呢?把玩想像構物的有趣之處,歡迎自行體驗。
由於很多TLA+ 入門教學似乎都沒有談到實務上要從哪裡開始使用 TLA+,所以這裡我想介紹實際上要怎麼做。一個 TLA+ 的檔案以.tla
為副檔名,其中由--- MODULE name ---
開頭,由===
結尾,例如
---- MODULE plustwo ----=====
在其中可以引用模組,寫成EXTENDS xxx, yyy, ...
---- MODULE plustwo ----EXTENDS Integers=====
比起直接寫出Spec
等不變式,先寫PlusCal language 的程式再使用用它生成的Spec
不變量會更簡單也更實用。因為 TLA+ 會嘗試生成所有可能的狀態,有可能出現所謂的unbound model,就結果而言對它進行檢查永遠不會完成。用 PlusCal 語言寫的程式相對容易發現這種錯誤。
---- MODULE plustwo ----EXTENDS IntegersCONSTANT Limit(* --algorithm plustwovariables x = 0;begin while x < Limit do x := x + 2; end while;end algorithm; *)\* BEGIN TRANSLATION (chksum(pcal) = "3f62e9ff" /\ chksum(tla) = "239a9ecd")\* END TRANSLATION =====
由 PlusCal 產出的不變量會被包在BEGIN TRANSLATION
到END TRANSLATION
裡面,可以發現它還會檢查 checksum。由於這個區塊內的程式會被機器生成的內容覆蓋,要記得千萬不要把自己寫的不變量放在這裡面。
上面的CONSTANT Limit
可以在 model 的設定檔.cfg
中指定,這是為了避免把常數寫死在 TLA+ 主程式中,好在檢查前可以進行修改。
在有了這些程式之後,可以開始增加自己的不變量
Even(x) == x % 2 = 0IsInc == x >= 0Inv == IsInc /\ Even(x)THEOREM Terminated == Spec => Termination
IsInc
要求x
總是大於初始值0
Even(x)
要求我們寫的程式只會產生偶數Inv
把所有我們想證明的不變量組合在一起,/\
表示邏輯的「a 且 b」語句。我想很容易猜到\/
表示邏輯的「a 或 b」語句THEOREM
部分宣告Spec
蘊含Termination
不變量,這兩者都是 PlusCal 產生的,所以不用太在意細節,這裡的意義是證明程式確實會終止。
這裡介紹了 TLA+ 如何運作,TLA+ 對現實程式的幫助會體現在編寫非同步的程式時,TLA+ 擅長對只有有限狀態、可以使用經典邏輯推導的程式進行檢查,主要可以發現死鎖與違反不變式等錯誤。對 TLA+ 所使用的數學方面的學習可以參考 Lamport 本人寫的A Science of Concurrent Programs。
在我最早的想法中,根據 \(\text {range }T = \text {null }T\),可以看出 \(T(Tv) = 0\) 對所有 \(v \in \R ^4\) 成立。因此,可以假設
\[ T = \begin {bmatrix} a_{11} & a_{12} & a_{13} & a_{14} \\ a_{21} & a_{22} & a_{23} & a_{24} \\ a_{31} & a_{32} & a_{33} & a_{34} \\ a_{41} & a_{42} & a_{43} & a_{44} \end {bmatrix} \]計算 \(TT\) 可以得
\[ T^2 = \begin {bmatrix} {a_{11}}^2 + a_{12}a_{21} + a_{13}a_{31} + a_{14}a_{41} & a_{11}a_{12} + a_{12}a_{22} + a_{13}a_{32} + a_{14}a_{42} & a_{11}a_{13} + a_{12}a_{23} + a_{13}a_{33} + a_{14}a_{43} & a_{11}a_{14} + a_{12}a_{24} + a_{13}a_{34} + a_{14}a_{44} \\ a_{11}a_{21} + a_{21}a_{22} + a_{23}a_{31} + a_{24}a_{41} & a_{12}a_{21} + {a_{22}}^2 + a_{23}a_{32} + a_{24}a_{42} & a_{13}a_{21} + a_{22}a_{23} + a_{23}a_{33} + a_{24}a_{43} & a14a_{21} + a_{22}a_{24} + a_{23}a_{34} + a_{24}a_{44} \\ a_{11}a_{31} + a_{21}a_{32} + a_{31}a_{33} + a_{34}a_{41} & a_{12}a_{31} + a_{22}a_{32} + a_{32}a_{33} + a_{34}a_{42} & a_{13}a_{31} + a_{23}a_{32} + {a_{33}}^2 + a_{34}a_{43} & a14a_{31} + a_{24}a_{32} + a_{33}a_{34} + a_{34}a_{44} \\ a_{11}a_{41} + a_{21}a_{42} + a_{31}a_{43} + a_{41}a_{44} & a_{12}a_{41} + a_{22}a_{42} + a_{32}a_{43} + a_{42}a_{44} & a_{13}a_{41} + a_{23}a_{42} + a_{33}a_{43} + a_{43}a_{44} & a14a_{41} + a_{24}a_{42} + a_{34}a_{43} + {a_{44}}^2 \\ \end {bmatrix} \]因此這裡就有了 16 個方程式。可以知道
\[ a_{i1} = \frac {-(a_{i2}a_{2j} + a_{i3}a_{3j} + a_{i4}a_{4j})} {a_{1j}} \]令 \(a_{1j} = 1\),得
\[ 1 = a_{11} = \frac {-(a_{i2}a_{2j} + a_{i3}a_{3j} + a_{i4}a_{4j})} {a_{11}} = -(a_{i2}a_{2j} + a_{i3}a_{3j} + a_{i4}a_{4j}) \]接著指定 \(a_{21} = 1, a_{31} = -1, a_{41} = -1\),得
\[ T = \begin {bmatrix} 1 & 1 & 1 & 1 \\ 1 & a_{22} & a_{23} & a_{24} \\ -1 & a_{32} & a_{33} & a_{34} \\ -1 & a_{42} & a_{43} & a_{44} \end {bmatrix} \]接著依次指定值滿足方程式,如
就可以湊出
\[ T = \begin {bmatrix} 1 & 1 & 1 & 1 \\ 1 & -1 & 1 & -1 \\ -1 & -1 & -1 & -1 \\ -1 & 1 & -1 & 1 \end {bmatrix} \]不過這個辦法適合求出具體的矩陣,卻很難用來證明任意次數的空間有或無這種線性變換的存在。有效率的方法是使用rank-nullity,在限制下可以知道 \(\text {rank}\;T = 2 = \text {nullity}\;T\) 因此只對 \(2\) 個維度造成影響的矩陣都可以。同理可以推論奇數有限維度皆不滿足,故 \(\R ^5 \to \R ^5\) 滿足這個性質的矩陣不存在。
最基本的範例如下
(component (core module $M (func (export "dup") (param i64) (result i64) local.get 0 local.get 0 i64.add) ) (core instance $m (instantiate $M)) (func $run (param "a" s64) (result s64) (canon lift (core func $m "dup")) ) (export "mdup" (func $run)))
這段程式碼以.wat 的 component 擴展格式寫成,其意義是
dup
canon lift
提升即可。不過要注意的是,如果函數帶有需要記憶體操作的簽名,例如有字串參數,就需要提供 memory 與 realloc 等參數,好讓 runtime 知道如何進行資料在不同 component 之間編碼傳遞mdup
,外部的使用者就可以調用了考慮 \(A\) 範疇是 \(0 \to 1\) 與 \(B\) 範疇,其中 \(fg=fh=k\) 但注意 \(f\) 不是 mono,因為這沒有蘊含 \(g=h\)
因此 functor category \([A,B]\) 是 \(B\) 的 arrow category。現在我們可以指出 natural transformation \((1_B, f) : (B,B)\to (B,C)\) 是 \([A,B]\) 中的 monomorphism,但其 component \(f\) 並不是 mono。要檢查 \((1_B,f)\) 是 mono 可以列出所有可以串在前面的 arrows,在這裡有四個。
對應的結果是 (左到右,上到下)
確實滿足 mono 的特性,\((1_B,f) \circ a = (1_B,f) \circ b\) 蘊含 \(a = b\)。
引用的程式庫
using Catlab.WiringDiagrams, Catlab.Graphicsimport Convex, SCSusing Catlab.Theories
產生 wiring 圖的程式
A = Ob(FreeBiproductCategory, :A)g = (mcopy(A) ⊗ id(A)) ⋅ (id(A) ⊗ mmerge(A))to_composejl(g)
g
是 monoidal category 的 morphism,to_composejl
會把它畫成 wiring diagram;也可以用to_tikz
或是to_graphviz
來畫。
要是想匯出到 latex 檔案中使用,可以參考下面的程式產生 tikz 程式。
import Catlab.Graphics: TikZto_tikz(g) |> TikZ.pprint
要回答這個問題,就要先知道什麼是程式語言,然後我們才能在這個基礎上解釋編譯器的目的與定義。
一個程式語言必然是有語法,是有限語法規則構成的一種形式系統,與用作推理基礎的邏輯系統不同的是
例如 XML 或是 JSON 等純標記語言就是刻意不設計對應的計算系統的。
以有計算規則為前提,則一個程式語言一般會有操作語意與指稱語意兩種描述方式。定位上,操作語意通常是實作程式語言時會參考的一組演繹規則,寫成相繼式,如
\[ \frac { \Gamma \vdash A \Downarrow u, B \Downarrow v }{ \Gamma \vdash A + B \Downarrow u + v } \]指稱語意是找出一組數學物件,並證明自己完全抽象了操作語意 (也就是滿足充分性定理),用來推理程式語言的行為的一個模型。細節在遞迴的表示一文中有描述,數學記號 \(\mathcal {C}\llbracket e \rrbracket \) 就是在描述一個接受語法,回傳相應的數學物件的指稱語意函數。另外可以進一步參考Gunter 的書。
此外,有一些具有計算規則,但不要求要有通用計算性的語言,這一類語言通常被稱為宣告式。
HTML、css 在瀏覽器底下具有計算意義,用來產生對應的畫面。還有 Prolog 與 SQL 等語言,一般都只是宣告所謂的query,並讓一些特定的求解系統自己計算答案。這層意義下 computer algebra system 或是 z3 這種 logic solver 都算是程式語言。
所以語法規則這部分的形式系統對程式語言來說必須存在,但描述計算的形式系統對則不是必要的,研究具有計算規則的程式語言對應的。
所以,編譯器其實只在語法規則與計算規則都有規範的程式語言上有意義,編譯器的意義是把目前程式語言的語法重新寫成目標語言的語法,所以讀者很可能聽過重寫系統這個說法。
電腦事實上是一種計算系統的物理案例,我們用電路把某種通用計算系統實現出來,用電訊號表示計算系統的計算結果。CPU 讀取指令進行相應電訊號發射,並將結果儲存在特定位置,這基本上就是現代電腦的運作機制。
但指令需要編碼才能被 CPU 讀取,因此會有一系列的數字與對應的指令,組合語言則是為了讓人類可以閱讀這些指令而設計的編碼,組譯器因此基本上只要直接把指令文字變成一連串數字即可!因此,可以看出組合語言確實是一種程式語言,而組譯器是最簡單的把語法變成數字語法的重寫系統,對應的計算系統則是電腦硬體執行的那個計算系統。
當然這省略了組譯器的模組化功能部分,不過這部分對理解組譯器的定位沒有什麼幫助。這部分是由被稱為 linker 的程式進行,把不同的物件檔連結起來,比較好的參考書籍有《Linker and Loader》
當然這時候有人會質疑,為什麼不要直接用數字指令,或是任意一種底層的可計算結構編寫計算就好呢?事實上,這種觀點等於在說他認為不需要有任何新的程式語言的發明,因為程式語言存在最主要的理由之一就是要賦予計算規則「好用的」語法規則,讓不同的開發者可以有效的用來溝通。現在,可以總結編譯器為,把程式語言重寫成另一種程式語言的系統!所以下面我們就有計算規則的這類程式語言,討論編譯器必須滿足哪些要求,與實現上的概覽。
也就是說如果一個語法 \(M\) 在當前的計算規則下應該得出 \(v\),那麼編譯之後得到的目標語法 \(M'\) 在目標計算系統裡面也應該算出 \(v\)。很不幸的是這件事通常沒這麼簡單,因為程式語言擁有的一些高級抽象很可能在組合語言這類語言裡面不存在,像Bool
這種值在組合語言裡面常常就只是 \(0\) 與非 \(0\)。這導致我們本來就需要對這類抽象進行編碼,當涉及到連續記憶體配置時 (像是字串與陣列等),這件事就更難做對了。不過總之語意被改變一般被認為是一種編譯器的錯誤。
除了不改變語意,編譯器還需要達成一些額外的目標,其中一項就是根據資料盡可能的最佳化在目標計算系統上的執行速度、或是減少空間消耗等,不過第二項就我所知幾乎都是開發者的工作。
讀者現在應該了解編譯器的存在目的與一點點形式化的背景,可以進一步學習指稱語意或是最佳化策略來了解程式語言的各種面向,此外,可計算程式語言一般還需要能與環境互動,這部分本身就有相當的複雜性,或許未來能夠再寫一篇文章介紹。
zoxide 這個軟體讓我們用簡短的縮寫跳轉到曾經去過的目錄
This is a smartercd
command. When I doz xxx
, it would bring me to the most frequently used directory with "xxx" in the name. More you use it, it would get more accurated.
atuin 紀錄 CLI history,互動操作更方便而且可以跨電腦同步指令
atuin
gives better interactive interface to do command history search, once you found a target, use
<tab>
to back to shell and edit the command; and<enter>
to execute the command directly.There is apost teach you to use self hosted sync server.
sd
替換sed
指令
Intuitive find & replace CLI (sed alternative).
sg
指令用語法而不是文字搜尋,對程式碼進行搜尋的效果會更好
A CLI tool for code structural search, lint and rewriting.
The tool send files from one computer to another securely.
croc 可以處理像是 keys 遷移這類問題
gpg -a --export > publickeys.ascgpg -a --export-secret-keys > privatekeys.ascgpg --export-ownertrust > trust.txt
Then use tools e.g.croc to transfer files. Apply below commands in new machine
gpg --import publickeys.ascgpg --import privatekeys.ascgpg -Kgpg -kgpg --import-ownertrust trust.txt
Now your gpg is migrated.
一般的OCaml 函數可以寫成
let f x y z = ...
一個直覺的想法是:每個型別都解釋成一個可數集合,該型別的 term 解釋成這個集合的元素。但有些函數會用到自己本身,例如整數階乘函數
let rec fac n = if n = 0 then 1 else n * fac(n-1)
它的值是什麼呢?答案是
\[ \mu (x : int \to int). \lambda (n : int). \begin {aligned} \begin {cases} 1 &\quad &(n = 0) \\ n \times x(n-1) &\quad &(n \ne 0) \end {cases} \end {aligned} \]\(\mu \) 中的 \(x\) 就是fac
自己,把原始 OCaml 程式中的fac
換成 \(x\) 即可。問題是集合論沒有辦法充分解釋這個運算,具體來說,集合解釋不滿足PCF 的 Adequacy theorem。
If \(M\) is closed term of ground type and \(\mathcal {C}\llbracket M \rrbracket = \mathcal {C}\llbracket V \rrbracket \) for a value \(V\), then \(M \Downarrow V\).
對一個形式系統來說,需要證明一個假定的 model 確實能表現系統的特徵,所以才需要證明這個定理。參考computational adequacy (of semantics)
一般來說,只考慮構造與操作規則的話,可以記成下面這樣
但我們想要知道在數學上可以用什麼物件表示運算子 \(\mu \),也就是指稱語意 (denotational semantic),我先定義一個這個目標需要達成的等式。
解釋 (interpretation)
\[\llbracket \Gamma \triangleright \mu (x:t). M : t \rrbracket \rho \]必須是一個能滿足下面等式的 \(\llbracket t \rrbracket \) 元素 \(d\)
\[d = \llbracket \Gamma , x:t \triangleright M : t \rrbracket (\rho [x \mapsto d])\]註:\(\rho \) 在後面講到語意解釋時會定義
問題是我們怎麼知道存在這麼一個元素呢?由於不動點定理,使得我們有動機把 \(\llbracket t \rrbracket \) 解釋成cpo,把計算解釋成 monotone function 再套用不動點定理。從而得到一個合理的定義:least fixed point 即是 \(\mu \) 的表示物件。
這裡採用 \(x \mapsto v\) 表示數學中的函數,\(x\) 是輸入 \(v\) 是輸出;但 \(\rho [x \mapsto d]\) 則是指 \(\rho \) 中的 \(x\) 被替換成 \(d\)
在開始之前我們需要大概了解 \(\mathcal {C}\llbracket x \rrbracket \) 這個解釋的定義。
需要 \(\rho \) 函數的部分,當我們在程式語言中寫下let f : T = M
時,就在 \(\rho \) 這個部分函數中加入了 \(f = M\) 的定義,注意到 \(\rho \) 是部分函數,因為也可能被問到未綁定的變數 \(z\),這時候 \(\rho (z) = \bot \)
把程式函數包裝成數學函數
直接利用作為解釋的數學函數進行調用
\(\mu \) 本身的公式倒沒有很複雜
\[ \mathcal {C}\llbracket \Gamma \triangleright \mu (x:t). M : t \rrbracket \rho = \text {fix}(f) \]其中數學函數 \(f\) 是
\[ d \mapsto \mathcal {C}\llbracket \Gamma , x : t \triangleright M : t \rrbracket \rho [x \mapsto d] \]但我們怎麼確認 \(\text {fix}(f)\) 的存在?我們已經知道 \(\mathcal {C}\llbracket t \rrbracket \) 是cpo。根據不動點定理我們知道只要再證明 \(f\) 是連續函數即可;接著根據下面的定理我們可以知道這能夠套用到任意來自 ground type 的 functional 上
If \(D\) and \(E\) arecpo, thenthecontinuous function space
\[ [D \to E] = \{ f : D \to E \mid f \ \text {is continuous} \}\]is a cpo under the pointwise order.
再來就可以選擇 least fixed point 作為 \(\text {fix}(f)\) 的解釋
\[\bigsqcup _{n \in \omega }d_n\]其中
不過這條鏈 \(d_n\) 不需要是唯一的,只要對任何一條都能這樣推理即可。
要證明函數 \(d \mapsto \mathcal {C}\llbracket \Gamma , x : t \triangleright M : t \rrbracket \rho [x \mapsto d]\) 對所有 \(\Gamma \)-環境 \(\rho \) 都成立有點麻煩,需要歸納所有的語法構造,所以這裡就跳過。或許哪天我會寫這部分,不過有興趣的讀者可以先參考Gunter 的書的第四章,或是自己根據 PCF 這個 metalanguage 進行證明。Sterling 的演講Synthetic Domains in the 21st Century 也是很好的資源。
quiver is a modern commutative diagram editor, and also is a proper small service to show what can we do with local k8s.
Notice that I do these withOrbStack, you will need to do proper modification to work on your computer, so this is not in introduction level.
AsOrbStack's document, every running service can be connected via domain*.k8s.orb.local
. So here we are going to create docker image for quiver.
First, you clonequiver repository into the current directory, then write downDockerfile
FROM python:3.11.2-slim-busterWORKDIR /appCOPY quiver/src /appCOPY app.py /appCMD [ "python3", "app.py" ]
Theapp.py
import http.serverimport socketserverPORT = 8000handler = http.server.SimpleHTTPRequestHandlerwith socketserver.TCPServer(("", PORT), handler) as httpd: print("Server started at localhost:" + str(PORT)) httpd.serve_forever()
Then use commanddocker build . -t quiver-quiver:latest
to create a docker image.
Now, we need configuration for pod and service.
apiVersion: v1kind: Podmetadata: name: quiver labels: app: quiverspec: containers: - name: quiver image: quiver-quiver:latest imagePullPolicy: Never ports: - containerPort: 8000 name: http-web-svc---apiVersion: v1kind: Servicemetadata: name: quiver-servicespec: selector: app: quiver ports: - protocol: TCP port: 80 targetPort: http-web-svc type: LoadBalancer
We use they via commandkubectl apply -f ./quiver.yml
.
Finally, you can go tohttp://k8s.orb.local and see you already run quiver tool on local machine. Other way is using traefik with docker compose, and goes tohttp://quiver.localhost.
在 docker compose 檔案的services
底下加入下列的代理服務設定
traefik: image: "traefik:v2.10" container_name: "traefik" command: - "--api.insecure=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" ports: - "80:80" # Web UI - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro"
並在實際的服務容器下加入 label 控制 traefik 的動作,就可以指定 DNS 域名了
labels: - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`xxx.localhost`)" - "traefik.http.routers.whoami.entrypoints=web"
市面上有越來越多的筆記軟體,而擁有發佈功能的也不少,也就是說當你寫好筆記時,就可以選擇是否要公開,這種方式非常好用,而且也不再需要擔心文章不能寫一半,這種模式下你的文章會隨著累積而自然組合出新的想法/成果。 在使用 Heptabase 一定時間之後,我對它也相當滿意,但隨著使用,我對能夠掌控細節的需要又開始出現,下面舉出我遇到的問題,以及未來的需求規劃,最終會談到如何在 forester 中實現。
已完成的軟體這種概念,是指一個軟體的功能已經沒有大幅度更動的必要,可以長期使用在產品上,而軟體本身只會進行必要的安全與移植性更新
外部連結是我讀到這個想法的地方對應到筆記軟體上,我不希望軟體一直更新,尤其是當我一打開工具需要寫筆記時,上面的更新按鈕非常的讓人煩躁。同時,這個想法也是一種解放我們原先對軟體想像的開端,比起軟體如何如何,更重要的是真的去做,外部連結裡面也談到冰與火之歌正是用這樣的軟體寫出。更多的想法可以參考公共程式與洪朝貴老師的盲人摸象看軟體。
白板在剛開始學習一個領域或是開發一個專案的時候非常的好用,但隨著技能與專案開始複雜化,白板的資訊就只是過多的無用資訊了。下圖是我的教學專案,一點編譯器入門就已經膨脹到這個程度,維護範疇論的白板經驗告訴我這是不可行的。當然,我知道白板的用途不是如此,問題是如果白板只是一種聯想用、暫時性的存在,那為何不直接用紙筆呢?
一個好的筆記軟體應該要能夠
下面我們就來談,forester 滿足與不滿足哪些要件。
forester 是一個精簡、hack 的工具,也就是說目前尚未有穩定的結果,我已經經歷過幾次大規模的更動,萬幸的是
正如前面所說,forester 的更新是為了更符合核心想法,所以在已完成這點上,是合格的。除此之外,forester 可以使用 \tex{\latex-preamble/xxx}{...}
來使用任何你有興趣的xxx.sty
(把.sty
原始碼封裝到變數\latex-preamble/xxx
中),因此生態成熟度相當高(latex 生態系),這點的直接成果就是可以使用 tikz 繪圖工具,下面是兩個案例。
A span is a \(\mathcal {C}\)-diagram \(A \leftarrow C \rightarrow B\), there is acategory of span with fixed \(\mathbb {C}\)-objects \(A, B\) is:
monad 是一個 endofunctor,所以必然跟某個範疇 \(C\) 有關,具有 \(M : C \to C\) 的簽名。並且,有兩個natural transformation
並滿足 monoid 條件。第一是 \(\mu \cdot (\eta \circ M) = id = \mu \cdot (M \circ \eta )\)
第二是 \(\mu \cdot (\mu \circ M) = \mu \cdot (M \circ \mu )\)
因此我們才說 monad 是 endofunctors 構成的 category 中的一個monoid object。
此外 RSS 是每個頁面都會有一個。在學術上,forester 也有針對 reference 的卡片分類,這裡引入一張卡片展示這個功能:
The language of ∞-categories provides an insightful new way of expressing many results in higher-dimensional mathematics but can be challenging for the uninitiated. To explain what exactly an ∞-category is requires various technical models, raising the question of how they might be compared. To overcome this, a model-independent approach is desired, so that theorems proven with any model would apply to them all. This text develops the theory of ∞-categories from first principles in a model-independent fashion using the axiomatic framework of an ∞-cosmos, the universe in which ∞-categories live as objects. An ∞-cosmos is a fertile setting for the formal category theory of ∞-categories, and in this way the foundational proofs in ∞-category theory closely resemble the classical foundations of ordinary category theory. Equipped with exercises and appendices with background material, this first introduction is meant for students and researchers who have a strong foundation in classical 1-category theory.
@book{riehl_verity_2022, place={Cambridge}, series={Cambridge Studies in Advanced Mathematics}, title={Elements of ∞-Category Theory}, DOI={10.1017/9781108936880}, publisher={Cambridge University Press}, author={Riehl, Emily and Verity, Dominic}, year={2022}, collection={Cambridge Studies in Advanced Mathematics}}
我個人使用的安裝方式是從原始碼編譯(用 nix 管理),因為我會參與開發跟使用最新功能,但這個辦法對沒有那麼想折騰的人來說可能不是那麼理想,這時候可以選擇用opam install forester
直接使用 opam 上註冊的最新版本。如果你也想要直接用原始碼的話,那麼進入專案之後執行opam pin add -y .
即可,往後更新只需要執行下列的指令就可以完成。
git pullopam updateopam upgrade
此外changelog 頁面也值得關注,具體的概念跟使用應該去這邊學習。如果你熟悉 nix 的話也可以用我做的template 專案當起點。
forester 具有很強的自由度,這也是我寫這段的理由:展示用法的多樣化。我這裡所談的管理方式或許對你來說沒有必要,這是我為什麼現在才談這件事。在我目前對筆記軟體使用上的最後一哩路是專案時程紀錄,因為一個大型的專案會涉及到長期追蹤,在時程安排上,我目前使用的是 orgmode 跟 Heptabase。由於提醒事項這個功能 forester 沒有也不會提供這類功能,所以我不會討論這部分,而且也不需要,我未來會只用 orgmode 紀錄警急需求,而專案則記錄在 forester 上。因此,這裡要談個人專案管理需要什麼。由於 forester 也有 backlink,因此我們可以考慮在每日頁面裡面提及某個事項,比如軟體專案中的某個功能是在這一日進行。並且在專案中建立兩個 scope transclude
\scope{ \put\transclude/title{working} \put\transclude/expanded{true} \query{ \open\query \isect{\tag{project-xxx}}{\tag{TODO}} }}\scope{ \put\transclude/title{complete} \put\transclude/expanded{true} \query{ \open\query \isect{\tag{project-xxx}}{\tag{DONE}} }}
上面的 scope transclude 表示當有project-xxx
與TODO
這兩個 tag 時視為事項正在進行,下面表示事項已完成。而我只會在DONE
的事項上面指定日期,因此我就知道是哪一天完成。但這也有一些缺點,比如我可能需要知道事項是什麼時候開始的,由於 forester 格式開放,因此我可以自行加上我需要的特殊閱讀工具,所以這些也是我在思考要怎麼加入 forester 或是有什麼額外工具可以做到的部分,因此在未來我或許可以談更多關於工作紀錄管理的細節,不過這一段就先到這裡吧。
我同意除了 latex 的超優秀支援,其他很多功能都是封閉軟體如我所使用的 Heptabase 可以做到的,所以結論要談為什麼這還是有嘗試的價值。
但在下判斷之前,也要了解到我是使用者也參與開發,所以我的判斷可能過於樂觀。因此我也推薦讀者要學習觀念而不是工具,並也考慮另一個或許不錯的替代品AFFiNE。最後,就如在已完成中所述,你要真的有在寫筆記,這一切才會對你有意義。
如果有興趣使用,可以參照這篇教學來了解怎麼開始。
ABoolean algebra is acomplementeddistributivelattice.
In boolean algebra, the complement of complement of \(x\) is \(x\).
This is a direct result fromat most one complement.
In boolean algebra, the problem can be expressed categorical: \(x \times y = 0\) iff \(y \to x^{\mathsf {c}}\).
We have product \(x \leftarrow 0 \rightarrow y\), and the \(y \to 1\) (terminal rule),but complement \(x^\mathsf {c}\) existed and \(x + y\) has no need to be \(1\), so somewhere between \(y \to 1\) has a \(x^\mathsf {c}\).
In boolean algebra, the problem can be expressed categorical: \(x \to y\) iff \(y^\mathsf {c} \to x^\mathsf {c}\).
By applyingproposition: \(x \sqcap y = 0\) iff \(y \sqsubseteq x^{\mathsf {c}}\),with fact that \(x \to y\),we know \(y^\mathsf {c} \sqcap x = 0\)
Applyproposition again, we can see the goal existed.
In boolean algebra, we can rewrite it categorical: \((x \times y)^\mathsf {c} = x^\mathsf {c} + y^\mathsf {c}\).
By removing the thing we no need, we can see that \((x \times y)^\mathsf {c} = x^\mathsf {c} + y^\mathsf {c}\).
In boolean algebra, we can rewrite in categorical language: \((x + y)^\mathsf {c} = x^\mathsf {c} \times y^\mathsf {c}\).
Boolean algebra can be encoded by indexing, for example, a venn diagram for two sets \(A, B\) divide diagram to four parts: \(1, 2, 3, 4\). Thus
The benefit of the encoding is the encoding let any sets can be treated as finite sets operation. So for any set check a boolean algebra is valid, indexing helps you check them by computer.
Here is the racket program.
(define I (set 1 2 3 4))(define A (set 1 2))(define B (set 1 3))(define ∅ (set))(define ∩ set-intersect)(define ∪ set-union)(define (not S) (set-subtract I S))(define (→ A B) (∪ (not A) B))(define (- A B) (∩ A (not B)))(define (≡ A B) (∪ (∩ A B) (∩ (not A) (not B))))
Now, you can check \(A \to B = (A - B)^{\mathsf {c}}\) by the following program.
(equal? (→ A B) (not (- A B)))
And you will know \((A \cap (A - B)^{\mathsf {c}}) = \emptyset \) is invalid since the following program returns false.
(equal? (∩ A (not (- A B))) ∅)
You can even extend this method for sets \(A, B, C\), for sets \(A, B, C, D\) and so on, but then that's too far for this article.
In adistributive lattice each element has at most one complement, which means \(y, z\) arecomplements of \(x\) implies \(y = z\).
The proof use category language, \(\sqcap \) (product) and \(\sqcup \) (coproduct).
Assuming there have two complements \(y, z\) for an element \(x\), then \(x + y = x + z = 1\) and \(x \times y = x \times z = 0\). By distributive law we have below diagram
Then we use \(x + y = x + z = 1\) to reduce it and get
Since there has at most one path, the diagram commute, hence \(y = z\).
為了了解 sound 與 complete 的比喻,我們需要觀察經典邏輯系統的 soundness 與 completeness 定理,因此我們先複習經典邏輯的公理與推導式
The twelve forms, where \(\alpha , \beta , \gamma \) denotes arbitrarysentences, are axioms of classical logic.
with single rule of inference.
From \(\alpha \) and \(\alpha \supset \beta \), the sentence \(\beta \) may be derived. Denote derivable formula \(\vdash _{cl} \alpha \), we can rewrite rule of detachment to \[ \frac { \vdash _{cl} \alpha \ \ \ \ \vdash _{cl} (\alpha \supset \beta ) }{ \vdash _{cl} \beta } \]
有了推導規則 Rule of Detachment,經典邏輯系統的 soundness 與 completeness 定理表示
If \(\vdash _{cl} \alpha \), then \(\alpha \) isclassically valid.
If \(\alpha \) isclassically valid, then \(\vdash _{cl} \alpha \).
這兩個定理也因此可以推廣到更多的系統中,比如靜態分析中的比喻
若是將比喻套進靜態分析中,便可以發現 sound 是「發現的錯誤都是真的」,也就是系統不會誤報;而 complete 則表示「所有的錯誤都會被系統找到」,也就是不會遺漏錯誤。但要記得這兩者在靜態分析中通常無法同時達成,而且兩者的極端都會產生沒用的系統。比如對所有程式都會檢測出錯誤那絕對有滿足 complete,但也肯定是沒用的系統;而滿足 sound 的系統則往往透露太少錯誤,而且這類錯誤通常開發人員也很容易自己發現,因此也不實用。因此靜態分析與證明系統發展上的差異,就是靜態分析需要在 sound 跟 complete 這些屬性裡面取得平衡。
因此可以發現,要用 soundness 與 completeness 時,只要關心特定屬性 \(p\),我們說一個系統 sound 就是在問「能導出的結果是否滿足 \(p\)」;我們說一個系統 complete 則是在問「滿足 \(p\) 的結果是否皆能導出」。
The proposition says a space isHausdorff if and only if its diagonal map \(\Delta : X \to X \times X\) toproduct space is closed, which given an alternative definition. Notice that close means its complement \(\Delta ^\mathsf {c}\) is open. The definition of \(\Delta \) is
\[ \Delta = \{ (x, x) \mid x \in X \} \]Not hard to see below argument also applies to all finite \(X\)-product spaces.
The first direction isHausdorff impliesdiagonal map is closed. Hausdorff means every two different points has a pair of disjoint neighborhoods \((U \in \mathcal {N}_x, V \in \mathcal {N}_y)\), where \(x \in U\) and \(y \in V\). therefore, every pair \((x, y)\) not line on the diagonal has \(U \times V\) cover them. The union of all these open sets \(U \times V\) indeed covers \(\Delta ^\mathsf {c}\), so the complement \(\Delta \) is closed.
The second direction isdiagonal map is closed impliesHausdorff. Since
\[\Delta ^\mathsf {c} = \{(x, y) \mid x, y \in X (x \ne y) \}\]is open, which implies for all \(x, y\) the pair \((x, y) \in \Delta ^\mathsf {c}\). Since \(\mathcal {N}_{(x, y)} = \mathcal {N}_x \times \mathcal {N}_y\), this implies the fact that \(\Delta ^\mathsf {c} \in \mathcal {N}_x \times \mathcal {N}_y\).
Also, for all \(U \in \mathcal {N}_x\) and \(V \in \mathcal {N}_y\), it's natural that \(U \times V \subseteq \Delta ^\mathsf {c}\), since the open set \(U \times V\) at most cover \(\Delta ^\mathsf {c}\).
Consider that reversely again, that means for all \((x, x) \in \Delta \), pair \((x, x) \notin U \times V\) (i.e. \(U \times V\) will not cover any part of diagonal), that implies \(U \cap V = \varnothing \) as desired.
To understand \(F\)-algebra, we will need some observations, the first one is we can summarize an algebra with a signature. For example, monoid has a signature:
\[ \begin {cases} 1 : 1 \to m \\ \cdot : m \times m \to m \end {cases} \]or we can say ring is:
\[ \begin {cases} 0 : 1 \to m \\ 1 : 1 \to m \\ + : m \times m \to m \\ \times : m \times m \to m \\ - : m \to m \end {cases} \]The next observation is we can consider these \(m\) as objects in a proper category \(C\), at here is acartesian closed category. For example
Now, we generalize algebra's definition.
With a proper category \(C\) which can encode the signature of \(F(-)\), and anendofunctor \(F : C \to C\), the \(F\)-algebra is a triple: \[(F, x, \alpha )\] where \(\alpha : F \; x \to x\) is a \(C\)-morphism.
With the definition of \(F\)-algebra, we wondering if \(F\)-algebras of a fixed \(F\) form a category, and the answer is yes.
For a fixedendofunctor \(F\) in a propercategory \(C\) (below notations omit fixed \(F\)),
We can extra check identity indeed works.
There is a theorem about the initial object of the category.
The evaluator \(j\) of aninitial algebra \((F, i, j)\) is an isomorphism.
Let \(F\;i\) be an initial in the \(F\)-algebra category, the following diagram commutes for any \(C\)-object \(a\)
Now, replace \(a\) with \(F\;i\), we have commute diagram
Then we consider a trivial commute diagram by duplicating the path \(F\;i \to i\)
Combine two diagrams, then we get another commute diagram
By definition now we know \(j \circ m\) is a homomorphism, and since \(F\;i\) is an initial, we must have\[F\;j \circ F\;m = 1_{Fi}\]
Therefore, we also have\[j \circ m = 1_i\]so \(m\) is the inverse of \(j\), proves \(j\) is an isomorphism.The theorem actually proves the corresponding \(C\)-object \(i\) ofinitial algebra \((F, i, j)\) is a fixed point of \(F\). By reversing \(j\) with its inverse, we get a commute diagram below.
In Haskell, we are able to define initial algebra
newtype Fix f = Fix (f (Fix f))unFix :: Fix f -> f (Fix f)unFix (Fix x) = x
View \(j\) as constructorFix
, \(j^{-1}\) asunFix
, then we can definem = alg . fmap m . unFix
. Sincem :: Fix f -> a
, we have definition of catamorphism.
cata :: Functor f => (f a -> a) -> Fix f -> acata alg = alg . fmap (cata alg) . unFix
An usual example isfoldr
, a convenient specialization of catamorphism.
As a dual concept, we can draw coalgebra diagram
and define anamorphism as well.
ana :: Functor f => (a -> f a) -> a -> Fix fana coalg = Fix . fmap (ana coalg) . coalg
I mostly learn F-algebras fromCategory Theory for Programmers, and take a while to express the core idea in details with my voice with a lot practicing. The article answered some questions, but we always with more. What's an algebra of monad? What's an algebra of a programming language (usually has a recursive syntax tree)? Hope you also understand it well through the article and practicing.
這篇文章介紹了 Lawvere's fixed point theorem 的定義與應用
在一個cartesian closed category 中,如果 \(A \xrightarrow {\phi } B^A\) 是point-surjective,則所有 \(B \xrightarrow {f} B\) 都存在不動點 \(1 \xrightarrow {s} B\)(滿足 \(f \circ s = s\))。
首先畫出交換圖
其中 \(\delta \) 的定義是 \(c \mapsto \langle c, c \rangle \),所以對 \(1 \xrightarrow {p} A\) 來說 \(\delta \circ p = \langle p, p \rangle \)。沿著這個定義,我們知道 \((\phi \times 1_A) \circ \delta \circ p = \langle \phi \circ p, p\rangle \)。根據point-surjective 我們知道 \(\phi \circ p\) 對每個 \(p\) 來說都是唯一確定的。現在把往下方 \(B\) 的 \(ev\) 也畫出,即可得出等式:
\[f \circ ev \circ \langle \phi \circ p, p\rangle = ev \circ \langle \phi \circ p, p\rangle \]換句話說 \(B \xrightarrow {f} B\) 的不動點即是
\[ev \circ \langle \phi \circ p, p\rangle \]編碼的方式是找一個只有兩個物件 \(1, T\) 的 category \(M\),讓 lambda calculus 的 terms 是 \(M\)-morphisms,這些技巧在categorical semantic 領域內相當常見。
到這裡必須檢查 lambda calculus 確實存在point-surjective,歡迎自行嘗試。按此編碼後可以得到 \(ev \circ \langle \phi \circ p, p\rangle \xrightarrow {encode} \phi (p)(p)\)。套到等式上\[f \circ ev \circ \langle \phi \circ p, p\rangle = ev \circ \langle \phi \circ p, p\rangle \]可以得到以下編碼\[f(\phi (p)(p)) = \phi (p)(p)\]把 \(\phi (p)\) 改寫成 \(q\),於是等式可以寫成 \(q(p) = f(\phi (p)(p))\),而函數套用語法可以用 \(\lambda \) 退化,於是得到\[q = \lambda x. f(\phi (x)(x))\]
注意到 \(q\) 的定義是非遞迴的,因此一定是可定義的。
計算即可發現確實 \(q(p) = \phi (p)(p) = f(\phi (p)(p))\)。因為所有的 \(\lambda \)-term 都屬於 \(T\),所以現在我們知道任何 lambda calculus 的函數都有不動點。
取 category \(\bold {Sets}\) 並令 \(B = 2\) 就可以證明Cantor's theorem。我們需要引理
If there exists \(B \xrightarrow {f} B\) such that \(f \circ b \ne b\) for all \(1 \xrightarrow {b} B\), then there has nopoint-surjective morphism can exist for \(A \xrightarrow {g} B^A\).
This is a reversed version ofLawvere's fixed point theorem, no need an extra proof.
這個定理也可以用到Gödel incompleteness、Tarski definability 等等問題上。論文Substructural fixed-point theorems and the diagonal argument: theme and variations 更進一步的簡化了前置條件。
Comma category is generated by two functors, denoted \((T \downarrow S)\).
To understand the idea, we can start fromslice & co-slice category, which is a special case of comma category. In co-slice category, we have objects \(\langle f, c \rangle \) where \(x \xrightarrow {f} c\), and morphism \(\langle f, c \rangle \xrightarrow {h} \langle f', c' \rangle \) where below diagram commutes:
We give another denotation \((x \downarrow C)\) for object \(x\) and its category \(C\) for this concept, and \((C \downarrow x)\) for the dual.
If we generalize the idea, by replacing category \(C\) with a functor \(S : D \to C\), then we get a category \((x \downarrow S)\) with
If we replace object \(x\) to another functor \(T\)? It's the full picture of comma category:
Givencategories and functors
The comma category \((T \downarrow S)\) (or \((T,S)\)) has
With the definition, now we can see howslice & co-slice category is a special case ofcomma category:
Take \(T = S = 1_C\), then \((C \downarrow C)\) is \(C^2\) (all morphisms of \(C\))
這個文章源自下面的問題
不過想問問專業的⋯⋯Golang 都有 interface 這種東西,提供泛型的必要性是什麼啊?
這是個常見的誤解,因為大部分語言不會多認真跟你講清楚到底啥是啥,看來好像都能接受多種不同的類型輸入不是嗎?所以這裡我們就來看各種機制的定義跟差別。
Go 語言的 interface,範例如下
type Abser interface {Abs() float64}
其中的Abs() float64
可以被改寫成抽象語法Abs : () -> float64
。因此一個 interface \(A\) 有一組與其關聯的一系列簽名 \(\hat P\)。並且,對 Go 而言下列的兩個 interface 並沒有差異
type A interface {F(C) D}type B interface {F(C) D}
因此我們可以更進一步認為 Go 的一個 interface \(A\) 可以完全由其簽名 \(\hat P\) 替換。
在 Java 之中可以定義 interface,範例如下
interface Comparable<T> { int compareTo(T other);}
相較於Go 中不用明確宣告,在 Java 中實現 interfaceI
需要寫成class T extends I
,因此雖然 Java 的 interface \(A\) 也有其相關的一組簽名 \(\hat P\),但兩個有同樣簽名 \(\hat P\) 的 interface 不是同一個型別。
而在 Java 中 bounded polymorphism 指的是以下的 interface 使用方法:
<S extends Comparable> S min(S a, S b)
這會使得沒有明確宣告實現Comparable
的型別無法被傳為min
的引數。
現在考慮一個簽名 \[ f : (S \le A) \Rightarrow S \times S \to S \] 在 Java 裡面可以確實保證兩個參數跟回傳的型別都是同一個。在 Go 裡面這個簽名就只能寫成 \[ f : \hat P \times \hat P \to \hat P \] 而兩個參數跟回傳的型別不一定相同。現在我們就會發現乍看之下 interface 對類型的約束跟多型一樣可以被多個不同的型別滿足,但事實上根本就是不同的東西。
interface 是一種子類型關係,換句話說當 \(T\) 實現 \(A\) 我們就說 \(T \le A\),在每個要求 \(A\) 的位置都可以用 \(T\) 取代。
多型的本體是一個型別等級的參數!在語意學上,上面的簽名可以改寫成 \(f : \Lambda S. S \times S \to S\),當你寫下 \[f \; k\] 的時候,乍看之下是一個完整的呼叫。實際上編譯器會先推導 \(k\) 的類型,記作 \(\uparrow k\),譬如假設 \(k : C\) 則 \(\uparrow k = C\),這時候就可以做型別替換 \((\Lambda S. S \times S \to S) C\) 得出 \(C \times C \to C\)。因此真正的呼叫程式碼是 \[f \; [C] \; k\]
子類型規則並不能取代替換這個語意。在 Java 的 \(f : (S \le A) \Rightarrow S \times S \to S\) 規則下,僅是多檢查了 \(C \le A\) 是否為真,子類型與多型仍然是不同的規則。
By introduce a indirect level of universe \(\mathcal {U}^-\), such that a subtype of normal universe \(\mathcal {U}\), and allows pattern matching.By restricting it can only be used at inductive type definitions' dependent position, it preserves parametricity, solvesthe problem easier compare withsubscripting universe.In this setup, every defined type has type \(\mathcal {U}^-\) first, and hence
\(\mathbb {L}\) didn't depend on \(\mathcal {U}^-\), so we keep using tagless encoding to explain
data Term Type | ℕ => add (Term ℕ) (Term ℕ) | 𝔹 => eq (Term ℕ) (Term ℕ) | a => if (Term 𝔹) (Term a) (Term a) | a => lit a
We have \(\text {Term} : \mathcal {U}^- \to \mathcal {U}^-\), and then, if one wantsList (Term Nat)
it still work since \(\mathcal {U}^- \le \mathcal {U}\). But if one tries to define code below:
inductive Split Type^ | Nat => nat | Bool => bool | _ => elsedef id (A : Type) (x : A) : A => match Split A | nat => 0 | bool => false | _ => x
Since the \(\mathcal {U}\) isn't the subtype of \(\mathcal {U}^-\), programSplit A
won't type check, the definition will not work as intended. This is indeed more boring than subscripting universe, but easier to check it does't break parametricity.
Till now, I haven't start to check the pattern of type, except the primitiveexact value, if I'm going to push this further, a good example is:inductive K Type^ | List a => hi a | _ => heThis is quite intuitive since in implementation inductive types' head are also rigid values, just like constructors.
This is an extension means to solvepattern matching on type's problem. We start from my old idea, an extension of inductive types.
An intutive extension of inductive types is, let constructor be subscripting set of the inductive type. For example, a type with definition
inductive Nat | zero | suc Nat
A typeNat[suc]
means onlysuc ...
is a term,zero
cannot have typeNat[suc]
. It's easy to seeNatNonZero = Nat[suc]
, this can also apply to
List1 = List[cons]
Int
is also a good motive exampleinductive Int | 0 | + Int[+, zero] | - Int[-, zero]
Int[+]
is positive,Int[-]
is negative. The diagram in its syntactic category:To ensure this, if the following syntax of each constructorc
is a list of argument typesTi ...
, we say the type of constructor of typeT
isTi ... -> T[c]
. The corresponding part is pattern matching's type rules will refine typeT
with the pattern matched constructorc
, below marks all binder's refined type. The typeT[c, ...]
is a subtype ofT
.
def foo : Int -> Int | 0 => 0 | + p => -- p : Int[+, 0] p | - n => -- n : Int[-, 0] n
An obvious problem is
def neg : Int -> Int | 0 => 0 | + p => - (neg p) | - n => + (neg p)
We can see that the type information issqueezed, the second and third case need type casting. A potential solution is case type, and hence,neg
has type like:
But then what's the type rule of it? Will need some time to explore.
To extend this on to universe typeType
, we say if there is an inductive familyT
inductive T (xi : Xi) ... | ci Ti ... | ...
, there is a bindingT : Xi ... -> Type[T]
. As usual,Type[T, ...]
is a subtype ofType
. Therefore, in this configuration, writes downid : {A : Type} -> A -> A
still has the only one implementation! And we can dotype pattern matching if we have subscriptings. Consider
Type
Nat
Bool
List
we have an example diagram as below
A motive example is the tagless encoding:
data Term Type | ℕ => add (Term ℕ) (Term ℕ) | 𝔹 => eq (Term ℕ) (Term ℕ) | a => if (Term 𝔹) (Term a) (Term a) | a => lit a
The final we can consider subtyping more, should we generally introduce subset of subscriptings as super type? In this setup thenType[Nat, Bool] <: Type[Nat] <: Type
.
However, this is an over complicated idea, I preferindirected universe more.
Element ormember is a natural concept in set theory, one can use \(x \in A\) to denote \(x\) is an element of \(A\). We can extend the idea from view it in thecategory \(\bold {Sets}\):
Each element \(x\) of a set \(A\) corresponding to a function (set-morphism) \[ \{\bullet \} \xrightarrow {x} A \]
Therefore, if we admit a category \(\mathcal {C}\) has a terminal object \(1\), we sayan element \(x\) of object \(A \in Ob(\mathcal {C})\) is a morphism \(1 \xrightarrow {x} A\).
NOTE: A terminal object \(1\) hasexact one morphism from elsewhere, therefore each \(1 \xrightarrow {x} A\) is a proper representation of asingle element \(x \in A\).
If \(A \xrightarrow {f} B\) and \(A \xrightarrow {g} B\) are morphisms in the category \(\mathcal {C}\) then \(f = g\) if and only if for every object \(X\) and every morphisms \(X \xrightarrow {x} A\) we have \(f x = g x\)
I'm considering a weird way to build inductive types, it's start onZhang's idea, dopattern matching to get constructors.
The idea is coming fromZhang's paper, a simpler encoding of indexed types. An example isVec
in Agda
data Vec (A : Set a) : ℕ → Set a where [] : Vec A zero _∷_ : ∀ (x : A) (xs : Vec A n) → Vec A (suc n)
One can still try[] : Vec A 10
, although the type check failed, it need a sophisticatedunification check. With Zhang's idea, we can do:
data Vec (A : Set a) : ℕ → Set a where zero => [] suc n => _∷_ A (Vec A n)
Now,[] : Vec A n
where \(n \ne 0\) is impossible to write down as usual, but now it's an easier unification!Since there has no constructor[]
for typeVec A n
where \(n \ne 0\).Another good example is finite set:
data Fin (n : N) | suc _ => fzero | suc n => fsuc (Fin n)
It requiresoverlapping pattern. One more last, we cannot defineusual equality type here (please check)
data Id (A : Type ℓ) (x : A) : A → Type ℓ where idp : Id A x x
Paper: Simpler indexed type essentially simplifies the problem of constructor selection just by turning the term-match-term problem to a term-match-pattern problem, which rules out numerous complication but also loses the benefit of general indexed types.
The benefit of theidea is clear, but it disallows definition liketagless interpreter:
data Term : Set → Set1 where lit : ∀ {a} → a → Term a add : Term ℕ → Term ℕ → Term ℕ eq : Term ℕ → Term ℕ → Term 𝔹 if : ∀ {a} → Term 𝔹 → Term a → Term a → Term aeval : ∀ {a} → Term a → aeval (lit x) = xeval (add x y) = eval x + eval yeval (eq x y) = eval x == eval yeval (if c t e) with eval ceval (if c t e) | true = eval teval (if c t e) | false = eval e
NOTE: There is a workaround in paper, and hence, the problem is inconvenience instead of impossible.
If I simply allow pattern matching on "Type", it's able to restore encoding fromthe problem:
data Term Type | ℕ => add (Term ℕ) (Term ℕ) | 𝔹 => eq (Term ℕ) (Term ℕ) | a => if (Term 𝔹) (Term a) (Term a) | a => lit a
But then it breaks parametricity! One now can read what is a polymorphic type concretely:
data C (A : Type) | ℕ => c1 | 𝔹 => c2 | _ => c3id : {A : Type} -> C A -> A -> Aid c1 x = 3id c2 x = falseid _ x = x
The first simple idea in my mind is forbiddingC P
whereThe question is, does this enough?
P
is a typeC
destruct aP
positionP
is a polymorphic type variable
哥德爾不完備定理是一個相當有趣的邏輯學發現,要了解他的意涵,要先考慮哥德爾的編碼
哥德爾數是一種編碼方式,在一個算術系統裡面,當我們把每個字符都排成一個有限的列,我們可以幫每個字符都指定一個自然數。具體來說,我們可能會寫下
Symbol | Number | Meta Meaning |
---|---|---|
\(\neg \) | 1 | not |
\(\lor \) | 2 | or |
\(\land \) | 3 | and |
\(\cdots \) | n | \(\cdots \) |
當有符號 \(s_i (i \in \N )\),其對應的哥德爾數為 \(n_i\)。我們並不是真的關心具體的每個符號,我們做這件事的理由是為了表示哥德爾編碼。所以這裡要開始定義哥德爾編碼,首先先看一個簡單的例子:當有系統的公式符號排列 \(s_1 s_{10} s_4\),我們說公式的哥德爾編碼為 \(2^{n_1}\cdot 3^{n_{10}}\cdot 5^{n_4}\)。
因此用函數 \(\alpha (i)\) 指示一個公式的每個位置 \(i\) 符號的 Gödel number,則哥德爾編碼確切的定義是
\[\prod _{i \in I}p_i^{n_{\alpha (i)}}\],也就是將質數以每個符號對應的哥德爾數為指數,將它們全部乘起來。這個辦法只是為了迫使每個公式有對應的編碼存在。我們用 \(\overline {G}\) 記號表示公式 \(G\) 的哥德爾數。
\(\alpha \) 函數給出第 \(i\) 個出現符號的在表中的位置。
在承認前述的系統 \(P\) 下,可以開始描述。
\(x[m/n]\) 表示將公式 \(x\) 中哥德爾數為 \(n\) 之符號換成 \(m\) 的哥德爾數再求此替換後公式的哥德爾編碼。
例如 \(\neg y[n/\overline {y}] = \overline {\neg n}\)
首先,用 \(\exists x. x \vdash k\) 表示有哥德爾數為 \(k\) 的公式在系統 \(P\) 中得到證明,而 \(x\) 是其演示
定義 \(n = \lnot \exists x. x \vdash y[y/y]\),但 \(y\) 是未知量,隨意給一個還沒被使用來編碼的數字即可,比如 \(\overline {y}\)。於是我們重寫成 \(n = \lnot \exists x. x \vdash y[y/\overline {y}]\)。
現在構造 \(G = \lnot \exists x. x \vdash n[n/\overline {y}]\),求其哥德爾編碼 \(\overline {G}\) 可以發現正是 \(n[n/\overline {y}]\) 所表示的編碼,因為
\[ n[n/\overline {y}] = \overline {\lnot \exists x. x \vdash n[n/\overline {y}]} = \overline {G} \]因此用 \(\overline {G}\) 替換 \(G\) 中的 \(n[n/\overline {y}]\),會得到
\[\lnot \exists x. x \vdash \overline {G}\]可以發現 \(G\) 的後設含義正是「有哥德爾編碼為 \(\overline {G}\) 的公式沒有系統 \(P\) 中的證明」,然而
綜合可知這意思就是 \(G\) 可證,若且唯若 \(G\) 可證否,是故承認 \(G\) 就是承認 \(P\) 不一致;反之,若 \(P\) 一致則 \(G\) 形式上就不可決定。
巧妙的是,並不難看出 \(G\) 的 meta 陳述是真確的,因為確實不存在任何整數作為編碼滿足這個性質。換句話說,存在形式上不能證明卻是真確、可寫下的公式,這就是第一不完備定理。接著根據第一不完備定理知道了 \(G\) 的真確性,卻在 \(P\) 中形式上不可決定,所以 \(P\) 不能證明一個真確的算術公式,因此 \(P\) 必定是不完備的,這就是第二不完備定理。
因此在The Blind Spot: Lectures on Logic 中可以看到對兩個定理的陳述更加關注核心:對一個足夠編碼自己又一致的系統
換句話說,要關心的並不是具體如何構造上面陳述的編碼,而是這類系統編碼系統自身的普遍性問題。
不久之前看到fizzyelt 的文章,所我前幾日開始研究自己以前寫的 strictly positive 筆記,因此找到了Andrej Bauer 在 stackexchange 的回答,整理後寫了這篇文章解釋何謂型別的大小
要了解型別的大小的意義,可以先考慮一個smallcartesian closed category,令型別是此範疇的物件(只有一個型別的 context)。
在這個情況下,對任意型別 \(t\),slice category \(C/t\) 表示「到達 \(t\) 的 morphism」所構成的集合,也就是 \(C/t\) 的 objects。
接著,我們要關心其中沒定義的 morphism,我們將基於此集合討論型別 \(T\) 有多大。技術上來說,是指從 terminal object \(1\) 出發的所有 morphisms(記為 \(\text {Hom}_{C}(1, T)\)),這些 morphisms 對應到內建的形式;以邏輯來說是指公理,而在函數式語言裡面,我們最常看到的定義公理的方式就是 data type!換句話說,型別的大小由建構子決定:
依此類推可以知道有 \(k\) 個單元建構子(即建構子c
滿足c : K
)的型別K
可以解釋為 \(k\)-type,接著 \(2 \to T\) 的元素應該有幾個呢?答案是 \(T \times T = T^2\),同理我們可以建立 \(k \to T = T \times ... \times T = T^k\) 的關係式。
依此可以建立一個簡單的直覺是c : T
表示 \(+1\),而更加複雜的型別如c : (2 -> T) -> T
就表示 \(+T^2\),建構子的參數表現了型別增長的速度,決定了型別的大小。
一個常見的案例是自然數,我們通常定義 \(z : \N \) 和 \(s : \N \to \N \) 兩個建構子來表示自然數 \(\N \)。用F-algebra 來表示,可以得到 \((1 + \mathbb {N}) \to \mathbb {N}\),從沒有循環參考的角度來看,當前 \(\N \) 的大小即取決於上一個 \(\N \) 的大小。畫出交換圖就可以了解到從基本點 \(z\) 出發,只有 \(s\) 一個方向可以前進,恰恰就是可數無限大的定義,是以看到這與歸納法的對應時,應當不會太過驚訝。
在 dependent type 語言裡面,data type 會變成 inductive data type,引入了更多的限制,而其中跟大小有關的限制就是這裡想要討論的。
c : (T -> T) -> T
有參數 \(T^T\) ,試問 \(T^T\) 有多大?[#261]答案是不知道,因為我們根本還不知道 \(T\) 到底是什麼。
當 \(T\) 定義完畢之後,這個簽名用在函數上倒是沒有問題,因為其大小已經確定,不會遇到自我指涉引發的麻煩。
雖然可以用公理強迫 \(T^T\) 有 size,但這樣做一來會破壞計算性;二來會顯著的複雜化 termination check。舉例來說,要是容許定義c
,就可以寫出
def foo (t : T) : T := match t with | c f => f t
接著foo (c foo)
就會陷入無限迴圈,為了要有強正規化,我們希望排除所有這類型的程式,比起一個一個去比對,直接禁止定義c
這類的建構子可以更簡單的達成目的。Haskell/OCaml 的 data type 則不做此限制,因為它們不需要強正規化,這也是為什麼 dependent type 語言常説其 data type 是 inductive data type,並不輕易省略 inductive 這個詞,因為這樣定義的類型滿足 induction principle。
另外一提,Bauer 的回答談到所有建構子都是為了符合 \(c : \Pi _{x : B} (A \; x \to T) \to T\) 的形式,有興趣的讀者可以著手證明。此外strictly positive 的遞迴定義可能更適合實現檢查機制。
把程式作為 object,而 continuation 作為 morphism,就可以發現尾遞迴完全對應到迴圈這個抽象,兩者都有
這兩個 morphism。從構造的角度來看,還可以說他們跟自然數有對應,上面的簽名恰恰正是 initial 跟 step。
典型的情況是 fibonacci 數列,展示了前面的型別大小如何與程式相關,常見的程式定義如下
def fib : Nat → Nat | 0 => 1 | 1 => 1 | n+2 => fib n + fib (n+1)
為了抽出計算部分的代數,我們用 inductive type 定義其計算
inductive Fib (a : Type) : Nat → Type where | z : a → Fib a 0 | o : a → Fib a 1 | s : Fib a n → Fib a (n+1) → Fib a (n + 2)
可以看到 induction case 就是 \((2 \to F a) \to F a = {F a}^2 \to F a = F a \times F a \to F a\),所以對應的程式就是兩次呼叫fib n + fib (n+1)
。當然,因為 fibonacci 還有一個利用矩陣計算的編碼
這個方法對應到 \(O(n)\) 的演算法,因此 fibonacci 不一定要用分形遞迴計算。這件事也告訴了我們代數簽名有時候比我們具體的計算更寬鬆,上面的 inductive type 並未限制如何使用s
,也因此可以摺疊時可能存在更快的計算方式。這也說明了當遇到c : (T -> T) -> T
一類的建構子時,其對應的計算難以寫出的問題,也就是前面沒辦法定義 \(T^T\) 的大小的情形。
這裡的想法我以前就在部落格裡面提到了,但是當時的設計並不夠通用,隨著後來拿來寫其他專案的時候標出型別就有了更廣泛的想法。
左遞迴是我們定義文法的時候會出現的一種形式,比如
\[\begin {equation} Expr \to Expr + Expr \end {equation}\]翻譯成遞歸下降解析器時會有像下面這樣的程式
def expr : Parsec E := let l <- expr match '+' let r <- expr return E.add l r
這時候expr
顯然是一個非終止的發散函數,而因為遞迴的原因是運算式的左邊,所以被稱為左遞迴。這樣的 infix 運算形式在文法中很常見,所以我們需要方法來消除文法中的左遞迴。
解析器組合子(parser combinator)最早來自論文 A new top-down parsing algorithm to accommodate ambiguity and left recursion in polynomial time, 在現在的使用中因為不同語言特性跟 parser combinator 指涉的比較像是一種程式方法的情況下,本文中的 parser combinator 是單純指把 parser 跟 higher order function 結合的一種程式方法。這個方案最大的好處就是遞歸下降解析跟程式寫法一一對應,因此相當直覺。
現在你知道為什麼我們需要了解遞歸下降解析中消除左遞迴的方式,以下面文法來說
\[\begin {align} Expr \to \; &Expr + Expr \\ | \; &Int \\ | \; &( Expr ) \end {align}\]我們可能會將定義改成
\[\begin {align} Expr &\to Term + Term \\ Term &\to Int \; | \; ( Expr ) \end {align}\]這個解法在對應的 parser combinator 中看起來像是
mutual def term := parse_int <|> parens expr def expr : Parsec E := let l <- term match '+' let r <- term return E.add l rend
上面的方法解決了左遞迴問題,但是要是有多個不同優先級的運算形式就會讓文法快速膨脹
\[\begin {align} Expr &\to Term + Term \\ Term &\to Factor * Factor \\ Factor &\to Int \; | \; ( Expr ) \end {align}\]這樣單調的修改在文法裡面確實很無聊,不過只要仔細觀察對應的 combinator,就會它們的型別發現這告訴了我們要怎麼利用 higher order function 來解決重複的問題!對 infix 運算形式(左結合)來說,通用的程式是
def infixL (op : Parsec (α → α → α)) (tm : Parsec α) : Parsec α := do let l ← tm match ← tryP op with | .some f => return f l (← tm) | .none => return l
這個 combinator 先解析左邊的 lowertm
,接著要是能夠解析op
就回傳op
combinator 中存放的函數,否則就回傳左半邊的tm
結果。使用上就像這樣
mutual def factor : Parsec Expr def expr : Parsec Expr := factor |> infixL (parseString "*" *> return Expr.mul) |> infixL (parseString "+" *> return Expr.add)end
parseString
是個假設會進行 whitespace 過濾並 match 目標字串的 combinatorExpr.mul
跟Expr.add
的型別被假設為Expr → Expr → Expr
這裡真正發生的就是使用組合子編碼了文法的層級,其中每個規則都被記錄成匿名函數,我們無需再另外命名。
因為有些運算子優先級相同,所以我們還需要再修改上面的函數來正確的支援這個概念;而且上面的程式為了避免複雜化,只解析一次 operator 加上tm
就退出了,會導致實際上1 + 2 * 3 * 4
這種算式的* 4
部分沒有被解析。要解決這個問題,我們需要貪婪解析右半邊op tm
的部分。綜上所述我們得到的程式碼是
def infixL (opList : List (Parsec (α → α → α))) (tm : Parsec α) : Parsec α := do let l ← tm let rs ← many do for findOp in opList do match ← tryP findOp with | .some f => return (f, ← tm) | .none => continue fail "cannot match any operator" return rs.foldl (fun lhs (bin, rhs) => (bin lhs rhs)) l
首先我們有一串 operator 而非一個,其次在右邊能被解析成op tm
時都進行解析,最後用foldl
把結果轉換成壓縮後的α
我希望這次有成功解釋怎麼從規則對應到 parser combinator,所以相似的規則可以抽出相似的 higher order function 來泛化,讓繁瑣的規則命名變成簡單的函數組合。這個技巧當然不會只有在這裡被使用,只要遇到相似形的文法都可以進行類似的抽換,相似的型別簽名可以導出通用化的關鍵。
在這裏提到的所有程式都實作在我幫 lean 寫的一個解析器擴充程式庫 parsec-extra 中
partial def infixR (opList : List (Parsec (α → α → α))) (tm : Parsec α) : Parsec α := go #[] where go (ls : Array (α × (α → α → α))) : Parsec α := do let lhs ← tm for findOp in opList do match ← tryP findOp with | .some f => return ← go (ls.push (lhs, f)) | .none => continue let rhs := lhs return ls.foldr (fun (lhs, bin) rhs => bin lhs rhs) rhs
op tm
def «prefix» (opList : List $ Parsec (α → α)) (tm : Parsec α) : Parsec α := do let mut op := .none for findOp in opList do op ← tryP findOp if op.isSome then break match op with | .none => tm | .some f => return f (← tm)
op tm
def «postfix» (opList : List $ Parsec (α → α)) (tm : Parsec α) : Parsec α := do let e ← tm let mut op := .none for findOp in opList do op ← tryP findOp if op.isSome then break match op with | .none => return e | .some f => return f e
In category theory, cone is a kind of natural transformation, to describe a diagram formally. The setup of cone is starting from a diagram, which we will define it as a category \(\mathcal {D}\) (usually is a finite one but no need to be) with two functors to the target category \(\mathcal {C}\). The two functors are
The first functor is very clear, we always can do that for any category; the second functor will need \(\mathcal {C}\) has that diagram. Consider \(\mathcal {D}\) as below
If such diagram exists in \(\mathcal {C}\), then we have a proper way to define \(F\), there can have many such diagram in \(\mathcal {C}\), we denote them as \(\mathcal {C}(\mathcal {D})\). Now consider if there is a morphism from \(c\) to all objects in \(\mathcal {C}(\mathcal {D})\), that lift a natural transformation from \(\Delta _c \to F\).
We say \(c\) is anapex and the \(\mathcal {C}(\mathcal {D})\) is a plane in this sense, thus, such a natural transformation gives conceptcone. With a fixed functor \(F\) (we also abuse language to say \(F\) is the diagram), varies \(\Delta _c\) bring different cones! When I get this, the picture in my mind is:
Image the head isapex and the body is the fixed diagram \(F\), you will also get the idea slowly.
To describe above idea, we make another category! By picking all apex of cone as objects, and picking morphism between apex in \(\mathcal {C}\) as morphisms, this is the category of cones (please check it does really a category).
With a fixed diagram \(\mathcal {D} \xrightarrow {F} \mathcal {C}\) and existing natural transformations \(\Delta _c \to F\), we get a category that consituited by
\(\Delta _c\) is a functor \(- \mapsto c : \mathcal {D} \to \mathcal {C}\) various on different \(c \in \mathcal {C}\).
Dual natural transformations \(F \xrightarrow {\beta } \Delta _c\) form cocones and a dual category.
The funny part we care here, is the terminal object of the category of cones, that is the next section. A limit or universal cone is a terminal object of category of cones. If you consider it carefully, and you will find this is the best cone of cones, because every other cones can be represented by composition of an addition morphism from itself to the limit!
With a fixed diagram \(\mathcal {D} \xrightarrow {F} \mathcal {C}\), alimit is aterminal of thecategory of cones, denoted as \(\lim _{\mathcal {D}} F\).
- notice that we can freely abuse language and say a \(\mathcal {C}\)-diagram is a functor target to \(\mathcal {C}\)
- Limit might not exist, so you have to ensure there has one.
The dual conceptcolimit is aninitial ofcategory of cocones, denoted as \(\underset {\mathcal {D}} {\text {colim}}F\).
With concept of cone and limit, you might already find there has some concept can be replaced by cone and limit, you're right and that would be fun to rewrite them in this new sense. Have a nice day.
當一個語言逐漸成熟,開發者常常會有一個想法就是用自己開發的語言寫這個語言的編譯器,但是這個決策會導致程式庫中有兩套目標一樣但是實現語言不同的編譯器程式。其一是本來的實現,另一個是用語言自身新寫的。一來這樣開發任何新功能的時候都需要寫兩次;二來這會減少可能的參與者人數,因為這下他得要熟悉兩個語言才行!解決這個問題的辦法就是啟動編譯器,通常是一個在多平台上可以直接執行的檔案。
約略是下面描述的樣子:
現在有了最佳化過的編譯器執行檔,就可以正常的使用語言自己對語言自己進行開發了。
現在可以來想一下為什麼是這樣的流程,首先一個程式語言除非被大量作業系統支援(比如 C、Python),否則系統上是不會有這個程式語言的編譯器的!這樣問題就來了:假設有人試圖參與這個編譯器專案,用的平台剛好跟既有開發者都不一樣,請問要由誰提供已經用語言自身編寫的編譯器的編譯器呢?想當然除了一些喪心病狂的作法,是不可能完成這個任務的!所以一個無論如何都已經可以執行的編譯器,哪怕效能比較差,也具有存在的價值。
而語言自身的編譯器用到新功能的時候,也一定要更新啟動編譯器,否則下一輪的新參與者就沒辦法正確的進行初始編譯。
前面提過說啟動編譯器通常是一個在多平台上可以直接執行的檔案,也提過哪怕效能不佳也可以,這兩個理由使得特定平台的可執行檔不是一個好的選擇。 當然,我們也可以選擇維護每個平台的啟動編譯器,chez scheme 就維護了一堆根據不同平台套用組合的二進位檔案做這件事。
回到正題上,啟動編譯器通常不會選擇這麼複雜的方式,而是會生成可以在多平台上執行的檔案。舉例來說,生成 C 或是 Python 這種已經被許多系統廣泛支援的語言,最近 zig 就是使用 wasm 達成這個目標。但這個選擇也不能太過隨便,比如要是語言自己的 type checking 任務很長,生成 Python 就會得到一個大家都不想等它跑完就不玩了的啟動編譯器。而限制太多的語言像是 haskell 或是 rust 可能也不是優秀的選擇,因為你的語言模型很可能跟這些目標語言非常不相配,進而讓編譯過程非常的痛苦。
有了這些概念,我想你已經有能力為自己的語言寫出啟動編譯器了!那麼剩下的篇幅我就可以來寫點 murmur,我覺得這個概念可以進一步推升到選擇一個夠容易編譯出來,也夠容易寫出通用最佳化編譯器的語言來達成。我個人是很看好 wasm,因為它確實容易當目標、最佳化,只可惜現在還有不少重要的功能都沒有定案。llvm 的 bytecode 確實也是一個方案,寫一個把 llvm bytecode 編譯成 executable 的 python 檔案並不困難,但 llvm 的連結性自己就是一個天殺的大麻煩所以這個方案我很少看到有人使用。Java bytecode 則是讓那些本來就預計只在 JRE 生態系內部的語言從一開始就沒有這個問題,微軟的 CLR 也是類似的狀況,缺陷是最後語言受制於 runtime,這個問題會有多大條取決於語言的目的是什麼。
好像是今年最後一天了,祝你不是在今天看到這篇文章的!
今天要解析的是Elaboration zoo 中的一段程式,其中用到了 conversion check 的技術。這種合一演算法在dependent type 語言裡面是主要的核心問題
這裡列出重要的兩個定義:
type Env = [(Name, Val)]type Ctx = [(Name, VTy)]
下面逐步介紹整個型別檢查的元件
在最上層的程式中,推導函數會直接被調用來得出 term 的 type,它會適當的調用check
去檢查是否有型別錯誤
infer :: Env -> Ctx -> Raw -> M VTyinfer env ctx = \case SrcPos pos t -> addPos pos (infer env ctx t) Var x -> case lookup x ctx of Just a -> return a Nothing -> report $ "Name not found: " ++ x U -> return VU t :@ u -> do tty <- infer env ctx t case tty of VPi _ a b -> do check env ctx u a return $ b $ eval env u tty -> report $ "Cannot apply on: " ++ quoteShow env tty Lam {} -> report "cannot infer type for lambda expression" Pi x a b -> do check env ctx a VU check ((x, VVar x) : env) ((x, eval env a) : ctx) b VU return VU Let x a t u -> do check env ctx a VU let ~a' = eval env a check env ctx t a' infer ((x, eval env t) : env) ((x, a') : ctx) u
SrcPos
這個情況只需要加上位置訊息之後往下 forward 即可t :@ u
) 也就是函數套用 (\(\beta \)-reduction) 的情況就比較複雜了t
得到tty
tty
不是一個函數型別 (\(\Pi \) type) 那麼就回報錯誤tty
的形式就會是 \(\Pi (x:A) \to B\),這時候要檢查u
是否是一個 \(A\)u
就會得到型別 \(B\ x\),也就是目標let x : a = t in u
,推導的過程如下a
是型別a
得到a'
,因為要從Tm
變成Val
(也就是化簡過的a
)t
的型別是否是a'
x : a'
與x = t
的綁定資訊推進 context 與 environment 再拿它們去推導u
最後使用infer
時,就像是這樣 (...
是省略號):
tm <- parse ...case infer [] [] tm of Left err -> ... Right ty -> ...
檢查函數接收一個 term 跟一個 type 用來找出 term 實際類型不匹配 type 的情況
check :: Env -> Ctx -> Raw -> VTy -> M ()check env ctx t a = case (t, a) of (SrcPos pos t, _) -> addPos pos (check env ctx t a) (Lam x t, VPi (fresh env -> x') a b) -> -- after replace x in b -- check t : bx check ((x, VVar x') : env) ((x, a) : ctx) t (b (VVar x')) (Let x a' t' u, _) -> do check env ctx a' VU let ~a'' = eval env a' check env ctx t' a'' check ((x, eval env t') : env) ((x, a'') : ctx) u a _ -> do tty <- infer env ctx t unless (conv env tty a) $ report (printf "type mismatch\n\nexpected type:\n\n \%s\n\ninferred type:\n\n \%s\n" (quoteShow env a) (quoteShow env tty))
SrcPos
這個情況只需要加上位置訊息之後往下 forward 即可fresh env -> x'
x
跟x'
可能是同名的,fresh
確保了它們不會被搞混expression -> pattern
x = x'
跟x : A
t
(lambda 的 body)的型別是不是 \(B\ x\)檢查 lambda 的方式就是讓 lambda 跟 \(\Pi \) 套用同一個參數之後再看一次
u
在新環境下是不是check
拿到的那個 type 而不是去推導u
infer
找出 term 的型別,然後讓它跟check
拿到的 type 做 conversion check化簡函數就是把 term 變成 value 的過程,它只需要 environment 而不需要 context
eval :: Env -> Tm -> Valeval env = \case SrcPos _ t -> eval env t Var x -> fromJust $ lookup x env t' :@ u' -> case (eval env t', eval env u') of (VLam _ t, u) -> t u (t, u) -> VApp t u U -> VU Lam x t -> VLam x (\u -> eval ((x, u) : env) t) Pi x a b -> VPi x (eval env a) (\u -> eval ((x, u) : env) b) Let x _ t u -> eval ((x, eval env t) : env) u
SrcPos
一如既往的只是 forwardVApp
儲存這個結果,conversion check 裡面會講到怎麼處理這些東西VApp
也常被叫做 spine
\u -> ...
u
去擴展 environment,也就是(x, u) : env
t
(在 \(\Pi \) 的情況就是執行b
)卡住在 dependent type 裡非常常見,舉例來說你有個函數
foo : (f : A -> U) -> (a : A) -> f a
在檢查foo
時執行到f a
就沒辦法被化簡,因為此時我們拿到的f
是一個VVar "f"
而不是VLam x t
conversion 是在 environment 中判斷兩個 value 是否能夠互相轉換的函數,對型別來說就是在判斷兩個型別是否相同
conv :: Env -> Val -> Val -> Boolconv env m n = case (m, n) of (VU, VU) -> True (VPi (fresh env -> x) a b, VPi x' a' b') -> conv env a a' && conv ((x, VVar x) : env) (b (VVar x)) (b' (VVar x)) (VLam (fresh env -> x) t, VLam x' t') -> conv ((x, VVar x) : env) (t (VVar x)) (t' (VVar x)) (VLam (fresh env -> x) t, u) -> conv ((x, VVar x) : env) (t (VVar x)) (VApp u (VVar x)) (u, VLam (fresh env -> x) t) -> conv ((x, VVar x) : env) (VApp u (VVar x)) (t (VVar x)) (VVar x, VVar x') -> x == x' (VApp t u, VApp t' u') -> conv env t t' && conv env u u' _ -> False
x
能不能讓兩個 \(B\ x\) 轉換VApp u (VVar x)
跟t (VVar x)
可以轉換,當x = VVar x
u
t
這裡就不再列出全部的列印(printing)跟解析(parsing)相關程式,主要關注對上面的程式有用途的部分。
原始語言的定義如下
type Name = Stringtype Ty = Tmtype Raw = Tmdata Tm = Var Name -- x | Lam Name Tm -- \x.t | Tm :@ Tm -- t u | U -- universe | Pi Name Ty Ty -- (x : A) -> B x | Let Name Ty Tm Tm -- let x : A = t; u {- helper -} | SrcPos SourcePos Tm -- annotate source position deriving (Eq)
執行會產出的語言的定義如下,可以看到 lambda 跟 \(\Pi \) 都運用了宿主環境的函數
type VTy = Valdata Val = VVar Name | VApp Val ~Val | VLam Name (Val -> Val) | VPi Name Val (Val -> Val) | VU
fresh
用在生成臨時變數時,不會引發命名衝突
fresh :: Env -> Name -> Namefresh env "_" = "_"fresh env x = case lookup x env of Just _ -> fresh env (x ++ "'") _ -> x
型別檢查時,下列的程式定義了檢查時的 monad 跟定位錯誤的工具
type M = Either (String, Maybe SourcePos)report :: String -> M areport s = Left (s, Nothing)addPos :: SourcePos -> M a -> M aaddPos pos ma = case ma of Left (msg, Nothing) -> Left (msg, Just pos) ma -> ma
這主要就是為了讓執行完的程式印出來的東西可以看
quote :: Env -> Val -> Tmquote env = \case VVar x -> Var x VApp t u -> quote env t :@ quote env u VLam (fresh env -> x) t -> Lam x $ quote ((x, VVar x) : env) (t (VVar x)) VPi (fresh env -> x) a b -> Pi x (quote env a) $ quote ((x, VVar x) : env) (b (VVar x)) VU -> Unf :: Env -> Tm -> Tmnf env = quote env . eval env
除了學到addPos
跟withPos
的有趣小技巧之外,寫下這篇紀錄也讓我更了解 conversion check 的過程跟各個部件的用途,像是 stuck 的存在跟如何處理,或是 lambda 為什麼不共用infer
再調用conv
等等。希望對你也一樣有幫助。
最近工作上的開發,對 wasm 的實務又有了更多的掌握,同時發現 wasm 各種資訊的缺乏。很多技術細節散亂在數十個不同的網頁中,各家編譯器跟 wasm 執行環境又充斥讓人頭痛的小毛病。所以我在這裡記錄下當下各種實用的技巧。
Rust 中的各種標記對編寫能用的 wasm module 置關重要,在其他語言很多 wasm 的特性根本用不出來。 這是目前多家編譯器各自實作 wasm 的碎片問題,不是每個語言都能良好的支援新的 wasm proposal。
#![feature(wasm_abi)]
跟extern "wasm"
[wasm-0002]用#![feature(wasm_abi)]
開啟特性之後,就不會發生回傳複雜型別的extern function 被改成用i32
參數的問題。 例如以下程式就不會被修改成foo(i32) -> ()
,而是正常的foo() -> i32
。
extern "wasm" { fn foo() -> StructType;}
當然,可以看到還是會被轉成用i32
表示的指標去傳遞資料,但比之前進步很多。
#[link(wasm_import_module = "mod")]
[wasm-0003]用#[link(wasm_import_module = "mod")]
修飾程式的用途是正確的引入其他模組, 舉個範例
#[link(wasm_import_module = "host")]extern "wasm" { fn host_println(str_ptr: *const u8, str_len: usize) -> ();}
用這個標記之後,它就會在host
尋找host_println
而不是其他名稱的模組,例如預設的模組env
。
這可以拿來塞任何你想要的資訊,或是拿去當 buffer,缺點是除了 Rust 好像沒有編譯器有要支援。
#[link_section = "hello"]pub static SECTION: [u8; 24] = *b"This is a custom section";
要使用 wasmedge SDK,需要在Cargo.toml
裡面加上依賴,讓 wasmedge-sys 使用 "*" 是因為兩者有對應,所以還是讓建構工具自己找出合適的依賴就好。
wasmedge-sdk = "0.6.0"wasmedge-sys = "*"
現在專案有了正確的依賴,就可以繼續開發了。
wasm 一個很實際的需求就是傳遞 non-primitive 的資料型別,在 WasmEdge 裡面做這件事的方法其實沒有完善的文件紀錄。 下面的程式碼是 runtime 設定
fn main() -> Result<(), anyhow::Error> { // 設定需要什麼能力 let config = ConfigBuilder::new(CommonConfigOptions::default()) .with_host_registration_config(HostRegistrationConfigOptions::default().wasi(true)) .build()?; // 建立 import object,語意是從 host 引入名為 host_suffix 的函數 let import = ImportObjectBuilder::new() .with_func::<(i32, i32), (i32, i32), !>("host_suffix", host_suffix, None)? .build("host")?; // 建立 vm 並註冊模組 let vm = Vm::new(Some(config))? .register_import_module(import)? .register_module_from_file("app", "app.wasm")?; // 執行叫做 app 模組中名叫 start 的函數並查看結果 let result = vm.run_func(Some("app"), "start", None)?; println!("result: {}", result[0].to_i32());}
Host function 的定義如下
#[host_function]fn host_suffix(caller: Caller, input: Vec<WasmValue>) -> Result<Vec<WasmValue>, HostFuncError> { let mut mem = caller.memory(0).unwrap(); let addr = input[0].to_i32() as u32; let size = input[1].to_i32() as u32; let data = mem.read(addr, size).expect("fail to get string"); let mut s = String::from_utf8_lossy(&data).to_string(); s.push_str("_suffix"); // 總之 wasm 模組的記憶體肯定不會用到還不存在的位址 let final_addr = mem.size() + 1; // 繼續增加一個 page size 的區塊 mem.grow(1).expect("fail to grow memory"); // 把要傳回去的字串寫入位址 mem.write(s.as_bytes(), final_addr) .expect("fail to write returned string"); Ok(vec![ // 第一個回傳值是指標 WasmValue::from_i32(final_addr as i32), // 第二個回傳值是長度 WasmValue::from_i32(s.len() as i32), ])}
在 wasm module 那邊則是寫
#![feature(wasm_abi)]#[repr(C)]struct HostString { ptr: *mut u8, size: usize,}#[link(wasm_import_module = "host")]extern "wasm" { fn host_suffix(str_ptr: *const u8, str_len: usize) -> HostString;}#[no_mangle]pub fn start() -> u32 { let s = "hello"; let s2 = unsafe { let HostString { ptr, size } = host_suffix(s.as_ptr(), s.len()); String::from_raw_parts(ptr, size, size) }; s2.len() as u32}
可以看到extern "wasm"
裡面HostString
可以自動從multi-values 復原回來。
做這個實驗的時候還發生了小插曲,我跟同事發現host_function
其實沒有正確的遵循 modifier, 所以即使你寫#[host_function] pub fn
它還是會把函數變成private 的。
vm
中的 wasm module instance[wasm-0007]let cvm = Box::new(vm.clone());let import = ImportObjectBuilder::new() .with_func::<(i32, i32), (), !>( "grow_module_memory", move |caller: CallingFrame, input: Vec<WasmValue>, _: *mut c_void| -> Result<Vec<WasmValue>, HostFuncError> { let mod_name = load_string(caller, input[0].to_i32() as u32, input[1].to_i32() as u32); let target_mod = cvm.to_owned().named_module(mod_name).unwrap(); // memory 這個名字是 LLVM 預設的生成結果 target_mod.memory("memory").unwrap().grow(1); Ok(vec![]) }, None, )?
因為不能試圖移動vm
,只好複製出來使用。
因為又一個插曲, 所以雖然這個技巧理論上能呼叫另一個註冊模組的函數,但目前功能是殘廢的。
總之,這團混亂最大的問題在於 wasm proposal 對實作的要求太少,比如說宣告軟體是否符合標準。也因此支援度混亂不一,各家編譯器跟執行環境都可以喊說自己有支援,但你頭洗下去才發現其實有很多平台特定的要求跟限制。當然反過來說這表示 wasm 正在蓬勃發展,很多有用的規範正在推進,希望能夠給大家帶來更多的功能。
strictly positive 是 data type 中對 constructor 的一種特殊要求形成的屬性,這是因為如果一個語言可以定義出不是 strictly positive 的 data type,就可以在 type as logic 中定義出任意邏輯,形成不一致系統。
現在我們知道為什麼我們想知道一個 data type 是不是 strictly positive 了!
了解完 strictly positive 的必要性後,我們用例子來理解什麼是不一致的系統。這裏我假設讀者都已經知道 type as logic(program as proof) 是什麼,所以不再重複。第一個例子是not-bad
:
data Bad bad : (Bad → Bottom) → BadnotBad : Bad → BottomnotBad (bad f) = f (bad f)isBad : BadisBad = bad notBadabsurd : Bottomabsurd = notBad isBad
Bottom
(\(\bot \)) 本來應該是不可能有任何元素的,即不存在x
滿足x : Bottom
這個 judgement,但我們卻成功的建構出notBad isBad : Bottom
。如此一來我們的型別對應到的邏輯系統就有了缺陷。
現在我們關心一下第二個例子loop
(修改自Certified Programming with Dependent Types):
data Term abs : (Term → Term) → Termapp : Term → Term → Termapp (abs f) t = f tw : Termw = abs (λ x → app x x)loop : Termloop = app w w
loop
的計算永遠都不會結束,然而證明器用到的 dependent type theory 卻允許型別依賴loop
這樣的值,因此就能寫出讓 type checker 無法停止的程式。換句話說,證明器仰賴的性質缺失。事實上Term
跟Bad
的問題就是違反了 strictly positive 的性質,或許也有人已經發現了兩者 constructor 型別的相似之處。接下來我們來看為什麼這樣的定義會製造出不一致邏輯。
首先我們需要理解以下兩條規則
根據這兩條規則,我們說 arrow types \(A \Rightarrow B\) 是 covariant in B 和 contravariant in A,或是說 A varies negatively 以及 B varies positively in \(A \Rightarrow B\)
所以我們稱 \(A\) 為 negative position、\(B\) 為 positive position,最後擴展到 \(\Pi \) type。至此我們有足夠的資訊來實作了,來看怎麼完成吧!
首先我們先訂出 data type 的語法框架,然後其中填上檢查程式:假設 constructor 會把其型別去糖,並假設有 check 函數。
(define-syntax-parser data [(_ name:id c*:constructor ...) (for ([c (attribute c*.desugar-type)]) (check #'name c)) #''ok])
接著補上型別依賴的語法,以及把型別帶來的隱式依賴展開,讓check
檢查到完整的型別。注:這裏的實作其實不是有用到才展開,但剛好我們要舉的例子都沒有踩到這個問題,所以我懶得修正了,讀者實作的時候自己注意一下。
(define-syntax-parser data ; ... [(_ (name:id d*:bind ...) c*:constructor ...) (for ([c (attribute c*.desugar-type)]) (check #'name (foldr (λ (n r) (n r)) c (attribute d*.lam)))) #''ok])
接著我們來看各個syntax-class
的定義
(begin-for-syntax (define-syntax-class type (pattern ty #:attr val (syntax->datum #'ty))) (define-syntax-class bind (pattern (name:id : ty:type) #:attr lam (λ (t) (Pi (syntax->datum #'name) (attribute ty.val) t)))) (define-syntax-class constructor (pattern (name b*:bind ... : ty:type) #:attr desugar-type (foldr (λ (n r) (n r)) (attribute ty.val) (attribute b*.lam)))))
最後則是重頭戲:檢查。我們會假設 constructor 的 type 是 positive 來開始,規則如下:
(begin-for-syntax (struct Pi (name t1 t2) #:transparent) ; strictly positive check ; @name: name of data type ; @c: type of constructor (define (check name c [positive? #true]) (define n (syntax->datum name)) (define (check-left-right t1 t2) (cond ; endofunctors are positive [(equal? t1 t2) (void)] ; self at negative [(and (equal? (if (symbol? t1) t1 (first t1)) n) (not positive?)) (raise-syntax-error 'negative "bad data type" name)]) (check name t1 (not positive?)) (check name t2 positive?)) (match c [(or (Pi _ t1 t2) `(-> ,t1 ,t2)) (check-left-right t1 t2)] [x (void)]))
文章到這邊告一段落,也解決了我這一年來對證明器實作的最大疑問之一,進一步的解答可以參考https://cs.stackexchange.com/questions/55646/strict-positivity/55674#55674
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 runcollection
(mark-sweep), then since each object is reachable fromroot
, so no one would be released.
After do some executions,obj1
don't needobj3
anymore, so it became:
Now when we runcollection
,obj3
is unreachable from root, so it won't be marked! When running to sweep, it will be dropped.
Categorical Logic and Type Theory
The category of PERs is consist of
\(\{ (0,0) \}\) and \(\N \times \N \) both are terminal objects of the category.
For \(S = \{ (0,0) \}\), we can see the unique function \(f\) is
\[\forall n \in |R|. f([n]_R) = [e \cdot n = \phi _e(n) = 0]_S\]since the only element of \(\N / \{ (0,0) \}\) is \([0]\), \(\phi _e\) just need to be a constant function maps to \(0\). In fact, it's easy to see why for each \(a \in \N \), the relation \(\{ (a,a) \}\) is a terminal object.
For \(S = \N \times \N \), we can see the unique function \(f\) is
\[\forall n \in |R|. f([n]_R) = [e \cdot n]_S\]\(\phi _e\) can be any function that codomain is \(\N \), because for all \(n \in \N \), the \([n]_S\) is the same.
A type theory that is used as a metalanguage for specifyiung another type theory is often called alogical framework.
Infinity categories are in a certain sense the limit case of a hierarchy of \((n,r)\)-categories. Let \(n\) stands for \(n\)-categories and \(r\) with \(0 \le r \le n+1\) for another index.
In an \((n,r)\)-category, \(k\)-morphisms become
In this context, the terminfinity categories often refers to \((\infty ,1)\)-categories.
\(n=0\) | \(n=1\) | \(n=2\) | \(\cdots \) | \(n=\infty \) | |
---|---|---|---|---|---|
\(r=0\) | set | groupoid | 2-groupoid | \(\cdots \) | \((\infty ,0)\)-category |
\(r=1\) | poset | category | \((2,1)\)-category | \(\cdots \) | \((\infty ,1)\)-category |
\(r=2\) | poset | \(2\)-poset | \(2\)-category | \(\cdots \) | \((\infty ,2)\)-category |
\(r=3\) | poset | \(2\)-poset | \(3\)-poset | \(\cdots \) | \((\infty ,3)\)-category |
\(\cdots \) | \(\cdots \) | \(\cdots \) | \(\cdots \) | \(\cdots \) | \(\cdots \) |
Domain-Theoretic Foundations of Functional Programming
Let \(P, Q\) be programs of type \(\sigma \), we say \(P\) and \(Q\) isdenotationally equal if
\[\llbracket P \rrbracket = \llbracket Q \rrbracket \in D_{\sigma }\]We say the operational semanticscorrect with respect to the denotational semantic iff \(P\) and \(V\) are denotationally equal whenever
\[P \Downarrow V\]We say the operational semanticscomplete with respect to the denotational semantic iff
\[P \Downarrow \overline {V}\]whenever \(\llbracket P \rrbracket = V \in D_{\sigma }\).
The \(\overline {V}\) represents the expression of \(V\), e.g. \(1\) has an expression1
in many programming languages.
In case the operational semantics is both correct and complete (with respect to) the denotational semantics for all programs and values, we say the denotational semantics iscomputationally adequate. i.e.
\[ P \Downarrow \overline {V} \iff \llbracket P \rrbracket = V \]For atangent space \(T_pM\),covectors at the point \(p\) form a dual vector space as \(T_pM\), so calledcotangent space of \(T_pM\), denotes \(T^*_pM\).
One can view a 1-form at least three different ways, let \(\alpha \) is a smooth 1-form, we have the following interpretations of \(\alpha \)
The differentials \(dx^i : p \mapsto dx^i\big \rvert _p\) define 1-forms on \(U\) such that
\[dx^1\big \rvert _p , \dots , dx^n\big \rvert _p\]form a basis of \(T^*_pM\) for each \(p \in U\).
A basis of tangent space usually denote as
\[(\partial _1, \dots , \partial _n) := (\frac {\partial }{\partial x^1}, \dots , \frac {\partial }{\partial x^n})\]A basis of cotangent space denote as
\[(dx^1, \dots , dx^n)\]and by definition
\[dx^i (\partial _j) = \delta ^i_{\ j}\]Let \(E_1, E_2, \dots , E_n\) be smoothvector fields defined on some open subset \(U \subseteq M\) of a smooth \(n\)-manifold \(M\). If \(E_1(p), E_2(p), \dots , E_n(p)\) form a basis for \(T_pM\) for each \(p \in U\), then we say \((E_1, E_2, \dots , E_n)\) is amoving frame or aframe field over \(U\).
A immediate consequence is that, for any vector field \(X\) defined on \(U\), we can write
\[X = \sum X^i E_i\]on \(U\). For \((E_i)\) is a moving frame over \(U\).
If \(U = M\) is hold, we say this is aglobal frame field, most manifolds do not have global frame fields.
The command-line utility dvisvgm is a tool for TEX/LaTEX users. It converts DVI, EPS, and PDF files to the XML-based vector graphics format SVG.
Manifolds and Differential Geometry
ALie algebra is
Notions of Computation as Monoids
Everymonoid \((M, \otimes , I)\) is a sub-monoid of the monoid of endomorphisms on \(M\).
Construct \(\text {rep} : M \to (M \to M)\) by currying \(\otimes \) \(\text {rep}(m) := \lambda m'. m \otimes m'\). This function is a monoid morphism, because
and it's an injection, since we can define \(\text {abs} : (M \to M) \to M\) such that
\[\text {abs}(k) = k(e)\]so \(\text {abs}(\text {rep(m)}) = m \otimes e = m\).
Abinoidal category is a category \(\mathbb {C}\) endowed with an object \(I \in \mathbb {C}\) and an object \(A \otimes B\) for each \(A, B \in \mathbb {C}\). There are functors
that coincide on \((A \otimes B)\).
The point is the definition allows tensor with identities (whiskering), functorially.
Thecentre \(\mathcal {Z}(\mathbb {C})\) is the wide subcategory of morphisms that do satisfy theinterchange law with any other morphism.
Since lists are monoids \(([a], ++, [])\), applythe representation theorem of monoid can get
type EList a = [a] -> [a]
and functions
rep :: [a] -> EList arep xs = (xs ++)abs :: EList aabs xs = xs []
by the theorem we knowabs ∘ rep = id
.
Promonads and String Diagrams for Effectful Categories
Aneffectful category is an identity-on-objects functor \(\color {blue}\mathbb {V}\color {black} \to \color {red}\mathbb {C}\color {black}\) from amonoidal category \(\color {blue}\mathbb {V}\color {black}\) (the pure morphisms, or "values") to apremonoidal category \(\color {red}\mathbb {C}\color {black}\) (the effectful morphisms, or "computations"), that strictly preserves all of the premonoidal structure and whose image is central.
Apremonoidal category is abinoidal category \((\mathbb {C}, \otimes , I)\) together with the following coherence isomorphisms
which are central, natural separately at each given component, and satisfy thepentagon andtriangle equations.
Apromonoid in a2-category is aproarrow \(M : \mathbb {A} \nrightarrow \mathbb {A}\) together with cells
satisfying unitiality and asociativity.
Elements of ∞-Category Theory
Awhiskered composite \(h \alpha k\) of a 2-cell
with a pair of 1-cells \(k : x \to a\) and \(h : b \to y\) is defined by the horizontal composite:
The paperPromonads and String Diagrams for Effectful Categories points out
this motivates us to find corresponding object of effects in premonoidal category, and uses the following additional (control) string to point out the order.
If each computation instance has three lines
then ensure their tensor will coherence at the gold line. InCollages of String Diagrams they point out an usage of bimodular categories to model basic binary semaphore concept.
The propositional extensionality says that propositions that imply each other are equal
\[\text {propext} : \forall \ p\ q : \text {Prop}.\ (p \leftrightarrow q) \to p = q\]The proof irrelevance is an axiom can be added into type theory to state that:
\[\frac { \Gamma \vdash p : \text {Prop} \quad \Gamma \vdash h : p \quad \Gamma \vdash h' : p }{ \Gamma \vdash h \equiv h' }\]sousing which proofs is irrelevance.
Let \(D\) be anintegral domain, \(a, b \in D\) areassociated if \(a = ub\) where \(u\) is aunit of \(D\).
A nonzero element \(a\) of anintegral domain \(D\) is calledirreducible if \(a\) is not a unit and whenever \(b,c \in D\) with \(a = bc\), then \(b\) or \(c\) is aunit.
A nonzero element \(a\) of anintegral domain \(D\) is called aprime if \(a\) is not aunit and
\[a \mid bc \implies a \mid b \text { or } a \mid c\]In an integral domain, every prime is an irreducible.
The next theorem is why define PID.
In anprincipal integral domain, an element is an irreducible if and only if it is a prime.
Apolynomial ishomogeneous if whose nonzero terms all have the same degree.
Asieve on the object \(U\) is a family of morphisms \(R\) thatsaturated in the sense that, \((V \xrightarrow {\alpha } U) \in R\) implies \((W \xrightarrow {\alpha \circ \beta } U) \in R\) for any \(W \xrightarrow {\beta } V\).
Let \(C\) be a small category. AGrothendieck topology on \(C\) is defined by specifying, for each object \(U \in C\), a set \(J(U)\) of sieves on \(U\), calledcovering sieves of the topology, such that
條件二使Grothendieck pretopology 中的 with pullbacks 是不必要的。
Topos Theory
Asite is asmall category equipped with a Grothendieck topology (Definition [math-00EY]Definition [math-00EY]).
Asieve on the object \(U\) is a family of morphisms \(R\) thatsaturated in the sense that, \((V \xrightarrow {\alpha } U) \in R\) implies \((W \xrightarrow {\alpha \circ \beta } U) \in R\) for any \(W \xrightarrow {\beta } V\).
Let \(C\) be a small category. AGrothendieck topology on \(C\) is defined by specifying, for each object \(U \in C\), a set \(J(U)\) of sieves on \(U\), calledcovering sieves of the topology, such that
條件二使Grothendieck pretopology 中的 with pullbacks 是不必要的。
Topos Theory
Let \(C\) be asmall category withpullbacks. AGrothendieck pretopology on \(C\) is defined by specifying, for each object \(U \in C\), a set \(P(U)\) of families of morphisms of the form
\[\{ U_i \xrightarrow {\alpha _i} U \mid i \in I \}\]calledcovering families of the pretopology, such that
Let \(S\) be anoriented regular surface, and let \(p \in S\). Let \(\partial _1, \partial _2\) be anorthonormal basis of \(T_pS\) with respect to which theWeingarten map is represented by a diagonal matrix
\[\mathcal {W}_p = \begin {bmatrix}k_1 & 0 \\ 0 & k_2\end {bmatrix}\]then
We now can also representGaussian curvature and mean curvature as
\[K(p) = k_1 k_2\]and
\[H(p) = \frac {1}{2}(k_1 + k_2)\]This is a formal way ofGaussian curvature (高斯曲率直覺方式)
The determinant ofWeingarten map
\[K(p) = \det {\mathcal {W}_p}\]is theGaussian curvature of \(S\) at \(p\). The half of trace
\[H(p) = \frac {1}{2} \mathcal {W}_p \]is themean curvature of \(S\) at \(p\).
Consider \(N : S \to S^2\), its differential is \(dN_p : T_pS \to T_{N(p)} S^2\). However, we can see
\[T_pS = T_{N(p)} S^2\]Thus, we can see \(dN_p : T_pS \to T_pS\).
For every \(p \in S\), the linear transformation
\[\mathcal {W}_p = -dN_p : T_pS \to T_pS\]is called theWeingarten map.
The idea still work for higher dimension. Let \(S\) be andifferentiable manifold with dimension \(n-1\), let \(N : S \to \R ^n\), then \(N : S \to S^{n-1} \subset \R ^n\).
Let \(M\) be adifferentiable manifold with anaffine connection \(\nabla \) and aRiemann metric \(\langle -,- \rangle \).
Riemannian Geometry §2
Given aRiemann manifold \(M\), there exists a uniqueaffine connection \(\nabla \) on \(M\) satisfying the conditions
The \(\nabla \) will be determined by
\[\begin {aligned} \langle Z, \nabla _YX \rangle = &\frac {1}{2}(X\langle Y,Z \rangle + Y\langle Z,X \rangle - Z\langle X,Y \rangle \\ &- \langle [X,Z],Y \rangle - \langle [Y,Z],X \rangle - \langle [X,Y],Z \rangle ) \end {aligned}\]A Riemannian (or Levi-Civita) connection on \(M\) is the unique connection from Levi-Civita theorem.
Let \((U,x)\) be a coordinate system. The functions \(\Gamma ^k_{ij}\) defined on \(U\) by
\[\nabla _{\partial _i}\partial _j = \Gamma ^k_{ij}\partial _k\]The coefficients of the connection \(\nabla \) on \(U\) orChristoffel symbols of the connection. FromTheorem [math-00EQ]
\[\Gamma ^l_{ij} g_{lk} = \frac {1}{2}(\partial _i g_{jk} + \partial _j g_{ki} - \partial _k g_{ij})\]where \(g_{ij} = \langle \partial _i, \partial _j \rangle \). By inverse matrix \(g^{km}\), we got
\[\Gamma ^m_{ij} = \frac {1}{2} \sum _k (\partial _i g_{jk} + \partial _j g_{ki} - \partial _k g_{ij}) g^{km}\]In term of Christoffel symbols, thecovariant derivative has the classical expression:
\[\frac {DV}{dt} = \sum _k ( \frac {d v^k}{d t} + \sum _{i,j} \Gamma ^k_{ij} v^j \frac {d x^i}{d t} ) \partial _k\]Let \(X\) and \(Y\) be two \(C^\infty \)tangent vectorfields on open set \(U\) of a differentiable manifold \(M\), the Lie bracket of \(X\) and \(Y\) is
\[[X,Y] := XY - YX\]which takes two tangent fields and produces a new tangent field. The Lie derivative
\[L_XY = [X,Y]\]Generally \(XY\) is not a tangent vector space, by not havingLeibniz property. However, \(XY - YX\) must be.
The boxed part is same at \(XY\) and \(YX\), and generally not \(0\), and \(XY - YX\) leave a part that satisfies Leibniz.
Lie bracket 的用途是,衡量
這兩種路徑的差距,一般來說都不是零。所以,下面的定理 Lie bracket 是核心關鍵
Let \(M\) be a \(n\)-dimensional \(C^\infty \)-manifold, \(q \in M\) and \(X_1, \dots , X_k\) be a list of linear independent \(C^\infty \)-vector fields, and \(1 \le k \le n\). Then if for all \(\alpha , \beta \)
\[[X_\alpha , X_\beta ] = 0\]There exists \(C^\infty \)-immersion locally, i.e.
\[\lambda : U \subseteq \R ^k \looparrowright M\]makes
Let \(\varphi ^\alpha _t\) be the flow of \(X_\alpha \), i.e.
\[ \frac {d }{d t} \varphi ^\alpha _t(x) = X_\alpha \text { at } x \text {, for all } x \in M\]so defines
\[\lambda (x^1, x^2, \dots , x^k) = \varphi ^k_{x^k} \circ \cdots \circ \varphi ^1_{x^1}(q)\]Can see that \(\lambda \) is the target immersion.
Algebra: Chapter 0 §II.7
Let \(H\) be anormal subgroup of \(G\), the quotient group of \(G\) modulo \(H\) denoted \(G / H\), is the group \(G / \sim \) obtained from the relation \(\sim \) defined as
\[G / \sim \ = \{ aH \mid a \in G \} = \{ Ha \mid a \in G \}\]In terms of cosets, the product in \(G / H\) is defined by
\[(aH)(bH) = (ab)H\]The identity \(e_{G / H} = e_G H = H\).
Kronecker delta \(\delta ^i_j\) is a two-index mathematical object such that
\[ \delta ^i_j = \begin {cases} 1 \text { if } i = j \\ 0 \text { if } i \ne j \end {cases} \]If we are not considering a tensor, denotes \(\delta _{ij}\) is also existed.
Consider a vector represents viaindex notation \(A^i\), then
\[A^i = \delta ^i_j A^j\]Consider \(\delta ^i_j\) as a finite matrix form, and \(i, j\) have the same dimension.
\[\begin {bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end {bmatrix}\]Then \(A^i = \begin {bmatrix}a\\b\\c\end {bmatrix} = \delta ^i_j \begin {bmatrix}a\\b\\c\end {bmatrix} = \delta ^i_j A^j\). It's clear that this idea is general, even \(i, j\) have different dimensions, the form
\[\begin {bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \end {bmatrix} \begin {bmatrix}a\\b\\c\end {bmatrix} = \begin {bmatrix}a\\b\end {bmatrix}\]Instead of denotes a vector as \(\vec {A}\), index form denotes \(A^\mu \), \(\mu \) is not exponent here, but index to each component. Let's take a concrete example, if \(A^\mu \) has dimension \(4\), then \(\mu = 0, 1, 2, 3\), thus
\[ A^\mu = \begin {bmatrix}A^0 \\ A^1 \\ A^2 \\ A^3\end {bmatrix} \]An usual example is partial derivations as components (e.g.tangent space (切空間))
\[ \partial _\mu = \frac {\partial }{\partial x^\mu } = \begin {bmatrix}\partial _0\\\partial _1\\\partial _2\\\partial _3\end {bmatrix} = \begin {bmatrix}\frac {\partial }{\partial x^0}\\\frac {\partial }{\partial x^1}\\\frac {\partial }{\partial x^2}\\\frac {\partial }{\partial x^3}\end {bmatrix} \]Let \(A_\mu \) and \(B^\mu \) both be dimension \(4\) vector, then
\[A_\mu B^\mu = \sum _{\mu =0}^3 A_\mu B^\mu = A_0B^0 + A_1B^1 + A_2B^2 + A_3B^3\]A Gentle Introduction to Homological Mirror Symmetry, §1.4
Let \(\mathbb {k}\) be a fixedfield. A category \(C\) is called a \(\mathbb {k}\)-linear category if all hom-spaces are \(\mathbb {k}\)-vector spaces and the multiplication is bilinear. An object \(X \in C\) is a zero object if for all \(Y \in C\), we have \(\text {Hom}_{C}(X, Y) = \text {Hom}_{C}(Y, X) = 0\).
A functor between two \(\mathbb {k}\)-linear categories is call \(k\)-linear if the maps between the hom-spaces are \(\mathbb {k}\)-linear.
Almost all natural functors between two \(\mathbb {k}\)-linear categories are \(\mathbb {k}\)-linear.
\(\text {VECT}(\mathbb {k})\), \(\text {vect}(\mathbb {k})\), \(\text {mat}(\mathbb {k})\) are examples of \(\mathbb {k}\)-linear categories. For any \(\mathbb {k}\)-algebra \(A\), we have \(\mathbb {k}\)-linear categories:
The zero object in these categories is zero vector space with trivial \(A\)-action. The hom-spaces in these categories are often denoted by \(\text {Hom}_{A}(M, N)\). Respectively, for left modules we have \(A\)-MOD, \(A\)-Mod, and \(A\)-mod.
Any \(\mathbb {k}\)-algebra \(A\) can also be considered as a \(\mathbb {k}\)-linear category \(A\) with one object.
Manifolds, Sheaves, and Cohomology, §14.2
A \(R\)-algebra \(C\) is a \(R\)-module \(C\) together with a bilinear map \(\cdot : C \times C \to C\), such that \((C, +, \cdot )\) is aring.
A \(R\)-algebra is commutative if the ring is commutative.
Let \(P : \mathcal {C}^{op} \times \mathcal {C} \to \mathcal {D}\) be a functor
Aend of \(P\) is anterminal wedge, which means below diagram:
commutes and unique split \(\zeta _X\) for all \(X \in \mathcal {C}\).
Due to functor can be viewed as diagonal functor that has dummy contravariant variable, we have a cool reuse of end notation. Let \(F, G : \mathcal {C} \to \mathcal {D}\) be functors, a natural transformation from \(F\) to \(G\) can be viewed as an end, and hence we have an isomorphism
\[\text {Nat}(F,G) \simeq \int _{X \in \mathcal {C}} \text {Hom}_{\mathcal {D}}(F(X), G(X))\]Mathematical Logic and Computation, §10.2
A formula if arithmetic is said to be \(\Delta _0\) if it has no unbounded quantifiers. Alternatively, the set of \(\Delta _0\) formulas is the smallest set containing atomic formulas in the language of arithmetic and closed under boolean operations and bounded quantification.
The hierarchies of \(\Sigma _n\) and \(\Pi _n\) formulas are defined simultaneously and inductively as follows
Anaffine connection \(\nabla \) on \(M\) is a mapping
\[ \nabla : \mathcal {X}(M) \times \mathcal {X}(M) \to \mathcal {X}(M) \]which satisfies the followings
for all \(X,Y,Z\in \mathcal {X}(M)\) and \(f,g \in \mathcal {D}(M)\)
Let \(M\) be a differentiable manifold with an affine connection \(\nabla \). There exists a unique correspondence which associates to a vector field \(V\) along the differentiable curve \(\gamma : [0,1] \to M\) another vector field \(\frac {DV}{dt}\) along \(\gamma \), called thecovariant derivative of \(V\) along \(\gamma \).
\[\frac {DV}{dt} = \frac {d v^j}{d t} \partial _j + \frac {d x^i}{d t} v^j \nabla _{\partial _i}\partial _j\]remind \(\partial _i = \frac {\partial }{\partial x^i}\), and summation convention is applied.
Covariant derivative has properties below:
\[ \begin {equation} \frac {D}{dt}(V+W) = \frac {DV}{dt} + \frac {DW}{dt} \end {equation}\quad \begin {equation} \frac {D}{dt}(fV) = \frac {d f}{d t} V + f\frac {DV}{dt} \end {equation} \]and if \(V\) is induced by a vector field \(Y\), e.g.
\[V(t) = Y(\gamma (t))\]then
\[\frac {DV}{dt} = \nabla _{ \frac {d \gamma }{d t} }Y\]An affine connection \(\nabla \) on a smooth manifold \(M\) is said to besymmetric if
\[\nabla _XY - \nabla _YX = [X,Y]\]for all vector fields \(X,Y\) on \(M\). In this case, the torsion tensor defined as
\[T(X,Y) = \nabla _XY - \nabla _YX - [X,Y]\]Let \(M\) be a differentiable manifold with an affine connection \(\nabla \). Avector field \(V\) along a curve \(\gamma : [0,1] \to M\) is calledparallel if for all \(t \in [0,1]\) its covariant derivative (Definition [math-00EO]) is zero, i.e.
\[\frac {DV}{dt} = 0\]Let \(M_1,M_2\) bedifferentiable manifolds. Adiffeomorphism \(\phi : M_1 \to M_2\) is a map which is
Let \(\varphi : M \to N\) be a differentiable map, if \(d\varphi _p : T_p M \to T_{\varphi (p)} N\) is an isomorphism, then \(\varphi \) is a local diffeomorphism at \(p\).
Adifferentiable mapping \(\varphi : M \to N\) is said to beimmersion if
\[d\varphi _p : T_p M \to T_{\varphi (p)} N\]isinjective for all \(p \in M\).
Say \(M\), \(N\) has dimension \(m\), \(n\), respectively, then \(\varphi \) is an immersion implies \(m \le n\).
If \(\varphi \) is a homeomorphism onto \(\varphi (M) \subset N\), where \(\varphi (M)\) has the subspace topology induced from \(N\), then \(\varphi \) is an embedding, \(M\) is a submanifold of \(N\).
Visual Differential Geometry and Forms: A Mathematical Drama in Five Acts
高斯曲率在點 \(p\) 之公式
\[ \mathcal {K}(p) = \lim _{\Delta _p \to p} \frac {\mathcal {E}(\Delta _p)}{\mathcal {A}(\Delta _p)} \]其中 \(\mathcal {E}(\Delta _p)\) 表示angular excess,也就是三角形的內角和減去 \(\pi \);\(\mathcal {A}(\Delta _p)\) 表示面積。
sphere 的高斯曲率:\(\mathcal {K} = +\frac {1}{R^2}\);Hyperbolic Geometry 的高斯曲率:\(\mathcal {K} = -\frac {1}{R^2}\)
令 \(\Delta \) 為曲面上之三角形,考慮一條測地線,從一角 \(\gamma \) 出發到對邊,將 \(\Delta \) 分為兩個三角形 \(\Delta _1\)、\(\Delta _2\)。則
由 \(\beta _1 + \alpha _2 = \pi \) 可知
\[\mathcal {E}(\Delta _1) + \mathcal {E}(\Delta _2) = \alpha + \beta + \gamma _1 + \gamma _2 - \pi = \mathcal {E}(\Delta )\]Visual Differential Geometry and Forms: A Mathematical Drama in Five Acts\[\mathcal {E}(\Delta ) = \alpha + \beta + \gamma - \pi = \iint _\Delta \mathcal {K} d \mathcal {A}\]
First,angular excess is additive, thus if repeatly cut a \(\Delta \) by the method, we get
\[\mathcal {E}(\Delta ) = \sum _i \mathcal {E}(\Delta _i)\]As the subdivision becomes finer and finer, curvature variees less and less each \(\Delta _i\), approaching the constant value \(\mathcal {K}_i\), and in its limit yields
\[\mathcal {E}(\Delta ) = \sum _i \mathcal {K}_i \mathcal {A}(\Delta _i)\]Every finitedistributive lattice is aframe.
All subsets are finite, thus each of them can define join and meet; and by definition distributive.
Let \(X\) be a set, \(X_\bot \) is apointed poset, by construction
\[X_\bot = X \cup \{ \bot \}\](called \(X\) lifted, or the flat domain on \(X\)), and define a partial order
\[\begin {aligned} &\bot \le \bot \\ &\bot \le x \quad &(x \in X) \\ &x \le y \text { iff } x = y \quad &(x,y \in X) \end {aligned}\]Let \(D\) be anintegral domain, apolynomial \(f(x) \in D[x]\) that
is said to beirreducible over \(D\) if, whenever
\[ f(x) = g(x) h(x) \]where \(g(x), h(x) \in D[x]\), then \(g(x) = 1\) or \(h(x) = 1\).
也就是說,沒有辦法把一個不可約多項式表達為兩個多項式的乘積。
Higher-Order Computability
A partial applicative structure \(A\) consists of
We ofren omit \(AB\) from \(\cdot _{AB}\) and treat \(\cdot \) as left-associative.
A partial applicative substructure \(A^\#\) of \(A^\circ \) consists of \(A^\# \subset A\) for each datatype \(A \in |A^\circ |\) such that
Above \((A^\circ ; A^\#)\) is arelative partial applicative structure.
A typed partial combinatory algebra is a partial applicative structure (Definition [math-00E1]) satisfying the following conditions
Anyhigher-order model yields an underlying TPCA.
範例
\underbrace{x + \cdots + x}_{n-\text{times}}\[ \underbrace {x + \cdots + x}_{n-\text {times}} \]
Anintegral domain \(R\) is aprincipal ideal domain if everyideal has the form \(\langle a \rangle = \{ r \cdot a \mid a \in R \}\) for some \(a \in R\).
Let \(F\) be afield, then it'spolynomial ring \(F[x]\) is a principal ideal domain.
By\(D\) an integral domain implies\(D[x]\) an integral domain, we know \(F[x]\) is a integral domain. Let \(I\) be an ideal in \(F[x]\), if \(I = \{ 0 \}\), then \(I = \langle 0 \rangle \). Otherwise, \(I \ne \{ 0 \}\)
With a fixed simplicial set \(X\), a \(n\)-simplex \(x \in X_n\) is said to bedegenerate if there is \(m\)-simplex \(y \in X_m\) (\(m < n\)) and a \(\alpha : [n] \to [m]\), such that \(\alpha ^* : X_m \to X_n\) satisfies
\[ x = \alpha ^*(y) \]In words, if there exists a lower \(m\)-simplex and a map from that to this \(n\)-simplex, then this \(n\)-simplex is degenerate.
A \(n\)-simplex is said to be non-degenerate, if it's not degenerate.
特徵多項式定義為
\[\Delta _A(\lambda ) = \det (\lambda I_n - A)\]化為矩陣多項式後,代入 \(A\) 結果為零
\[\Delta _A(A) = 0\]特徵多項式為 \(\begin {vmatrix}\lambda - 1 & 2 \\ -3 & \lambda - 2\end {vmatrix} = \lambda ^2 - 3 \lambda - 4\),化為矩陣多項式後代入 \(A\) 得
\[ A^2 - 3A - 4I_2 = \begin {bmatrix} 1 & 2 \\ 3 & 2 \end {bmatrix}^2 - 3 \begin {bmatrix} 1 & 2 \\ 3 & 2 \end {bmatrix} - 4 \begin {bmatrix} 1 & 0 \\ 0 & 1 \end {bmatrix} = \begin {bmatrix} 0 & 0 \\ 0 & 0 \end {bmatrix} \]Anysimple closed curve cuts the plane to two parts.
Let \(\gamma : [a,b]\to \R ^2\) be a simple closed curve. For any \(p \in \R ^2 \setminus \gamma \) not on the curve, there is a family of vectors
\[ \overrightarrow {p \gamma (t)} \]Take these vectors only by direction form a map \(f_p : [a,b] \to S^1\), and let \(W(p)\) be thedegree of \(f_p\).
Consider a very close window, so \(\gamma \) is merely a line, then pick two points \(p_1\) and \(p_2\), such that makes \(|W(p_1) - W(p_2)| = 1\), this is possible because one covers the bottom half of \(S^1\) counterclockwise, the other covers the top half of \(S^1\) clockwise, therefore the difference exactly turned around.
Follow the orientation of \(\gamma \), move the window, can see \(p_1\) and \(p_2\) will not change the coverage at any point of \(\gamma \), and hence there are twopath-connected components wrap \(\gamma \).
Finally, for any \(p\) not on the curve \(\gamma \), the shortest path to \(\gamma \) must touch a \(p_1\) or a \(p_2\) first! Thus, the curve indeed cut the plane to two components.
Therotation index of asimple closed curve \(\gamma \) on plane is either \(1\) or \(-1\).
I highly recommend draw vectors during \(D(1)\) transformation proof step by step.
Let \(\gamma : [a,b] \to \R ^2\) be a simple closed curve.
A crucial step is defined \(\gamma (a) = \gamma (b) = p\), where \(p\) is the tangent point of a \(S^1\) that covers \(\gamma \),
Please try to figure out why this is crucial by yourself.
then consider a triangle
\[T=\{ (t_1, t_2) \mid a \le t_1 \le t_2 \le b \}\]Define a continuous function \(\psi : T \to S^1\) as follows
\[\psi (t_1,t_2)=\begin {cases} \gamma '(t_1) \quad \text {if } t_1 = t_2 \\ -\gamma '(a) \quad \text {if } \{ t_1,t_2 \}=\{ a,b \} \\ \frac {\gamma (t_2) - \gamma (t_1)}{\Vert \gamma (t_2) - \gamma (t_1)\Vert } \quad \text {if } t_1 \ne t_2 \\ \end {cases}\]Thus, for most inputs \(\psi (t_1, t_2)\) is the unit vector from \(\gamma (t_1)\) to \(\gamma (t_2)\). Rest cases are defined to make this function iscontinuous.
Let \(\alpha _0 : [0,1] \to T\) be the line segment from \((a,a)\) to \((b,b)\)
and \(\alpha _1 : [0,1] \to T\) be the line segment from \((a,a)\) to \((a,b)\) to \((b,b)\)
Now, defines ahomotopy from \(\alpha _0\) to \(\alpha _1\), parameterize middle-segments by \(s : [0,1] \to T\) as \(\alpha _s\) to be a continuously family, which means \((s,t) \mapsto \alpha _s(t)\) should be a continuous function from \([0,1] \times [0,1] \to T\).
For each \(s \in [0,1]\), use \(D(s)\) denote the degree of \(\psi \circ \alpha _s : [0,1] \to S^1\).
Uselemma 2 to prove \(D(s)\) is locally constant, this is obvious because each \(s\) should uniquely determined a segment, which leads to same degree (the degree of \(\psi \circ \alpha _s\)). therefore continuous on \([0,1]\).
\(D : [0,1] \to \R \) is integer-valued and continuous, \(D\)must be constant on \([0,1]\), so \(D(1) = D(0)\).
\(D(0)\) by definition is the defree of the unit tangent function of \(\gamma \), which equals to the rotation index of \(\gamma \); we cannot prove \(D(0) = 1 \text { or } -1\), but if we can prove below \(D(1) = 1 \text { or } -1\), we are able to say the proof is complete.
Let's track the transformation:
Now we know \(D(1)\) must turn around, and \(\gamma \)'s orientation decides we get \(1\) or \(-1\).
Acommutative ring \(R\) isNoetherian if everyideal of \(R\) is finitely generated.
A freegroup \(F(A)\) on set \(A\) will be aninitial object in \(\mathcal {F}^A\).
In category language, which means if \(F(A)\) is a free group on \(A\) if there is a set-function \(j : A \to F(A)\) such that, for all groups \(G\) and set-functions \(f : A \to G\), there exists a unique group homomorphism \(\varphi : F(A) \to G\) such that
commutes.Algebra: Chapter 0 proves free group exists for any set \(A\), with beautiful direction-hinted graph. Conclusionally, we can say a free group \(F(A)\) is constructed by
If \(A = \{ a \}\), then \(F(A) \cong \Z \).
A freeabelian group \(F^{ab}(A)\) on set \(A\), means there is a set-function \(j : A \to F^{ab}(A)\) such that, for all abelian group \(G\) and set-functions \(f : A \to G\), there exists a unique group homomorphism \(\varphi : F^{ab}(A) \to G\) such that the following diagram commutes
Therefore, \(F^{ab}(A)\) is aninitial object of the category of abelian groups \(Ab\).
Each element of \(\Z ^{\oplus A}\) can be written
\[ \sum _{a \in A} m_a j(a), m_a \ne 0 \text { for finitely many } a \in A\]For any abelian group \(G\), we can define \(\varphi : \Z ^{\oplus A} \to G\) as
\[ \varphi \big ( \sum _{a \in A} m_a j(a) \big ) := \sum _{a \in A} m_a f(a) \]Then check \(\varphi \) is a homomorphism, by commutativity, internal \(m_a\) can put together, so proved.
A free \(R\)-module \(F^R(A)\) on a set \(A\) is aninitial object in \(R\)-Mod. Since the category of abelian groups \(Ab\) is the category of \(\Z \)-modules \(\Z \)-Mod, it's natural to ask \(R^{\oplus A} \cong F^R(A)\)
The proof is basically same asfree abelian group, by replacing \(\Z \) with general \(R\).
The construction of \(b : A \to R^{\oplus A}\) is clear
\[ b(x) = (b_i(x), b_j(x), \dots ) \]such that, for all \(x \in A\)
\[ b_i(x) := \begin {cases} 1 \text { if } x = i \\ 0 \text { if } x \ne i \end {cases} \]so that every element of \(R^{\oplus A}\) can be written uniquely as a finite sum
\[ \sum _{a\in A} r_a b(a) \]i.e. as finite sum means only finite many \(r_a \ne 0\).
Switch from \(R\)-modules to commutative \(R\)-algebras:polynomial ring \(R[A]\) is a free commutative \(R\)-algebra on the set \(A\).
An isometry of \(n\)-dimensional space \(\R ^n\) is a function \(\R ^n \to \R ^n\) that preserves distance.
Let \(F \subseteq \R ^n\) be a set of points in \(\R ^n\), the symmetry group of \(F\) in \(\R ^n\) is the set of all isometries of \(\R ^n\) that carry \(F\) onto itself. The group operation \(\cdot \) is function composition \(\circ \).
Let \(G\) be a group, a sequence of subgroups is thetower.
\[ G = G_0 \supset G_1 \supset G_2 \supset \cdots \supset G_m \]A group \(G\) is said to besolvable if it has an abelian tower, whose last element \(G_m\) is the trivial subgroup.
F-algebra 中的 initial/terminal 等特殊 object
Thetangent bundle \(TM\) isorientable even when the manifold \(M\) is not.
We need to show \(y_\beta ^{-1} \circ y_\alpha \) (reparameterize on \(TM\)) has positive determinant, whenever what determinant \(x_\beta ^{-1} \circ x_\alpha \) (reparameterize on \(M\)) has. Let's view reparameterizations as matrices, and by definition \(x_\beta ^{-1} \circ x_\alpha \) works on \(M\) part and \(d(x_\beta ^{-1} \circ x_\alpha )\) works on tangent vectors.
Thus, we can view the reparameterization matrix on \(TM\) as (fill zeros to fit the dimension)
\[\begin {bmatrix} x_\beta ^{-1} \circ x_\alpha & 0 \\ 0 & d(x_\beta ^{-1} \circ x_\alpha ) \end {bmatrix}\]Then we can see that \(y_\beta ^{-1} \circ y_\alpha \) must have positive determinant, since \(d(x_\beta ^{-1}\circ x_\alpha )\) will have the same determinant as \(x_\beta ^{-1}\circ x_\alpha \), so
Thecofactor of an element \(a_{ij}\) of a matrix \(A\) is called \(a^{ij}\) and is defined as \((-1)^{i+j}\) times the determinant of the \((n-1) \times (n-1)\) matrix formed by eliminating from \(A\) the row and column that \(a_{ij}\) belongs to.
With definition ofcofactor, we now can define
\[ \det (A) = \sum ^n_{j=1} a_{ij} a^{ij} \]for any fixed \(i\). This recursively defines a determinant for any rank matrix.
For \(2\times 2\) matrix, we have
\[\begin {bmatrix}a & b \\ c & d\end {bmatrix}\]The determinant of such matrix is defined as \(ad - bc\).
Consider aRiemann metric \(g\) (use angle notation \(\langle -,- \rangle \)), it's a \(\begin {pmatrix}0 \\ 2\end {pmatrix}\) tensor (i.e. it takes two vectors and returns a real number). By definition, \(g\) is symmetric, and hence if use basis of tangent space \(\frac {\partial }{\partial x^i}\) as input vectors, form a symmetric matrix
\[ g_{ij} = \langle \frac {\partial }{\partial x^i}, \frac {\partial }{\partial x^j} \rangle \]Asview\(\R ^n\) as a manifold (and when a Riemannian metric is flat) said, we say the metric is the Euclidean metric (flat) if \(g_{ij} = \delta _{ij}\).
But if \(g_{ij}\) is not flat, we want to see if we can simplify it, and indeed there is a way to do so.
Geometrical Methods of Mathematical Physics §2.29
Consider a transformation \(\Lambda \), we get
\[ g_{i'j'} = \Lambda ^k_{\ \ i'} \Lambda ^l_{\ \ j'} g_{kl} \]Which can also be viewed as \( \Lambda ^T g \Lambda \). Since \(\Lambda \) is picked by us, and \(g\) is symmetric, it's make sense to let
\[ \Lambda = OD \]where \(O^T = O^{-1}\) is aorthogonal matrix and \(D^T = D\) is adiagonal matrix. In this selection, we get
\[ \Lambda ^T = (OD)^T = D^T O^T = D O^{-1} \]and hence, we get
\[ DO^{-1}gOD \]Introduction to Linear Algebra §6.4
\(g\) is symmetric, thus, \(O^{-1}gO = g_d\) is a diagonal matrix, now say if \(g_d = \text {diag}(g_1, g_2, \dots , g_n)\), then we pick
\[ D = \text {diag}(d_1, d_2, \dots , d_n) \]such that \(d_i = \sqrt {\vert g_i \vert }\), then output diagonal matrix will only have \(1\) or \(-1\) as component on the diagonal line. If we choose \(O\) to let all \(1\) or all \(-1\) appear first, we call it thecanonical form of metric \(g\). The canonical form is anorthonormal basis.
The sum of the canonical form's diagonal elements (i.e. the trace of the canonical form) is called thesignature of the metric \(g\).
If the canonical form is positive-definite or negative-definite, it's flat.
A metric is called aMinkowski metric if it's canonical form is \(\text {diag}(-1, 1, 1, 1)\) or \(\text {diag}(1, -1, -1, -1)\). Thespecial relativity has such a metric for \(n = 4\).
The inverse of Minkowski metric is Minkowski metric.
Riemannian Geometry p.22
Agroup \(G\) acts on adifferentiable manifold \(M\) if there exists a map \(\varphi : G \times M \to M\) such that
這裡讓一個群 \(G\) 的元素與 \(M \to M\) 的各種變換一一對應
這個想法很自然的延伸就是定義一個等價類,令 \(a \sim b\) 若且唯若存在某個 \(g \in G\) 滿足 \(b = \varphi _g(a)\)。這個就是 \(M / G\)
projective spaces 是定義為 \(S^n\) 取 \(x \sim -x\),這表示也可以定義成由群 \(G = \{ A, A^2 = I \}\) 所產生的 quotient space \(S^n / G\)。其中 \(A\) 表示 antipodal mapping
\[ A(x) = -x \]W <- G.vertices-- W 表示 working setwhile W ≠ ∅ -- 1. 從 W 選出有最大 saturation 的頂點 u -- 2. 選出不在鄰邊的顏色集合中,最小的顏色 c color[u] <- c -- 3. 分配顏色 c 給 u W <- W - {u} -- 從 W 中刪除 u
這個演算法還需要最大 saturation 的定義:
\[ \text {saturation}(u) = \{ c \;|\; \exists v. v\in \text {adjacent}(u) \;\text {and}\; \text {color}(v) = c \} \]saturation 是一個集合,最大指的是該集合的大小, 所以 \(W\) 可以用 leftist tree 之類的結構來快速選出有最大 saturation set 的那個頂點
在連結中有詳細的教學,此外要注意放入
\usepackage{tikz}\usepackage{pgfkeys}\usetikzlibrary {backgrounds,arrows}
才能在 latex 中正常使用
Seven Sketches in Compositionality: An Invitation to Applied Category Theory
A unital commutative quantale is asymmetricmonoidal closed preorder \(\mathcal {V} = (V, \le , I, \otimes , \multimap )\) that has all joins \(\vee A\) exists for all \(A \subseteq V\). The empty join often denote as \(0 := \vee \varnothing \).
If the preorder is non-symmetric, we got non-commutative quantale obviously.
A Klesli category \(C^M\) related with amonad \(M : C \to C\) is consisting
We will need to check the idea really works, for each object \(X\), the identity morphism \(X \to M\;X\) is given by \(\eta \) of \(M\).
For any two morphisms \(f : X \to M\;Y\) and \(g : Y \to M\;Z\), the composition is
monad 是一個 endofunctor,所以必然跟某個範疇 \(C\) 有關,具有 \(M : C \to C\) 的簽名。並且,有兩個natural transformation
並滿足 monoid 條件。第一是 \(\mu \cdot (\eta \circ M) = id = \mu \cdot (M \circ \eta )\)
第二是 \(\mu \cdot (\mu \circ M) = \mu \cdot (M \circ \mu )\)
因此我們才說 monad 是 endofunctors 構成的 category 中的一個monoid object。
diskutil listdiskutil unmountDisk /dev/diskNsudo dd if=/CentOS-6.6-x86_64-bin-DVD1.iso of=/dev/diskN
執行forester build
之後,在output
目錄中會出現所有的xxx-NNNN.xml
文件。接著使用 forester-to-latex 中的 xsl 檔案跟xsltproc
產出 tex 檔案再產生 pdf
xsltproc ./book.xsl ~/blog/trees/math-00D3.xml > test.texlatexmk -interaction=nonstopmode -lualatex xxx-NNNN.tex
latex 支援中文需要安插以下的 latex 程式
\usepackage[UTF8]{ctex}\setCJKmainfont{Songti TC}\setCJKmonofont{inconsolata}\renewcommand*{\proofname}{Proof}
註:因為 forster 已經使用了inconsolata
所以我只是把setmonofont
修改成setCJKmonofont
;但處理setCJKmainfont
要記得檢查系統有什麼繁中字型不能照抄。
我們從Proposition [math-00D1] 跟兩個 lemma 得知 \(\mathcal {K}_1 \not \simeq \Lambda ^0 /_{=\beta }\)。
所有PCA 都沒有 decidable equality。
考慮一個 PCA \(A\),假定有元素 \(d \in A^\#\) 是一個 decidable equality,這表示對任意 \(x, y \in A\)
\[ d \cdot x \cdot y = \begin {aligned} \begin {cases} \text {true} &\text { if } x = y \\ \text {false} &\text { otherwise} \end {cases} \end {aligned} \]只要定義 \(v = Y(d\ \text {false})\) 就能得到 \(v = d\ \text {false}\ v\),其值不可判定,所以 \(d\) 不是 decidable equality。
若 \(A\) 跟 \(B\) model 等價 \(A \simeq B\),則 \(A\) 有 decidable equality 若且唯若 \(B\) 也有 decidable equality。
The set of lambda terms \(\Lambda / _\sim \) with \(\alpha \) and \(\beta \) equivalence form acomputability model.
Check that \(\text {fst}(\text {pair}\ M\ N) \sim M\) and \(\text {snd}(\text {pair}\ M\ N) \sim N\)
Any element can play the role of a weak terminal: \(\lambda x. i\) for all \(i \in \Lambda / _\sim \)
Let \(\cdot \) be given by application, if \(M \in \Lambda \) induces an operation in \([L \bowtie L, L]\) representing some \(f : L \times L \to L\) then \(\lambda xy. M(\text {pair}\ x\ y)\) induces the corresponding operation in \(L, L \Rightarrow L\); conversely, if \(N\) induces an operation in \([L, L \Rightarrow L]\), then \(\lambda z. N (\text {fst}\ z) (\text {snd}\ z)\) induces the corresponding one in \([L \bowtie L, L]\).
There is a submodel \(\Lambda ^0/_\sim \) for closed terms.
Use \(\beta \)-equivalence then we denote \(\Lambda / _{=_\beta }\).
記號繼承自Higher-Order Computability
標題的描述有點複雜,但其實只是說 \(\kappa \circ \gamma \not \succeq id_{\Lambda ^0 /_{=_\beta }}\),表示 \(\kappa \circ \gamma \) 不是 \(\lambda \)-definiable。
兩個computability model 的等價 \(\simeq \),表示他們可以互相模擬並且兩個模擬的兩種組合都跟模擬自己的函數相似。Kleene's first model \(\mathcal {K}_1\) 與closed lambda terms \(\Lambda ^0 /_{=_\beta }\) 的模擬細節定義在下面,由於兩者都只有一個 datatype,所以元素的選擇是明顯的。
\(\kappa : \mathcal {K}_1 \triangleright \Lambda ^0 /_{=_\beta }\) 由以下關係定義
\[ M \Vdash ^\kappa n \text { iff } M =_\beta \widetilde {n} =_\beta \lambda f.\lambda x. f^n x \]\(f^n\) 表示重複 \(f\) 剛好 \(n\) 次
在回答下面兩個問題之前,我們要考慮 \(\gamma \circ \kappa : \mathcal {K}_1 \triangleright \mathcal {K}_1\) 會建立什麼?展開我們可以看到
\[ \gamma \circ \kappa (n) = \gamma (\kappa (n)) = \gamma (\widetilde {n}) = \lceil \widetilde {n} \rceil \]反過來就困難得多,\(\kappa \circ \gamma : \Lambda ^0 /_{=_\beta } \triangleright \Lambda ^0 /_{=\beta }\) 展開可以得到
\[ \kappa \circ \gamma (M) = \kappa (\gamma (M)) = \kappa (\lceil M \rceil ) = \widetilde {\lceil M \rceil } \]這裡需要用到 Kleene enumeration theorem,說明存在一個 \(P \in \Lambda ^0\),令式
\[ P(\widetilde {\lceil M \rceil }) =_\beta M \]對所有 \(M \in \Lambda ^0\) 成立。直覺上來說,是因為我們可以從外部看到 \(\lceil M \rceil \) 的定義之後再找滿足條件的 \(P\)。
Higher-Order Computability
Kleene's first model \(\mathcal {K}_1\) is acomputability model consists of
The model has standard products, the computable operation
\[ \langle m,n \rangle = (m+n)(m+n+1)/2 + m \]defines a bijection \(\N \times \N \to \N \) and satisfiedweak product. Any element \(i \in \N \) may serve as a weak terminal, because \(\Lambda n. i\) is computale.
Here \(\N \Rightarrow \N \) can only be \(\N \), so need a suitable operation \(\cdot : \N \times \N \to \N \). Let \(T_0, T_1, \dots \) be some chosen enumeration of all Turing machines for computing partial functions \(\N \rightharpoonup \N \), then there is a Turing machine that accepts two inputs \(e, a\) and returns the result of applying the machine \(T_e\) to the single input \(a\).
The partial functions \(f : \N \times \N \rightharpoonup \N \) representable within the model via the standard product operations are just the partial computable ones. We may also see that these coincide exactly with those represented by some total computable \(\tilde {f} : \N \to \N \), in the sense that \(f(c,a) \simeq \tilde {f}(c) \cdot a\) for all \(c,a \in \N \).
One half of this is immediate: given a computable \(\tilde {f}\) the operation \(\Lambda (c,a). \tilde {f}(c) \cdot a\) is computable. The other half is precisely the content ofKleene's s-m-n from basic computability theory: for any Turing machine \(T\) accepting two arguments, there is a machine \(T'\) accepting one argument such that for each \(c\), \(T'(c)\) is an index for a machine computing \(T(c,a)\) from \(a\).
Higher-Order Computability
Acomputability model \(\mathbb {C}\) has weak (binary cartesian) products if there is an operation assigning to each \(A,B \in \vert \mathbb {C} \vert \) a datatype \(A \bowtie B \in \vert \mathbb {C} \vert \) along with operations \(\pi _A \in \mathbb {C}[A \bowtie B, A]\) and \(\pi _B \in \mathbb {C}[A \bowtie B, B]\), such that for any \(f \in C[C,A]\) and \(g \in \mathbb {C}[C,B]\), there exists \(\langle f,g \rangle \in \mathbb {C}[C, A \bowtie B]\) satisfying the following for all \(c \in C\).
We say that \(d \in A \bowtie B\) represents the pair \((a,b)\) if \(\pi _A(d) = a\) and \(\pi _B(d) = b\).
Higher-Order Computability
A higher-order structure is acomputability model \(C\) possessing a weak terminal \((I,i)\), and endowed with the following for each \(A, B \in \vert C \vert \)
A higher-order (computability) model is a higher-order structure \(C\) satisfying the following conditions for some (or equivalently any) weak terminal \((I,i)\)
Higher-Order Computability
Acomputability model \(C\) over a set \(T\) of type names consists of
such that
A computability model is a category of sets and partial functions.
Denote \(C[A, B]\) for \(C[\sigma , \tau ]\) where \(A = C(\sigma )\) and \(B = C(\tau )\).
A computability model istotal if every operations \(f \in C[A,B]\) is a total function \(A \to B\).
The Möbius strip (plane model) can be defined as aquotient topology of \([0, 1] \times (-1, 1)\) with usual \(\R \) metric, the equivalence relation is defined as
\[(0, s) \sim (1, -s)\]Let \((a_n)_{n\in \N }\) be a sequence of a topological space \(X\), we say it converges to \(a \in X\) if for all neighborhoods \(N_a\) of \(a\), there is a \(N \in \N \) let all \(a_k \in N_a\) for all \(k \ge N\).
Let \((\R , \mathcal {T})\) be a topological space, \(\mathcal {T} = \{ \varnothing , \R \} \cup \{ (b,\infty ) \mid b \in \R \}\). The sequence
\[(a_n)_{n\in \N } = \bigg (\frac {1}{n}\bigg )_{n\in \N }\]converges to many points.
The argument can work on every \(b \in \R \) if \(b < 0\), so not every topological space can work with usual convergence definition that generalized frommetric space, leads us to defineHausdorff.
A type theory isextensional ifpropositional equality impliesdefinitional equality.
A term isclosed if no variables occur free in it. For example,
(let ([x 1]) (let ([y 2]) (+ x y)))is closed, but
(let ([y 2]) (+ x y))
is not! Ask this question from where is important.We can reshape this description to: A term isclosed if it has no free variables, and a term isopen if it's not closed.
A prime ideal \(A\) of acommutative ring \(R\) is a properideal of \(R\) such that \(a,b \in R\) and \(a \cdot b \in A\) imply \(a \in A\) or \(b \in A\).
A maximal ideal of a commutative ring \(R\) is a proper ideal of \(R\) such that, whenever \(B\) is an ideal of \(R\) and \(A \subseteq B \subseteq R\), then \(B = A\) or \(B = R\).
A projective space \(P^n(\R )\) is the set of all 1-dimensional subspaces of \(\R ^{n+1}\), can be defined as aquotient topology of \(S^n\)
\[S^n = \{ \Vert x\Vert = 1 \mid x \in \R ^{n+1} \}\]by equivalence relation \(x \sim -x\), so
\[ x \sim y := x = y \text { or } x = -y \]so we define \(P^n(\R ) := S^n/_\sim \).
Each \(P^n(\R )\) isHausdorff
Let \(R\) be acommutative ring with unity and \(A\) be anideal of \(R\).
\(R/A\) is anintegral domain if and only if \(A\) isprime.
A subset \(S\) of aring \(R\) is asubring of \(R\) if \(S\) is itself a ring with the operations of \(R\).
A nonempty set \(S\) of a ring \(R\) is a subring if \(S\) is closed under subtraction and multiplication. Which means \(a - b \in S\) and \(a \cdot b \in S\) should hold for all \(a, b \in S\).
\(\{ 0 \}\) and \(\R \) are subrings of \(\R \).
For each \(n \in \N \), the set
\[n\Z = \{ 0, \pm n, \pm 2n, \pm 3n, \dots \}\]is a subring of \(\Z \).
Topology via Logic
Let \(A\) be aframe, its elements are opens. Let \(X\) be a set, its elements are points. Let \(\vDash \) be a subset of \(X \times A\), if \((x,a) \in \ \vDash \) then we write \(x \vDash a\) and say \(x\) satisfies \(a\). \((X,A,\vDash )\) is atopological system if
If \(D = (X, A)\) is a topological system, denote \(\Omega D = A\) and \(\text {pt} D = X\).
\[D = (X,A) = (\text {pt} D, \Omega D)\]Higher-Order Computability
Alanguage \(L\) isTuring complete if any partial computable function \(\N \rightharpoonup \N \) can be implemented in \(L\).
Higher-Order Computability
Let \(\Gamma \) be a finite set of alphabets, \(M\) be a single datatype of memory states. A memory state is a function \(m : \Z \to \Gamma \). Any Turing machine \(T\) can be regarded as computing a certain partial function \(f_T : M \rightharpoonup M\) in the way: \(f_T(m) = m'\) if the execution of \(T\) with initial state \(m\), eventually halts yielding the final memory state \(m'\).
The model \(T_2\) consisting of the single datatype \(\N \) together with all Turing-computable partial functions \(\N \rightharpoonup \N \). This model needs some convention for representing natural numbers via memory states.
Also known asKleene's first model.
The model \(T_3\) conceptually have a read-only input tape, a write-only output tape, and a working tape that permits both reading and writing. The input and output tapes are functions \(d : \N \to \Gamma \), \(D\) is the set of all such total functions. Thus, the model consisting of the single datatype \(D\) and all machine-computable partial functions \(f : D \rightharpoonup D\).
Higher-Order Computability
Let \(C\) and \(D\) becomputability models with types indexed by \(T, U\) respectively. A simulation \(\gamma \) of \(C\) in \(D\) (denotes \(C \triangleright D\)) consists of
subject to the following conditions
By definition of \(T_2\), a simulation \(T_2 \triangleright T_1\) is given. If \(n \in \N \) and \(m\) is a memory state, we take
\[m \Vdash n\]iff \(m\) represents \(n\) in the sense we have defined. Every operation in \(T_2\) is tracked by one in \(T_1\).
We cannot have a simulation \(T_1 \triangleright T_2\), because there are uncountably many memory states. But there is a simulation for variant of \(T_1\), by restricting \(T_1\)'s memory states to those with a designated blank symbol in all but finitely many cells. Such memory states can be coded as natural numbers, and the action of any Turing machine may then be emulated by a partial computable function \(\N \rightharpoonup \N \). We thus obtain a simulation \(T_1^\text {fin} \triangleright T_2\).
A lie group is a \(C^\infty \)-manifold \(G\) that is also a group such that the multiplication
\[\mu : G \times G \to G, \mu (a,b) = ab\]and the inverse
\[\eta : G \to G, \eta (a) = a^{-1}\]are \(C^\infty \) functions.
The left multiply function \(L_a(b) = ab\) is adiffeomorphism.
We can simply found since \(\mu \) is \(C^\infty \), each partial differential of it still \(C^\infty \), and \(L_{a^{-1}}(b)\) is the inverse function share the same form and hence also \(C^\infty \), concludes that \(L_a\) is a diffeomorphism.
The general linear group is defined as
\[ GL(n, \R ) := \{ A \in \R ^{n\times n} \mid \det A \ne 0 \} = \det {}^{-1}(\R \setminus \{ 0 \}) \]The determinant function \(\det : \R ^{n\times n} \to \R \) is continuous, \(GL(n, \R )\) is an open subset of \(\R ^{n\times n}\), with the standard topology on \(\R ^{n\times n}\).
Consider the \((i,j)\)-entry of the product of its elements \(A, B\)
\[ (AB)_{ij} = \sum _{k=1}^n a_{ik}b_{kj} \]we can see it's a polynomial in the coordinates of \(A\) and \(B\), so \(\mu : GL(n,\R ) \times GL(n,\R ) \to GL(n,\R )\) is a \(C^\infty \) map.
By Cramer's rule, we have
\[ (A^{-1})_{ij} = \frac {1}{\det A} \cdot (-1)^{i+j} ((j,i)\text {-minor of } A) \]which is a \(C^\infty \)-function, and hence \(\eta : GL(n,\R ) \to GL(n,\R )\) is also a \(C^\infty \)-map. Tell \(GL(n, \R )\) is a Lie group.
\(\R ^n\) is the usual Euclidean space, the distance function
\[d(p - q) = |p - q|\]let \((x^1, \dots , x^n) = x^ie_i\) be the coordinate system on \(\R ^n\), which means
\[e_i = (0, \dots , 1 (\text {position } i), \dots , 0)\]then we can get
\[d(p,q) = \sqrt {\sum _{i=1}^n (x^i(p) - x^i(q))}\]Now for any point \(p \in \R ^n\), its \(T_p\R ^n\) is all vector from \(p\), which means
\[T_p\R ^n \ni X = \overrightarrow {pq} = (x^i(q) - x^i(p))e_i\]so if we consider \(X, Y \in T_p\R ^n\) (\(Y = \overrightarrow {pr}\)), we have
\[g(X,Y) = \sum _{i=1}^n (x^i(q) - x^i(p))(x^i(r) - x^i(p))\]then we get the standard Riemannian metric (Kronecker delta)
\[ g_{ij} = g\big (\frac {\partial }{\partial x^i}, \frac {\partial }{\partial x^j}\big ) = \delta _{ij} = \begin {cases} 1 \text { if } i = j \\ 0 \text { if } i \ne j \end {cases} \]We call anyRiemannian metric \(g\) satisfies this condition is flat.
A frame is a completelattice \(L\) satisfying the distributivity law
\[ (\bigvee A) \wedge b = \bigvee \{ a \wedge b \mid a \in A \} \]for any \(A \subseteq L\) and \(b \in L\).
Aposet \(A\) is aframe iff
Write \(\text {true}\) for empty meet (top), \(\text {false}\) for empty join (bottom).
Let \(s_n\) represents the \(n\)-th bit of a stream, and \(s_n = 0\) and \(s_n = 1\) are subbasic observations. No doubt we have
\[s_n = 0 \wedge s_n = 1 \quad = \quad \text {false}\]hold for all \(n\). And then, instead of \(s_n = 0 \vee s_n = 1 \quad =\quad \text {true}\), we interpret \(s_n = 0 \vee s_n = 1\) as the \(n\)-th bit has now been read. Thus, we have
\[ s_{n+1} = 0 \vee s_{n+1} = 1 \implies s_n = 0 \vee s_n = 1 \]Which means, to read \(n+1\)-th bit, we must already read \(n\)-th bit.
A frame is said to bespatial if it's isomorphic to a \(\Omega (X)\) which ismade by the frame functor.
For any topological space \(X\), we have a frame \(\Omega (X)\) (referstopology and lattice) and frame homomorphisms
\[\Omega (f) : \Omega (Y) \to \Omega (X)\]for continuous maps \(f : X \to Y\) resulting a contravaiant functor
\[\Omega : Top \to Frm\]Let \(A\) be aframe. The locale corresponding to \(A\) is thetopological system \(D\) defined by
\(2\) stands for a frame that has only \(\{ \text {true},\text {false} \}\) in the carry set, and \(\text {false} \le \text {true}\)
The category of locales \(Loc\) is the opposite category ofcategory of frames \(Frm\).
Manifolds, Sheaves, and Cohomology
A real \(C^\alpha \)-premanifold is alocally\(\R \)-ringed space \((M, \mathcal {O}_M)\) with an open covering
\[ M = \bigcup _{i \in I}U_i \]such that for all \(i \in I\) there exist \(m \in \N \), an open \(Y \subseteq \R ^m\), and an isomorphism of locally \(\R \)-ringed spaces \((U_i, {\mathcal {O}_M}_{\rvert {U_i}}) \cong (Y, \mathcal {C}^\alpha _Y)\) (called chart).
符號 \(\alpha \in \widehat {\N } = \N \cup \{ \infty , \omega \}\),\(C^\alpha \) 是可微分幾次的意思。\((Y, \mathcal {C}^\alpha _Y)\) 是帶有 sheaf of \(\R \)-valued \(C^\alpha \)-functions 的子空間 \(Y\)。
Let \(M, N\) bedifferentiable manifolds, a mapping \(\varphi : M \to N\) is differentiable at \(p\) if
\[ y^{-1} \circ \varphi \circ x : \R ^m \to \R ^n \]isdifferentiable at \(x^{-1}(p)\).
I found the diagram below is helpful.
The differential of map \(\varphi \) at \(p\) is a map oftangent vectors \(T_p M \to T_{\varphi (p)} N\)
Let \(M, N\) be differentiable manifolds (\(m\) and \(n\) dimensional, resp) and let \(\varphi : M \to N\) be a differentiable mapping (Definition [math-00CB]). For every \(p \in M\) and for each \(v \in T_p M\), choose adifferentiable curve \(\alpha : (-\epsilon ,\epsilon ) \to M\) with \(\alpha (0) = p\), \(a'(0) = v\). Take \(\beta = \varphi \circ \alpha \). The linear mapping
\[\begin {aligned} &d \varphi _p &:& &T_p M \to T_{\varphi (p)} N \\ &d\varphi _p(v) &=& &\beta '(0) \end {aligned}\]is calledthe differential of \(\varphi \) at \(p\).
The differential does not depend on the choice of \(\alpha \).
We first expand the mapping \(\varphi \) to parameterized form
\[ y^{-1} \circ \varphi \circ \textcolor {red}{x}(q) = (y_1(x_1, \dots , x_m), \dots , y_n(x_1, \dots , x_m)) \]then expand \(\alpha \) to parameterized form
\[ \textcolor {red}{x^{-1}} \circ \alpha (t) = (x_1(t), \dots , x_m(t)) \]Therefore, use first after the second formula
so
\[ y^{-1} \circ \beta (t) = (y_1(x_1(t), \dots , x_m(t)), \dots , y_n(x_1(t), \dots , x_m(t))) \]and hence we can express \(\beta '(0)\) as
\[ \beta '(0) = d\varphi _p(v) = \bigg (\frac {\partial y_i}{\partial x_j}\bigg ) (x_j'(0)) \\ = \begin {bmatrix} \frac {\partial y_1}{\partial x_1} & \cdots & \frac {\partial y_1}{\partial x_m} \\ \vdots & \ddots & \vdots \\ \frac {\partial y_n}{\partial x_1} & \cdots & \frac {\partial y_n}{\partial x_m} \\ \end {bmatrix} \begin {bmatrix} x_1'(0) \\ \vdots \\ x_m'(0) \\ \end {bmatrix} \]equivalence\simeq | \(\simeq \) |
---|---|
equal\= | \(=\) |
Thecharacteristic of aring \(R\) is the least positive integer \(n\) such that
\[\forall x \in R, nx = 0\]\(nx\) is the shorthand of \(\underbrace {x + \cdots + x}_{n-\text {times}}\)
If no such integer exists, then the characteristic is \(0\).
The characteristic of anintegral domain is \(0\) or prime.
Let \(C,D\) be two categories. Given two functors \(P, Q : C^{op} \times C \to D\) adinatural transformation \(\alpha : P \multimap Q\) consists of a family of morphisms
\[ \alpha _c : P(c,c) \to Q(c,c) \]indexed by the objects \(c \in C\) and such that for any \(f : c \to c'\) the following diagram commutes
Let \(\gamma : [a,b] \to \R ^2\) be a regularclosed curve on plane \(\R ^2\), then there exists a smooth function \(\theta : [a,b] \to \R \) such that for all \(t \in [a,b]\), the unit tangent vector satisfies
\[\vec {\mathfrak {t}}(t) = (\cos \theta (t), \sin \theta (t))\]therotation index of \(\gamma \) is defined as
\[ \frac {1}{2\pi } (\theta (b) - \theta (a)) \]The rough meaning of rotation index is the number of times the domain \([a,b]\) is wrapped counterclockwise around the circle.
If \(f : [a,b] \to S^1\) is a continuous function with \(f(a) = f(b)\), then there exists a continuous angle function \(\theta : [a,b] \to \R \) such that for all \(t \in [a,b]\)
\[ f(t) = (\cos \theta (t), \sin \theta (t)) \]This function is unique up to adding an integer multiple of \(2\pi \).
Let \(f_1, f_2 : [a,b] \to S^1\) be continuous functions with \(f_1(a) = f_2(b)\) and \(f_2(a) = f_2(b)\). If \(f_1\) and \(f_2\) have different rotation indicies (Definition [math-00C5]), then exists \(t_0 \in [a,b]\) satisfies
\[f_1(t_0) = -f_2(t_0)\]Let \(\theta _1, \theta _2 : [a,b] \to \R \) be angle functions respectively. Consider
\[\delta (t) = \theta _2(t) - \theta _1(t)\]This is not zero since the rotation indicies are different, so we have
\[ \vert \delta (b) - \delta (a) \vert = \vert (\theta _2(b) - \theta _2(a)) - (\theta _1(b) - \theta _1(a)) \vert \ge 2\pi \]since \(\delta \) has a net change of at least \(2\pi \), there must be an odd integer \(n\) multiple \(n\pi \) between \(\delta (a)\) and \(\delta (b)\). The intermediate value theorem implies that \(\delta \) achieves this value for some \(t_0 \in [a,b]\), so \(f_1(t_0) = -f_2(t_0)\).
The idea behinds this is two angles will be exactly be oppsite place on \(S^1\) at some point \(t_0\).
Manifolds, Sheaves, and Cohomology, §4.1
Let \(X\) be a topological space, \(\mathcal {F} : \mathcal {O}(X)^{op} \to Sets\) be apresheaf on \(X\). Thecolimit
\[\mathcal {F}_x := \underset {\mathcal {U}(x)} {\text {colim}} \mathcal {F}\]is called thestalk of \(\mathcal {F}\) in \(x\). Where \(\mathcal {U}(x)\) is the set of open neighborhoods of \(x\) for each point \(x \in X\).
\(\mathcal {U}(x)\) ordered by inclusion, can be viewed as afull subcategory of \(\mathcal {O}(X)\).
Alocally \(R\)-ringed space is an \(R\)-ringed space \(X,\mathcal {O}_{X}\) such that for each point \(x \in X\), the stalk (Definition [math-00B5]) \(\mathcal {O}_{X,x}\) is a local ring. We then denote
A connected graph \(T\) is a tree if and only if for each subgraph, there exists a point with degree 0 or 1.
(\(\Longrightarrow \)) First, we only need to consider connected subgraph, since \(T\) is a tree. Then for any subgraph we can inherit tree order from the tree, then form a subtree and hence has leaf (with degree 1) or has a single point (with degree 0).
(\(\Longleftarrow \)) Suppose \(T\) is not a tree, which means it has a cycle, then we pick that cycle as subgraph, and that's contradict to the condition, and hence \(T\) is a tree.
A Martin-Löf category is alocally cartesian closed category with disjointcoproducts andinitial algebras for container functors, so it closed under formation ofW-types.
Containers: Constructing strictly positive types
A unary container is given by a type of shapes \(S\) and a family of position types indexed by \(S\), thus
\[ s : S \vdash P(s) \]as a container we dnote this as \((s : S \triangleright P s)\) or \((S \triangleright P)\). An extension of a container is a functor
\[ \llbracket S \triangleright P \rrbracket X = \sum _{s : S} P(s) \to X \]注意到 \(X\) 是一個類型,\(P(s)\) 也是一個類型。用 \(\text {List} = \mu X. 1 + A \times X\) 舉例的話就是
\[ \llbracket \N \triangleright \text {Fin} \rrbracket X = \sum _{n : \N } \text {Fin}(n) \to X \]因此對於能充分表達類型的範疇 \(\mathbb {C}\),將 extension 作為 container functor 的定義。
A functor \(F : \mathbb {C} \to \mathbb {C}\) is acontainer functor iff it isnaturally isomorphic to a functor of the form
\[X \mapsto \sum _{a : A} B(a) \to X\]or more concisely \(\sum _A(B \to X)\), for some family \(A \vdash B\) in \(\mathbb {C}\), i.e., \(A \in \mathbb {C}\) and \(B \in \mathbb {C} / A\).
NOTE: due to the relation \(A \vdash B\), we need \(\mathbb {C}\) be at leastLCCC, and induce the definition ofMartin-Löf category.
Containers: Constructing strictly positive types
Strictly positive types are those types which can be formed using \(0, 1, +, \times , \to , \mu , \nu \) with the restriction that types on the left hand side of the arrow have to be closed with respect to type variables. So, a strictly positive type in \(n\) variables is a type expression (with type variables \(X_1, \dots , X_n\)) by the following rules inductively
andnon-inductive strictly positive type means the expression has no any \(\mu \) and \(\nu \) involved.
The central insight of the paper is all strictly positive types can be represented ascontainers.
Lists over \(A\) can be expressed as a solution to \(\text {List}\ A \cong 1 + A \times \text {List}\ A\), there are two canonical choices of fixpoint
檢查機制org-002K
Let \(X\) be a topological space, \(X/_\sim \) is a set defined as
\[X/_\sim = \{ [x]_\sim \mid x \in X \}\]\([x]_\sim \) denotes the equivalence class of \(x \in X\).
and a surjective map
\[\begin {aligned} &\pi : X \to X/_\sim \\ &\pi = x \mapsto [x]_\sim \end {aligned}\]Then the quotient topology on \(X/_\sim \) is induced by: \(U\) is open in \(X/_\sim \) if \(\pi ^{-1}(U)\) is open in \(X\).
For every topological space \(Z\) and every map \(f : S \to Z\), \(f\) iscontinuous iff \(f \circ \pi \) is continuous.
This function is a minimal example that concurrency might not able to do it:
|| | true | false | \(\bot \) |
---|---|---|---|
true | true | true | true |
false | true | false | \(\bot \) |
\(\bot \) | true | \(\bot \) | \(\bot \) |
If a concurrency process is actually do by time sharing with the only unit, it might fall into a loop at one side and never check another computation, and hence cannot have the same semantic.
Thering of integers is the tuple \((\mathbb {Z}, 0, 1, +, \times )\).
A \(n \times n\) matrix \(A\) is calledorthogonal if \(| A \cdot p | = | p |\) for all \(p \in \R ^n\).
distance notation: \(| p | = | p - 0 | = d(p, 0)\)
Arigid motion of \(\R ^n\) is a function \(f : \R ^n \to \R ^n\) that preserves distances:
\[d(f(p), f(q)) = d(p, q)\]for all \(p, q \in \R ^n\)
Let \(X\) be a vector space over a field \(\mathbb {F}\), if there is a function \(\langle -,- \rangle : X \times X \to \mathbb {F}\), such that
Conjugate symmetry will be just symmetry if \(\mathbb {F} = \R \).
The usual \(\R ^n\) space has inner product
\[ \langle u,v \rangle = a_1b_1 + a_2b_2 + \cdots + a_nb_n = \sum _{i=0}^n a_ib_i \]where \(u = \begin {bmatrix}a_1\\ \vdots \\ a_i \\ \vdots \\ a_n \end {bmatrix}\) and \(v = \begin {bmatrix}b_1\\ \vdots \\ b_i \\ \vdots \\ b_n \end {bmatrix}\).
Let \(X = V(f_i)_{i\in I}\), each \(f_i(x, x) = 0\). Let \(g(x) = f_i(x,x)\) for some \(i\). SinceProposition [math-00BP] we have \(g(1) = f_i(1,1) = 0\), implies \((1,1) \in X\), leads to contradiction. Thus, \(X\) is not an affine variety.
Let \(R = V(f_i)_{i\in I}\), each \(f_i(x, y) = 0\). We can write \(f_i\) in form
\[ f_i = \sum _{j = 0}^2 g_j(y) x^j \]since all \(x\in \R \) are included, and hence \(g_j\) are forced to be zero functions, and hence are zero polynomials. Which force \(R\) to include all \(y\in \R \) in \(R\), leads to contradiction. Thus, \(R\) is not an affine variety.
Let \(k\) be an infinitefield and let \(f \in k[x_1, \dots , x_n]\) be apolynomial. Then \(f = 0\) in \(k[x_1, \dots , x_n]\) if and only if \(f : k^n \to k\) is the zero function.
The zero polynomial's coefficients are all zero, so if direction is clear. The converse part can be show by induction on the number of variables \(n\):
Assume converse is true for \(n-1\), and let \(f \in k[x_1,\dots ,x_n]\) be a polynomial that vanishes at all points of \(k^n\). By collecting the various powers of \(x_n\), \(f\) can be wrote in the form
\[ f = \sum _{i=0}^N g_i(x_1, \dots , x_{n-1}) x^i_n \]where \(g_i \in k[x_1,\dots ,x_{n-1}]\). We will show that each \(g_i\) is the zero polynomial in \(n-1\) variables, which will force \(f\) to be the zero polynomial in \(k[x_1, \dots , x_n]\).
If we fix \((a_1, \dots , a_{n-1}) \in k^{n-1}\), we get the polynomial \(f(a_1, \dots , a_{n-1}, x_n) \in k[x_n]\). By our hypothesis on \(f\), this vanishes for every \(a_n \in k\). It follows from the case \(n=1\) that \(f(a_1, \dots , a_{n-1}, x_n)\) is the zero polynomial in \(k[x_n]\).
Use the above formula of \(f\), we see that the coefficients of \(f(a_1,\dots ,a_{n-1},x_n)\) are \(g_i(a_1, \dots ,a_{n-1})\), and thus \(g_i(a_1,\dots ,a_{n-1}) = 0\) for all \(i\). Since \((a_1,\dots ,a_{n-1})\) was arbitrarily chosen in \(k^{n-1}\), it follows that each \(g_i\) gives the zero function on \(k[x_1, \dots , x_{n-1}]\). Our inductive assumption then implies that each \(g_i\) is the zero polynomial in \(k[x_1, \dots , x_{n-1}]\). This force \(f\) to be the zero polynomial in \(k[x_1,\dots ,x_n]\) and completes the proof.
Adifferentiable manifold of dimension \(n\) is a set \(M\) and a family of injective mappings \(x_\alpha : U_\alpha \subset \R ^n \to M\) of open sets \(U_\alpha \) of \(\R ^n\) into \(M\) such that
A family \(\{ (U_\alpha , x_\alpha ) \}\) is called a differentiable structure on \(M\).
Let \(M\) and \(N\) be differentiable manifolds (Definition [math-00BN]), and let \(\{ (U_\alpha ,x_\alpha ) \}\), \(\{ (V_\beta ,y_\beta ) \}\) be differentiable structures respectively. A mapping \(z_{\alpha \beta }(p,q) = (x_\alpha (p), y_\beta (q))\) for all \(p \in U_\alpha \) and \(q \in V_\beta \), then \(\{ (W_{\alpha \beta }, z_{\alpha \beta }) \}\) is a differentiable structure on \(M \times N\).
We need two parts: covering and differentiable to show it.
It's notable that \(\pi _1 : M \times N \to M\) and \(\pi _2 : M \times N \to N\) are differentiable.
\(\pi _1\) is differentiable if \(x_\alpha ^{-1} \circ \pi _1 \circ z_{\alpha \beta }\) is differentiable, so we expand it
\[ x_\alpha ^{-1} \circ \pi _1 \circ (x_\alpha , y_\beta ) = x_\alpha ^{-1} \circ x_\alpha \]and this function by definition is differentiable. The same argument can be applied to \(\pi _2\).
Asubring \(A\) of aring \(R\) is aideal of \(R\) if for every \(r \in R\) and every \(a \in A\), both \(r \cdot a\) and \(a \cdot r\) are in \(A\).
A nonempty subset \(A\) is an ideal of \(R\) if
Let \(k\) be afield, and let \(f_1, \dots , f_s\) bepolynomials in \(k[x_1, \dots , x_n]\) (or \(k[\underline {x}]\) for short). Then an affine variety
\[ V(f_1, \dots , f_s) = \{ (a_1, \dots , a_n) \in k^n \mid f_i(a_1,\dots ,a_n)=0 \text { for all } 1 \le i \le s \} \]is the set of all solutions of the system of equations
\[f_1(x_1, \dots , x_n) = \cdots = f_s(x_1, \dots , x_n) = 0\]If \(p\) is prime, then \(a^p \div p\) has the remainder \(a\).
Let \(M\) be amanifold, \((M,g)\) is aRiemann manifold if for each point \(p \in M\) there is aninner product function defined fortangent space \(T_pM\)
\[ \langle -,- \rangle : T_pM \times T_pM \to \R \]such that have
we called \(\langle -,- \rangle \) is the Riemann metric (or just metric) of the space \(M\).
Below are all usual notation for the metric
\[\langle -,- \rangle = \langle -,- \rangle _p = g(-,-)\]Let \(x^i\) be basis of a local coordinate at \(p\), then \(T_pM\) has basis \(\partial _i = \frac {\partial }{\partial x^i}\)
\[ g_{ij} = \langle \partial _i, \partial _j \rangle \]\((g_{ij})\) will be the matrix that each component is \(g_{ij}\). The inverse matrix denotes \((g^{ij})\)
For any two points \(p,q \in M\), we define the distance function
\[ d(p,q) = \inf _\gamma s(\gamma ) \]\(\gamma \) is any differentiable curve (aka \(\gamma : [0,1] \to M\)) connects \(p\) and \(q\), where \(s\) defined as
\[ s(\gamma ) = \int ^1_0 \sqrt {\langle \frac {d \gamma }{d t} , \frac {d \gamma }{d t} \rangle } dt \]Notice the \(\inf _\gamma \) means, we take theshortest path.
ARiemann manifold \((M,d)\) is ametric space, i.e. proving three properties below:
By definition, \(d(p,q) = s(\gamma )\) for a \(\gamma \) with least \(s(\gamma )\), so
\[ d(p,q) = \int ^1_0 \sqrt {\langle \frac {d \gamma }{d t} , \frac {d \gamma }{d t} \rangle } dt \]since \(\langle -,- \rangle \) is positive-defined, the integral result is positive.
\[\begin {aligned} & d(p,q) = 0 \\ \iff & \exists \gamma , \langle \frac {d \gamma }{d t} , \frac {d \gamma }{d t} \rangle = 0 \\ \iff & \exists \gamma , \frac {d \gamma }{d t} = 0 \\ \iff & p = q \end {aligned}\]To show symmetry, we suppose it does not
\[ d(p,q) = s(\gamma _0) \ne s(\gamma _1) = d(q,p) \]whether \(s(\gamma _0) \gt s(\gamma _1)\) or \(s(\gamma _0) \lt s(\gamma _1)\), we know it doesn't make sense to use \(\gamma _0\) (or \(\gamma _1\)) to be shortest path, and hence one of \(d(p,q)\) and \(d(q,p)\)'s definition is wrong, so \(d(p,q) = d(q,p)\) has to be hold.
To show triangle inequality, we first rewrite
\[ d(p,r) + d(r,q) \ge d(p,q) \]in terms of curves
\[ s(\gamma _0) + s(\gamma _1) \ge s(\gamma _2) \]but notice that \(\gamma _1\) after \(\gamma _0\) is also a curve from \(p\) to \(q\), and \(\gamma _2\) by definition is one of the path with shortest length, and hence the length of \(\gamma _1\) plus \(\gamma _0\) at less equals to the length of \(\gamma _2\), or be bigger.
Chocolatey - Software Management for Windows. Installation command:
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
This is because afterchocolatey installation, the environment needs to be renew.
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
Usechocolatey
choco install visualstudio2022community
In powershell
$vsPath = (vswhere -latest -property installationPath)Import-Module (Join-Path $vsPath "Common7\Tools\Microsoft.VisualStudio.DevShell.dll")Enter-VsDevShell -VsInstallPath $vsPath -SkipAutomaticLocation -DevCmdArguments "-arch=x64 -host_arch=x64"
& "C:\Program Files (x86)\Microsoft Visual Studio\Installer\setup.exe" modify --channelId "VisualStudio.17.Release" --productID "Microsoft.VisualStudio.Product.Community" --add "Microsoft.VisualStudio.Component.VC.Tools.x86.x64" --add "Microsoft.VisualStudio.Component.Windows11SDK.14393" --add "Microsoft.VisualStudio.Component.VC.ATL" --quiet --norestart
Agroup \(G\) is abelian if for all \(g,h \in G\), we have
\[gh = hg\]This is asubcategory of the category of groups.
For two elements \(g,h \in G\) of a group \(G\), the conjugation \(g^h = h^{-1} g h\). This can be applied to a subset \(A \subseteq G\), by \(A^k = \{ a^k \mid a \in A \}\).
Two subsets \(A,B\) of \(G\) are conjugate if there exists \(h \in G\) such that \(B = A^h\), this is an equivalence relation, and hence has equivalence class \(\text {conj}(A)\). A singleton \(\{ g \}\) via \(g \in G\) simply denote by \(\text {conj}(g)\).
A subset \(A\) is self-conjugate if \(\text {conj}(A) = \{ A \}\).
Linear Algebra Done Right
Alinear functional on aspace \(V\) is alinear map from \(V\) to its scalar field \(F\).
For \(v \in V\), thenorm of \(v\), denoted \(\Vert v \Vert \) is defined by
\[ \Vert v \Vert = \sqrt {\langle v,v \rangle } \]\(\langle v,v \rangle \) is ainner product of the vector space.
An orthonormal basis of \(V\) is an orthonormal (Definition [math-00BB]) list of vectors in \(V\) that is also a basis of \(V\).
A list of vectors isorthonormal if each vector in the list hasnorm \(1\) and is orthogonal to all other vectors in the list. In the other word
\[ \langle e_j , e_k \rangle = \begin {cases} 1 \text { if } j = k \\ 0 \text { if } j \ne k \end {cases} \]Any vector \(v \in V\) can be represented by a basis
\[ v = a_1e_1 + \cdots + a_ne_n = \sum ^n_{i=0} a_i e_i \]For arbitrary basis of \(V\), to compute each \(a_i\) is hard. But fororthonormal basis is very easy, we have \(a_i = \langle v,e_i \rangle \). Therefore, one can write
\[ v = \langle v,e_1 \rangle e_1 + \cdots + \langle v,e_n \rangle e_n = \sum ^n_{i=0} \langle v,e_i \rangle e_i \]First write a vector in linear combination form \(v = a_1e_1 + \cdots + a_ne_n\). Now see that
\[ \langle v,e_i \rangle = a_1 \langle e_i,e_1 \rangle + \cdots + a_n \langle e_i,e_n \rangle \]By definition, we have a list of \(0\) except \(1 = \langle e_i,e_i \rangle \), and hence \(\langle v,e_i \rangle = a_i\)
Manifolds, Sheaves, and Cohomology
Let \(X\) be a topological space, anétalé space over \(X\) is a pair \((E, \pi )\), where \(E\) is a topological space and \(\pi : E \to X\) is alocal homeomorphism.
A category of étalé spaces has
Denote by \(Ét/X\) the category of étalé spaces over \(X\).
Acontinuous map \(f : X \to Y\) is alocal homeomorphism if there exists anopen covering \((U_i)_i\) of \(X\) such that \(f_{\rvert U_i} : U_i \to Y\) is an opentopological embedding.
Atopological embedding is a map \(j : Y \to X\) such that yields ahomeomorphism \(Y \to j(Y)\), where \(j(Y)\) is endowed with the topology induced by the topology on \(X\).
Mathematical Logic and Computation
The set of primitive recursive functions is the set of functions from the natural numbers to the natural numbers, of various arities, defined inductively:
closed under compositionIf \(f\) is a \(k\)-ary primitive recursive function and \(g_0, \dots , g_{k-1}\) are \(l\)-ary primitive recursive functions, then the composition of \(f\) with \(g_0, \dots , g_{k-1}\) is primitive recursive (\(l\)-ary): \[ f(g_0(x_0, \dots , x_{l-1}), \dots , g_{k-1}(x_0, \dots , x_{l-1})) \]
closed under primitive recursionIf \(f\) is a \(k\)-ary primitive recursive function and \(g\) is a \(k+2\)-ary primitive recursive function, then the function defined by primitive recursion from \(f\) and \(g\) is primitive recursive: \[\begin {aligned} h(0, z_0, \dots , z_{k-1}) &= f(z_0, \dots , z_{k-1}) \\ h(x+1, z_0, \dots , z_{k-1}) &= g(x, h(x, z_0, \dots , z_{k-1}), z_0, \dots , z_{k-1}) \end {aligned}\]
Manifolds, Sheaves, and Cohomology, §3.1
Let \(X\) be a topological space, asheaf \(\mathcal {F}\) is apresheaf that for all open sets \(U\) in \(X\) and every open covering \(U = \bigcup _{i\in I}U_i\) the following condition holds:
Given \(s_i \in \mathcal {F}(U_i)\) for all \(i \in I\) such that
\[ {s_i}_{\rvert {U_i \cap U_j}} = {s_j}_{\rvert {U_i \cap U_j}} \]for all \(i,j\in I\). Then there exists a unique \(s \in \mathcal {F}(U)\) such that \({s_i}_{\rvert {U_i}} = s_i\) for all \(i \in I\).
A morphism of sheaves is a morphism of presheaves, we denote \(\text {Sh}(X)\) for the category of sheaves on \(X\).
A set \(\mathcal {B}\) of open subsets of \(X\) is abasis of the topology if every open subset of \(X\) is a union of sets in \(\mathcal {B}\).
A topological space \(X\) iscompact if everyopen covering of \(X\) has a finite subcovering.
Manifolds, Sheaves, and Cohomology
Let \(X\) be a topological space.
Let \(X\) be a topological space and let \(Y\) be a subset of \(X\). A family \((A_i)_{i \in I}\) of subsets of \(X\) is called acovering of \(Y\) in \(X\) if
\[Y \subseteq \bigcup _{i\in I} A_i\]A type theory is intensional if it distinguishes between equalities that
Two terms \(u, v : T\) are definitionally equal if they reduce to the same normal form.
Two terms \(u, v : T\) are propositionally equal if there is a proof \(u = v\) using the inductive equality type \(=\) at type \(T\). For example, an inductive equality type in agda looks like
data _≡_ {A : Set} (x : A) : A → Set where refl : x ≡ x
Prove that a function \(f : X \to Y\) iscontinuous if and only if \(f^{-1}B\) is open for every \(B\) in a basis for the topology on \(Y\).
A function is continuous iff \(f^{-1}U\) is open whenever \(U\) is open in \(Y\), of course, basis are open.
Reversely, \(f^{-1}B\) is open for every basis \(B\). Every \(U\) is open is built by some union of basis, \(f^{-1}U\) is built by some union of \(f^{-1}B\) open sets, and hence are open sets, implies a function is continuous.
Consider a topological space \(X\) and an arbitrary subset \(A\) of it,
The idea is based on facts aboutinterior and closure:
Suppose \(X \setminus \text {int}(A) \ne \overline {X \setminus A} = \mathfrak {C}\), then we have
\[ X \setminus A \subset \overline {X \setminus A} \subset X \setminus \text {int}(A) \]implies that
\[ \text {int}(A) \subset X \setminus \mathfrak {C} \subset A \]shows \(\text {int}(A)\) is not the interior of \(A\), leads contradiction, so \(X \setminus \text {int}(A) = \overline {X \setminus A}\).
Suppose \(X \setminus \overline {A} \ne \text {int}(X \setminus A) = \mathfrak {O}\), then we are saying
\[ X \setminus \overline {A} \subset \text {int}(X \setminus A) \subset X \setminus A \]implies that
\[ A \subset X \setminus \mathfrak {O} \subset \overline {A} \]shows \(\overline {A}\) is not the closure of \(A\), leads contradiction, so \(X \setminus \overline {A} = \text {int}(X \setminus A)\).
Categorical Realizability
Anassembly over apca \(\mathcal {A}\) is a set \(X\) together with a relation \(\Vdash \) between \(\mathcal {A}\) and \(X\) such that for all \(x \in X\), there exists at least one element \(a\in \mathcal {A}\) with \(a\Vdash x\).
The relation \(a \Vdash x\) pronounced "\(a\) realizes \(x\)" or "\(a\) is arealizer of \(x\)". \(a\) can be thought as an implementation of \(x \in X\) in the pca \(\mathcal {A}\).
Given an assembly \(X\), we wrote \(|X|\) for its underlying set and \(\Vdash _X\) for its relation between \(\mathcal {A}\) and \(|X|\).
The assembly of booleans is defined as
\[ |2| \doteq \{ 0,1 \} \quad \text {with realizers}\quad \bold {false}\Vdash _2 0 \;\text {and}\; \bold {true}\Vdash _2 1 \]The assembly of natural numbers is defined as
\[ |N| \doteq \N \quad \text {with realizers}\quad \bar {n}\Vdash _N n \;\text {for each}\;n\in \N \]Categorical Realizability
First, we define map between assemblies.
Anassembly map from an assembly \(X\) to an assembly \(Y\) is a function \(f : |X| \to |Y|\) that is tracked by some element.
Forassembilies \(X\) and \(Y\), we say that an element \(t \in \mathcal {A}\)tracks a function \(f : |X| \to |Y|\) if for all \(x \in |X|\) and \(a \in \mathcal {A}\), if \(a \Vdash _X x\), then \(t\ a\) is defined and \(t\ a \Vdash _Y f(x)\).
Then, we checkassembilies and assembly maps form a category.
We denote \(\text {Asm}_{\mathcal {A}}\) for the category of assembilies over a pca \(\mathcal {A}\).
Thetrivial pca has \(\text {Asm}_{\{ \star \}} = \text {Set}\).
The terminal object \(1\) in \(\text {Asm}_{\mathcal {A}}\) is given by
\[ |1| \doteq \{ \star \} \quad \text {and}\quad a\Vdash _1 \star \ \text {for all}\ a \in \mathcal {A} \]The product \(X \times Y\) of two assembilies is given by
\[ |X \times Y| \doteq |X| \times |Y| \quad \text {and}\quad \bold {pair}\ a\ b \Vdash _{X \times Y} (x, y) \ \text {for all}\ a \Vdash _X x \ \text {and}\ b \Vdash _Y y \]The exponential \(Y^X\) of two assembilies is given by
\[ |Y^X| \doteq \text {the set of assembly maps from}\ X\ \text {to}\ Y \quad \text {and}\quad t \Vdash _{Y^X} f\ \text {if}\ t\ \text {tracks}\ f \]The evaluation morphism \(ev : Y^X \times X \to Y\) is given by \((f,x) \mapsto f(x)\) is tracked by \(\langle x \rangle .\ \bold {fst}\ u(\bold {snd}\ u)\). Every \(g : Z \times X \to Y\) induces a unique assembly map \(\bar {g} : Z \to Y^X\) making the commute diagram:
Since there is a unique assignment \(\bar {g}(z) \doteq (x \mapsto g(z, x))\) and the assignment is tracked by \(\langle u \rangle .\ (\langle v \rangle .\ t_g(\bold {pair}\ u\ v))\) when \(t_g\) tracks \(g\).
The equalizer \(E\) of two assembly maps \(f,g : X \to Y\) is given by
\[ |E| \doteq \{ x \in |X| \mid f(x) = g(x) \} \quad \text {and}\quad a \Vdash _E x\ \text {if}\ a \Vdash _X x \]The initial object \(0\) is given by \(|0| \doteq \varnothing \) with empty realizability relation (no element so empty realizability is fine).
The coproduct \(X + Y\) is defined by
\[\begin {aligned} |X + Y| \doteq |X| + |Y| \quad \text {and}\quad \bold {left}\ &a \Vdash _{X+Y} \text {inl}(x)\ \text {for}\ a \Vdash _X x \\ \bold {right}\ &b \Vdash _{X+Y} \text {inr}(y)\ \text {for}\ b \Vdash _Y y \end {aligned}\]where
\[ \bold {left} \doteq \bold {pair}\ \bold {false} \ \text {and}\ \bold {right} \doteq \bold {pair}\ \bold {true} \]The coequalizer \(C\) of assembly maps \(f,g : X \to Y\) is given by
\[ |C| \doteq |Y|/\sim \quad \text {and}\quad a \Vdash _C [y] \ \text {if}\ a \Vdash _Y y' \ \text {for some}\ y' ~ y \]where \(\sim \) is the least equivalence relation on \(|Y|\) generated by \(f(x) ~ g(x)\) for all \(x \in |X|\).
Forassembilies \(X\) and \(Y\), we say that an element \(t \in \mathcal {A}\)tracks a function \(f : |X| \to |Y|\) if for all \(x \in |X|\) and \(a \in \mathcal {A}\), if \(a \Vdash _X x\), then \(t\ a\) is defined and \(t\ a \Vdash _Y f(x)\).
Let \(b,c\in X\), \(\alpha \) is a path from \(b\) to \(c\), then \(\alpha \) induces an isomorphism of \(\pi _1(Xb)\) and \(\pi _1(X,c)\)
\[\begin {aligned} a_\star : \pi _1(X,c) &\to \pi _1(X, b) \\ [\gamma ] &\mapsto a_\star ([\gamma ]) = [\alpha ][\gamma ][\alpha ]^{-1} \end {aligned}\]數學:我思故我在
\(\pi _1(X,b)\) is the fundamental group with base-point \(b\) on \(X\), in the following sense. With a topology space \(X\) and a point \(b \in X\), consider ahomotopy class of allloops on \(b\). The collection of these paths are \(\pi _1(X,b)\), there are four properties
Due tothe isomorphic theorem, on apath-connected space \(X\), we define \(\pi _1(X)\) as the fundamental group of space \(X\).
數學:我思故我在
因為homotopy 是等價關係,因此可以把 \(a\) 點到 \(b\) 點的所有路徑用同倫關係分成數類,這些類就叫做 homotopy class。一條路徑 \(\gamma \) 所屬的同倫類記為 \([\gamma ]\)。
若 \(\alpha \) 表示 \(a\) 到 {b} 的一條路徑,\(\beta \) 表示 \(b\) 到 {c} 的一條路徑,則可以定義 \([\alpha ][\beta ] = [\alpha \beta ]\)。
數學:我思故我在
同倫中端點是 \(a\) 到 \(a\) 的這種路徑叫做 loop,擴展記號寫成 \([a]\)。顯然若有 \(\gamma \) 是 \(a\) 到 \(b\) 的路徑則
\[[a][\gamma ] = [\gamma ] = [\gamma ][b]\]若有路徑 \(\gamma \) 從 \(a\) 到 \(b\) 則 \(\gamma ^{-1}\) 表示從 \(b\) 到 \(a\)。且若 \([\gamma _0] = [\gamma _1]\) 則 \([\gamma _0^{-1}] = [\gamma _1^{-1}]\)
Inverse path 讓我們可以定義反同倫類
\[[\gamma ]^{-1} = [\gamma ^{-1}]\]Categorical Realizability
Fix a countably infinite set of variables, inductively define the set ofterms over a pca \(\mathcal {A}\):
A closed term isdefined if, when we interpret \(s\ t\) as \(s\) applied to \(t\) in \(\mathcal {A}\), all these applications are defined.
Extends to open term \(t\) then is if all possible substitutions of all variables in \(t\) by elements of \(\mathcal {A}\), the obtained closed term is defined.
For a variable \(x\) and a term \(t\), we can define a new term \(\langle x \rangle .\ t\) by recursion on terms:
\(\langle xy \rangle .\ t\) writes for \(\langle x \rangle .\ (\langle y \rangle .\ t)\)
Now, we can work on it, e.g.
\[ \bold {true} \doteq \langle xy \rangle .\ x \\ \bold {false} \doteq \langle xy \rangle .\ y \\ \bold {if} \doteq \langle x \rangle {x} \]so
\[ \bold {if}\ \bold {true}\ a\ b = a \quad \text {and}\quad \bold {if}\ \bold {false}\ a\ b = a \]Pair and projections are
\[ \bold {pair} \doteq \langle xyz \rangle .\ zxy \\ \bold {fst} \doteq \langle w \rangle .\ w\ \bold {true} \\ \bold {snd} \doteq \langle w \rangle .\ w\ \bold {false} \]A Scott domain \((X, \mathcal {F})\) is a set \(X\) with an axiomatics \(\mathcal {F}\) made of sequents \(x_1, \dots , x_n \vdash x\) and \(x_1, \dots , x_n \vdash x_i, \dots \) (\(x, x_i \in X\)) consistent with respect to logical consequence.
Acoherent subset of \((X,\mathcal {F})\) is a set \(A \subseteq X\) such that
\[ \mathcal {F} \cup \{ \vdash x \mid x \in A \} \]is consistent.
A coherent subset issaturated when all \(y\) such that \( \mathcal {F} \cup \{ \vdash x \mid x \in A \} \) proves \(\vdash y\) already belong to \(A\).
Categorical Realizability
Apartial combinatory algebra is a set \(\mathcal {A}\) together with apartial operation \(\mathcal {A} \times \mathcal {A} \to \mathcal {A}\), denoted by juxtaposition, \((a,b)\mapsto a\ b\), such that there exist elements \(K\) and \(S\) satisfying:
\(\cong \) here stands forKleene equality and means: either both sides are undefined, or both are defined and are equal elements of \(\mathcal {A}\).
The trivial pca is a set \(\{ \star \}\) with application map \((\star , \star ) \mapsto \star \). For sure, \(K := \star \) and \(S := \star \).
Write \(\Lambda \) for closed terms of untyped lambda calculus quotiented by the equivalence relation generated by \(\beta \)-reduction. With application of lambda calculus the set \(\Lambda \) forms a pca with \(K\) and \(S\) given by the equivalence classes of \(\lambda xy.x\) and \(\lambda xyz.(xz)(yz)\), respectively.
一個球面 \(S^2\) 當然可以用 \(\R ^3\) 的子集合描述
\[ \{ (x,y,z) \mid x^2+y^2+z^2=1 \} \]但這需要一個外部的空間 \(\R ^3\) 來表示它,而微分幾何的目的正是探討如何從內部的觀點來處理一個形狀。從微分幾何出發,表示要尋找一些chart map \(\phi : S^2 \to \R ^n\),而且我們知道一個 chart map 肯定不能達成目標,因為 \(S^2\) 是 compact space,而 \(\R ^n\) 則並非如此,因此無法找到 \(S^2\) 到 \(\R ^n\) 的 chart map (條件topological homeomorphism (同胚))。
由於 \(S^2\) 並不複雜,我們很快就能想到如果是兩個不同點出發的投影幾何,就能做出 \(S^2\) 的atlas。為了計算上的簡便,把 \(S^2\) 想像成地球,並取北極點 \(N = (0,0,1)\) 與南極點 \(S = (0,0,-1)\)。接著,用赤道面作為投射的目標,這個平面由 \(\{ (r,s,0) \mid r,s\in \R \}\) 構成。不同的 \(r,s\) 所定義的點與 \(S\) 之間的直線,會與 \(S^2\) 正好交於一點 \(Q \in S^2\)。此點可以描述為
\[ Q = S + \lambda (P-S) = (0,0,-1) + \lambda (r,s,1) = (\lambda r,\lambda s, \lambda - 1) \]現在重新考慮 \(S^2\) 的 \(\R ^3\) 子集合描述,得到等式
\[ (\lambda r)^2 + (\lambda s)^2 + (\lambda - 1)^2 = 1 \\ \iff \lambda ^2r^2 + \lambda ^2s^2 + \lambda ^2-2\lambda +1 = 1 \\ \iff \lambda ^2(r^2+s^2+1)-2\lambda = 0 \\ \iff \lambda = 0\ \text {or}\ \lambda = \frac {2}{1+r^2+s^2} \]用非平凡解替換 \(Q\) 的公式得
\[ Q = (\frac {2r}{1+r^2+s^2}, \frac {2s}{1+r^2+s^2}, \frac {1-r^2-s^2}{1+r^2+s^2}) \]這個定義等於是 \(\R ^2 \to S^2 \setminus \{ S \}\) 的函數,因為沒有任何 \(r,s \in \R \) 可以令 \(Q\) 是 \(S\)。把前述的函數表示為 \(\phi _S^{-1}\),反過來求 \(\phi _S : S^2 \setminus \{ S \} \to \R ^2\):
\[ (r,s,0) = \lambda (x,y,z) + (1-\lambda )(0,0,-1) \]因此 \(\lambda = \frac {1}{z+1}\),得 \(r=\frac {x}{1+z},s=\frac {y}{1+z}\)。跟 \(\phi _S^{-1}\) 的公式結合,發現這確實是一對 homeomorphism,因此 \(\phi _S : S^2 \setminus \{ S \} \to \R ^2\) 是一個 chart map。
對 \(N\) 做一樣的操作可以得到 \(\phi _N\) 作為另一個 chart map \(r = \frac {-x}{z-1},s=\frac {-y}{z-1}\)。由於在各自的極點外 \(\phi _S\) 與 \(\phi _N\) 皆是同胚映射,因此這時候已經算出了 \(\{ (S^2\setminus \{ S \}, \phi _S), (S^2\setminus \{ N \}, \phi _N) \}\) 足以作為 \(S^2\) 的 altas。
If \(\Gamma \vdash A\), then \(A \in \Gamma \).
數學:我思故我在
假設 \(X\) 為一拓樸空間,其中從 \(a\) 點到 \(b\) 點有兩條path 為 \(\gamma _0, \gamma _1\)。我們稱 \(\gamma _0\) 與 \(\gamma _1\) 在固定端點下同倫 (homotopic with endpoints fixed),記為 \(\gamma _0 \cong \gamma _1\ \text {rel}\{ 0,1 \}\),若存在一個連續函數
\[ F : [0,1] \times [0,1] \to X \\ (s,t) \mapsto F(s,t) \]滿足
這時候,說 \(F\) 是 \(\gamma _0\) 與 \(\gamma _1\) 之間的一個同倫 (homotopy)。
Mathematical Logic and Computation
A set ofpropositional formulas isinconsistent if it proves \(\bot \), andconsistent otherwise.
Mathematical Logic and Computation
A set of formulas \(\Gamma \) issaturated if the following hold
When dealing intuitionistic logic rather than minimal logic, add condition that \(\Gamma \) isconsistent.
這是在郵件列表問到的方法,因為 subtree 也可以被scope
影響,所以只要寫成下面這樣就可以了
\scope{ \put\transclude/expanded{false} \subtree{ }}
A fiber bundle is a space \(E\) for which the following are given
all of which satisfy the following restrictions
Locally the bundle is trivial, which means that the bundle over any set \(U_j\) which is just \(\pi ^{-1}(U_j)\), has a homeomorphism onto the product space \(U_j \times F\). Part of this homeomorphism is a homeomorphism from each fiber, say \(\pi ^{-1}(x)\) where \(x \in B\), onto \(F\). We define \(h_j(x)\) as
\[ h_j(x) = \pi ^{-1}(x) \]When two open sets \(U_j\) and \(U_k\) overlap, a given point \(x \in U_j \cap U_k\) has two homeomorphism \(h_j(x)\) and \(h_k(x)\) from its fiber onto \(F\). Since a homeomorphism is invertible, the map \(h_j(x) \circ h_k^{-1}(x)\) is a homeomorphism of \(F\) onto \(F\). This is required to be an element of the structure group \(G\).
An example istangent bundle \(TM\), the fibers are the spaces \(T_p\) for each point \(p\).
Let \(E = TS^1, B = S^1\), typical fiber \(F = \R ^1\), and projection \(\pi = (x, \vec {v}) \mapsto x\), where \(x \in S^1\) and \(\vec {v}\) is a vector in tangent space \(T_x\), \(\vec {v} \in T_x\). The homeomorphism of \(T_x\) onto \(\R \) which are part of the definition of \(TS^1\) are defined to be
\[\begin {aligned} &h_j(x) : T_x \to \R \\ &h_j(x) = \vec {v} \mapsto \alpha _{(j)} \end {aligned}\]If \(x\) is in two neighborhoods \(U_j\) and \(U_k\) there are two such homeomorphims \(T_x \to \R \), and since \(\lambda _j\) and \(\lambda _k\) are unrelated, the \(\alpha _{(j)}\) and \(\alpha _{(k)}\) can be any two nonzero real numbers, the homeomorphim \(h_j(x) \circ h_k^{-1}(x) : F \to F\) is therefore just multiplication by the numbers.
\[ r_{jk} = \alpha _{(j)} / \alpha _{(k)} \]since \(r_{jk}\) is any real number other than zero, the structure group is \(\R ^1 \setminus \{ 0 \}\).
In passing above for an \(n\)-dimensional manifold \(M\), the structure group of \(TM\) is the set of all \(n\times n\) matrices with nonzero determinant, which is called \(\text {GL}(n, \R )\) (general linear groups).
So called fundamental theorem of linear maps inLinear Algebra Done Right.
Suppose \(V\) is a finite-dimensionalvector space and \(T : V \to W\). Then \(\text {range }T \) is finite-dimensional and
\[ \dim V = \dim \text {null}\;T + \dim \text {range}\;T \]or \(\dim V = \text {rank}\;T + \text {nullity}\;T \) by definition that
\[ \text {nullity}\;T = \dim \text {null}\;T \\ \text {rank}\;T = \dim \text {range}\;T \]The Blind Spot: Lectures on Logic
A Kripke model is a non-emptypartially ordered set \((I, \preceq )\), equipped with a relation \(i \Vdash P\) between elements of \(I\) and propositional atoms. Satisfies
\[ i \Vdash P \land i \preceq j \implies j \Vdash P \]For each \(A\) and each \(i \in I\) we define \(i \Vdash A\):
The elements of \(I\) are callednodes orworlds of the Kripke model.
Let \(\alpha > 0\)
\[ \Gamma (\alpha ) = \int _0^\infty { e^{-x} x^{\alpha - 1} dx } \]Another way is fromThe Art of Computer Programming, Vol. 1: Fundamental Algorithms
\[ n! = \Gamma (n+1) = n \Gamma (n) \]and hence
\[ \Gamma (x) = \frac {x!}{x} = \lim _{m\to \infty } \frac {m^x m!}{x(x+1)(x+2)\cdots (x+m)} \]Obviously \(\Gamma (z)\) is not well defined when \(z\) is zero or negative integer, but \(1/\Gamma (z)\) is well defined for all complex \(z\).
\[ \frac {1}{\Gamma (z)} = \frac {1}{2\pi i} \oint \frac {e^t dt}{t^z} \]If \(\alpha > 0\), then \(\int _0^\infty { e^{-x} x^{\alpha - 1} dx }\) converges.
If \(\alpha > 1\), then \(\Gamma (\alpha ) = (\alpha -1)\Gamma (\alpha -1)\).
-DWASMEDGE_BUILD_TOOLS=ON
-DWASMEDGE_BUILD_TESTS=ON
-DCMAKE_BUILD_TYPE=Debug
-GNinja
基本指令
cmake -Bbuild -GNinja .cmake --build build
執行ctest
指令,要記得開始 build tests (參考wasmedge 的 cmake options)。常見選項
ctest -Vctest -R <name>ctest -j
Let \(P\) and \(Q\) be directed posets, \(D\) be acpo, and
\[ f : P \times Q \to D \]be a monotone function. Then
\[ \coprod _{x\in P}\coprod _{y\in Q} f(x,y) = \coprod _{y\in Q}\coprod _{x\in P} f(x,y) \]For every \(x' \in P\), we have
\[ \coprod _{y \in Q} f(x', y) \sqsubseteq \coprod _{y\in Q}\coprod _{x\in P} f(x,y) \]implies for every \(y' \in Q\), we have
\[ f(x', y') \sqsubseteq \coprod _{y\in Q}\coprod _{x\in P} f(x,y) \]It's easy to do again then have (notice the resolve order)
\[ f(x', y') \sqsubseteq \coprod _{x\in P}\coprod _{y\in Q} f(x,y) \]for any \(x'\in P, y'\in Q\), and hence the equality holds.
Here proves underpropositional logic, below three can be carry over to first-order logic.
If \(\Gamma \vdash A\) and \(\Gamma ' \supseteq \Gamma \) then \(\Gamma ' \vdash A\).
If \(\Gamma \vdash A\) then for some finite subset \(\Gamma '\) of \(\Gamma \), \(\Gamma ' \vdash A\).
If \(\Gamma \cup \{ A \} \vdash B\) then \(\Gamma \vdash A \to B\).
notes for talk given at TUPLE 2024
This is a very good start point before formalizing languages that more complicated.
要使用 wasmedge plugin,需要設定環境變數讓 wasmedge 知道 plugin 的檔案位置。例如
WASMEDGE_PLUGIN_PATH=~/secondstate/WasmEdge/build/plugins/wasi_http
or
\[ (x + y)^n = \sum _{k=0}^n \binom {n}{k} x^k y^{n-k} \]A context
\[\Gamma = A_1, \dots , A_n\]is a list of propositions. A sequent, or a judgement, is a pair
\[\Gamma \vdash A\]the statement can be read as\(A\) is provable from \(\Gamma \).
A zero object \(0\) is an object which is bothinitial and terminal.
In a category with zero object, a morphism \(f : A \to B\) is a zero morphism if it factors through the zero object \(0\).
The zero morphism is unique, this is easy to check by universal property of zero object.
In a category with zero object \(0\), the kernel of an arrow \(f : A \to B\) is theequalizer of \(f\) and the zero morphism \(A \to 0 \to B\). The cokernel of \(f\) is defined dually.
Since kernel is an equalizer, it's a monomorphism (equalizer is monomorphism).
Semantics of Programming Languages: structures and techniques
A bc-domain is abounded-completealgebraic cpo.
If \(D\) and \(E\) are bc-domains, then so is \([D \to E]\).
Let \(R\) be aring. The concept of module is the generalization of vector space, but replacefields with rings.
The category of \(R\)-modules denotes \(R\)-Mod.
A left-\(R\)-module on an abelian group \(M\) consists of a map \( \cdot : R \times M \to M, (r,m) \mapsto rm \) such that
A right-\(R\)-module on an abelian group \(M\) consists of a map \( \cdot : M \times R \to M, (m,r) \mapsto mr \) such that
Theabelian groups are exactly the modules overthe ring of integers \(\Z \).
In a2-category \(\mathcal {C}\), consider two 1-cells \(f : A \to C\) and \(g : A \to B\). The Kan extension of \(f\) along \(g\), when exists, is a pair \((h, \alpha )\) where
Consider2-categories \(C, D\), 2-functors \(F, G : C \rightrightarrows D\) and 2-natural-transformations \(\alpha , \beta : F \Rightarrow G\). A modification
\[ \Xi : \alpha \rightsquigarrow \beta \]consists in giving, for every object \(X \in C\), a 2-cell \( \Xi _X : \alpha _X \Rightarrow \beta _X\) is such a way that the following axiom is satisfied: for every pair of morphisms \(f, g : X \rightrightarrows X'\) and every 2-cell \(\alpha : f \Rightarrow g\) in \(C\), the equality
\[ \Xi _{X'} \circ F\alpha = G\alpha \circ \Xi _X\]holds in \(D\).
Aring homomorphism is a function \(\varphi : R \to S\) such that preserves two operations
Theinitial in this category is \((\Z , +, \cdot )\).
Algebra: Chapter 0
Let \(R\) be aring, apolynomial \(f(x)\) is a finite linear combination of nonnegative powers of \(x\) with coefficients \(a_i\) in \(R\):
\[ f(x) = \sum _{i \ge 0} a_i x^i = a_0 + a_1 x + a_2 x^2 + \cdots \]\(a_i\) are coefficients and \(a_i = 0\) for \(i \gg 0\).
Two polynomials are equal if all the coefficients are equal.
with operations
Algebra: Chapter 0
A ring \(R\) is anabelian group \((R,+)\) with a multiplication operator \(\cdot \) such that \((R, \cdot )\) is amonoid, and further interacting with \(+\) viadistributive properties below
\[ (r + s) \cdot t = r \cdot t + s \cdot t \text { and } t \cdot (r + s) = t \cdot r + t \cdot s \]hold for all \(r,s,t \in R\).
Ring without identity means \(\cdot \) has associative, but no identity, and hence \((R, \cdot )\) is not a monoid, but a semigroup in this definition.
A ring iscommutative if \(r \cdot s = s \cdot r\) for all \(r,s\in R\).
These groups are also commutative rings by adding \([a]_n \cdot [b]_n = [ab]_n\) as multiplication.
The cancel law cannot generally works in rings, in particular, \[[2]_6 \cdot [4]_6 = [2]_6 \cdot [1]_6\] holds in the commutative ring \(\Z / 6 \Z \), but \([4]_6 \ne [1]_6\).
Aleft zero divisor is an element \(a\) in a ring \(R\) if there exist elements \(b \ne 0\) in \(R\) for which \(ab = 0\).
Aright zero divisor \(a \in R\) inherits above, but if \(ba = 0\).
An element \(u \in R\) of ring \(R\) is
An useful interpretion of a \(\bold {Bool}\)-profunctor \(\varphi : A^{op} \times B \to \bold {Bool}\) is given \(b \in B\) we can do \(a \in A\).
Let
and suppose \(b' \to b\), means "if one can walk to somewhere, then one can drive to that place". Let \(a\) be "go to school"; if I can walk to school, then \(\varphi (a, b') = true\), by it's a functor \(\varphi (a, b') \to \varphi (a, b)\) exists, which means I can also drive a car to school.
Acategory \(C\) isconnected if it is non-empty and, given any two objects \(X, Y \in C\), there is a finite sequence ofzigzag \[X = Z_0, Z_1, Z_2, \dots , Z_{n-1}, Z_n = Y\] together with either a \(Z_{i} \to Z_{i+1}\) or \(Z_{i+1} \to Z_{i}\) where \(0 \le i \lt n\), in the category \(C\).
The direction of arrows in zigzag is not the point, refers toEric Wofsey's answer.
Afunctor \(F : C \to D\) isfinal if for every category \(A\) and functor \(F : D \to A\), we have
A functor \(G : C \to D\) is final as long as it satisfies
\[\forall d \in D, \exists c \in C, \exists G(c) \xrightarrow {f} d\]and for all black part, the orange part exists and the diagram commutes
Handbook of categorical algebra, volume 1, proposition 2.11.2
Prove that if \(\Gamma \vdash A \to B\) and \(\Gamma \vdash B \to C\) then \(\Gamma \vdash A \to C\).
這完全是朋友教我的,自己試就算了xd
Let \(\Gamma = \{ A \to B, B \to C \}\)
In a2-category \(\mathcal {C}\). Let \(f : A \to B, g : B \to A\) be 1-cells in \(\mathcal {C}\), the \((f,g)\) is an adjoint pair if there exists 2-cells
such that
\[ (1_f * \epsilon ) \cdot (\eta * 1_f) = 1_f \ \text {and}\; (\epsilon * 1_g) \cdot (1_g * \eta ) = 1_g \]this is calledtriangular condition.
Let \(C\) be a category withpullbacks, for each arrow \(f : A \to B\) there is an induced functor, calledbase change functor
\[ f^* : C/B \to C/A \]by the pullback along \(f\). The functor is created by for each \(p : K \to B\), there exists pullback \(P\) for \((p, f)\)
Therefore, for each \(p \in C/B\), \(f^*\) is defined as \(p \mapsto p^*\). Consider \(P'\) as another pullback from \(K' \to B\), this induces \(P\) as the pullback of \((P' \to K', K \to K')\).
If \(C\) isfinitely complete, then the pullback is the product \(P = A \times K\).
Let \(C\) be afinitely complete category. Then \(C\) islocally cartesian closed if and only if each \(f^* : C/B \to C/A\) from \(f : A \to B\) admits a right adjoint \(\prod _f : C/A \to C/B\).
Suppose \(f^* \dashv \Pi _f\), then
\[ \text {Hom}_{C/A}(f^*(Y), X) \cong \text {Hom}_{C/B}(Y, \Pi _f(X)) \]holds; and \(f^* = K \mapsto A \times K\) by \(C\) with finite limits.
Remember induced by \(f\) is an important condition to ensure some arrows will be there.
We are trying to prove \[ \text {Hom}_{C/A}(A\times Y, X) \cong \text {Hom}_{C/B}(Y, \Pi _f(X)) \] for all \(A, Y, X \in C\); since slice categories are cartesian closed, picking \(\Pi _f(-) = (-)^A\) in \(C/B\); then doing exponential adjunction, we can prove this is the right adjoint of \(f^*\).
Apply adjunction condition then cancel \(X\), then we have \[ A \times (-) \cong (-)^A \] this admits exponential functor in \(C/B\) for all \(A, B \in C\), and hence each slice category is cartesian closed.
Let \(C\) be acategory with pullbacks, an internal category \(A\) in \(C\) is defined as
These data must satisfy the following axioms:
Let \(C\) be a category with pullbacks. Given two internal categories \(C, D\), an internal functor \(F : C \to D\) is a pair of morphisms \((F_0, F_1)\) in \(C\)
\[ F_0 : C_0 \to D_0 \\ F_1 : C_1 \to D_1 \]which satisfies the following conditions
Let \(A, B\) be two internal categories, and internal functors \(F, G : A \to B\), an internal natural transformation \(F \Rightarrow G\) is a morphism \(\alpha : A_0 \to B_1\) such that
Every small category \(C\) can be embedded as a full subcategory in a Cauchy complete small category \(\overline C\).
The following statements are equivalent:
Let \(F : C \to D\) be afunctor and \(B \in D\). A reflection of \(B\) along \(F\) is a pair \((R_B \in C, \eta _B)\) where
Afucntor \(F : C \to D\) satisfies the solution set condition with respect to an object \(B \in D\) when there exists a set \(S_B \subseteq |A|\) of objects such that
\[ \begin {aligned} &\forall A \in C, \\ &\forall g : B \to F(A), \\ &\exists S \in S_B, \exists f : S \to A, \\ &\exists h : B \to F(S), \\ &g = F(f) \circ h \end {aligned} \]The set \(S_B\) called a solution set.
A Lax functor \(F : A \to B\) between2-categories \(A, B\) consists
For every triple of 1-cells \(X \xrightarrow {f} Y \xrightarrow {g} Z\) in \(A\), the following equality between 2-cells holds
For every 1-cell \(f : X \to Y\) in \(A\), the following equality holds
When \(\gamma _{XYZ}\) and \(\delta _X\) are natural isomorphisms, then a Lax functor \(F\) is called a pseudo-functor.
A category \(C\) is Cauchy complete if allidempotents \(e\) of \(C\) split, which mean, form aretraction \(e = i \circ r\).
Every small category \(C\) can be embedded as a full subcategory in a Cauchy complete small category \(\overline C\).
Let \(A, B\) be two small categories, the following conditions are equivalent
Let \(F : A \to B\) be a functor, where \(A\) is Cauchy complete, the following conditions are equivalent
Let \(F : A \to B\) and \(G : A \to C\) be functors. The left Kan extension of \(G\) along \(F\), if exists, is a pair \(\text {Lan}_F G = (K, \alpha )\)
where \(K : B \to C\) is a functor and \(\alpha : G \Rightarrow K \circ F\) is a natural transformation. If there exists another pair \((H, \beta )\), then there is a natural transformation \(\gamma : K \Rightarrow H\) satisfying \[\beta = (\gamma * F) \circ \alpha \]
A category \(C\) isfiltered if for every finite diagram in it, there exists acocone, and for every two parallel arrows in it \(u, v : A \to B\), there exists \(w : B \to C\) such that \(w \circ u = w \circ v\).
A category \(C\) iscofiltered if \(C^{op}\) isfiltered. In the other words, for every finite diagram in it, there exists a cone, and for every two parallel arrows in it \(u, v : B \to C\), there exists \(w : A \to B\) such that \(u \circ w = v \circ w\).
A filtered colimit is a colimit of a functor \(F : D \to C\) where \(D\) is a filtered category.
A functor \(F : \mathcal {C} \to \bold {Set}\) isflat if thecategory \(\text {Elts(F)}\) iscofiltered. A functor \(F : \mathcal {C} \to \mathcal {D}\) isflat if for each \(A : \mathcal {D}\) the functor \(\text {Hom}_{\mathcal {D}}(A, F(-)) : \mathcal {C} \to \bold {Set}\) isflat.
Which means compose two flat functors will get a flat functor.
Let \(\text {Hom}_{C}(X, -)\) be a hom functor of \(X \in C\), the functor is flat.
The category of elements \(\text {Elts}(\text {Hom}_{C}(X, -))\) has an object \((X, 1_X)\). Consider any \((X, 1_X) \to (Y, f)\), it will be an arrow \(g : X \to Y\) such that \(f = g \circ 1_X\), and hence \((X,1_X)\) is an initial object, serve as a cone for any diagram.
If functor \(F : A \to B\) with a left adjoint, then \(F\) is flat.
The target is prove \(\text {Hom}_{B}(X, F(-))\) is flat. Let \(G : B \to A\) be a left adjoint, then
\[ \text {Hom}_{B}(X, F(-)) \cong \text {Hom}_{A}(G(X), -) \]followsProposition [math-008P] we have \(\text {Hom}_{A}(G(X), -)\) is flat, and hence \(\text {Hom}_{B}(X, F(-))\) is flat.
A functor \(F : A \to B\) isabsolutely flat if it is \(\alpha \)-flat for every regular cardinal \(\alpha \).
A morphism \(e : A \to A\) isidempotent if \(e \circ e = e\).
Let \(F : \mathcal {C} \to \bold {Set}\) be a functor, the category \(\text {Elts(F)}\) ofelements of \(F\) is defined as
Let \(A, B\) be two finitely complete categories, afunctor \(F : A \to B\) isleft exact if it preserves finite limits.
Which means compose two left exact functors will get a left exact functor.
The category \(\text {Lex}(A, \bold {Set})\) is a full subcategory of the functor category \([A, \bold {Set}]\), where have only left exact functors.
Let \(\mathbb {C}\) be a category, and \(\Sigma \) is a class of morphisms. The class \(\Sigma \) admits aright calculus of fractions when the following conditions hold:
If \((C^{op}, \Sigma ^{op})\) admits right calculus of fractions (Definition [math-008A]), then \((C, \Sigma )\) admits left calculus of fractions.
Let \(B\) be a category and a reflective subcategory \(A \xrightarrow {i} B\), withreflection \(r \dashv i\). Write \(\Sigma \) for the class of all \(B\)-morphisms \(f\) such that \(r(f)\) is an isomorphism. Thecategory of fractions exists and is equivalent to \(B \xrightarrow {r} A\). Then the class \(\Sigma \) admits aleft calculus of fractions.
Consider acategory \(C\) and a class of \(C\)-arrows \(\Sigma \). The category of fractions \(C[\Sigma ^{-1}]\) is said to exist if there exists a functor
\[ \varphi : C \to C[\Sigma ^{-1}] \]with properties
When \((\mathcal {C}, \Sigma )\) admitsright calculus of fractions, the category of fractionsDefinition [math-0089] \(\mathcal {C}[\Sigma ^{-1}]\) can be said in a simpler way:
Each composition of the equivalence classes\[ [(s,I,f) : A \to B], [(t,J,g) : B \to C] \]in \(\mathcal {C}[\Sigma ^{-1}]\) is \( [(s \circ r, K, g \circ h)] : A \to C \) where \(r \in \Sigma \) and \(h \in \mathcal {C}\)are any morphisms such that \(f \circ r = t \circ h\)
If \(C\) is finitely complete and \(\Sigma \) admits aright calculus of fractions and the category of fractionsDefinition [math-0089] \(C[\Sigma ^{-1}]\) exists, then \(C[\Sigma ^{-1}]\) and the canonical functor \(\varphi : C \to C[\Sigma ^{-1}]\) preserves finite limits.
Let \(C\) be a category and \(\Sigma \) is a class of morphisms where \(\varphi : C \to C[\Sigma ^{-1}]\) exists. Then \(\Sigma \) issaturated if \(\varphi (f)\) is an isomorphism iff \(f \in \Sigma \).
A factorization system on a category \(C\) is a pair of classes of morphisms \((\mathcal {E},\mathcal {M})\), such that
Two arrows \(A \xrightarrow {f} B\) and \(C \xrightarrow {g} D\) in a category \(C\), \(f\) is orthogonal to \(g\) and denoted \(f\ \bot \ g\), if given arbitrary morphisms \(u, v\) such that \( v \circ f = g \circ u \) then there exists a unique morphism \(w\) such that \(w \circ f = u\) and \(g \circ w = v\), as commute diagram
A basic block is a linear sequence of instructions such that, one can only run this sequence from the entry instruction, and will only exit when reach the final instruction. Compiler will decompose the program into several basic blocks when do analysis.
A family \((G_i)_{i\in I}\) of objects of \(\mathcal {C}\) is afamily of generators if, given any two parallel morphisms \[u, v : A \to B\] in \(\mathcal {C}\), \[ \forall i\in I. \forall G_i \xrightarrow {g} A. u \circ g = v \circ g \implies u = v \] when a family has only one object, the object \(G\) is called agenerator.
of a generator \(G \in \mathcal {C}\) isfaithful.
In a category with coproducts, and family of generators \((G_i)_{i\in I}\), then there is a unique morphism from coproduct of \((G_i)\) to each \(C\) forms
\[ \coprod _{i\in I}G_i \xrightarrow {\gamma _C} C \]each \(f\) can be factor as \(f = \gamma _C \circ f'\) is an epimorphism.
FollowsProposition [math-0087], if each epimorphism \(\gamma _C\) isstrong/regular than \((G_i)_{i\in I}\) is a strong/regular family.
Let \(\mathcal {G}\) be a full subcategory generated by family \((G_i)_{i\in I}\), and \(\mathcal {G} / X\) for full subcategory of \(\mathcal {C} / X\) collecting \(f : G_i \to X\).
Expand the definition of \(\mathcal {G} / X\), it's saying that if \(G_i \to X\) is there, than \(G_i \in \mathcal {G} / X\), of course will be a subcategory, since \(\mathcal {G} / X \subseteq \mathcal {C} / X\) by \(\mathcal {C}\) potentially have more \(Y \to X\).
Then family \((G_i)\) is a dense family if for each object \(X \in \mathcal {C}\), the colimit of the functor \[ \begin {aligned} &\Gamma ^X : &\mathcal {G} / X &\to &\mathcal {C} \\ &\Gamma ^X = &G_i \xrightarrow {f} X &\mapsto &G_i \end {aligned} \] is \((X, (f)_{f\in \mathcal {G} / X})\).
Let \(C\) be a category, \(F : C \to \bold {Set}\) is a set-valued functor. There is abijection between \(F(A)\) and allnatural transformations from \(\text {Hom}_{C}(A, -)\) to \(F\), which means
\[ [C,\bold {Set}] (\text {Hom}_{C}(A, -), F) \cong F(A) \]Every \(n\)-vertex graph with at least \(\lfloor n^2/4 \rfloor + 1\) edges contains at least \(\lfloor n/2 \rfloor \) triangles.
A \(n\)-vertex graph \(G\) with \(\lfloor n^2/4 \rfloor \) edges is isomorphic to \(K_{\lfloor n/2 \rfloor ,\lceil n/2 \rceil }\). Insert a new edge on bipartite graph can only connect two vertices of the same part, will create \(\lfloor n/2 \rfloor \) triangles. Therefore, at least \(\lfloor n/2 \rfloor \) triangles will be there for edges \(\lfloor n^2/4 \rfloor +1\).
Let \(X\) be an object in a symmetric monoidal category \((\mathcal {C}, \otimes , I)\). AFrobenius structure on \(X\) consists of a 4-tuple \((\mu ,\eta ,\delta ,\epsilon )\) such that \((X, \mu ,\eta )\) is a commutative monoid and \((X,\delta ,\epsilon )\) is a cocommutative comonoid, which satisfies the six equations above ((co)associativity, (co)unitality, (co)commutativity), as well as the following equations:
and
An object \(X\) equipped with a Frobenius structure is aFrobenius monoid.
Graph Theory and Additive Combinatorics: Exploring Structure and Randomness
Every \(n\)-vertex triangle-free graph has at most \(\lfloor n^2/4 \rfloor \) edges.
運算表是群 \(G\) 的函數 \(G \times G \to G\),把 \(g,h\in G\) 映到 \(gh\)
首先是唯一性的證明,假設 \(g\) 列有重複的結果 \(h\),這表示存在 \(ga = gb = h\),但我們總是可以取消 \(g\) 所以這表示 \(a = b\),這跟前提 \(a \ne b\) 矛盾,故 \(h\) 是唯一的;行是同樣的證明。
接著要能證明每個元素都有出現過。
AGrothendieck universe \(\mathcal {U}\) is a set such that
For a function \(f : \R ^n \to \R ^m\), maps \(x \in \R ^n\) to \(f(x) \in \R ^m\), the Jacobian matrix is a \(m\times n\) matrix, defined as
\[ J = \begin {bmatrix} \frac {\partial f}{\partial x_1} & \cdots & \frac {\partial f}{\partial x_n} \end {bmatrix} = \begin {bmatrix} \frac {\partial f_1}{\partial x_1} & \cdots & \frac {\partial f_1}{\partial x_n} \\ \vdots & \ddots & \vdots \\ \frac {\partial f_m}{\partial x_1} & \cdots & \frac {\partial f_m}{\partial x_n} \end {bmatrix} \]or we can say \(J_{ij} = \frac {\partial f_i}{\partial x_j}\).
Every set belongs to someuniverse.
A function \(f : V^k \to \R \) is\(k\)-linear if it's linear in each of its \(k\) arguments:
\[ f(\dots , av+bw, \dots ) = af(\dots , v, \dots ) + bf(\dots , w, \dots ) \]for all \(a,b\in \R \) and \(v,w\in V\). \(V\) is avector space, and \(V^k\) is cartesian product space.
Let \(f\) be a \(k\)-linear function and \(g\) be a \(l\)-linear function on a vector space \(V\), their tensor product is the \((k+l)\)-linear function \(f \otimes g\) defined as
\[ f\otimes g(v_1, \dots , v_{k+l}) = f(v_1, \dots , v_k) g(v_{k+1}, \dots , v_{k+l}) \]The \(k,l\) are indicies.
Let \(C\) and \(D\) becategories, and let \(F, G : C \to D\) befunctors. Anatural transformation \(\alpha : F \Rightarrow G\) is a function that
A natural transformation is called anatural isomorphism if each component \(\alpha _c\) is an isomorphism in \(D\).
Introduction to Topology
A metric space \((X, d)\) consists of:
These satisfy the following properties:
A metric space isextened if \(d : X \times X \to [0, \infty ] = \R _{\ge 0} \{ \infty \}\).
Amonoidal category \((B, \otimes , I, \alpha , \lambda , \rho )\) is a category \(B\) with a bifunctor \(\otimes : B \times B \to B\), an object \(I \in B\), and three natural isomorphisms \(\alpha , \lambda , \rho \).
with following coherence conditions:
The following diagram commutes for all objects \(a, b, c, d \in B\).
The following diagram commutes for all objects \(a, c \in B\).
This immdeiately provides \(\lambda _I = \rho _I : I \otimes I \to I\).
A monoidal category isstrict if three natural isomorphisms are identities.
A monoidal category issymmetric if we add a coherence:
\[a \otimes b \cong b \otimes a\]A monoidal category \(\mathcal {V}\) isclosed if for every two objects \(B,C\in \mathcal {V}\), there is an object \(B \multimap C \in \mathcal {V}\), calledhom-element orexponential, such that
\[ \text {Hom}_{\mathcal {V}}(A \otimes B, C) \cong \text {Hom}_{\mathcal {V}}(A, B \multimap C) \]The following diagram in a monoidal category commutes
First considering pentagonal with \(a = b := I\) and \(c := b\) then \(d := c\)
then we have a huge picture that attach second coherence axiom on to pentagonal.
Now, we need to prove \(\alpha _{I,b,c} \circ \rho _I \otimes 1 = (\rho _I \otimes 1) \otimes 1 \circ \alpha _{I\otimes I,b,c}\), but \(\alpha _{I\otimes I,b,c}\) and \(\alpha _{I,b,c}\) are same arrangement by lifting \(I\otimes I\) and \(I\) as parameter. Then \(\rho _I\) is the only left function, therefore, this diagram commutes.
If \(\mathcal {P}\) is apreorder, and \(\mathcal {C}\) is an abritary category, then at most onenatural transformation for two functors \(F, G : \mathcal {C} \to \mathcal {P}\).
In this sense, a left adjoint is a functor frompreorder \((\R , \le )\) to \((\Z , \le )\).
If we suppose \(L\) is a left adjoint of \(\lceil x/3 \rceil \), then we should have a diagram
Now, consider \(z = 1\), by Archimedean's principle, we have \(\forall y > 0, \lceil y/3 \rceil \le 1\); thus, we have \(L(1) \le 0\) and hence \(L(1) \le 0\).
However, this leads to \(1 \le 0\), so there has no left adjoint for \(\lceil x/3 \rceil : \Z \to \R \).
If below ispullback and \(f\) is mono, then \(f'\) is mono.
First transform the square
The two small square behind are pullbacks,
, so the big square also a pullback. Now, transform to another view, which shares the same big square.
Consider the right small square is a pullback, leads left small square is a pullback as well; thus, the \(f'\) is mono.
linear logic's\multimap | \(\multimap \) |
---|---|
QED\square | \(\square \) |
variant of \(\rho \)\varrho | \(\varrho \) |
斜上 arrow\nearrow | \(\nearrow \) |
向上的 partial arrow\upharpoonright | \(\upharpoonright \) |
\Vdash | \(\Vdash \) |
\vDash | \(\vDash \) |
\preceq | \(\preceq \) |
\succeq | \(\succeq \) |
\widetilde{x} | \(\widetilde {x}\) |
\wedge | \(\wedge \) |
\vee | \(\vee \) |
\bowtie | \(\bowtie \) |
A \(U \subseteq \R \) is oepn if for every \(x \in U\), there is a number \(\delta > 0\) such that \((x - \delta , x + \delta ) \subseteq U\). A set \(A\) is closed if its complement set \(A^c\) is open.
Let \(D\) be aDCPO, thelifting of \(D\) is adding a least element \(\bot \) to bepointed \(D_\bot \). Thus, alift monad \((-)_\bot : DCPO \to DCPO\) is anendofunctor that sends a \(D\) to \(D_\bot \).
It's obvious the lift monad creates aKlesli category, \(DCPO_\bot \), has same objects as\(DCPO\); however, a \(D \to E\) morphism in \(DCPO_\bot \) is caming from a morphism \(D \to E_\bot \) in \(DCPO\), a partial continuous function.
\(DCPO_\bot \) is closed with respect to this monoidal structure. Let the internal hom \(D \multimap E\) defined as \(D \Rightarrow _{DCPO} E_\bot \). Then \((-) \otimes D\) is left adjoint of \(D \multimap (-)\).
Let \(\mathbb {U}\) be a DCPO \(\N \multimap 2\), we called it the universal domain.
A DCPO \(D\) is a domain if it is aretract of \(\mathbb {U}\) in \(DCPO_\bot \).
一個形式語言是一個三元組 \((\Gamma , \Delta , a)\) 構成的集合,
A \(L\)-structure \(\mathfrak {U} = (U, I)\) of alanguage \(L\) is a set \(U\) called universe of model, and a function \(I\) assigns to each \(k\)-ary function symbol in \(\Gamma \) a \(k\)-ary function \(U \to U\) and to each \(k\)-ary relation symbol a \(k\)-ary relation on \(U\). Denotes
Let \(\mathfrak {U}\) and \(\mathfrak {B}\) are models of \(L\), a homomorphism \(\varphi \) is a function from \(|\mathfrak {U}| \to |\mathfrak {B}|\) such that, for all for \( a_0, \cdots , a_{k-1} \in |\mathfrak {U}| \)
A homomorphism isembedding if it'sinjective and the second clause is strengthened to
\(\varphi (R^\mathfrak {U}(a_0, \cdots , a_{k-1}))\) if and only if \(R^\mathfrak {B}(\varphi (a_0), \cdots , \varphi (a_{k-1}))\)
Forward can be omitted since it's proved by definition, and backward can be proved as below.
For a language \(L\), the set of terms of \(L\) is defined inductively as below
A set of propositional formulas is defined inductively
Let \(\Sigma \) be abritary set, a tree on \(\Sigma \) is a set of finite sequences of elements of \(\Sigma \) that closed under initial segments.
A string \(s\) is an initial segment of \(t\) if \(length(s) < length(t)\) and \(s\) is a prefix string of \(t\), denotes \(s \subseteq t\).
closed under initial segments means if \(\tau \) is in the tree and \(\sigma \subseteq \tau \) then \(\sigma \) is also in the tree.
A path through a tree \(T\) is a set \(P\) such that
The set ofwell-founded trees of \(\Sigma \) is defined inductively
By induction
A tree isfinitely branching if every node has finitely many children.
Let \(T\) be afinitely branching tree on \(\Sigma \). Then below are equivalent
An equivalent statement is: a finitely branching tree with infinite nodes has infinite path.
1 implies 2 and 3 is clearly. Prove 3 implies 1 can complete the proof, usingpropoisition 3.4, \(T\) has no infinite path, and \(T\) is finitely branching; which means the amount of nodes are a sum of a finite sequence of finite natural numbers, leads to \(T\) is finite.
這個反例證明了 well-founded 樹還是可以有無限多個元素,只要容許無限多分支。
A tree that, for all \(n \in \N \), the \(n\)-length path through it are existed, can still bewell-founded. Consider a tree indexed by \(\Sigma = \N \), with nodes \( \{ 1, 21, 321, 4321, \cdots \} \) up to \(\omega \). It looks like
The tree has all finite \(n\)-path, but has no infinite path.
令 \(\Sigma = \{ 0, 1 \}\) 的有限樹,這正是一般二元樹的定義。下面定義樹的深度與元素數量
對任意二元樹 \(a\) 有 \(\text {size}(a) \le 2^{\text {depth}(a)+1} - 1\)
二元樹的 \(\text {size}\) 可以表示為等比數列和 \(1 + 2 + 4 + 8 + \cdots \),故為
\[ \frac {1(1 - 2^n)}{1-2} = 2^n - 1 \]\(n\) 正好等於 \(\text {depth}(a)+1\),故 \(\text {size}(a) \le 2^{\text {depth}(a)+1} - 1\)。
Start from a natural number \(n\),
repeating the process will get \(1\).
這個概念是我看到 Kristopher 的貼文 (上列連結) 之後回應的統整。簡單來說目前的 C 位址並非是完全抽象的,因此會導致 double free 會出問題。而正確解決這件事的方式就是讓 reference 是一個完全抽象的存在,並且加上 shift 數表示移位操作。在這個體系下每次我使用malloc(size)
的時候,都應該得到一個與真實儲存偏移值完全無關,不提供通用逆函數的數字來表示這個 reference,而 shift 數表示我正在操作此 reference 的第幾個 bit。這樣 double free 的時候因為對應的 reference 已經被釋放了,因此就不會對真實的偏移值造成影響。進一步可以使用bit stealing 來表示 reference,因為真實位址通常不會真的用到全部的 64-bits。
A profunctor \(\phi : C \nrightarrow D\) is afunctor \(\phi : D^{op} \times C \to \bold {Set}\), such that if \(f \in D\) and \(g \in C\),
and there is an element \(x \in \phi (d', c)\), then \(x \circ f \in \phi (d, c)\) and \(g \circ x \in \phi (d', c')\).
It's related to(co)end.
Profunctor creates a "pseudo" arrow between two categories \(C\) and \(D\).
It's natural to not restrict ourselves in \(\bold {Set}\). Let \(\mathcal {V}\) be a unital commutative quantale, and let \(\mathcal {X}\) and \(\mathcal {Y}\) be \(\mathcal {V}\)-categories. A \(\mathcal {V}\)-profunctor from \(\mathcal {X}\) to \(\mathcal {Y}\), denoted \(\phi : \mathcal {X} \nrightarrow \mathcal {Y}\), is a \(\mathcal {V}\)-functor
\[\phi : \mathcal {X}^{op} \times \mathcal {Y} \to \mathcal {V}\]Elaboration with first-class implicit function types
此演算法可判定,且解是唯一的。理由如下
因此 pattern unification 可判定,且因為 2 3 都只有唯一解,所以整個 unification 的解是唯一的。其實際演示參考elaboration zoo 中的合一演算法與隱式參數。
AHeyting algebra is abounded lattice equipped with a binary operation \(a \to b\) of implication such that \(c \land a \le b\) is equivalent to \(c \le (a \to b)\).
A Heyting algebra \(H\) is aboolean algebra iff for all \(x \in H\)
\[\lnot \lnot x = x\]or equivalent
\[x \lor \lnot x = 1\]If \(f : I \to \R \) is \((n + 1)\)-differentable, if \(\Delta a \in \R \) and \(a + \Delta a \in I\) then
\[ f(a + \Delta a) = \sum _{k = 0}^n { \frac {f^{(k)}(a)} {k!} \cdot {\Delta a}^k + R_n(\Delta a) } \]and there is a \(\xi \in (a, a + \Delta a)\) or \(\xi \in (a + \Delta a, a)\), such that
\[ R_n(\Delta a) = \frac { f^{(n+1)}(\xi ) }{(n+1)!} \cdot {\Delta a}^{n+1} \]Consider partial maps \(u = [f,m]\) and \(v = [g,n]\), the composition is a partial map \[v \circ u = [ m \circ f^{-1}(n) , g \circ n^*f]\] makes below pullback
Adomain structure \((\mathcal {K}, \mathcal {D})\) is a pair, where \(\mathcal {D}\) is awell-powered category \(\mathcal {D}\) and a category \(\mathcal {K}\), such that \(\mathcal {D}\) is a full-on-objects subcategory of \(\mathcal {K}\) all of whose morphisms aremonos in \(\mathcal {K}\), with the following closure property: Every diagram
is a pullback in \(\mathcal {K}\), with \(f \in \mathcal {K}\), \(n \in D\), and \(f^{-1}(n) \in \mathcal {D}\).
Notice how is this related tocomposition of partial maps.
這個專案的用途是幫 type 生成各種函數,像是輸出的字串只要在最後加上[@@deriving show]
就能夠使用([%show: xxx] v)
來把v : xxx
變成string
。但我們很有可能會想控制輸出的內容,一個常見的案例是 AST 的 pretty print,這裡面的[@printer ...]
指令可以控制輸出用的樣板,show_xxx
可以遞迴調用產出的 printer。
type typ = | Var of string [@printer fun fmt -> fprintf fmt "%s"] | Arrow of typ * typ [@printer fun fmt (a, b) -> fprintf fmt "%s -> %s" (show_typ a) (show_typ b)][@@deriving show]
對結構類的資料也有作用
type card = { title: string; [@printer fun fmt -> fprintf fmt "<%s>"] date: string}
eq, ord
等函數enum
能指定數值iter, map, fold
能產生結構的列舉程式make
,這裡面可以用[@default v]
讓欄位的預設值變成v
gpg --edit-key XXXXXX
;adduid
, then answer questions;quit
then save.Acategory \(C\) with a terminal and all pullbacks has all finite limits:
Then applyall finite limits can be constructed from finite products and equalizers.
steps
A partial derivation is defined on function with more than one parameter, e.g. two parameters function
\[z = f(x,y)\]then
\[ \begin {aligned} \frac {\partial z}{\partial x} &= \lim _{h \to 0}{\frac {f(x+h, y) - f(x,y)}{h}} \\&= f_x(x,y) \quad \text {(if this is still a function)} \end {aligned} \]and
\[ \begin {aligned} \frac {\partial z}{\partial y} &= \lim _{h \to 0}{\frac {f(x, y+h) - f(x,y)}{h}} \\&= f_y(x,y) \quad \text {(if this is still a function)} \end {aligned} \]Extend the symbol, for function \(f\) below
\[f(x_1, x_2, ..., x_n)\]where \(n \in \N , n \ge 2\). We have
\[ \frac {\partial }{\partial x_i} = \lim _{h\to 0}\frac { f(x_1, \cdots , x_i + h, \cdots , x_n) - f(x_1, x_2, ..., x_n) }{h} \]The four definition below are equivalent
Therefore, a satisfiable problem is a logical statement such that it's inverse is not a tautology.
We will say a function \(f\) ispartial iff there has some elements \(x\) of domain, \(f(x)\) has no definition; of course, we can alsodetect a partial function via two functions.
We say \(f : A \to \R \) if for all \(\epsilon > 0\) there exists some \(\delta > 0\) such that, for all \(x,y\in A\)
\[|x - y| < \delta \quad \implies \quad |f(x) - f(y)| < \epsilon \]The definition of Harmonic series is
\[ \sum _{k=1}^\infty \frac {1}{k} \]The most famous fact about it is it's divergent, this is again a good example shows that intuitive is not work here, even the adding things are smaller and smaller, the sum is divergent.
\(\alpha \) is a cardinal iff \(\alpha = |\alpha |\); a cardinal of a set \(A\) (\(A\) iswell-ordered) is the least \(\alpha \) that \(\alpha \approx A\), denotes \(|A|\); a cardinal \(\alpha \) is infinite if \(\alef _0 \precsim \alpha \).
Under theaxiom of choice, \(|A|\) is defined for every \(A\).
To expand the definition, we need below
Which means there is no surjective map from \(A\) to its powerset of \(A\).
The hypothesis says no cardinal \(\xi \) satisfies
\[\alef _0 \prec \xi \prec 2^{\alef _0}\]However, the hypothesis is independent from ZFC. The generalized version, for all infinite cardinal \(\alef \), no \(\xi \) satisfies
\[\alef \prec \xi \prec 2^{\alef }\]is also independent.
A topological function \(f : X \to Y\) iscontinuous iff for every open set \(V\) in \(Y\), the preimage \(f^{-1}(V)\) is open in \(X\).
It's easy to port this definition back to analysis (or metric space) by picking \(\epsilon \)-neighborhood.
If \(\sum _{k=1}^\infty {a_k}\) and \(\sum _{k=1}^\infty {b_k}\) are convergent, and the \(\lambda \in \R \), then
A convergent sequence is a Cauchy sequence (in real analysis), it says
\[ \sum _{k=1}^\infty {a_k} \ \text {is convergent} \iff \forall \epsilon > 0, \exists N \in \N , \forall N \le m \le n, \bigg | \sum _{k = m}^n {a_k} \bigg | < \epsilon \]也就是,存在 \(N\) 讓級數在超過 \(N\) 之後隨便加都可以任意小。
A function \(f(x)\) isdifferentiable at a point \(a\) if \(a\) is contained in an open interval of domain, and the limit
\[ \lim _{h \to 0} \frac {f(a + h) - f(a) }{h} \]exists. We also denote \( \frac {d f}{d x} (a)\) or \( \frac {d y}{d x} \), the later is more common in my background that \(y = f(x)\), but the first one is more suitable if we like to view derivative as a function.
The concept differentiable is more strict thatcontinuous, this is a common mistake that early mathematicians made, until Weierstrass found the first example of a function that is continuous everywhere but differentiable nowhere.
For every real-functions \(f, g\) that differentable at \(a\) and a constant \(c\)
We first consider \(f(x) = x^2\), in this case we apply product rule by view it as \(x^2 = x \cdot x\):
\[ \frac {d }{d x} (x^2) = \frac {d }{d x} (x \cdot x) = x \cdot \frac {d x}{d x} + \frac {d x}{d x} x = 2x \]For \( \frac {d }{d x} (x^3)\) we have
\[ \frac {d }{d x} (x^3) = \frac {d }{d x} (x^2\cdot x) = x \cdot \frac {d x^2}{d x} + \frac {d x}{d x} \cdot x^2 = x \cdot 2x + x^2 = 3 x^2 \]It's easy to see for \(a \in \N \) we have
\[ \frac {d }{d x} (x^a) = \frac {d }{d x} (x^{a-1}\cdot x)= x \cdot \frac {d x^{a-1}}{d x} + x^{a-1}\]Inductively get
\[ \frac {d }{d x} (x^a) = a x ^ {a-1}\]This will need to back to original definition:
\[ \begin {aligned} \frac {d }{d x} (a^x) &= \lim _{h\to 0}\frac { a^{x+h} - a^x }{ h } \\ &= a^x \lim _{h\to 0}\frac {a^h - 1}{h} \\ &= a^x \frac {1}{\log _a e} \\ &= a^x \log _e a \\ &= a^x \ln a \end {aligned} \]The idea is, under \(h \to 0\), \(a^h\) is closed to \(1\), thus, if we say \(t \to \infty \), then
\[1 + \frac {1}{t} \to 1\]can replace \(a^h\). Therefore, we have
\[ \lim _{h \to 0, t \to \infty }{ \frac { (1 + \frac {1}{t}) - 1 }{h} } \]Now, we want to remove \(h\), let \(h = \log _a {(1 + \frac {1}{t})}\)
\[ \lim _{t \to \infty }{ \frac { \frac {1}{t} }{ \log _a (1 + \frac {1}{t}) } } = \lim _{t \to \infty }{ \frac {1}{ \log _a (1 + \frac {1}{t})^t } } \]Apply
\[\lim _{t \to \infty }{ (1 + \frac {1}{t})^t } = e \]Now get
\[ \lim _{t \to \infty }{ \frac {1}{\log _a e} } = { \frac {1}{\log _a e} } \]This leads to famous result
\[ \frac {d }{d x} (e^x) = e^x \ln e = e^x\]Consider \(log_a x\) is the inverse of \(a^x\) such thatcontinuous and monotone, thus
\[ \frac {d }{d x} (log_a x) = \frac {1}{x \ln a}\]also leads
\[ \frac {d }{d x} (\ln x) = \frac {1}{x \ln e} = \frac {1}{x}\]The dimension of a space is thecardinal of its basis. For vector space, the definition is in common sense that \(n\)-D such that \(n \in \N \), but there also hasHausdroff dimension that very unusual.
事實上,這個定義下座標系就是指一組 basis。
A series \(\sum _{k=1}^\infty {a_k}\) and abijective map \(\tau : \N \to \N \), a reordering of series \(\sum _{k=1}^\infty {a_k}\) is a series
\[ \sum _{k=1}^\infty {a_{\tau (k)}} \]A series is absolutely convergent, then its reordering cannot change the limit; of course, the reordering is then absolutely convergent
\[ \sum _{k=1}^\infty {a_k} = \sum _{k=1}^\infty {a_{\tau (k)}} \]export 公鑰
gpg --armor --export <email>
加密指令可以用 pipeline
echo "message" | gpg --encrypt --armor --recipient <email>
或是檔案
gpg --encrypt --armor --recipient <email> --output [encrypted_file] [msg_file]
解密
gpg --decrypt [encrypted_file]
A \(C^\alpha \)-manifold is a \(C^\alpha \)-premanifold whose underlying topological space isHausdroff andsecond countable.
當一個連通拓墣空間 \(M\) 可以表示成有限開覆蓋時,對其中每個點 \(p \in M\) 都存在鄰域 \(U\) 帶有所謂的 chart map \(U \xhookrightarrow {\varphi } \R ^n\),其中 \(\varphi \) 是一個同胚映射,所以 \(\varphi (U)\) 是 \(\R ^n\) 中的開集合;這時候說 \(M\) 是拓墣流形(topological manifold),並且稱 \(\varphi \) 指定了一組鄰近座標 (local coordinates),或是直接說 \(\varphi \) 是一組座標,根據定義一組座標跟一個點可以互相表示。
每個 chart map \(\varphi : U \hookrightarrow \R ^n\) 都可以看成多個 component maps 構成的一個 map
\[ \varphi (p) = (\varphi ^1(p), \varphi ^2(p), \cdots , \varphi ^n(p)) \]通常個別的 chart map 是不能描述整個流型的,但流型可以被一組 chart maps 覆蓋,因此引出了 atlas 的概念。
chart map 當然也可以定義成 \(U \subset \R ^n \hookrightarrow M\),這通常跟作者習慣用哪一個方向思考有關。
An atlas for a manifold \(M\) is an indexed set \(\{ \phi _i : U_i \to W_i \}\) of charts such that together all the domains \(U_i\) cover \(M\) (\(M = \bigcup _{i\in I} U_i\)).
為了能夠在上面操作微積分,所以額外要求 \(\varphi \) 是可微分的,這時候稱 \(M\) 為可微流形 (differentiable manifold)。
manifold 上的一個曲線是一個 \(g : \R \to M\) 的injective 函數,通常把實數參數記為 \(\lambda \) 並寫成 \(g(\lambda )\)。也有定義成 \([0,1] \to M\) 或是 \((-\epsilon ,\epsilon ) \to M\) 的,這些概念其實都類似。
A curve \(\gamma : [a,b] \to M\) isclosed if \(\gamma (a) = \gamma (b)\).
A curve \(\gamma : [a,b] \to M\) issimple if there is no \(s, t \in [ a, b )\) satisfy \(\gamma (s) = \gamma (t)\).
The idea is the curve does not self cross.
對一個 manifold \(M\) 上的一點 \(p \in M\) 來說,切空間是一組向量的線性組合構成的向量空間,記成 \(T_pM\),總共有三種不同觀點但等價的定義。
對 maximal atlas \(\mathcal {A}\) 的每個 chart 附加一組切向量空間並定義同餘。
Manifolds and Differential Geometry §2.1.3
把 tangent vector 定義為 \(v_p : C^\infty (M) \to \R \) 的線性函數,並且滿足 Leibniz law,若 \(f,g \in C^\infty (M)\) 則
\[v_p(fg) = v_p(f)g(p) + f(p)v_p(g)\]可以看到顯然 \(C^\infty (M) = M \to \R \)。這裡,我們也稱 tangent vector \(v_p\) 是 algebra \(C^\infty (M)\) 在 \(p\) 點的微分
用代數版本可以看出,給定 \((U, x)\) 作為 \(p\) 的chart,則切空間的標準基底是
\[\frac {\partial }{\partial x^i} \Biggr \rvert _p : C^\infty (M) \to \R \]套用 \(f : C^\infty (M)\) 定義為
\[\frac {\partial }{\partial x^i} \Biggr \rvert _p f := \frac {\partial f}{\partial x^i}(p)\]A smoothvector field on \(M\) is a smooth map from \(M\) totangent bundle
\[X : M \to TM\]such that \(X(p) \in T_pM\). We denote \(X_p := X(p)\), and denote all vector fields on \(M\) by \(\mathfrak {X}(M)\).
\[X \in \mathfrak {X}(M)\]換句話說,一個向量場的用途就是,為每一點 \(p \in M\) 選一個關聯向量 \(\vec {v} \in T_p M\)。
Let \(V\) be avector space over a field \(F\), a covector is a function \(\widetilde {\omega } : V \to F\) such that preserves linearity:
\[ \alpha \widetilde {\omega }(\vec {v}) + \beta \widetilde {\omega }(\vec {w}) = \widetilde {\omega }(\alpha \vec {v} + \beta \vec {w}) \]for all \(\alpha , \beta \in F\). Then we define multiplication
\[ (\alpha \widetilde {\omega })(\vec {v}) = \alpha \widetilde {\omega }(\vec {v}) \]and addition
\[ (\widetilde {\omega } + \widetilde {\sigma })(\vec {v}) = \widetilde {\omega }(\vec {v}) + \widetilde {\sigma }(\vec {v}) \]Thus, all covectors form a dual vector space \(V^*\).
平面裡面的 row vector \(\begin {bmatrix}a&b\end {bmatrix}\) 可以視為 column vector \(\begin {bmatrix}x \\ y\end {bmatrix}\) 的函數,定義成
\[ \begin {bmatrix}a&b\end {bmatrix}(\begin {bmatrix}x \\ y\end {bmatrix}) := \begin {bmatrix}a&b\end {bmatrix}\begin {bmatrix}x \\ y\end {bmatrix} = ax + by \]Congruence is a set of curves that fill the manifold, or some part of it.
If \(x \in A\) then define
\[pred(A, x, R) = \{ y \in A \mid y R x \}\]選擇公理的邏輯式要求對所有集合 \(A\) 存在 relation \(R\) 可以排序 \(A\):
\[\forall A, \exists R, A \ \text {well-ordered by} \ R\]這個定義的用途是為了用反覆選擇 \(R\)-least element 從而進行 cardinal 的比較。但實際上這是獨立的,所以從集合論 ZF 出發我們只能選擇要不要相信這個公理。
For every cardinal \(\kappa \) there exists aninaccessible cardinal \(\kappa '\) with \(\kappa ' > \kappa \).
A set \(A\) is anordinal off \(A\) istransitive andwell-ordered by \(\in _A\).
\[\in _A = \{ \langle y, z \rangle \in A \times A \mid y \in z \}\]Notice \(\{ \{ \{ \varnothing \} \}, \{ \varnothing \}, \varnothing \}\) is an example oftransitive but not an ordinal.
We usually drop \(\in _A\) part and just sayan ordinal \(A\).
The formal description is
\[\lnot \exists z. \forall x. (x \ \text {is an ordinal} \implies x \in z)\]We can first define such set:
\[ON = \{ x \mid x \ \text {is ordinal} \}\]However, we can prove \(ON\) iswell-ordered viatheorem 2-3, 2-4, 2-5; then we can prove \(ON\) istransitive viatheorem 2-1. Thus, \(ON\) is an ordinal, is \(ON \in ON\)? This is a Russell paradox, a proper conclusion is \(ON\) is not existed or it's not a set.
No need complicated philosophy here, this is justno greatest ordinal there.
A set of ordinals \(A\) is an ordinal iff \(\forall x \in A, \forall y \in x \implies y \in A\).
Let \(\alpha \) be an ordinal
\[S(\alpha ) = \alpha \cup \{ \alpha \}\]For any ordinal \(\alpha \),
This is how we build natural number from set theory (one of methods).
The natural number building leads to \(\omega \) is the set of natural numbers (all finite ordinals).
\(\omega \) is theleast limit ordinal.
A set \(A\) with a relation \(R\) iswell-ordering iff \(\langle A, R \rangle \) is atotal ordering and every non-empty subset \(S\) of \(A\) has an \(R\)-least element \(l\), which means for any \(x \in S\), the \(lRx\) holds.
A set \(x\) istransitive iff the relation \(\in \) is transitive on \(x\), so for every \(y \in x\) and \(z \in y\) we have \(z \in x\). In other words, every element of \(x\) is a subset of \(x\).
An ordinal is a transitive set which is well ordered by \(\in \).
In this system, class is the basic objects of the theory, and a set is just a class that can be an element of other classes.
atuin 紀錄 CLI history,互動操作更方便而且可以跨電腦同步指令
atuin
gives better interactive interface to do command history search, once you found a target, use
<tab>
to back to shell and edit the command; and<enter>
to execute the command directly.There is apost teach you to use self hosted sync server.
A category is a collection \(C\), the elements are called morphisms, together with two endofunctions \(s, t : C \to C\) ("source" and "target") on \(C\) and a partialfunction \(\circ : C \times C \to C\), such that satisfy the following axioms
We usually denote \(f \circ g\) (\(f\) after \(g\)), but also ok with \(fg\) or \(g \gg f\) (\(g\) then \(f\)).
One can compare this version with usual definition (below). This version is more essentials, in the sense that, a category is the "algebra of morphisms".
We say \(\mathcal {C}\) is a category if
They satisfied:
not every morphism \(f : x \to x\) is an identity.
If we define categories on the usual set/class formalization setting (meansZF with NBG axioms), we are now able to define what's small (a set) and large (a class). Beside that, usinglarge cardinal axiom we can fix a sequence of inaccessible cardinals \[\kappa _0 < \kappa _1 < \kappa _2 < \cdots \] and their associated universes \(\mathcal {V}_{<\kappa }\); in this sense, a set is
One can see that we discuss categories in different foundations, the definitions about categories size below depends on the particular foundation we pick.
With a particular foundation, a category is small if its collection of morphisms is small.
With a particular foundation, a category is locally small if all hom-collections \(\text {Hom}_\mathcal {C}(a, b)\) are small.
otherwise, a category is large.
Some definition even take locally small as default, usually is because author are not going to discuss category theory itself, but use categories as a tool to discuss other topics.
The condition that the collection of morphisms is a set implies the collection of objects is a set.The set/class distinction is raised fromset theory, since the collection of all sets as collection of objects forms acategory of sets, denotes \(\bold {Sets}\). Its collection of objects cannot be a set, we have to consider this fundamental issue.
Follows the size idea, we can also consider finite category.
Acategory is finite if its objects and morphisms are both finite set.
We can easier find why monoid is an one object category with this definition:
Amonoid is a category such that, any two morphisms \(x, y\) satisfy
These say two things: 1. it has the only one object 2. we can determined the \(I\) element is the identity morphism.
A monoid \((M, \bullet )\) constituted by a set \(M\) and a binary function \(\bullet : M \times M \to M\), such that
This is also why we have a joke: a category is just a monoidoid (extend monoid concept to work with many-object).
The tool send files from one computer to another securely.
gpg -a --export > publickeys.ascgpg -a --export-secret-keys > privatekeys.ascgpg --export-ownertrust > trust.txt
Then use tools e.g.croc to transfer files. Apply below commands in new machine
gpg --import publickeys.ascgpg --import privatekeys.ascgpg -Kgpg -kgpg --import-ownertrust trust.txt
Now your gpg is migrated.
zoxide 這個軟體讓我們用簡短的縮寫跳轉到曾經去過的目錄
This is a smartercd
command. When I doz xxx
, it would bring me to the most frequently used directory with "xxx" in the name. More you use it, it would get more accurated.
在下載好 iso 檔案之後,把 USB 隨身碟接上 macOS 電腦,用diskutil
判斷是哪個diskN
裝置,然後用下列指令把檔案安裝進去
diskutil eraseDisk "MS-DOS FAT32" USB /dev/diskNdiskutil unmountDisk /dev/diskNsudo dd bs=4M if=Endeavouros-Galileo-11-2023.iso of=/dev/diskN conv=fsync oflag=direct status=progress
A total map is a set function, a well-known concept.
Apartial function \(A \rightharpoonup B\) can be described by
we said \([m, f] : A \rightharpoonup B\) is adescription of the partial function.Descriptions are not unique, for any two \([m, f]\) and \([n, g]\) thatdescribes same partial function, there exists an isomorphism \(i\) satisfies
\[m = n \circ i \ \text {and} \ f = g \circ i\]A partial map is an equivalence class of thesedescriptions.
Consider partial maps \(u = [f,m]\) and \(v = [g,n]\), the composition is a partial map \[v \circ u = [ m \circ f^{-1}(n) , g \circ n^*f]\] makes below pullback
The \(LB\) stands forlifting of \(B\).
Let \((\mathcal {K}, \mathcal {D})\) be adomain structure. Aclassifier of partial maps with target \(B\) is a mono \(n : B \rightarrowtail LB\) in \(\mathcal {D}\) such that for every partial map \([m,f] : A \rightharpoonup B\), there is a unique total map \(\chi _{[m,f]} : A \to LB\) calledcharacteristic map of \([m,f]\), make below a pullback.
Aposet \(D\) iscomplete if everydirected subset \(P \subseteq D\) has a least upper bound.
Every discrete poset \((A, =)\) is aDCPO, every singleton sets \(\forall x \in A, \set {x}\) are directed, with least upper bound \(x\).
DCPOs withScott continuous, via Scott topology, it's afull subcategory of the category of topological spaces.
Let \(D\) be acpo. A subset \(U\) of \(D\) is said to beScott oepn if
Scott open subsets of \(D\) form a topology, this is theScott topology on \(D\). A continuous function \(f : D \to E\) will preserve directed least element \[ f(\sqcup _D X) = \sqcup _E f(X) \] for all directed \(X \subseteq D\).
A2-category \(\mathcal {C}\) is a category with
such that
For each fixed pair of objects \(a , b \in \mathcal {C}\), the 1-cells and 2-cells form a category:
The objects and 1-cells define a category; each object has an identity arrow \(1_a : a \to a\).
The objects and 2-cells form a category.
The horizontal composition is functorial with respect to the vertical composition:
基於 mercurial 的一些特性,得出多人協作下 mercurial 的開發流程
當然,要是只有自己在開發的話倒是不用這麼麻煩,因為自己開發就算忘記先 pull 也很容易 merge 成功。
mkdir repo
目錄repo/public
目錄hg clone public feature-xxx
feature-xxx
目錄裡面寫好之後直接送 email 出去hg import
mboxhg pull/up
跟hg push
hg tag (release)
這裡只是想嘗試非歸納證明的方法。
在證明之前需要一些觀察。首先,可以把命題改寫成對所有 \(n\) 存在 \(k\) 令 \(4^n - 1 = 3k\),於是開始觀察數列 \(4^n - 1\) 與 \(k\) 的關係
\(n\) | \(4^n - 1\) | \(k\) |
---|---|---|
\(1\) | \(3\) | \(1\) |
\(2\) | \(15\) | \(5\) |
\(3\) | \(63\) | \(21\) |
\(4\) | \(255\) | \(85\) |
只看到這邊應該還沒辦法知道什麼,不過只要拿到一個數列我們就能嘗試The book of numbers 中提到的技術:項差列。在這裡,根據 \(n\) 而得到的 \(k\) 們的項差列是
\[\{4, 16, 85\} = \{5 - 1, 21 - 5, 85 - 21\}\]據此可以提出一個猜想:
\[4^n - 1 = 3 \cdot \sum _0^{n-1}{4^n}\]也就是說,總是存在 \(k = \sum _0^{n-1}{4^n}\) 這個整數。
經過一番改寫之後,我們終於可以開始證明。
\[\begin {equation} 4^n - 1 = 3 \cdot \sum _0^{n-1}{4^n} \end {equation}\] \[\begin {equation} 4^n = 1 + 3 \cdot \sum _0^{n-1}{4^n} \end {equation}\] \[\begin {equation} 4^n = 1 + 3 \cdot 4^0 + 3 \cdot \sum _1^{n-1}{4^n} \end {equation}\] \[\begin {equation} 4^n = 4 + 3 \cdot \sum _1^{n-1}{4^n} \end {equation}\]根據等比數列和可以求得
\[\begin {equation} 4^n = 4 + 3 \cdot \frac {4(1-4^{n-1})}{1 - 4} \end {equation}\] \[\begin {equation} 4^n = 4 + 3 \cdot \frac {4 - 4^n}{1 - 4} \end {equation}\] \[\begin {equation} 4^n = 4 + 3 \cdot \frac {4^n - 4}{3} \end {equation}\] \[\begin {equation} 4^n = 4 + (4^n - 4) \end {equation}\]式 (8) 證明關係式確實成立,\(4^n - 1\) 可以分解成 \(3k = 3 ( \frac {4^n - 4}{3} )\),由於 \(k\) 來自整數和,所以也還是一個整數 \(\square \)
因為只要把Haskell 的undefined
被包進 pair(undefined, undefined)
,根據 lazy semantic 就不會執行裡面的兩個函數,因此不應有異常,而呼叫undefined
則會有異常,因此表達成數學式就是
在新版本裡面這個問題被「修正」了,問題是這導致(undefined, undefined)
不遵循 lazy semantic,在理論上只是變成更大的問題。
The command performs real revert for commit.
hg strip -r . --keep
根據 Jon 在 external 連結中的描述,只要日期2023-12-04.tree
這樣的卡片存在,則每則該日筆記的日期就會產出一個連結到這張日期卡片上,要如何運用還需要研究。
我想這對forester-0006 描述的問題也有用
列表的主要原則是展示一個語言的強項、好用的工具跟做出的產品,所以大致上不是入門內容,不過我也可能在其中指向其他外部教學文章。
內容會不定期更新,可以訂閱每個語言的 RSS(網址.xml
部分改成.rss.xml
)。
An industrial-strength functional programming language with an emphasis on expressiveness and safety. When developing ocaml project, you might like to rundune build --watch
and keep modify your files.
這個專案的用途是幫 type 生成各種函數,像是輸出的字串只要在最後加上[@@deriving show]
就能夠使用([%show: xxx] v)
來把v : xxx
變成string
。但我們很有可能會想控制輸出的內容,一個常見的案例是 AST 的 pretty print,這裡面的[@printer ...]
指令可以控制輸出用的樣板,show_xxx
可以遞迴調用產出的 printer。
type typ = | Var of string [@printer fun fmt -> fprintf fmt "%s"] | Arrow of typ * typ [@printer fun fmt (a, b) -> fprintf fmt "%s -> %s" (show_typ a) (show_typ b)][@@deriving show]
對結構類的資料也有作用
type card = { title: string; [@printer fun fmt -> fprintf fmt "<%s>"] date: string}
eq, ord
等函數enum
能指定數值iter, map, fold
能產生結構的列舉程式make
,這裡面可以用[@default v]
讓欄位的預設值變成v
Effects-based direct-style IO for multicore OCaml.
This library was motivated by the name modifiers in the "import" or "include" statements present in all practical programming languages.
"asai" is the transliteration of "浅井", the family name of the character Kei Asai (浅井 ケイ) in the Japanese light novel Sagrada Reset (サクラダリセット, also known in English as Sakurada Reset). His ability is perfect photographic memory that is even immune to the "Reset" ability owned by another main character. This OCaml library should record all messages, just like the character.
🦠 Reusable components based on algebraic effects
Menhir is a parser generator. It turns high-level grammar specifications, decorated with “semantic actions” (fragments of executable code), into parsers. It is based on Knuth’s LR(1) parser construction technique. It is strongly inspired by its precursors: yacc, ML-Yacc, and ocamlyacc, but offers a large number of minor and major improvements that make it a more modern tool.
Fuzzy search in OCaml's documentation for almost all opam packages.
Agda is a dependently typed programming language / interactive theorem prover.
我使用的編輯器工具是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 中你打的程式碼直接當成結果,一樣類型要是正確的hello : A → B hello a = {! !}ctrl+c, ctrl+c 會問你要把哪個變數用構造子分開,回答
a
,假設有a1
與a2
兩個構造子,程式就會變成hello : A → B hello a1 = {! !} hello a2 = {! !}
使用 Linux 的使用者可以更改預設的 copy/cut 指令以免衝突。
notes for talk given at TUPLE 2024
This is a very good start point before formalizing languages that more complicated.
@software{agda-unimath, author = {Rijke, Egbert and Stenholm, Elisabeth and Prieto-Cubides, Jonathan and Bakke, Fredrik and {others}}, license = {MIT}, title = {{The agda-unimath library}}, url = {https://github.com/UniMath/agda-unimath/}}
TLA+ is a high-level language for modeling programs and systems--especially concurrent and distributed ones. It's based on the idea that the best way to describe things precisely is with simple mathematics.
我使用的編輯器工具是TLA+ on vscode,常用操作是用Cmd+Shift+P
調用指令
TLA+: Parse module
解析模組並且更新生成的約束TLA+: Check model with TLC
按照.cfg
檔案的指示檢查模組ㄋPlusCal is an algorithm language—a language for writing and debugging algorithms. It is especially good for algorithms to be implemented with multi-threaded code. Instead of being compiled into code, a PlusCal algorithm is translated into a TLA+ specification. An algorithm written in PlusCal is debugged using the TLA+ tools—mainly the TLC model checker. Correctness of the algorithm can also be proved with the TLAPS proof system, but that requires a lot of hard work and is seldom done.
Lean is a functional programming language that makes it easy to write correct and maintainable code. You can also use Lean as an interactive theorem prover. Lean programming primarily involves defining types and functions. This allows your focus to remain on the problem domain and manipulating its data, rather than the details of programming.
Lean 作為證明器的主要成果,有大量的數學證明。
With below line in Lean prover
import Mathlib.Tactic.Observe
One can useexact?
,apply?
tactics to search in Lean4 library.
Julia was designed with technical and scientific users in mind. These users often have very large data sets or very complex mathematical problems that they want to solve. This means they want to write code that can run on a computer very quickly, so that they don’t have to wait days or even weeks to get a result. Most of the programming languages that run very fast are also quite a bit trickier to use than some “high level” languages that you might have heard of, like Python or Matlab. For example, C and Fortran are known to be very fast, but they require that the user provides a lot of information to the computer about the program they are writing as they write it. This takes more time and often more programming experience than working in a language like Python.
這個程式庫可以操作跟繪製範疇論相關的概念,由數個子專案組成。
The package ManifoldDiffEq aims to provide a library of differential equation solvers on manifolds. The library is built on top of Manifolds.jl and follows the interface of OrdinaryDiffEq.jl.
計算 Jacobian 矩陣與行列式
using ForwardDiffusing StaticArraysf(x,y) = @SVector [x^2 + y^3 - 1, x^4 - y^4 + x*y]a = [1.0,3.0]J = ForwardDiff.jacobian(x -> f(x[1],x[2]), a)using LinearAlgebraJ |> det
著重在創造語言的程式語言,主要的缺點是它真的太擅長創造新的語言了,整合其他人的程式碼並不容易,實際上僅適合個人研究/專案等用途。不過在程式語言理論中的工具相當齊全,這是一個好的採用理由。
這是一個定義形式系統跟化簡規則的工具,典型的用途是分析化簡的分支,對系統的公式支援多種輸出格式,另外它整合了 racket 的繪圖工具讓你直接看到化簡過程(下圖複製自教學網站)。
可以快速產生新的型別論的語言,而且各個規則可以模組化的定義,不需要寫在一起。
racket 內建的繪圖工具,對 3D 數學的支援良好(下圖複製自教學網站)。
Haskell 是一個函數式與多態並且相當在意不可變與惰性的程式語言,這個進入點用來記錄 Haskell 中好用的工具與程式庫。
安裝與版本管理工具,最常用到的指令是ghcup tui
,可以開啟 terminal UI 進行安裝與卸載操作。
進行文字解析的程式庫,特色是採用 parser combinator,是同類程式庫中目前功能最齊全的
OpenFlexibleContexts
extension can release the power of monad transformers, a simple example here
import Control.Monad.Exceptimport Control.Monad.Statefoo :: (MonadIO m) => (MonadError String m) => (MonadState Int m) => m ()foo = do liftIO $ putStrLn "hello" modify (+ 1) throwError "error"
The program
hello
these effects are able since the type class constraints areIO
,State Int
, andExcept String
. Then, we can instantized the function:
foo1 :: ExceptT String (StateT Int IO) ()foo1 = foofoo2 :: StateT Int (ExceptT String IO) ()foo2 = foo
let's take a look at how to invoke
main :: IO ()main = do (a, s) <- runStateT (runExceptT foo1) 0 putStrLn $ show a putStrLn $ show s
The output is
helloLeft "error"1
Even the program isfailed, you still get the state! However,foo2
gives a different result:
main :: IO ()main = do b <- runExceptT $ runStateT foo2 0 putStrLn $ show b
This program drop the state whenever the program failed. The result is
hello1
This is why the contexts are called flexible. The order of transformers is non-trivial, it can affect the behavior of the program. Two transformers bring two order, three bring six order, though not every permutation is useful or make different, but a flexible program maybe more polymorphic than one think. That maybe will not be your expectation, and hence, you might need to export a stable interface for your module, but inside of your module? Just let it free.
Dafny is a verification-aware programming language that has native support for recording specifications and is equipped with a static program verifier.
數學符號 | dafny 程式 |
---|---|
聯集 \(A \cup B\) | A + B |
交集 \(A \cap B\) | A * B |
差集 \(A \setminus B\) | A - B |
勢 \(|A|\) | |A| |
\(x \in A\) | x in A |
\(x \not \in A\) | x !in A or!(x in A) |
\(A \subset B\) | A < B |
\(A \subseteq B\) | A <= B |
F* (pronounced F star) is a general-purpose proof-oriented programming language, supporting both purely functional and effectful programming. It combines the expressive power of dependent types with proof automation based on SMT solving and tactic-based interactive theorem proving.
A lattice is aposet such that any two elements \(x, y\) of it have
A lattice is bounded if it has bothinitial and terminal.
For any two elements of lattice, there is apullback and pushout.
Any two elements has a product and coproduct, which means below diagram exists
and just likepreorder pullbacks are products reason, there has at most one \(x \sqcap y \to x \sqcup y\), so this diagram must be a pullback square, and must also be a pushout square.
Powersets \(\mathscr {P}(A)\) of a set \(A\) with \(\subseteq \) relation is a lattice, where
Let \(I\) be a topological space, its open sets \(\Theta \) with \(\subseteq \) forms a lattice \((\Theta , \subseteq )\) just likepowerset and lattice, since open sets \(\Theta \) will be a sub collection of \(\mathscr {P}(I)\).
A lattice \(A\) is said to bedistributive if admits the following law
\[x \sqcap (y \sqcup z) = (x \sqcap y) \sqcup (x \sqcap z)\]for all \(x, y, z \in A\), or equivalent version is \(x \sqcup (y \sqcap z) = (x \sqcup y) \sqcap (x \sqcup z)\).
In abounded lattice, \(y\) is acomplement of \(x\) if \(x \sqcup y = 1\) and \(x \sqcap y = 0\). A bounded lattice iscomplemented if each of its element has acomplement in the lattice.
Apullback is alimit of \(\bullet \rightarrow \bullet \leftarrow \bullet \); apushout is a colimit of \(\bullet \leftarrow \bullet \rightarrow \bullet \).
For any morphism \(f\) the below is pullback.
In theoriginal setup I already explain the configuration, to do the same with Protonmail will need to installProton 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>
A monomorphism isregular if it is theequalizer of a pair of arrows; an eipmorphism isregular if it is thecoequalizer of a pair of arrows.
An epimorphism isstrong if for every diagram \(z \circ u = v \circ f\), with \(z\) is mono,
there is a unique \(w : B \to X\) makes \(w \circ f = u\) and \(z \circ w = v\).
An epimorphism isstrong if and only if for every monomorphism \(g\), \(f\) isorthogonal to \(g\) (\(f\ \bot \ g\)).
An isomorphism \(\alpha \) is both mono and epic.
If \(f\) is a monic then below ispullback
and if \(g\) is an epic then below is a pushout
\(f\) is monic means \(fa = fb \implies a = b\), therefore, consider
if \(fa = fb\) then there are unique \(a'\) and \(b'\), where \(a = 1_\bullet a'\) and \(b = 1_\bullet b'\), makes \(f 1_\bullet a' = f 1_\bullet b'\), by mono we know \(1_\bullet a' = 1_\bullet b'\). Therefore, by cancel law we can only have \(a' = b'\), then \(a = b\).
Apply dual we get epic can reframe as a pushout.
If below ispullback and \(f\) is mono, then \(f'\) is mono.
First transform the square
The two small square behind are pullbacks,
, so the big square also a pullback. Now, transform to another view, which shares the same big square.
Consider the right small square is a pullback, leads left small square is a pullback as well; thus, the \(f'\) is mono.
The map \(\pi : [0,1] \to S^1\) defined by \(\pi (t) = (\cos (2\pi t), \sin (2\pi t))\) is a quotient map.
For two topological spaces \(X, Y\), their product topological space \(X \times Y\) is cartesian product of sets \(X\) and \(Y\), where open sets are cartesian product \(U \times V\) of all open sets \(U \subset X, V \subset Y\).
A simplicial set is apresheaf \(X : \Delta ^{op} \to Sets\) overthe category \(\Delta \), denote \(sSet = \widehat \Delta \) for the category of simplicial sets.
A \(n\)-simplex \(x\) is an element of \(x \in X_n := X([n])\).
With a fixed simplicial set \(X\), a \(n\)-simplex \(x \in X_n\) is said to bedegenerate if there is \(m\)-simplex \(y \in X_m\) (\(m < n\)) and a \(\alpha : [n] \to [m]\), such that \(\alpha ^* : X_m \to X_n\) satisfies
\[ x = \alpha ^*(y) \]In words, if there exists a lower \(m\)-simplex and a map from that to this \(n\)-simplex, then this \(n\)-simplex is degenerate.
A \(n\)-simplex is said to be non-degenerate, if it's not degenerate.
A set \(U\) is a subspace ofvector space \(V\) if alllinear combinations of vectors are closed.
Closed means results of the operation are still elements of subspace.
Let \(F\) be a field than \(\set {(x_1, x_2, 0) \mid x_1, x_2 \in F}\) is a subspace of \(F^3\).
A subset \(U\) of \(V\) is a subspace of \(V\) iff \(U\) satisfies below three conditions
Suppose \(U\) and \(W\) are subspaces of \(V\). Then \(U + W\) is adirect sum if and only if \(U \cap W = \{ 0 \}\)
An (co)equalizer is a (co)limit of the diagram
by \(eq(f,g)\) is the limit and \(coeq(f,g)\) is the colimit
Therefore, for two morphisms \(f, g : A \to B\) in a category \(C\), their equalizer (if existed) is an object \(eq(f, g)\) with a morphism \(eq(f, g) \xrightarrow {e} A\), such that \(f \circ e = g \circ e\), and given any \(h : C \to A\) satisfy \(f \circ h = g \circ h\), there is a unique factorization \(k\) let \(h = e \circ k\).
equalizer 是常見的等式類定義的範疇描述
\[\{ x^2 + 1 = 0 \mid x \in \R \}\]此例的 \(f(x) = x^2 + 1\) 而 \(g(x) = 0\)
The dual concept coequalizer is a colimit of same diagram, and hence the coequalizer (if existed) of \(f,g : A\to B\) is an object \(coeq(f,g)\) with a morphism \(c : B \to coeq(f,g)\) such that \(c \circ f = c \circ g\), and any \(h : A \to X\) satisfy \(h \circ f = h \circ g\) can be expressed as \(h = h' \circ c\) via a unique factorization \(h'\).
A factorization, of course, is a morphism.
coequalizer 是在函數局部相似處取值的函數的範疇描述,比如 holomorphic function 在複數平面 \(\mathbb {C}\) 中於 \(a\) 點局部相似就是在 \(|z - a| < r\) 的範圍內兩個 holomorphic functions 的展開式相同,這也被稱為 \(a\) 處此函數的 germs 類。
If \(E \xrightarrow {e} A\) is an equalizer, then \(e\) is amonomorphism.
If there is any \(f, g : C \to E\), due to \(C \to A\) has a unique \(C \to E\), therefore, \(f = g\) must be true.
A category with binary product and pullback admits equalizer.
We don't have to denote it as \(eq(f,g)\). Anyway, it's a pullback means \[(f,g) \circ e = (1_B, 1_B) \circ e\] , which admits \(f \circ e = g \circ e\).
If a category has equalizers andfinite products then it has finite limits.
Has all finite products means whatever singular points have a product, and has all equalizers means all multi-arrows has an equalizer, this is indeed all finite limits.
Acategory with attributes consists of:
Depedent types in context \(\Gamma \) are elements of \(\text {Ty}(\Gamma )\); object \(\Gamma .A\) represents the result of extending the context \(\Gamma \) by the type \(A\). Terms \(\Gamma \vdash a : A\) are interpreted as sections of map \[\Gamma .A \xrightarrow {p_A} \Gamma \]
Of course, equations can also rewrite to diagrams:
and composition of substituions
\(\bold {Fam}\) is a category of families of small sets, consists with
Acategory with families is a category \(\mathbb {C}\) with a distinguished terminal object \(\diamond \), and the following
such that for any two contexts \(\Gamma \), \(\Delta \) and morphism of them \(\Delta \xrightarrow {\sigma } \Gamma \) satisfy
Each element \(A \in \text {Ty}(\Gamma )\) is a dependent type \(\Gamma \vdash A\), and each element \(a \in \text {Tm}(\Gamma , A)\) is a term \(\Gamma \vdash a : A\).
An object \(I\) of \(\mathbb {C}\) is initial if for any other object \(A\), there is an unique morphism \(I \to A\).
An object \(T\) of \(\mathbb {C}\) is terminal if for any other object \(A\), there is an unique morphism \(A \to T\).
Mitchell-Benabou language, also known asinternal language oftopos, every term can beinterpreted as a morphism in the topos (in multiple ways), such that the final target is its type.
The simplicial category is formed by
we denote this category as \(\Delta \). There are two special maps in \(\Delta \):
For every \(n \ge 0\) and \(0 \le i \le n\), face maps are the maps
\[d_i : [n-1] \to [n]\]such that uniquely determined by \(i \not \in \text {Im}(d_i)\) and \(d_i\) is injective.
For every \(n \ge 1\) and \(0 \le i \le n-1\), degeneracy maps are the maps
\[s_i : [n] \to [n-1]\]such that uniquely determined by \(|s_i^{-1}(i)| = 2\) and \(s_i\) is surjective.
By definition, we have \(s_i(i) = s_i(i+1) = i\).
The standard \(n\)-simplex is the topological space
\[ \text {Simp}_{n} = \{ (x_0, \dots , x_{n-1}) \in [0,1]^n \mid \sum _i x_i = 1 \} \]so \(\text {Simp}_{0}\) is a point, \(\text {Simp}_{1}\) is a line, \(\text {Simp}_{2}\) is a triangle.
A category \(\mathbb {C}\) issmall-complete if for allsmall category \(\mathbb {S}\), the functor \(\mathbb {S} \to \mathbb {C}\) has a limit. We can narrow it to finite complete.
A category \(C\) isfinitely complete if it admits all finite limits, that means all limits for any diagrams \(F : J \to C\), where \(J\) is afinite category.
Let \(A, B\) be two finitely complete categories, afunctor \(F : A \to B\) isleft exact if it preserves finite limits.
Which means compose two left exact functors will get a left exact functor.
The category \(\text {Lex}(A, \bold {Set})\) is a full subcategory of the functor category \([A, \bold {Set}]\), where have only left exact functors.
Given a type theory \(T\), a syntactic category \(\text {Con}(T)\) given by
Let \(\Gamma \) and \(\Delta \) be contexts of a type theory \(T\)
\[ \Gamma = x_0 : A_0, x_1 : A_1(\overrightarrow {x_0}), x_2 : A_2(\overrightarrow {x_{1}}), ..., x_n : A_n(\overrightarrow {x_{n-1}}) \]and
\[ \Delta = y_0 : B_0, y_1 : B_1(\overrightarrow {y_0}), y_2 : B_2(\overrightarrow {y_{1}}), ..., y_m : B_m(\overrightarrow {y_{m-1}}) \]The \(\overrightarrow {x_n}\) notation expanded to \(x_0, ..., x_n\) that represents types can depends on eariler variables. Then a morphism \(\Gamma \to \Delta \) is a sequence of terms
\[\begin {aligned} &\Gamma \vdash \sigma _0 : B_0 \\ &\Gamma \vdash \sigma _1 : B_1(\overrightarrow {\sigma _0}) \\ &... \\ &\Gamma \vdash \sigma _m : B_m(\overrightarrow {\sigma _{m-1}}) \end {aligned}\]So a morphism of contexts is a sequence of terms satisfying requirement of target context \(\Delta \), where we should be able to construct these terms from source context \(\Gamma \). The abbreviation of these terms are \(\sigma = (\sigma _0, ..., \sigma _m)\). For any context with size \(n\), the identity substitution is obvious: its variables \(x_0, ..., x_n\).
The empty context is denoted as \(\bullet \), it's the terminal object ofthe category, this is obvious since only one way to satisfy the empty context: do nothing.
A type \(A\) isclosed, if it's derivable fromempty context \(\bullet \).
\[\bullet \vdash A \text { type}\]Any closed type can be viewed as a context by concat it back to empty context
\[\bullet , (\_ : A) = (\_ : A)\]by abusing the notation, we also say it's a context \(A\). In this sense, a closed term is a morphism \(\bullet \to A\), where \(A\) is a closed type.
If a type theory \(T\) has a closed type \(\N \),
\[\bullet \xrightarrow {(1,1)} (m : \N , n : \N ) \xrightarrow {m + n} \N \]the composition above is \(2 : \bullet \to \N \).
Syntactic category is highly related toclassifying categories, which is focusing on type's signature. If we must find a different, classifying categories are not with any fixed judgement rules, so they can be shared by different type theories. In fact, if a classifying category with axioms, denote as \(Cl(\Sigma , \mathcal {A})\), I believe it's the syntactic category here, since a type theory is made by signature and axioms (equation rules).
Unification is an usual operation in logic programming language and type system, for example, one can say "I let a is b" then ask "Is b equals to a?". This is very common thing, in polymorphic type system, we want to avoid type application again and again, especially when it's trivial to find. That's why we have unification algorithm. In polymorphic type system, we want to have a property: If \(A \cong B\), I can use \(A\) as \(B\) and vice versa. Therefore, an unification algorithm will receive a question like:
Is \(\text {List Nat} \cong \text {List } A\)? (In the sense that \(A\) is a type variable.)
By the structural recursion rule, that question can be break down to
If \(\text {Nat} \cong A\), then \(\text {List Nat} \cong \text {List } A\)
By the primitive rule, a variable is similar to anything with the same type. At here, they both have type \(\text {Type}\), so
\[A : \text {Type} \cong \text {Nat} : \text {Type}\]So the unification algorithm will judge they are the same type, users can pass \(\text {List Nat}\) as \(\text {List } a\). However, one must remember, once in a context we already verify an equation
\[A \cong \text {Nat}\]another equation will fail, for example
\[A \cong \text {Bool}\]this is because \(\text {Nat} \ncong \text {Bool}\). So \(f\ a\ b\) is an invalid term under context
\[ \bullet , f : \forall A : A \to A \to A, a : \text {Nat}, b : \text {Bool} \]The kernel of \(\varphi : G \to G'\) is a special kind subgroup of \(G\) such that\[ \text {ker } \varphi \ \dot {=} \ \{ g \in G \mid \varphi (g) = 1_{G'} \} = \varphi ^{-1}(1_{G'}) \]
Let \(\varphi : G \to G'\) be ahomomorphism, for any trivial map \(\varphi \circ \alpha \), the inclusion map \(\text {ker }\varphi \) from the kernel to \(G\), below diagram commutes
The kernel \(\text {ker }\varphi \) is anormal subgroup of \(G\).
Asubgroup \(N\) is anormal subgroup of \(G\) if for all \(g \in G\) and \(n \in N\) the condition holds
\[gng^{-1} \in N\]Another definition: A subgroup \(H\) of a group \(G\) is anormal subgroup if it isself-conjugate.
The kernel \(\text {ker }\varphi \) is anormal subgroup of \(G\).
A presheaf \(F\) of asmall category \(C\) is afunctor \(F : C^{op} \to \bold {Sets}\).
The set \(X_a\) via a presheaf \(X\) evaluates at an object \(a\) is sometimes called thefibre, the elements of \(X_a\) thus namedsections of \(X\) over \(a\).
Manifolds, Sheaves, and Cohomology
A elaborated version about presheaf \(\mathcal {F}\) on a topological space \(X\) consists of the following data:
such that the following conditions hold:
In this case, we denote the category of presheaves on \(X\) as \(\text {PSh(X)}\).
If \(U \subseteq V\) are open sets of \(X\) and \(s \in \mathcal {F}(V)\) we will usually use \(s \vert _U\) instead of \(\text {res}^V_U(s)\).
If we consider open sets of \(X\) as a category (morphisms are relation \(U \subseteq V\), denote \(\mathcal {O}(X)\)), then we can apply the categorical definition (Definition [math-002C]Definition [math-002C]).
A group \(H\) is called a subgroup of \(G\) if there is an inclusion function \(i : H \hookrightarrow G\) is agroup homomorphism.
Equivalent, a subgroup \(H\) is a subset of \(G\) containing the unit element, and \(H\) is closed under composition (if \(a,b\in H\) then \(ab\in H\)) and inverse (if \(x \in H\) then \(x^{-1} \in H\)).
A nonempty subset \(H\) of a group \(G\) is a subgroup (shares \(G\)'s operation) if and only if
\[\forall a, b \in H, \; ab^{-1} \in H\]If \(H\) is a subgroup, the element calculus of course closed under \(H\). Now, prove the oppsite that condition hold implies \(H\) is a subgroup. Since \(H\) is nonempty, there is an element \(h \in H\), by condition, we know
\[1_G = hh^{-1} \in H\]thus \(H\) has an identity. Let \(a = 1_G\) and \(b = h\), then we have
\[h^{-1} = 1_Gh^{-1} \in H\]thus \(H\) have inverses of its elements. Let \(a = x\) and \(b = y^{-1}\), get
\[x y = x (y^{-1})^{-1} \in H\]thus \(H\) is closed under the operation. Finally, since \(H\) shares \(G\)'s operation, the associative is preserved, proves \(H\) is a group.
The kernel of \(\varphi : G \to G'\) is a special kind subgroup of \(G\) such that\[ \text {ker } \varphi \ \dot {=} \ \{ g \in G \mid \varphi (g) = 1_{G'} \} = \varphi ^{-1}(1_{G'}) \]
Let \(\varphi : G \to G'\) be ahomomorphism, for any trivial map \(\varphi \circ \alpha \), the inclusion map \(\text {ker }\varphi \) from the kernel to \(G\), below diagram commutes
The kernel \(\text {ker }\varphi \) is anormal subgroup of \(G\).
Categorical Logic and Type Theory
A classifying category (or term model) \(Cl(\Sigma )\) is a category generated by term calculus on asignature \(\Sigma \).
Identity is ensured by use variables of the context as terms.
Composition
is a \(k\)-tuples \((L_1, ..., L_k)\) defined by simultaneous substitution \[L_i = N_i[M_1/v_1, ..., M_m/v_m]\]
For any two contexts \(\Gamma \) and \(\Delta \), the concatenation \(\Gamma , \Delta \) isthe product of them.
Atopos \(\xi \) is acategory with all finite limits, equipped with an object \(\Omega \), and for each \(\xi \)-object \(A\), there is an isomorphism forsubobjects of \(A\) and morphisms from \(A \to \Omega \).\[\text {Sub}_{\xi }(A) \cong \text {Hom}_{\xi }(A, \Omega )\]The condition also calledwell-powered, which ensures \(\Omega \) is a subobject classifier. Then, a functor \(P : \xi ^{op} \to \xi \) with condition\[\text {Hom}_{\xi }(B \times A, \Omega ) \cong \text {Hom}_{\xi }(A, PB)\]This also tells \(PB = \Omega ^B\). Thus, We can also combine them into one axiom.\[\text {Sub}_{\xi }(B \times A) \cong \text {Hom}_{\xi }(A, \Omega ^B)\]
We can also definetopos as acartesian closed category with asubobject classifier. This version is not that essential but convenience to work with, also
A model ofmany-typed signature \(\Sigma \) in a category \(B\) with finite products, is a functor \(\mathcal {M}\) fromclassifying category to \(B\) \[Cl(\Sigma ) \xrightarrow {\mathcal {M}} B\] preserving finite products. The category of \(B\)-models is a subcategory offunctor category \([Cl(\Sigma ), B]\) such that objects are models.
A subobject classifier in a category \(C\) with finite limits is amonic \(true : 1 \to \Omega \), such that for every monic \(m : S \rightarrowtail A\) there is a unique morphism \(\phi \) forms a pullback square.
By abuse of language, a subobject of \(A\) is an object \(S\) that with a monic \(m : S \rightarrowtail A\), or the monic \(m\). The class of subobjects of \(A\) is \(\text {Sub}_{C}(A)\).
A span is a \(\mathcal {C}\)-diagram \(A \leftarrow C \rightarrow B\), there is acategory of span with fixed \(\mathbb {C}\)-objects \(A, B\) is:
A product of two \(C\)-object \(a, b\) is an object \(p\) with a pair of morphisms\[a \xleftarrow {\pi _1} p \xrightarrow {\pi _2} b\], makes below diagram commutes, and the dashed line is unique.
We usually denoted product as \(a \times b\).The dual coproduct is an object \(c\) with a pair of morphisms\[a \xrightarrow {inj_1} c \xleftarrow {inj_2} b\], makes below diagram commutes, and the dashed line is unique.
We usually denoted coproduct as \(a + b\).
A span is a \(\mathcal {C}\)-diagram \(A \leftarrow C \rightarrow B\), there is acategory of span with fixed \(\mathbb {C}\)-objects \(A, B\) is:
A functor \(F : C \to D\) is a map fromcategory \(C\) to category \(D\), such that
\(C \to C\) functor is called endofunctor.
A presheaf \(F\) of asmall category \(C\) is afunctor \(F : C^{op} \to \bold {Sets}\).
The set \(X_a\) via a presheaf \(X\) evaluates at an object \(a\) is sometimes called thefibre, the elements of \(X_a\) thus namedsections of \(X\) over \(a\).
Manifolds, Sheaves, and Cohomology
A elaborated version about presheaf \(\mathcal {F}\) on a topological space \(X\) consists of the following data:
such that the following conditions hold:
In this case, we denote the category of presheaves on \(X\) as \(\text {PSh(X)}\).
If \(U \subseteq V\) are open sets of \(X\) and \(s \in \mathcal {F}(V)\) we will usually use \(s \vert _U\) instead of \(\text {res}^V_U(s)\).
If we consider open sets of \(X\) as a category (morphisms are relation \(U \subseteq V\), denote \(\mathcal {O}(X)\)), then we can apply the categorical definition (Definition [math-002C]Definition [math-002C]).
An object \(x\) is weakly initial if for every other object \(y\) there is a morphism \(x \to y\).
AF-algebra \((F, i, j)\) is an initial algebra if and only if \(F\ i\) is an initial object of thecategory of F-algebras.
Consider \(F\) is a fixed point we are seeking, then\[F' = \lambda f. F(f \; f)\]is a variant version of \(F\), by \(f \; f = f\) and \(F \; x = x\) we believing.Now, using substitution we can obtain \(F' F' = F(F' F')\), which means \(F' F'\) is the fixed point of \(F\).Therefore, we derived\[(\lambda f. F(f \; f)) (\lambda f. F(f \; f))\]and the Y combinator is\[\lambda F. (\lambda f. F(f \; f)) (\lambda f. F(f \; f))\]
If \(g \in G\) isan element of finite order, and \(\varphi : G \to H\) is ahomomorphism, then \( | \varphi (g) | \) divides \(|g|\).
A space \(X\) isHausdorff if and only if for every two points \(x, y \in X\) (where \(x \ne y\)), there exist disjoint open sets \(U\) and \(V\) with \(x \in U\) and \(y \in V\).
Let \(x, y\) be different points (\(x \ne y\)) in ametric space, we will get a distance \(d(x, y) > 0\), then we can see two open balls \(B_\epsilon (x)\) and \(B_\epsilon (y)\) (where \(\epsilon \le \frac {d(x,y)}{2}\)) are indeed disjoint.
Thecategory \(\text {Grp}\)'s objects are formed by all groups, and morphisms aregroup homomorphism.
考慮群 \(G\) 到群 \(H\) 的變換 \[\varphi : (G, m_G) \to (H, m_H)\] 時,除了這必然是個映射底層集合 \(G \to H\) 的函數之外,還希望能夠考慮到 \(m_G\) 的行為被保留。因此,將 group homomorphism 定義成滿足下圖交換的函數 \(\varphi \)
傳統寫法是 \(\varphi : G \to H\) 對所有 \(a, b \in G\) 須滿足 \(\varphi (a \cdot b) = \varphi (a) \cdot \varphi (b)\)
但為什麼這也能保證 unit 跟 inverse 也會被保留呢?想知道的人可以參考命題。
The statement can be expressed as: Let \(\varphi : G \to H\) be agroup homomorphism, then
For the first property, we use \[1_H \cdot \varphi (1_G) = \varphi (1_G) = \varphi (1_G \cdot 1_G) = \varphi (1_G) \cdot \varphi (1_G)\] as the lemma, by cancel \(\varphi (1_G)\) we get \(1_H = \varphi (1_G)\).
For the second part, we use \[ \varphi (a) \cdot \varphi (a)^{-1} = 1 = \varphi (1) = \varphi (a \cdot a^{-1}) = \varphi (a) \cdot \varphi (a^{-1}) \] as the lemma, by cancel \(\varphi (a)\) we get \(\varphi (a)^{-1} = \varphi (a^{-1})\).
import Mathlib.Algebra.Group.Defsimport Mathlib.Algebra.Hom.Group.Defs
Before we start to prove the proposition, we have to defineis_hom
for what's a homomorphism
def is_hom [Group G] [Group H] [MulHomClass F G H] (φ : F) : Prop := ∀ a b : G, φ (a * b) = φ (a) * φ (b)
Then below code proves the proposition
theorem preserve_identity [Group G] [Group H] [MulHomClass F G H] (φ : F) : is_hom φ → 1 = φ 1 := by intro H have inner_one : φ 1 = φ (1 * 1) := by refine Eq.symm (FunLike.congr_arg φ ?h₂) exact one_mul 1 have lem : 1 * φ 1 = φ 1 * φ 1 := by rw [one_mul <| φ 1, ← H] exact inner_one apply mul_right_cancel (a := 1) (b := φ 1) (c := φ 1) lem
theorem preserve_inv [Group G] [Group H] [MulHomClass F G H] (φ : F) : is_hom φ → ∀ a : G, (φ a)⁻¹ = φ a⁻¹ := by intro H a have lem : φ a * (φ a)⁻¹ = φ a * φ a⁻¹ := by refine Iff.mpr mul_left_cancel_iff ?_ refine DivisionMonoid.inv_eq_of_mul (φ a) (φ a⁻¹) ?_ rw [← H, mul_right_inv a] exact Eq.symm (preserve_identity φ H) exact mul_left_cancel (a := φ a) (b := (φ a)⁻¹) (c := φ a⁻¹) lem
安裝指令nix profile install <package name>
取代了nix-env -iA <package name>
A morphism \(A \xrightarrow {\phi } B\) is point-surjective iff for every point \(1 \xrightarrow {q} B\), there exists a point \(1 \xrightarrow {p} A\) that lifts \(q\) (satisfy \(\phi \circ p = q\)).
With below line in Lean prover
import Mathlib.Tactic.Observe
One can useexact?
,apply?
tactics to search in Lean4 library.
A morphism \(\phi : B \to C^A\) is weakly point surjective, iff for every \(A \xrightarrow {f} C\) there is \(1 \xrightarrow {x} B\) such that for every \(1 \xrightarrow {a} A\), we have commute diagram
The \(C^A \to C^A \times A\) is given by
This is a weaker version ofpoint-surjective.
A functor \(LC : Set \to Set\) takes any set of variables \(V\) to the set of term \(T = LC(V)\), this is theterm constructors' algebra. \[ \begin {aligned} &- : &V \to T \quad &\text {mbox variable} \\ &-(-) : &T \times T \to T \quad &\text {mbox abstraction} \\ &\lambda : &V \times T \to T \quad &\text {mbox application} \\ \end {aligned} \]
Consider \[\Omega = \omega (\omega )\] where \(\omega = \lambda x. x(x)\), it's easier to verify \(\Omega \downarrow _{\beta } \Omega \), an infinite loop. Now think about \[(\lambda x. \lambda y. x)(\lambda x. x)(\Omega )\], this example is interesting if we consider eager/lazy semantic. In the eager semantic, the result is stuck due to \(\Omega \), because we calculate \(\Omega \) before we use it as an argument. In the lazy semantic, the result is identity function \(\lambda x.x\).
The key point of the post is about:when \(\beta \)-reduction can happend anywhere in the term, there aretoo many 2-morphisms to model lazy lambda calculus. Therefore, the post suggests introducing reduction context \[[-] : T \to T\] into the algebra above, for marking where we can do \(\beta \)-reduction. The new rules are
The post also suggests if we replace rule \[[t(t')] \downarrow _{\text {ctx}} [[t] (t')]\] with \[[t(t')] \downarrow _{\text {ctx}} [t] (t')\] the number of occurences of \([ - ]\) will never increase. Then \([[ \cdots [t] \cdots ] ]\) the number of \(\beta \)-reductions are bound. In the paper, they reuse this way to representa processor or computer in a network.
Below implements a part of the system.
inductive Tm : Type where | var : String → Tm | app : Tm → Tm → Tm | lam : String → Tm → Tm | ctx : Tm → Tmdef Tm.subst (t : Tm) (s : Tm) (x : String) : Tm := match t with | .var y => if x == y then s else .var y | .app t u => .app (t.subst s x) (u.subst s x) | .lam y b => if x == y then .lam y b else .lam y (b.subst s x) | .ctx t => .ctx (t.subst s x)def Tm.r : Tm → Tm | .ctx (.app t t') => .ctx (.app (.ctx t |> r) t') | t => tdef Tm.β : Tm → Tm | .ctx (.app (.ctx (.lam x t)) t') => subst (.ctx t) t' x | .ctx t => .ctx (t.β) | .app t t' => .app t.β t' | t => tdef ω : Tm := .lam "x" (.app (.var "x") (.var "x"))def Ω : Tm := (.app ω ω)def e : Tm := (.ctx (.app (.app (.lam "x" (.lam "y" (.var "x"))) (.lam "x" (.var "x"))) Ω))#eval e#eval e.r#eval e.r.β#eval e.r.β.β
Quarto 這個工具有相當多功能,我只是想要移植以往放在 hackmd 上的簡報,因為簡報使用了 graphviz 的功能,所以我沒有辦法像hami2023 那樣直接嵌入這個網站裡面,至少 reveal.js 內建的功能沒辦法如此。而quarto render
產生的網頁也一樣有問題,所以最後type cafe2023 跟hami2022 還是放到了獨立的專案之中,用 GitHub Pages 運作。這篇筆記因而誕生,首先要用
quarto create-project <name>
產生一個專案,接著就能進去改檔案了。在<name>.qmd
裡面安插
title: "XXX"author: "your name"format: revealjs
也可以更進一步的設定 reveal.js 的選項
format: revealjs: theme: dark
接著可以用quarto preview
觀察簡報的狀態。對於我需要的 graphviz 功能,可以在檔案中寫下
```{dot}graph G { layout=neato run -- intr; intr -- runbl; runbl -- run; run -- kernel; kernel -- zombie; kernel -- sleep; kernel -- runmem; sleep -- swap; swap -- runswap; runswap -- new; runswap -- runmem; new -- runmem; sleep -- runmem;}```
最後,下列指令就可以自動發布 GitHub Pages 了(要先確認git remote origin
連結到的專案確實能發佈 Pages)。
quarto publish gh-pages
Proof net 是 Girard 的 linear logic 引入的一種新語法,用圖去表現證明,在研究 cut-elimination 時更加方便。
Polymorphic type in System F severely constrain the behavior of their elements. For example, if \(i : \forall (t.t \to t)\), then the definition can only be \(i = \lambda x.x\).
Similarly, there only have two terms, \[\Lambda t. \lambda x : t. \lambda y : t. x\] and \[\Lambda t. \lambda x : t. \lambda y : t. y\] with type \(\forall (t.t\to t\to t)\).
Such thing that, properties of a program in System F can be knowing by type known as parametricity properties.
I use gmail, and hence, I need toget 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 usegit send-email
command:
git switch -c branch-patchgit format-patch maingit 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 viagit config --edit
, and add below to omit email list in command line.
[sendemail] to = <target email list>
Compactness and Contradiction
Let \(P\) be a program that takes a string \(S\) as input, returns a yes-no answer \(P(S)\) as output, and which always halts in finite time. Then there exists a string \(G\) that is a program with no input, such that if \(P\) is given \(G\) as input, then \(P\) does not determine correctly whether \(G\) halts in finite time.
FromCompactness and Contradiction
Let \(C\) be a partially ordered class with
Compactness and Contradiction
Let \(f : \N \to \N \) be a computable function. Then there exists a natural number \(n\) and a program \(G\) of length \(n\) (taking no input) that halts in finite time, but requires more than \(f(n)\) steps before it halts.
For acategory \(C\) and an object \(x \in C\), there is a slice category \(C/x\) and a coslice category \(x/C\) (dual concept).
\(C/x\)-objects are all \(C\)-morphisms where target is \(x\), \(C/x\)-morphisms are all \(C\)-morphism \(g\) where makes the following diagram commutes:
\(x/C\)-objects is dual, they are \(C\)-morphisms where source is \(x\).
It's easy to prove the statement by checking the following diagram is commute.
or we can also reduce the diagram to
Draw a \(A/a\) diagram makes it clear, the following relationship stands for every proper \(b\) in \(A\).
The functor \(f_*\) takes any object \(g : b \to a\) of \(A/a\) to \(f \circ g\) of \(A/b\).
The first point is realizing if such \(f\) existed, then we have same two \(b, b'\), for both \(a, a'\), by concating \(f\) after every \(b \to a\) morphism. This makes sure we will have if objects existed in \(A/a\) so do in \(A/a'\), remember functor no need to cover \(A/a'\). Now, we can have the proof diagram:
Convert it to a functor diagram will help.
The \(\bold {Sets}/I\) is a category with
Combine withtopos fundamental theorem, the category ofpresheaves is atopos.
For any twocategories \(C, D\), theirfunctors and natural tranformations form a category, denotes \([C, D]\) or \(D^C\).
Here is a proof in Lean4.
variable (A B : Prop)theorem h (a : A ↔ (A → B)) : B := match a with | ⟨f, g⟩ => f (g (λ a => f a a)) (g (λ a => f a a))
Go 語言的 interface,範例如下
type Abser interface {Abs() float64}
其中的Abs() float64
可以被改寫成抽象語法Abs : () -> float64
。因此一個 interface \(A\) 有一組與其關聯的一系列簽名 \(\hat P\)。並且,對 Go 而言下列的兩個 interface 並沒有差異
type A interface {F(C) D}type B interface {F(C) D}
因此我們可以更進一步認為 Go 的一個 interface \(A\) 可以完全由其簽名 \(\hat P\) 替換。
If a small category \(\mathcal {C}\) hasonly one object, andeach morphism is an isomorphism, then there is a group detected by the category.
Category \(\mathcal {C}\) | Group \(G\) |
---|---|
morphisms in \(\mathcal {C}\) | elements of the group |
composition of morphism | The binary operation of the group |
identity morphism of the only object | identity element of the group |
在 Java 之中可以定義 interface,範例如下
interface Comparable<T> { int compareTo(T other);}
相較於Go 中不用明確宣告,在 Java 中實現 interfaceI
需要寫成class T extends I
,因此雖然 Java 的 interface \(A\) 也有其相關的一組簽名 \(\hat P\),但兩個有同樣簽名 \(\hat P\) 的 interface 不是同一個型別。
而在 Java 中 bounded polymorphism 指的是以下的 interface 使用方法:
<S extends Comparable> S min(S a, S b)
這會使得沒有明確宣告實現Comparable
的型別無法被傳為min
的引數。
We usual define a preorder is a set \(X\) with a binary relation \(\le \), where the relation is reflexive and transitive.
Every preorder can also be viewed as a small category, where all composition morphism of \(A \to B\) and \(B \to C\) is the unique morphism \(A \to C\). Or we say there is at most one morphism from one object to another.
#lang rhombusoperator n^m: ~stronger_than: + math.expt(n, m)
951413^7 + 853562^7 = 1035740599994317978862520154990926528420925
1005025^7 = 1035709726461858968099232282235113525390625
For example, one cancd /usr/local
and search simdjson library related files
find . -name 'simdjson*'
A \(\omega \)-chain \((x_n)_{n\in \omega }\) in partial order \(D\) is a set of elements \(x_n \in D\) such that \(x_n \sqsubseteq x_m\) whenever \(n \le m\).A partial order \(D\) is \(\omega \)-complete (and hance an \(\omega \)-cpo) if every \(\omega \)-chain has a least upper bound.Given \(\omega \)-cpo's \(D\) and \(E\), a monotone function \(f : D \to E\) is said to be \(\omega \)-continuous if
\[ f(\bigsqcup _{n\in \omega } x_n) = \bigsqcup _{n\in \omega } f(x_n) \]for any \(\omega \)-chain \((x_n)_{n\in \omega }\).
\(\omega \)-chain preserves it's least upper bound with \(\omega \)-continuous function.
Suppose \(D\) is \(\omega \)-cpo and \(f : D \to D\) is \(\omega \)-continuous.For \(x \in D\) such that \(x \sqsubseteq f(x)\), there is a least element \(y \in D\) such that
If \(D\) isa pointedcpo and \(f : D \to D\) iscontinuous, then it hasa least fixed point \(\text {fix}(f) \in D\) that satisfied
Instead of usual definition, theVector
inLean Prover is based onsubtype.
def Vector (α : Type u) (n : ℕ) := { l : List α // l.length = n }
Three ways of writing factorial
fun factorial(x): match x | 0: 1 | n: n * factorial(n-1)fun| factorial(0): 1| factorial(n): n * factorial(n-1)operator n!: ~stronger_than: + - * / match n | 0: 1 | _: n * (n - 1)!
def T : Nat -> Type | 0 => Unit | .suc _ => Boolinductive Int : Type where | mk : (n : Nat) -> T n -> Int
Therefore, the definition has
Int.mk 0 ()
for \(0\)Int.mk n true
for positive integer \(n\)Int.mk n false
for negative integer \(-n\)For the same number indeed has definitional equality.
By introduce a indirect level of universe \(\mathcal {U}^-\), such that a subtype of normal universe \(\mathcal {U}\), and allows pattern matching.By restricting it can only be used at inductive type definitions' dependent position, it preserves parametricity, solvesthe problem easier compare withsubscripting universe.In this setup, every defined type has type \(\mathcal {U}^-\) first, and hence
\(\mathbb {L}\) didn't depend on \(\mathcal {U}^-\), so we keep using tagless encoding to explain
data Term Type | ℕ => add (Term ℕ) (Term ℕ) | 𝔹 => eq (Term ℕ) (Term ℕ) | a => if (Term 𝔹) (Term a) (Term a) | a => lit a
We have \(\text {Term} : \mathcal {U}^- \to \mathcal {U}^-\), and then, if one wantsList (Term Nat)
it still work since \(\mathcal {U}^- \le \mathcal {U}\). But if one tries to define code below:
inductive Split Type^ | Nat => nat | Bool => bool | _ => elsedef id (A : Type) (x : A) : A => match Split A | nat => 0 | bool => false | _ => x
Since the \(\mathcal {U}\) isn't the subtype of \(\mathcal {U}^-\), programSplit A
won't type check, the definition will not work as intended. This is indeed more boring than subscripting universe, but easier to check it does't break parametricity.
Till now, I haven't start to check the pattern of type, except the primitiveexact value, if I'm going to push this further, a good example is:inductive K Type^ | List a => hi a | _ => heThis is quite intuitive since in implementation inductive types' head are also rigid values, just like constructors.
For each process:
shared scheduler_lock : SpinLockshared ready_list : queue threadprivate current_thread : threadprocedure reschedule() t : thread loop t := ready_list.dqueue() if t != null exit scheduler_lock.release() scheduler_lock.acquire() transfer(t)procedure yield() disable_signals() scheduler_lock.acquire() ready_list.enqueue(current_thread) reschedule() scheduler_lock.release() reenable_signals()procedure sleep_on(Q : queue thread) Q.enqueue(current_thread) reschedule()
Fluid Binding | Default | Meaning |
---|---|---|
\transclude/title | (none) | To override the tree's title during transclusion. |
\transclude/taxon | (none) | To override the tree's taxon during transclusion. |
\transclude/toc | true | Show the tree in the table of contents. |
\transclude/expanded | true | Whether the tree is expanded or not. |
\transclude/heading | true | If set tofalse , the tree's contents will be inlined. |
\transclude/metadata | false | Show in a tree's heading. |
\transclude/numbered | true | Whether the tree is displayed with a number or not, transitively on subtrees. |
Elements of ∞-Category Theory §A.1
Acategory \(\mathcal {V}\) iscartesian closed when it
The introduction version about cartesian closed is focusing on a category has
Of course, this is equivalent toDefinition [math-002H].
An intutive extension of inductive types is, let constructor be subscripting set of the inductive type. For example, a type with definition
inductive Nat | zero | suc Nat
A typeNat[suc]
means onlysuc ...
is a term,zero
cannot have typeNat[suc]
. It's easy to seeNatNonZero = Nat[suc]
, this can also apply to
List1 = List[cons]
Int
is also a good motive exampleinductive Int | 0 | + Int[+, zero] | - Int[-, zero]
Int[+]
is positive,Int[-]
is negative. The diagram in its syntactic category:To ensure this, if the following syntax of each constructorc
is a list of argument typesTi ...
, we say the type of constructor of typeT
isTi ... -> T[c]
. The corresponding part is pattern matching's type rules will refine typeT
with the pattern matched constructorc
, below marks all binder's refined type. The typeT[c, ...]
is a subtype ofT
.
def foo : Int -> Int | 0 => 0 | + p => -- p : Int[+, 0] p | - n => -- n : Int[-, 0] n
An obvious problem is
def neg : Int -> Int | 0 => 0 | + p => - (neg p) | - n => + (neg p)
We can see that the type information issqueezed, the second and third case need type casting. A potential solution is case type, and hence,neg
has type like:
But then what's the type rule of it? Will need some time to explore.
Category Theory for Programmers andSeven Sketches in Compositionality: An Invitation to Applied Category Theory.
Let \(\mathcal {V}\) be amonoidal category, and say it's the base category.
A category is a \(\mathcal {V}\)-enriched category (or \(\mathcal {V}\)-category) if
we may also say it's enriched from \(\mathcal {V}\).
NOTE: InElements of ∞-Category Theory the enrichment is more specific than this, the base category shall be acartesian closed category.
Seven Sketches in Compositionality: An Invitation to Applied Category Theory
Let \(\mathcal {V} = (V, \le , I, \otimes )\) be asymmetric monoidal preorder. A \(\mathcal {V}\text {-category}\) \(\mathcal {X}\) consists of two contituents
they satisfy two propreties
We call \(\mathcal {V}\) thebase of enrichment for \(\mathcal {X}\), or say that \(\mathcal {X}\) is enriched in \(\mathcal {V}\).
\(\bold {Bool}\)-categories arepreorders. Notice that, \(\bold {Bool}\) itself is a preorder, and hence, \(\bold {Bool}\) enriches itself.
The monoidal structure denotes \(\bold {Bool} = (\mathbb {B}, \le , \text {true}, \land )\),
\(\land \) | \(\text {false}\) | \(\text {true}\) |
---|---|---|
\(\text {false}\) | \(\text {false}\) | \(\text {false}\) |
\(\text {true}\) | \(\text {false}\) | \(\text {true}\) |
從 preoder 構造 \(\bold {Bool}\)-category 的方法是把 \(a \to b\) 標記為 \(a \le b = \text {true}\),否則 \(a \le b = \text {false}\),然後表列出來,熟悉圖論的讀者就可以發現這正好是普通圖的矩陣;從 \(\bold {Bool}\)-category 構造 preorder 的方式是把表列的元素先畫成點,再把值為 \(\text {true}\) 的部分作為邊繪出,最後捨棄出自傳遞性的邊。
A Lawvere metric space is aCost-categories, theCost defines as below
Let \([0,\infty ]\) denote the set of nonnegative real numbers tigether with \(\infty \). Consider the preorder \(([0,\infty ], \ge )\), with the usual notion of \(\ge \), where \(\infty \ge x\) for all \(x \in [0, \infty ]\).
A monoidal structure on this preorder is
\[ \bold {Cost} := ([0,\infty ], \ge , 0, +) \], where \(x + \infty = \infty \) for all \(x \in [0,\infty ]\).
這個結構可以對應權重圖,把每個存在的直接邊的權重寫到乘法表中,非直接邊就記成 \(\infty \),自己到自己則記成 \(0\);逆向的時候把權重邊畫出即可。
但要注意圖對應的 category size
\(d(\nearrow )\) | A | B | C | D | E |
---|---|---|---|---|---|
A | \(0\) | \(\infty \) | \(3\) | \(\infty \) | \(\infty \) |
B | \(2\) | \(0\) | \(\infty \) | \(3\) | \(\infty \) |
C | \(4\) | \(\infty \) | \(0\) | \(\infty \) | \(\infty \) |
D | \(\infty \) | \(\infty \) | \(\infty \) | \(0\) | \(\infty \) |
E | \(\infty \) | \(\infty \) | \(5\) | \(6\) | \(0\) |
Suomea | English |
---|---|
Jää on kylmää. | Ice is cold. |
Marja on pieni ja sininen. | The berry is small and blue. |
Puro on jäässä. | The stream is frozen. |
Koko puro on jäässä. | The whole stream is frozen. |
Koko perhe etsii poroa. | The whole family is looking for the reindeer. |
Karhu seisoo kylmässä purossa. | The bear is standing in the cold stream. |
Harmaa velho kävelee metsässä. | The gray wizard walks in the forest. |
Japanese | 中文 |
---|---|
うどん | 烏龍麵 |
うどん ていし よくはいくら ですか | 烏龍麵定食要多少錢? |
ラーメン を ひとつ ください | 請給我一碗拉麵 |
コーピー を ふたつ ください | 請給我兩杯咖啡 |
根據parametricity properties,對於類型 \(\forall X. X \to X\),可以發現其唯一的元素正是 \(\Lambda X. \lambda x. x\);而對於類型 \(\forall X. X \to X \to X\) 則有唯二的元素
因此也可以定義 \(1 = \forall X. X \to X\) 跟 \(2 = \forall X. X \to X \to X\),這個定義很容易推廣到任意整數。更有趣的是我們能定義出一個 \(V\) 滿足 \(V \cong (V \to 2) \to 2\),用集合論解釋的話就會發現這導引出 \(V\) 的 powerset 小於自己,在集合論中是矛盾的,因此System F 無法用集合論作模型。
With adisplay function \(\varphi : X \to I\), we say
The \(\bold {Sets}/I\) is a category with
Combine withtopos fundamental theorem, the category ofpresheaves is atopos.
The \(\bold {Sets}^{\to }\) is a category with
好處
類區分為兩種:一種是可以順利進行類運算的「良性類」,我們把這種「良性類」稱為集合;另一種是要限制運算的「本性類」,對於本性類,類運算並不是都能進行的。 在數學導論中有更完整的背景介紹為何要定義的如此複雜。
當集合 \(A\) 對任意 \(\epsilon > 0\) 都存在一組為可數多個的區間 \(I_k\),滿足全部 \(I_k\) 可以蓋住 \(A\) \[ A \subseteq \bigcup _{k=1}^{\infty } {I_k} \] 跟所有 \(I_k\) 的長度和小於 \(\epsilon \) \[ \sum _{k=1}^{\infty }{\mathcal {L}(I_k)} < \epsilon \] 兩個條件
其中 \(\mathcal {L}\) 的定義是區間的長度,比如 \([a, b]\) 跟 \((a, b)\) 的長度都是 \(b-a\)
但這種方法只能對一種特定的 interpreter 擴展
def naive_lit (x : Int) : Int := xdef naive_add (a b : Int) : Int := a + b
可以對任意 interpreter 擴充
class Expr (α : Type) where lit : Int → α add : α → α → αdef lit [e : Expr α] : Int → α := e.litdef add [e : Expr α] : α → α → α := e.add
這可以讓我們寫出下面的使用案例
instance : Expr Int where lit x := x add a b := a + binstance : Expr String where lit x := s!"{x}" add a b := s!"{a} + {b}"def expr [Expr α] : α := add (lit 1) (lit 2)#eval (expr : String) -- "1 + 2"#eval (expr : Int) -- 3
這個編碼確實對任意 interpreter 都可以擴充,舉例來說
class ExprSub (α : Type) where sub : α → α → αinstance : ExprSub Int where sub a b := a - binstance : ExprSub String where sub a b := s!"{a} - {b}"def sub [e : ExprSub α] : α → α → α := e.subdef expr [Expr α] [ExprSub α] : α := sub (add (lit 1) (lit 2)) (lit 3)#eval (expr : String) -- "1 + 2 - 3"#eval (expr : Int) -- 0
可以看到只要增加新的約束,interpreter 就會被擴充。但這個編碼要是遇到不同型別就會掛掉,所以需要引入一層 type 函數
Type → Type
)[#269]除了 expression 的編碼,也一併定義這裡要支援的兩個 interpreter
class FTExpr (f : Type → Type) : Type where lit : Int → f Int add : f Int → f Int → f Int compare : f Int → f Int → f Bool@[reducible]def Pretty (_ : Type) : Type := Stringinstance : FTExpr Pretty where lit x := s!"{x}" add a b := s!"{a} + {b}" compare a b := s!"{a} =? {b}"@[reducible]def Eval (α : Type) : Type := αinstance : FTExpr Eval where lit x := x add a b := a + b compare a b := a == b
使用起來這也比較複雜一點,我們要定義一串有點亂的程式
def ftlit [e : FTExpr f] : Int → f Int := e.litdef ftadd [e : FTExpr f] : f Int → f Int → f Int := e.adddef ftcompare [e : FTExpr f] : f Int → f Int → f Bool := e.comparedef ft_expr [FTExpr f] : f Bool := ftcompare (ftlit 3) (ftadd (ftlit 1) (ftlit 2))def ft_expr2 [FTExpr f] : f Int := ftadd (ftlit 1) (ftlit 2)
現在可以驗證看看結果
#eval (ft_expr : Eval Bool) -- true#eval (ft_expr : Pretty Bool) -- "3 =? 1 + 2"#eval (ft_expr2 : Eval Int) -- 3#eval (ft_expr2 : Pretty Int) -- "1 + 2"
你可以像前面那樣增加其他的運算機制到 interpreter 上來檢驗是否可以達到
在okmij 中可以找到更多對 tagless final 的研究,但對我來說現在這樣應該就夠了 XD
OpenFlexibleContexts
extension can release the power of monad transformers, a simple example here
import Control.Monad.Exceptimport Control.Monad.Statefoo :: (MonadIO m) => (MonadError String m) => (MonadState Int m) => m ()foo = do liftIO $ putStrLn "hello" modify (+ 1) throwError "error"
The program
hello
these effects are able since the type class constraints areIO
,State Int
, andExcept String
. Then, we can instantized the function:
foo1 :: ExceptT String (StateT Int IO) ()foo1 = foofoo2 :: StateT Int (ExceptT String IO) ()foo2 = foo
let's take a look at how to invoke
main :: IO ()main = do (a, s) <- runStateT (runExceptT foo1) 0 putStrLn $ show a putStrLn $ show s
The output is
helloLeft "error"1
Even the program isfailed, you still get the state! However,foo2
gives a different result:
main :: IO ()main = do b <- runExceptT $ runStateT foo2 0 putStrLn $ show b
This program drop the state whenever the program failed. The result is
hello1
This is why the contexts are called flexible. The order of transformers is non-trivial, it can affect the behavior of the program. Two transformers bring two order, three bring six order, though not every permutation is useful or make different, but a flexible program maybe more polymorphic than one think. That maybe will not be your expectation, and hence, you might need to export a stable interface for your module, but inside of your module? Just let it free.
With a fixed diagram \(\mathcal {D} \xrightarrow {F} \mathcal {C}\) and existing natural transformations \(\Delta _c \to F\), we get a category that consituited by
\(\Delta _c\) is a functor \(- \mapsto c : \mathcal {D} \to \mathcal {C}\) various on different \(c \in \mathcal {C}\).
Dual natural transformations \(F \xrightarrow {\beta } \Delta _c\) form cocones and a dual category.
With a fixed diagram \(\mathcal {D} \xrightarrow {F} \mathcal {C}\), alimit is aterminal of thecategory of cones, denoted as \(\lim _{\mathcal {D}} F\).
- notice that we can freely abuse language and say a \(\mathcal {C}\)-diagram is a functor target to \(\mathcal {C}\)
- Limit might not exist, so you have to ensure there has one.
The dual conceptcolimit is aninitial ofcategory of cocones, denoted as \(\underset {\mathcal {D}} {\text {colim}}F\).
The benefit of theidea is clear, but it disallows definition liketagless interpreter:
data Term : Set → Set1 where lit : ∀ {a} → a → Term a add : Term ℕ → Term ℕ → Term ℕ eq : Term ℕ → Term ℕ → Term 𝔹 if : ∀ {a} → Term 𝔹 → Term a → Term a → Term aeval : ∀ {a} → Term a → aeval (lit x) = xeval (add x y) = eval x + eval yeval (eq x y) = eval x == eval yeval (if c t e) with eval ceval (if c t e) | true = eval teval (if c t e) | false = eval e
NOTE: There is a workaround in paper, and hence, the problem is inconvenience instead of impossible.
這裡列出重要的兩個定義:
type Env = [(Name, Val)]type Ctx = [(Name, VTy)]
下面逐步介紹整個型別檢查的元件
在最上層的程式中,推導函數會直接被調用來得出 term 的 type,它會適當的調用check
去檢查是否有型別錯誤
infer :: Env -> Ctx -> Raw -> M VTyinfer env ctx = \case SrcPos pos t -> addPos pos (infer env ctx t) Var x -> case lookup x ctx of Just a -> return a Nothing -> report $ "Name not found: " ++ x U -> return VU t :@ u -> do tty <- infer env ctx t case tty of VPi _ a b -> do check env ctx u a return $ b $ eval env u tty -> report $ "Cannot apply on: " ++ quoteShow env tty Lam {} -> report "cannot infer type for lambda expression" Pi x a b -> do check env ctx a VU check ((x, VVar x) : env) ((x, eval env a) : ctx) b VU return VU Let x a t u -> do check env ctx a VU let ~a' = eval env a check env ctx t a' infer ((x, eval env t) : env) ((x, a') : ctx) u
SrcPos
這個情況只需要加上位置訊息之後往下 forward 即可t :@ u
) 也就是函數套用 (\(\beta \)-reduction) 的情況就比較複雜了t
得到tty
tty
不是一個函數型別 (\(\Pi \) type) 那麼就回報錯誤tty
的形式就會是 \(\Pi (x:A) \to B\),這時候要檢查u
是否是一個 \(A\)u
就會得到型別 \(B\ x\),也就是目標let x : a = t in u
,推導的過程如下a
是型別a
得到a'
,因為要從Tm
變成Val
(也就是化簡過的a
)t
的型別是否是a'
x : a'
與x = t
的綁定資訊推進 context 與 environment 再拿它們去推導u
最後使用infer
時,就像是這樣 (...
是省略號):
tm <- parse ...case infer [] [] tm of Left err -> ... Right ty -> ...
檢查函數接收一個 term 跟一個 type 用來找出 term 實際類型不匹配 type 的情況
check :: Env -> Ctx -> Raw -> VTy -> M ()check env ctx t a = case (t, a) of (SrcPos pos t, _) -> addPos pos (check env ctx t a) (Lam x t, VPi (fresh env -> x') a b) -> -- after replace x in b -- check t : bx check ((x, VVar x') : env) ((x, a) : ctx) t (b (VVar x')) (Let x a' t' u, _) -> do check env ctx a' VU let ~a'' = eval env a' check env ctx t' a'' check ((x, eval env t') : env) ((x, a'') : ctx) u a _ -> do tty <- infer env ctx t unless (conv env tty a) $ report (printf "type mismatch\n\nexpected type:\n\n \%s\n\ninferred type:\n\n \%s\n" (quoteShow env a) (quoteShow env tty))
SrcPos
這個情況只需要加上位置訊息之後往下 forward 即可fresh env -> x'
x
跟x'
可能是同名的,fresh
確保了它們不會被搞混expression -> pattern
x = x'
跟x : A
t
(lambda 的 body)的型別是不是 \(B\ x\)檢查 lambda 的方式就是讓 lambda 跟 \(\Pi \) 套用同一個參數之後再看一次
u
在新環境下是不是check
拿到的那個 type 而不是去推導u
infer
找出 term 的型別,然後讓它跟check
拿到的 type 做 conversion check化簡函數就是把 term 變成 value 的過程,它只需要 environment 而不需要 context
eval :: Env -> Tm -> Valeval env = \case SrcPos _ t -> eval env t Var x -> fromJust $ lookup x env t' :@ u' -> case (eval env t', eval env u') of (VLam _ t, u) -> t u (t, u) -> VApp t u U -> VU Lam x t -> VLam x (\u -> eval ((x, u) : env) t) Pi x a b -> VPi x (eval env a) (\u -> eval ((x, u) : env) b) Let x _ t u -> eval ((x, eval env t) : env) u
SrcPos
一如既往的只是 forwardVApp
儲存這個結果,conversion check 裡面會講到怎麼處理這些東西VApp
也常被叫做 spine
\u -> ...
u
去擴展 environment,也就是(x, u) : env
t
(在 \(\Pi \) 的情況就是執行b
)卡住在 dependent type 裡非常常見,舉例來說你有個函數
foo : (f : A -> U) -> (a : A) -> f a
在檢查foo
時執行到f a
就沒辦法被化簡,因為此時我們拿到的f
是一個VVar "f"
而不是VLam x t
conversion 是在 environment 中判斷兩個 value 是否能夠互相轉換的函數,對型別來說就是在判斷兩個型別是否相同
conv :: Env -> Val -> Val -> Boolconv env m n = case (m, n) of (VU, VU) -> True (VPi (fresh env -> x) a b, VPi x' a' b') -> conv env a a' && conv ((x, VVar x) : env) (b (VVar x)) (b' (VVar x)) (VLam (fresh env -> x) t, VLam x' t') -> conv ((x, VVar x) : env) (t (VVar x)) (t' (VVar x)) (VLam (fresh env -> x) t, u) -> conv ((x, VVar x) : env) (t (VVar x)) (VApp u (VVar x)) (u, VLam (fresh env -> x) t) -> conv ((x, VVar x) : env) (VApp u (VVar x)) (t (VVar x)) (VVar x, VVar x') -> x == x' (VApp t u, VApp t' u') -> conv env t t' && conv env u u' _ -> False
x
能不能讓兩個 \(B\ x\) 轉換VApp u (VVar x)
跟t (VVar x)
可以轉換,當x = VVar x
u
t
If \(h \in G\) is an identity of group \(G\), then \(h = 1_G\).
Let \(f\) has inverse \(a\) and \(b\), then \(a = b\)
racket 8.7 這次我比較晚更新,才發現我居然用了快 10 秒才想到下面的 migrate 指令,所以我覺得要把流程紀錄一下。 下載網站就和過去的發佈一樣在 https://download.racket-lang.org/,只要根據自己的電腦選擇合適的版本即可。
這邊是跟 executable 有關的設定,下面會為 macOS 特化
export PATH=/Applications/Racket\ v8.7/bin:$PATHexport PATH=$HOME/Library/Racket/8.7/bin:$PATH
這可以把之前安裝的東西搬到新家
raco pkg migrate 8.6
GPG 還蠻麻煩的,所以順手紀錄一下整個流程順便複習自己的知識
用gpg --list-secret-keys --keyid-format=long
讀出 keys
要是你還沒有 key,那麼就需要 gpg --gen-key 先生成一把
gpg --default-new-key-algo rsa4096 --gen-key
它會詢問
注意要是你的 gpg key 還需要能夠加密的話,就需要用gpg --full-generate-key
並選擇正確的選項。
要讓 git 採用 gpg 簽名,首先要設定
git config commit.gpgsign true
你會輸入git config --global user.signingkey <keyid>
讓 git 知道要用哪一隻,假設說你的 key ID 是3AA5C3431567BD2
,那就會像是下面的指令
git config --global user.signingkey 3AA5C3431567BD2
要讓 GitHub 也能認出來,就需要用gpg --export -a <keyid>
去拿到 PGP public key block,然後在SSH and GPG keys 設定頁面把 PGP public key block 填進去。
記錄一下一個有趣的函數:joint denial(又稱為Peirce's arrow 或是NOR)。它的真值表是
\(P\) | \(Q\) | \(P \downarrow Q\) |
---|---|---|
\(true\) | \(true\) | \(false\) |
\(true\) | \(false\) | \(false\) |
\(false\) | \(true\) | \(false\) |
\(false\) | \(false\) | \(true\) |
這個函數好玩的地方是我們熟悉的所有邏輯謂詞都可以用它替換
The Archimedean principle is: If \(a\) and \(b\) are real numbers with \(a > 0\), then there exists a natural number \(n\) such that \(na > b\).
So \(n > \frac {b}{a}\), by this we can have a particular example.
Let \(a = \epsilon \) and \(b = 1\), then \(n > \frac {1}{\epsilon }\), and \(\epsilon > \frac {1}{n}\). Show that \[\inf \Big (\Big \{ \frac {1}{n} : n \in \mathbb {N} \Big \} \Big ) = 0\].
Let \(A = \{\frac {1}{n} : n \in \mathbb {N}\}\). Since \(1\) and \(n\) are positive for each \(n \in \mathbb {N}\), shows \(\frac {1}{n} > 0\), so \(0\) is a lower bound of \(A\).
Let \(\epsilon > 0\), by Archimedean principle there exists some \(n \in \mathbb {N}\) such that \(\frac {1}{n} < \epsilon \). This element is in \(A\) and is less than \(0 + \epsilon \). Thus, \(0\) is infimum of \(A\) by definition: \(0 + \epsilon \) is not a lower bound of \(A\) for all \(\epsilon > 0\).
這篇是我對 HoTT (Homotopy Type Theory) 的理解與整理,連結是相關的程式。
要理解 hott 就要先知道 unique identity,即x ≡ y
這樣的型別,在 extensional type theory(e.g. MLTT)裡面只有一個元素,即對P Q : x ≡ y
可以證明P ≡ Q
。這就叫 UIP(Uniqueness of Identity Proofs)
UIP : (X : Set) → ∀{x x' : X} → ∀(r s : x ≡ x') → r ≡ sUIP X {x} {.x} refl refl = refl
Axiom K 跟它的關係是 \(K \implies \text {UIP}\) 且 \(\text {UIP} \implies K\) 。
但這個公理成立的時候我們沒辦法表示一些 topology,比如說 circle。因為 identity 在 HoTT 裡對應的解釋是一個 path,x ≡ y
就是x
到y
的路徑,而P Q : x ≡ y
自然就是x
到y
的兩條路徑,如果P ≡ Q
可證明,那P
就跟Q
可以替換,於是你可以先變成一條線,再收縮成一個點。circle 需要的兩條路徑就沒辦法成立,此類的拓墣都沒辦法表示,因此 agda 給了一個選項 without K 來取消這個公理,才能編寫 homotopy 系列的類型論。
一個具體的情況是Bool
可以有兩種同構,也就是id ∘ id
跟not ∘ not
,然而這兩條路徑在 extensional type theory 裡面無法區分,也就是可以證明兩者相等,在同倫類型論之中則否。
另一個重要的性質是 \(n\)-types,使用 \(n\) 維度之上沒有洞的特性來分類類型
命題被解釋成是一個點,也就是 true;或是一個什麼都沒有的空間,也就是 false。所以定義為
isProp : ∀{i} → Type i → Type iisProp A = (x y : A) → x ≡ y
Let \(T\) be a type, the propositional truncation of \(T\) is the type \(\Vert T \Vert \) defined by
截斷 \(\Vert A \Vert \) 表示 \(A\) 有證明,但沒有具體證明的資訊
For any proposition \(P\), precomposition with \(\vert \_\vert \) is an equivalence of type
\[ (\Vert T \Vert ) \to P \cong (T \to P) \]Let \(T\) be a type, we say \(T\) is non-empty if we have an element of \(\Vert T \Vert \).
允許用 equivalence 構造出 equality
.global printNumberEntryprintNumberEntry:// asked two words on stack sub sp, sp, #16 mov x15, #10 mov x12, x0// print prepare// fd(x0) = 1(stdout) mov x0, #1// len(x2) = 1 mov x2, #1// Unix write system call mov x16, #4printNumber:// number = x12// x14 = x12 / 10// now x14 is rounded-down quotient of x12 udiv x14, x12, x15// x13 = x14 * 10 - x12 msub x13, x14, x15, x12// store rounded-down quotient to x12 for next loop mov x12, x14// digit to string add x13, x13, #48 strb w13, [sp]// buf(x1) = sp mov x1, sp svc #0// loop part cmp x12, #0 b.eq exit b printNumberexit: mov x13, #10 strb w13, [sp] mov x1, sp svc #0// put used stack back add sp, sp, #16 ret
The idea is coming fromZhang's paper, a simpler encoding of indexed types. An example isVec
in Agda
data Vec (A : Set a) : ℕ → Set a where [] : Vec A zero _∷_ : ∀ (x : A) (xs : Vec A n) → Vec A (suc n)
One can still try[] : Vec A 10
, although the type check failed, it need a sophisticatedunification check. With Zhang's idea, we can do:
data Vec (A : Set a) : ℕ → Set a where zero => [] suc n => _∷_ A (Vec A n)
Now,[] : Vec A n
where \(n \ne 0\) is impossible to write down as usual, but now it's an easier unification!Since there has no constructor[]
for typeVec A n
where \(n \ne 0\).Another good example is finite set:
data Fin (n : N) | suc _ => fzero | suc n => fsuc (Fin n)
It requiresoverlapping pattern. One more last, we cannot defineusual equality type here (please check)
data Id (A : Type ℓ) (x : A) : A → Type ℓ where idp : Id A x x
Paper: Simpler indexed type essentially simplifies the problem of constructor selection just by turning the term-match-term problem to a term-match-pattern problem, which rules out numerous complication but also loses the benefit of general indexed types.
Tapejulia
in shell, after getting into the interactive environment of Julia, tape right square bracket to get into pkg mode:
_ _ _ _(_)_ | Documentation: https://docs.julialang.org (_) | (_) (_) | _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help. | | | | | | |/ _` | | | | |_| | | | (_| | | Version 1.5.0 (2020-08-01) _/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release|__/ |(@v1.5) pkg>
In this mode tape:generate HelloWorld
(@v1.5) pkg> generate HelloWorld
In the current directory would have a new directory calledHelloWorld
. In directoryHelloWorld/
we will see:
Project.tomlsrc/ HelloWorld.jl
To play with definitions in moduleHelloWorld
, in pkg mode tapeactivate .
(@v1.5) pkg> activate .
Then use;
+enter
back to interactive mode:
julia> import HelloWorldjulia> using HelloWorld
Consider identity function:
\[ \lambda x : nat.x \\ \lambda x : bool.x \\ \lambda x : (nat \to bool).x \]For per type, there is anidentity function, but all with same definition. Therefore, we want to use the same way to build it, here we go:
\[\lambda \alpha : \star . \lambda x : \alpha . x\]\(*\) denotes a type of all types, since \(\lambda \alpha : \star . \lambda x : \alpha . x\) is a term, we say this isterms depend on types. This is second order \(\lambda \)-abstraction(or type-abstraction).
second order abstraction rule:
\[\frac { \Gamma , \alpha : \star \vdash M : A }{ \Gamma \vdash \lambda \alpha : \star .M : \Pi \alpha : \star . A }\]second order application rule:
\[\frac { \Gamma \vdash M : \Pi \alpha : \star .A \;\;\; \Gamma \vdash B : \star }{ \Gamma \vdash M B : A[a := B] }\]因為我很懶所以就隨便記錄一下 iptables 就好了
iptables -t nat -I PREROUTING -j LOG --log-prefix="table nat PREROUTING start "
-t
指定 table-I
是 insert to XXX 的意思-j
是插入的規則LOG
會讓 kernel 印出經過這個規則的封包--log-prefix
是附在這些封包訊息前面的字串另外如果使用 rawsocket 來製作 gateway,必須處理 kernel 的重複封包,因為原理上是 kernel 把封包複製一份給 user space,我最近遇到的問題就是因為 kernel 原本的那份封包被放回 NIC 的 TX ring,出到 bridge 時又被 routing rule 丟回來 (ip route add CIDR via GATEWAY_IP
),所以這些封包就在 gateway 跟 bridge 之間被踢來踢去近乎佔滿所有網卡的 IO 導致淒慘的 45kbps 效能 (笑)
xsltproc
[software-0010]The toolxsltproc
can load.xsl
and.xml
files and produces proper output. For example, using https://git.sr.ht/~jonsterling/forester-to-latex one can produce latex slide from forester tree:
xsltproc ~/forester-to-latex/beamer.xsl math-000E.xml
The tool can open.djvu
files, some books use this format.
Penrose is a tool to create beautiful diagrams.
Converts html syntax to forester namespace html syntax.
Converts*.lagda.tree
to*.tree
.
project: | github.com/llir/llvm |
ticket tracker: | github.com/llir/llvm/issues |
這個專案是承襲 multipass compiler 精神的編譯器教學專案。將編譯器分成多個階段,可以大幅減少每個階段的複雜性,提升可維護的程度,在效能上也沒有嚴重的損失。以下是編譯器的主要工作階段
這個 pass 的目的是確保所有操作(不管是內建的加減乘除指令或是函數呼叫的引數)的 operand 都是 atomic。
雖然不同語言對什麼是 atomic 有不同的定義,但通常都是整數或是變數等電腦容易表達的資料。
雖然電腦沒有變數的直接概念,但暫存器跟堆疊可以提供適當的模擬。
實現這個 pass 的想法是
rco_atom : expr -> atom * (string * rco_expr) list
rco_expr : expr -> rco_expr
rco_atom
回傳的第二個結果用來生成對應的 let bindings。
這同時也是Compiling with Continuations 第二章中指出用 continuations 表達控制流的好處之一。
這個 pass 把簡單表達式rco_expr
轉換成 C-風格的程式,定義如下(略去cexpr
、catom
等)
type ctail = | Return of cexpr | Seq of cstmt * ctail | Goto of label | If of { cmp : cmp_op; a : catom; b : catom; thn : label; els : label }and cstmt = Assign of string * cexpr | AsStmt of ctailand basic_block = { name : label; body : ctail } and basic_blocks = (label * basic_block) list
可以從下列四個函數出發
explicate_tail : rco_expr -> ctail(* 參數意義分別是 指定值的表達式、指定變數名稱、續延 *)explicate_assign : rco_expr -> string -> ctail -> ctail(* 參數意義分別是 predicate 表達式、then 續延、else 續延 *)explicate_pred : rco_expr -> ctail -> ctail -> ctailexplicate_atom : atom -> catom
當然,也不能忘記這個 pass 還需要產出一串基本區塊,因此需要加入適當的basic_blocks ref
。
Patch instruction for each assign statement and return expression from previous C-style AST.
This compiler analysis is trying to find out living variable set of current statement (or instruction since it’s easier to do it with asm-like program). The definition is:
where
For example, arm64 instructionmov x0, x1
means movingx1
tox0
, and hence \(R(k) = \{ x1 \}\) and \(W(k) = \{ x0 \}\)
Jump instruction has a special rule, it’s \(L_\text {after}\) will be the read set of the target block. Refers toCFG.Conditional jump should use the union of read sets of target blocks, since it jumps to more than one place.
一個在沒有迴圈下可行的方案是利用 coroutine,當
這個 pass 的用途是根據 liveset (Pass [minic-0006]) 分析不能同時使用的變數跟 register,把這些衝突關係記錄成一張圖
movq s, d
, then for every \(v \in L_\text {after}(k)\), if \(v \ne d\) and \(v \ne s\), add edge \((d, v)\)register allocation 是根據衝突圖,進行實際的 register 分配。這個需求就等於在 conflict graph 上著色,相鄰點不同色,所以需要著色演算法。
W <- G.vertices-- W 表示 working setwhile W ≠ ∅ -- 1. 從 W 選出有最大 saturation 的頂點 u -- 2. 選出不在鄰邊的顏色集合中,最小的顏色 c color[u] <- c -- 3. 分配顏色 c 給 u W <- W - {u} -- 從 W 中刪除 u
這個演算法還需要最大 saturation 的定義:
\[ \text {saturation}(u) = \{ c \;|\; \exists v. v\in \text {adjacent}(u) \;\text {and}\; \text {color}(v) = c \} \]saturation 是一個集合,最大指的是該集合的大小, 所以 \(W\) 可以用 leftist tree 之類的結構來快速選出有最大 saturation set 的那個頂點
After register allocation, we might have instruction trying to read/write a stack pointer with shift. However, one cannot just touch stack like that in AArch64, and hence, we need a patch to replace
ldr
to read stackstr
to write stackin proper place.
假設今天想要比較x0 <= x1
是否為真,那就可以用下列指令
cmp x0, x1mov x2, 1mov x3, 0csel x0, x2, x3, le
最後的csel
會在 LE 成立時把x0
設定為x2
,反之則把x0
設為x3
,以此達成儲存比較結果的功能
An effect system integrated with typed/racket.
violet is a programming language I created for researching dependent type in use, the source code is written inlean. If you want to contribute the project, you will need the below information:
project: | sr.ht/~dannypsnl/violet |
ticket tracker: | sr.ht/~dannypsnl/violet/trackers |
mailing lists: | sr.ht/~dannypsnl/violet/lists |
The language currently support
A local cache management system for webmentions, it daily
LLVM bindings for racket