Start drafting CEK
This commit is contained in:
parent
f4d9ae6b14
commit
56bbbc5dee
7 changed files with 185 additions and 29 deletions
|
@ -124,6 +124,7 @@ a code {
|
||||||
}
|
}
|
||||||
|
|
||||||
pre > code {
|
pre > code {
|
||||||
|
color: $text-color;
|
||||||
display: block;
|
display: block;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
@ -156,7 +157,56 @@ table.table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.post-container {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
@media screen and (max-width: 520px) {
|
||||||
|
flex-direction: column;
|
||||||
|
.toc-drawer { display: block; }
|
||||||
|
.toc-list { display: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 520px) {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
|
||||||
|
.toc-drawer { display: none; }
|
||||||
|
.toc-list {
|
||||||
|
top: 0;
|
||||||
|
display: block;
|
||||||
|
position: sticky;
|
||||||
|
min-width: 160px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.post-content {
|
.post-content {
|
||||||
|
min-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc-draw #TableOfContents, .toc-list #TableOfContents {
|
||||||
|
ul {
|
||||||
|
list-style-type: "\22A2 ";
|
||||||
|
padding-left: 1rem;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li ul {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.division .post-content, .post-content {
|
||||||
|
.heading {
|
||||||
|
a {
|
||||||
|
color: $heading-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> p {
|
> p {
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'PragmataPro Mono Liga';
|
font-family: 'PragmataPro Mono Liga';
|
||||||
src: url('/fonts/PragmataPro_Mono_R_liga_0829.woff2') format('woff2');
|
src: url("/fonts/PragmataPro_Mono_R_liga_0829.woff2") format("woff2"),
|
||||||
|
url(https://mzhang.io/fonts/PragmataPro_Mono_R_liga_0829.woff2) format("woff2");
|
||||||
}
|
}
|
||||||
|
|
||||||
$sansfont: "Helvetica", "Arial", "Liberation Sans", sans-serif;
|
$sansfont: "Helvetica", "Arial", "Liberation Sans", sans-serif;
|
||||||
|
@ -26,7 +27,7 @@ $monofont: "PragmataPro Mono Liga", "Roboto Mono", "Roboto Mono for Powerline",
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
$background-color: #15202B;
|
$background-color: #151520;
|
||||||
$faded-background-color: lighten($background-color, 10%);
|
$faded-background-color: lighten($background-color, 10%);
|
||||||
$heading-color: #E4E4E4;
|
$heading-color: #E4E4E4;
|
||||||
$text-color: #BCBCBC;
|
$text-color: #BCBCBC;
|
||||||
|
|
|
@ -9,7 +9,7 @@ language = "languages"
|
||||||
|
|
||||||
[markup.tableOfContents]
|
[markup.tableOfContents]
|
||||||
endLevel = 4
|
endLevel = 4
|
||||||
ordered = true
|
ordered = false
|
||||||
startLevel = 2
|
startLevel = 2
|
||||||
|
|
||||||
[markup.goldmark.renderer]
|
[markup.goldmark.renderer]
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
+++
|
||||||
|
title = "a formal cek machine in agda"
|
||||||
|
draft = true
|
||||||
|
date = 2022-02-02
|
||||||
|
tags = ["computer-science", "programming-languages", "formal-verification", "lambda-calculus"]
|
||||||
|
languages = ["agda"]
|
||||||
|
layout = "single"
|
||||||
|
toc = true
|
||||||
|
+++
|
||||||
|
|
||||||
|
<!--more-->
|
||||||
|
|
||||||
|
Last semester, I took a course on reasoning about programming languages using
|
||||||
|
Agda, a dependently typed meta-language. For the term project, we were to
|
||||||
|
implement a simply-typed lambda calculus with several extensions, along with
|
||||||
|
proofs of certain properties.
|
||||||
|
|
||||||
|
My lambda calculus implemented `call/cc` on top of a CEK machine.
|
||||||
|
|
||||||
|
## Foreword
|
||||||
|
|
||||||
|
**Why is this interesting?** Reasoning about languages is one way of ensuring
|
||||||
|
whole-program correctness. Building up these languages from foundations grounded
|
||||||
|
in logic helps us achieve our goal with more rigor.
|
||||||
|
|
||||||
|
As an example, suppose I wrote a function that takes a list of numbers and
|
||||||
|
returns the maximum value. Mathematically speaking, this function would be
|
||||||
|
_non-total_; an input consisting of an empty set would not produce reasonable
|
||||||
|
output! If this were a library function I'd like to tell people who write code
|
||||||
|
that uses this function "don't give me an empty list!"
|
||||||
|
|
||||||
|
Unfortunately, just writing this in documentation isn't enough. What we'd really
|
||||||
|
like is for a tool (like a compiler) to tell any developer who is trying to pass
|
||||||
|
an empty list into our maximum function "You can't do that." Unfortunately, most
|
||||||
|
of the popular languages being used today have no way of describing "a list
|
||||||
|
that's not empty."
|
||||||
|
|
||||||
|
## Lambda calculus
|
||||||
|
|
||||||
|
The lambda calculus is a mathematical structure for describing computation. At
|
||||||
|
the most basic level, it defines a concept called a _term_. Everything that can
|
||||||
|
be represented in a lambda calculus is some combination of terms. A term can
|
||||||
|
have several constructors:
|
||||||
|
|
||||||
|
- **Var.** This is just a variable, like `x` or `y`. During evaluation, a
|
||||||
|
variable can resolve to a value in the evaluation environment by name. If
|
||||||
|
the environment says `{ x = 5 }`, then evaluating `x` would result in 5.
|
||||||
|
|
||||||
|
- **Abstraction, or lambda (λ).** An _abstraction_ is a term that describes some
|
||||||
|
other computation. From an algebraic perspective, it can be thought of as a
|
||||||
|
function with a single argument (i.e f(x) = 2x is an abstraction, although
|
||||||
|
it would be written `(λx.2x)`)
|
||||||
|
|
||||||
|
- **Application.** Application is sort of the opposite of abstraction, exposing
|
||||||
|
the computation that was abstracted away. From an algebraic perspective,
|
||||||
|
this is just function application (i.e applying `f(x) = 2x` to 3 would
|
||||||
|
result in 2\*3. Note that only a simple substitution has been done and
|
||||||
|
further evaluation is required to reduce 2*3)
|
||||||
|
|
||||||
|
### Why?
|
||||||
|
|
||||||
|
The reason it's set up this way is so we can reason about terms inductively. The
|
||||||
|
idea is that because terms are just nested constructors, we can describe the
|
||||||
|
behavior of any term by just defining the behavior of these 3 constructors.
|
||||||
|
|
||||||
|
Interestingly, the lambda calculus is Turing-complete, so any computation can be
|
||||||
|
reduced to those 3 constructs. I used numbers liberally in the examples above,
|
||||||
|
but in a lambda calculus without numbers, you could define integers recursively
|
||||||
|
like this:
|
||||||
|
|
||||||
|
- Let `z` represent zero.
|
||||||
|
- Let `s` represent a "successor", or increment function. `s(z)` represents 1,
|
||||||
|
`s(s(z))` represents 2, and so on.
|
||||||
|
|
||||||
|
In lambda calculus terms, this would look like:
|
||||||
|
|
||||||
|
- 0 = `λs.(λz.z)`
|
||||||
|
- 1 = `λs.(λz.s(z))`
|
||||||
|
- 2 = `λs.(λz.s(s(z)))`
|
||||||
|
- 3 = `λs.(λz.s(s(s(z))))`
|
||||||
|
|
||||||
|
In practice, many lambda calculus have a set of "base" values from which to
|
||||||
|
build off, such as unit values, booleans, and natural numbers (having numbers in
|
||||||
|
the language means we don't need the `s` and `z` dance to refer to them).
|
||||||
|
|
||||||
|
### Turing completeness
|
||||||
|
|
||||||
|
As I noted above, the lambda calculus is _Turing-complete_. One feature of
|
||||||
|
Turing complete systems is that they have a (provably!) unsolvable "halting"
|
||||||
|
problem.
|
||||||
|
|
||||||
|
### Simply-typed lambda calculus (STLC)
|
||||||
|
|
||||||
|
## CEK machine
|
||||||
|
|
||||||
|
A CEK machine
|
3
layouts/_default/_markup/render-heading.html
Normal file
3
layouts/_default/_markup/render-heading.html
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<h{{ .Level }} id="{{ .Anchor | safeURL }}" class="heading">
|
||||||
|
<a href="#{{ .Anchor | safeURL }}">{{ .Text | safeHTML }}</a>
|
||||||
|
</h{{ .Level }}>
|
|
@ -1,5 +1,6 @@
|
||||||
<table style="width: 100%;">
|
<table style="width: 100%;">
|
||||||
{{- range .Pages -}}
|
{{- range .Pages -}}
|
||||||
|
{{ if not .Draft }}
|
||||||
<tr class="postlisting-row">
|
<tr class="postlisting-row">
|
||||||
<td>
|
<td>
|
||||||
<span class="title">
|
<span class="title">
|
||||||
|
@ -15,5 +16,6 @@
|
||||||
<br />
|
<br />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{{ end }}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -18,24 +18,28 @@
|
||||||
- {{ .ReadingTime }} min read
|
- {{ .ReadingTime }} min read
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
<div class="post-container">
|
||||||
{{ if .Params.toc }}
|
{{ if .Params.toc }}
|
||||||
<div class="toc">
|
<div class="toc-drawer">
|
||||||
<details>
|
<details>
|
||||||
<summary>Table of Contents</summary>
|
<summary>Table of Contents</summary>
|
||||||
{{ .TableOfContents }}
|
{{ .TableOfContents }}
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="toc-list">
|
||||||
|
{{ .TableOfContents }}
|
||||||
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<div id="content" class="post-content">{{ .Content }}</div>
|
<div id="content" class="post-content">{{ .Content }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<small>
|
<small>
|
||||||
Thanks for reading!
|
Thanks for reading!
|
||||||
{{ if .Params.mastodon }}
|
|
||||||
Have comments? Discuss this post on <a href="{{ .Params.mastodon }}" target="_blank">Mastodon</a>.
|
Have comments? Discuss this post by sending me a
|
||||||
{{ end }}
|
<a href="mailto:~mzhang/public-inbox@lists.sr.ht?subject=Re:+{{ .Title }}">public email</a>.
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
Loading…
Reference in a new issue