This commit is contained in:
parent
334e6cb1bf
commit
3833a310e0
10 changed files with 10179 additions and 8466 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -20,4 +20,5 @@ pnpm-debug.log*
|
||||||
# macOS-specific files
|
# macOS-specific files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
PragmataPro-Mono-Liga-Regular-Nerd-Font-Complete.woff2
|
PragmataPro-Mono-Liga-Regular-Nerd-Font-Complete.woff2
|
||||||
|
*.agdai
|
|
@ -1,7 +1,6 @@
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import mdx from "@astrojs/mdx";
|
import mdx from "@astrojs/mdx";
|
||||||
import sitemap from "@astrojs/sitemap";
|
import sitemap from "@astrojs/sitemap";
|
||||||
import { astroImageTools } from "astro-imagetools";
|
|
||||||
import { rehypeAccessibleEmojis } from "rehype-accessible-emojis";
|
import { rehypeAccessibleEmojis } from "rehype-accessible-emojis";
|
||||||
|
|
||||||
import remarkReadingTime from "./plugin/remark-reading-time";
|
import remarkReadingTime from "./plugin/remark-reading-time";
|
||||||
|
@ -10,24 +9,31 @@ import remarkMermaid from "astro-diagram/remark-mermaid";
|
||||||
import remarkDescription from "astro-remark-description";
|
import remarkDescription from "astro-remark-description";
|
||||||
import remarkAdmonitions from "./plugin/remark-admonitions";
|
import remarkAdmonitions from "./plugin/remark-admonitions";
|
||||||
import remarkMath from "remark-math";
|
import remarkMath from "remark-math";
|
||||||
|
|
||||||
import rehypeKatex from "rehype-katex";
|
import rehypeKatex from "rehype-katex";
|
||||||
|
|
||||||
|
import addProofMacros from "./utils/mzproofs";
|
||||||
|
import remarkAgda from "./plugin/remark-agda";
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
site: "https://mzhang.io",
|
site: "https://mzhang.io",
|
||||||
integrations: [mdx(), sitemap(), astroImageTools],
|
integrations: [
|
||||||
|
mdx(),
|
||||||
|
sitemap(),
|
||||||
|
//astroImageTools
|
||||||
|
],
|
||||||
markdown: {
|
markdown: {
|
||||||
syntaxHighlight: "shiki",
|
syntaxHighlight: "shiki",
|
||||||
shikiConfig: { theme: "css-variables" },
|
shikiConfig: { theme: "css-variables" },
|
||||||
remarkPlugins: [
|
remarkPlugins: [
|
||||||
remarkAdmonitions,
|
remarkAdmonitions,
|
||||||
remarkReadingTime,
|
remarkReadingTime,
|
||||||
remarkMath,
|
remarkAgda,
|
||||||
|
[remarkMath, {}],
|
||||||
remarkMermaid,
|
remarkMermaid,
|
||||||
emoji,
|
emoji,
|
||||||
[remarkDescription, { name: "excerpt" }],
|
[remarkDescription, { name: "excerpt" }],
|
||||||
],
|
],
|
||||||
rehypePlugins: [rehypeKatex, rehypeAccessibleEmojis],
|
rehypePlugins: [[rehypeKatex, { macros: addProofMacros({}) }], rehypeAccessibleEmojis],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
2
blog.agda-lib
Normal file
2
blog.agda-lib
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
include: src/content/posts
|
||||||
|
depend: standard-library
|
18271
package-lock.json
generated
18271
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -34,6 +34,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash-es": "^4.17.9",
|
"@types/lodash-es": "^4.17.9",
|
||||||
"mdast": "^3.0.0",
|
"mdast": "^3.0.0",
|
||||||
|
"mdast-util-from-markdown": "^2.0.0",
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.0.3",
|
||||||
"prettier-plugin-astro": "^0.12.0",
|
"prettier-plugin-astro": "^0.12.0",
|
||||||
"sass": "^1.66.1",
|
"sass": "^1.66.1",
|
||||||
|
|
54
plugin/remark-agda.ts
Normal file
54
plugin/remark-agda.ts
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import type { RemarkPlugin } from "@astrojs/markdown-remark";
|
||||||
|
import { fromMarkdown } from "mdast-util-from-markdown";
|
||||||
|
|
||||||
|
import { spawnSync } from "node:child_process";
|
||||||
|
import { mkdtempSync, mkdirSync, readFileSync } from "node:fs";
|
||||||
|
import { tmpdir } from "node:os";
|
||||||
|
import { join, parse } from "node:path";
|
||||||
|
|
||||||
|
const remarkAgda: RemarkPlugin = () => {
|
||||||
|
return function (tree, { data }) {
|
||||||
|
const path: string = data.astro.fileURL.pathname;
|
||||||
|
if (!(path.endsWith(".lagda.md") || path.endsWith(".agda"))) return;
|
||||||
|
|
||||||
|
console.log("data", data);
|
||||||
|
|
||||||
|
const tempDir = mkdtempSync(join(tmpdir(), "agdaRender."));
|
||||||
|
const outDir = join(tempDir, "output");
|
||||||
|
mkdirSync(outDir, { recursive: true });
|
||||||
|
console.log("work dir", tempDir);
|
||||||
|
|
||||||
|
const childOutput = spawnSync(
|
||||||
|
"agda",
|
||||||
|
[
|
||||||
|
"--html",
|
||||||
|
`--html-dir=${outDir}`,
|
||||||
|
"--highlight-occurrences",
|
||||||
|
"--html-highlight=code",
|
||||||
|
data.astro.fileURL.pathname,
|
||||||
|
],
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("output", childOutput.output.toString());
|
||||||
|
const filename = parse(path).base.replace(/\.lagda/, "");
|
||||||
|
console.log();
|
||||||
|
console.log("filename", filename);
|
||||||
|
|
||||||
|
const fullOutputPath = join(outDir, filename);
|
||||||
|
console.log("outDir", fullOutputPath);
|
||||||
|
console.log();
|
||||||
|
|
||||||
|
const doc = readFileSync(fullOutputPath);
|
||||||
|
const tree2 = fromMarkdown(doc);
|
||||||
|
console.log("tree", tree);
|
||||||
|
|
||||||
|
tree.children = tree2.children;
|
||||||
|
|
||||||
|
// visit(tree, "", (node) => {
|
||||||
|
// console.log("node", node);
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default remarkAgda;
|
154
src/content/posts/2023-10-10-dtt-project.lagda.md
Normal file
154
src/content/posts/2023-10-10-dtt-project.lagda.md
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
---
|
||||||
|
title: DTT Project
|
||||||
|
date: 2023-10-11T04:05:23.082Z
|
||||||
|
draft: true
|
||||||
|
toc: true
|
||||||
|
tags:
|
||||||
|
- type-theory
|
||||||
|
---
|
||||||
|
|
||||||
|
References:
|
||||||
|
|
||||||
|
- https://www.cl.cam.ac.uk/~nk480/bidir.pdf
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
Agda Imports
|
||||||
|
<small>for the purpose of type-checking</small>
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
```agda
|
||||||
|
{-# OPTIONS --allow-unsolved-metas --allow-incomplete-matches #-}
|
||||||
|
open import Data.Nat
|
||||||
|
open import Data.Product
|
||||||
|
open import Data.String hiding (_<_)
|
||||||
|
open import Relation.Nullary using (Dec)
|
||||||
|
open import Relation.Nullary.Decidable using (True; toWitness)
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Damas-Hindley-Milner type inference
|
||||||
|
|
||||||
|
Unification-based algorithm for lambda calculus.
|
||||||
|
|
||||||
|
## First try
|
||||||
|
|
||||||
|
Implement terms, monotypes, and polytypes:
|
||||||
|
|
||||||
|
```agda
|
||||||
|
data Term : Set
|
||||||
|
data Type : Set
|
||||||
|
data Monotype : Set
|
||||||
|
```
|
||||||
|
|
||||||
|
Regular lambda calculus terms:
|
||||||
|
|
||||||
|
$e ::= x \mid () \mid \lambda x. e \mid e e \mid (e : A)$
|
||||||
|
|
||||||
|
```agda
|
||||||
|
data Term where
|
||||||
|
Unit : Term
|
||||||
|
Var : String → Term
|
||||||
|
Lambda : String → Term → Term
|
||||||
|
App : Term → Term → Term
|
||||||
|
Annot : Term → Type → Term
|
||||||
|
```
|
||||||
|
|
||||||
|
Polytypes are types that may include universal quantifiers ($\forall$)
|
||||||
|
|
||||||
|
$A, B, C ::= 1 \mid \alpha \mid \forall \alpha. A \mid A \rightarrow B$
|
||||||
|
|
||||||
|
```agda
|
||||||
|
data Type where
|
||||||
|
Unit : Type
|
||||||
|
Var : String → Type
|
||||||
|
Existential : String → Type
|
||||||
|
Forall : String → Type → Type
|
||||||
|
Arrow : Type → Type → Type
|
||||||
|
```
|
||||||
|
|
||||||
|
Monotypes (usually denoted $\tau$) are types that aren't universally quantified.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> In the declarative version of this algorithm, monotypes don't have existential quantifiers either,
|
||||||
|
> but the algorithmic type system includes it.
|
||||||
|
> TODO: Explain why
|
||||||
|
|
||||||
|
```agda
|
||||||
|
data Monotype where
|
||||||
|
Unit : Monotype
|
||||||
|
Var : String → Monotype
|
||||||
|
Existential : String → Monotype
|
||||||
|
Arrow : Monotype → Monotype → Monotype
|
||||||
|
```
|
||||||
|
|
||||||
|
### Contexts
|
||||||
|
|
||||||
|
```agda
|
||||||
|
data Context : Set where
|
||||||
|
Nil : Context
|
||||||
|
Var : Context → String → Context
|
||||||
|
Annot : Context → String → Type → Context
|
||||||
|
UnsolvedExistential : Context → String → Context
|
||||||
|
SolvedExistential : Context → String → Monotype → Context
|
||||||
|
Marker : Context → String → Context
|
||||||
|
|
||||||
|
contextLength : Context → ℕ
|
||||||
|
contextLength Nil = zero
|
||||||
|
contextLength (Var Γ _) = suc (contextLength Γ)
|
||||||
|
contextLength (Annot Γ _ _) = suc (contextLength Γ)
|
||||||
|
contextLength (UnsolvedExistential Γ _) = suc (contextLength Γ)
|
||||||
|
contextLength (SolvedExistential Γ _ _) = suc (contextLength Γ)
|
||||||
|
contextLength (Marker Γ _) = suc (contextLength Γ)
|
||||||
|
|
||||||
|
-- https://plfa.github.io/DeBruijn/#abbreviating-de-bruijn-indices
|
||||||
|
postulate
|
||||||
|
lookupVar : (Γ : Context) → (n : ℕ) → (p : n < contextLength Γ) → Set
|
||||||
|
-- lookupVar (Var Γ x) n p = {! !}
|
||||||
|
-- lookupVar (Annot Γ x x₁) n p = {! !}
|
||||||
|
-- lookupVar (UnsolvedExistential Γ x) n p = {! !}
|
||||||
|
-- lookupVar (SolvedExistential Γ x x₁) n p = {! !}
|
||||||
|
-- lookupVar (Marker Γ x) n p = {! !}
|
||||||
|
|
||||||
|
data CompleteContext : Set where
|
||||||
|
Nil : CompleteContext
|
||||||
|
Var : CompleteContext → String → CompleteContext
|
||||||
|
Annot : CompleteContext → String → Type → CompleteContext
|
||||||
|
SolvedExistential : CompleteContext → String → Monotype → CompleteContext
|
||||||
|
Marker : CompleteContext → String → CompleteContext
|
||||||
|
```
|
||||||
|
|
||||||
|
### Type checking
|
||||||
|
|
||||||
|
```agda
|
||||||
|
postulate
|
||||||
|
check : (Γ : Context) → (e : Term) → (A : Type) → Context
|
||||||
|
```
|
||||||
|
|
||||||
|
```agda
|
||||||
|
-- check Γ Unit A = Γ
|
||||||
|
```
|
||||||
|
|
||||||
|
```agda
|
||||||
|
-- check Γ (Var x) A = {! !}
|
||||||
|
-- check Γ (Lambda x e) A = {! !}
|
||||||
|
-- check Γ (App e e₁) A = {! !}
|
||||||
|
-- check Γ (Annot e x) A = {! !}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Type synthesizing
|
||||||
|
|
||||||
|
```js
|
||||||
|
const x = () => {};
|
||||||
|
```
|
||||||
|
|
||||||
|
```agda
|
||||||
|
postulate
|
||||||
|
synthesize : (Γ : Context) → (e : Term) → (Type × Context)
|
||||||
|
-- synthesize Γ Unit = Unit , Γ
|
||||||
|
-- synthesize Γ (Var x) = {! !}
|
||||||
|
-- synthesize Γ (Lambda x e) = {! !}
|
||||||
|
-- synthesize Γ (App e e₁) = {! !}
|
||||||
|
-- synthesize Γ (Annot e x) = {! !}
|
||||||
|
```
|
|
@ -76,3 +76,126 @@
|
||||||
--astro-code-token-link: black;
|
--astro-code-token-link: black;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre.Agda {
|
||||||
|
a {
|
||||||
|
color: var(--astro-code-color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// .Keyword {
|
||||||
|
// color: var(--astro-code-token-keyword);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .Comment {
|
||||||
|
// color: var(--astro-code-token-comment);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .Symbol {
|
||||||
|
// color: var(--astro-code-token-punctuation);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .Function {
|
||||||
|
// color: var(--astro-code-token-function);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Aspects. */
|
||||||
|
.Agda .Comment {
|
||||||
|
color: #b22222;
|
||||||
|
}
|
||||||
|
.Agda .Background {
|
||||||
|
}
|
||||||
|
.Agda .Markup {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
.Agda .Keyword {
|
||||||
|
color: #cd6600;
|
||||||
|
}
|
||||||
|
.Agda .String {
|
||||||
|
color: #b22222;
|
||||||
|
}
|
||||||
|
.Agda .Number {
|
||||||
|
color: #a020f0;
|
||||||
|
}
|
||||||
|
.Agda .Symbol {
|
||||||
|
color: #404040;
|
||||||
|
}
|
||||||
|
.Agda .PrimitiveType {
|
||||||
|
color: #0000cd;
|
||||||
|
}
|
||||||
|
.Agda .Pragma {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.Agda .Operator {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NameKinds. */
|
||||||
|
.Agda .Bound {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.Agda .Generalizable {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.Agda .InductiveConstructor {
|
||||||
|
color: #008b00;
|
||||||
|
}
|
||||||
|
.Agda .CoinductiveConstructor {
|
||||||
|
color: #8b7500;
|
||||||
|
}
|
||||||
|
.Agda .Datatype {
|
||||||
|
color: #0000cd;
|
||||||
|
}
|
||||||
|
.Agda .Field {
|
||||||
|
color: #ee1289;
|
||||||
|
}
|
||||||
|
.Agda .Function {
|
||||||
|
color: #0000cd;
|
||||||
|
}
|
||||||
|
.Agda .Module {
|
||||||
|
color: #a020f0;
|
||||||
|
}
|
||||||
|
.Agda .Postulate {
|
||||||
|
color: #0000cd;
|
||||||
|
}
|
||||||
|
.Agda .Primitive {
|
||||||
|
color: #0000cd;
|
||||||
|
}
|
||||||
|
.Agda .Record {
|
||||||
|
color: #0000cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OtherAspects. */
|
||||||
|
.Agda .DottedPattern {
|
||||||
|
}
|
||||||
|
.Agda .UnsolvedMeta {
|
||||||
|
color: black;
|
||||||
|
background: yellow;
|
||||||
|
}
|
||||||
|
.Agda .UnsolvedConstraint {
|
||||||
|
color: black;
|
||||||
|
background: yellow;
|
||||||
|
}
|
||||||
|
.Agda .TerminationProblem {
|
||||||
|
color: black;
|
||||||
|
background: #ffa07a;
|
||||||
|
}
|
||||||
|
.Agda .IncompletePattern {
|
||||||
|
color: black;
|
||||||
|
background: #f5deb3;
|
||||||
|
}
|
||||||
|
.Agda .Error {
|
||||||
|
color: red;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.Agda .TypeChecks {
|
||||||
|
color: black;
|
||||||
|
background: #add8e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Standard attributes. */
|
||||||
|
.Agda a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
// .Agda a[href]:hover {
|
||||||
|
// background-color: #b4eeb4;
|
||||||
|
// }
|
||||||
|
|
|
@ -46,17 +46,19 @@ code {
|
||||||
font-family: var(--monofont);
|
font-family: var(--monofont);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 1px 5px;
|
padding: 1px 5px;
|
||||||
background-color: var(--faded-background-color);
|
// background-color: var(--faded-background-color);
|
||||||
// color: $code-color;
|
// color: $code-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre > code {
|
pre > code,
|
||||||
|
pre.Agda {
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
display: block;
|
display: block;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
font-family: var(--monofont);
|
font-family: var(--monofont);
|
||||||
line-height: 1.15rem;
|
line-height: 1.15rem;
|
||||||
|
background-color: var(--faded-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
a code {
|
a code {
|
||||||
|
|
|
@ -52,10 +52,23 @@
|
||||||
border: 1px solid var(--hr-color);
|
border: 1px solid var(--hr-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
pre > code {
|
pre > code,
|
||||||
|
pre.Agda {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid var(--hr-color);
|
border: 1px solid var(--hr-color);
|
||||||
|
// background-color: var(--astro-code-color-background);
|
||||||
|
|
||||||
|
a {
|
||||||
|
background-color: unset;
|
||||||
|
|
||||||
|
&:not([href]):hover {
|
||||||
|
}
|
||||||
|
|
||||||
|
&[href]:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue