update
This commit is contained in:
parent
f5dc06fc69
commit
f2eee785d8
5 changed files with 149 additions and 9 deletions
7
Makefile
7
Makefile
|
@ -1,4 +1,9 @@
|
|||
deploy:
|
||||
SOURCES := $(shell find . -name "*.typ")
|
||||
|
||||
oplss.pdf: oplss.typ $(SOURCES)
|
||||
typst compile $<
|
||||
|
||||
deploy: oplss.pdf
|
||||
rsync -azr \
|
||||
--exclude .git \
|
||||
./ root@veil:/home/blogDeploy/public/public-files/oplss-2024
|
|
@ -24,4 +24,5 @@ data evaluationContext : Set where
|
|||
dot : evaluationContext
|
||||
EIf_Then_Else_ : evaluationContext → Term → Term → evaluationContext
|
||||
EAppLeft : evaluationContext → Term → evaluationContext
|
||||
EAppRight : Value → evaluationContext → evaluationContext
|
||||
EAppRight : Value → evaluationContext → evaluationContext
|
||||
|
||||
|
|
140
ahmed/notes.typ
140
ahmed/notes.typ
|
@ -1,11 +1,11 @@
|
|||
#import "../common.typ": *
|
||||
#import "@preview/prooftrees:0.1.0": *
|
||||
#show: doc => conf(doc)
|
||||
#show: doc => conf("Logical Relations", doc)
|
||||
|
||||
#let ifthenelse(e, e1, e2) = $"if" #e "then" #e1 "else" #e2$
|
||||
#let safe = $"safe"$
|
||||
|
||||
= Mon. Jun 3 \@ 14:00
|
||||
= Lecture 1, Mon. Jun 3 \@ 14:00
|
||||
|
||||
== Logical relations
|
||||
|
||||
|
@ -195,8 +195,7 @@ Use $gamma$ as a substitution from variables to values.
|
|||
|
||||
Now define semantic soundness:
|
||||
|
||||
$
|
||||
Gamma tack.r.double e : tau :equiv forall (gamma in G db(Gamma)) . gamma(e) in Epsilon db(tau)$
|
||||
$ Gamma tack.r.double e : tau :equiv forall (gamma in G db(Gamma)) . gamma(e) in Epsilon db(tau) $
|
||||
|
||||
Prove:
|
||||
|
||||
|
@ -242,4 +241,135 @@ To prove B:
|
|||
_Proof._ Suppose $e'$ s.t. $e mapstostar e'$ .
|
||||
|
||||
- Case : $not "irreducible" (e')$ then $exists e'' . e' mapsto e''$
|
||||
- Case : $"irreducible" (e')$ then $isValue(e')$ trivially.
|
||||
- Case : $"irreducible" (e')$ then $isValue(e')$ trivially.
|
||||
|
||||
#pagebreak()
|
||||
|
||||
= Lecture 2, Tue. Jun 4 \@ 11:00
|
||||
|
||||
#set enum(numbering: "A.")
|
||||
|
||||
Recall the lemmas we're proving:
|
||||
|
||||
1. $dot tack.r e : tau arrow.r.double e in Epsilon db(tau)$
|
||||
2. $e in Epsilon db(tau) arrow.r.double safe(e)$
|
||||
|
||||
#set enum(numbering: "1.")
|
||||
|
||||
To prove lemma A, we must prove the fundamental property: $Gamma tack.r e:tau arrow.r.double Gamma tack.r.double e:tau$. "Syntactically well-typed implies semantic well-typed"
|
||||
|
||||
$ Gamma tack.r.double e : tau :equiv forall (gamma in G db(Gamma)) . gamma(e) in Epsilon db(tau) $
|
||||
|
||||
=== Proving A case for $lambda$
|
||||
|
||||
Case:
|
||||
|
||||
#tree(
|
||||
axi[$Gamma , x : tau tack.r e : tau_2$],
|
||||
uni[$Gamma tack.r lambda (x : tau_1) . e : tau_1 arrow.r tau_2 $]
|
||||
)
|
||||
|
||||
*Show:* $Gamma tack.r.double lambda (x : tau_1) . e : tau_1 arrow tau_2$.
|
||||
|
||||
Suppose $gamma in G db(Gamma)$. Then we ned to *show*:
|
||||
|
||||
$ &gamma (lambda (x : tau_1). e) in Epsilon db(tau_1 arrow tau_2) \
|
||||
equiv &lambda (x:tau_1).gamma(e) in Epsilon db(tau_1 arrow tau_2)
|
||||
$
|
||||
|
||||
Suffices to show: $lambda (x:tau_1) gamma(e) in V db(tau_1 arrow tau_2)$.
|
||||
|
||||
Suppose $v in V db(tau_1)$. Then we need to show:
|
||||
|
||||
$ &subst(x, v, gamma(e)) in Epsilon db(tau_2) \
|
||||
equiv & gamma[x mapsto v] (e) in Epsilon db(tau_2)$
|
||||
|
||||
By the induction hypothesis, $Gamma,x:tau_1 tack.r e:tau_2$, so $Gamma,x:tau_1 tack.r.double e:tau_2$.
|
||||
|
||||
Because $gamma[x mapsto v] in G db(#[$Gamma, x : tau_1$])$, we can instantiate $Gamma,x:tau_1$ with $gamma[x mapsto v]$. (basically just translating it over to $gamma$)
|
||||
|
||||
Therefore, $gamma[x mapsto v](e) in Epsilon db(tau_2)$
|
||||
|
||||
#TODO Do the app case at home.
|
||||
|
||||
== Adding recursive types
|
||||
|
||||
$ Omega :equiv (lambda x . x " " x) (lambda x . x " " x) $
|
||||
|
||||
Cannot be type-checked in STLC, but adding recursive types allows this to be typechecked.
|
||||
|
||||
$ tau ::= 1 | "bool" | tau_1 arrow tau_2 | alpha | mu alpha . tau $
|
||||
|
||||
For example:
|
||||
|
||||
- $"tree" = mu alpha . 1 + ("int" times alpha times alpha)$
|
||||
- $"intlist" = mu alpha . 1 + ("int" times alpha)$
|
||||
|
||||
$ e ::= ... | "fold"(e) | "unfold"(e) $
|
||||
|
||||
#tree(
|
||||
axi[$Gamma tack.r e : subst(alpha, mu alpha . tau, tau)$],
|
||||
uni[$Gamma tack.r "fold"(e) : mu alpha . tau $],
|
||||
)
|
||||
|
||||
#tree(
|
||||
axi[$Gamma tack.r e : mu alpha . tau $],
|
||||
uni[$Gamma tack.r "unfold"(e) : subst(alpha, mu alpha . tau, tau)$],
|
||||
)
|
||||
|
||||
*NOTE*: Fold usually needs to be annotated with $mu alpha . tau$ in order to guide type checking.
|
||||
|
||||
== Type-checking $Omega$
|
||||
|
||||
$ Omega :equiv (lambda (x : ?) . x " " x) (lambda (x : ?) . x " " x) $
|
||||
|
||||
With inductive types, we can give the second $x$ some type $alpha$.
|
||||
Then the first $x$ that calls it would be $alpha arrow tau$ for some $tau$.
|
||||
|
||||
$ "SA" : (mu alpha . alpha arrow tau) arrow tau \
|
||||
"SA" :equiv lambda (x : mu alpha . alpha arrow tau) . ("unfold" x) x$
|
||||
|
||||
Then re-define $Omega$ to be:
|
||||
|
||||
$ Omega' :equiv "SA" ("fold" "SA") $
|
||||
|
||||
== Proving soundness for lambda calculus with recursive types with logical relations
|
||||
|
||||
$ v ::= ... | "fold"(v) $
|
||||
|
||||
*NOTE:* Unfold will not be a value.
|
||||
|
||||
$ E ::= ... | "fold" E $
|
||||
|
||||
New reduction rule:
|
||||
|
||||
$ "unfold"("fold" v) mapsto v $
|
||||
|
||||
$V db(mu alpha . tau) = { "fold"(v) | forall v in V db(subst(alpha, mu alpha. tau, tau)) }$
|
||||
|
||||
This is *not* a well-founded relation, because $V$ would depend on itself. This was an open problem (ATTAPL exercise) for a long time.
|
||||
|
||||
=== Step Indexing
|
||||
|
||||
This shows that this is well founded.
|
||||
|
||||
"If i were to run my program for $k$ steps, then I would not be able to tell that $V$ isn't well-founded"
|
||||
|
||||
#rect[$V_k db(tau)$]
|
||||
|
||||
$V_k db("bool") = {"true" , "false"}$
|
||||
|
||||
$V_k db(mu alpha . tau) = {"fold" v | v in V_(k-1) db(subst(alpha , mu alpha. tau , tau))}$
|
||||
|
||||
- Doing $"unfold"("fold" x) mapsto x$ "consumes" a step of $k$, so that's why $v$ already consumes a step.
|
||||
|
||||
$V_k db(tau_1 arrow tau_2) = {lambda (x : tau_1) . e | forall (j lt.eq k, v in V_j db(tau_1)) arrow.r.double subst(x, v, e) in Epsilon_j db(tau_2)}$
|
||||
|
||||
- Think of this as a timeline, starting with $k$ steps left
|
||||
- $j+1$ is the number of steps left when you get to the application of the lambda
|
||||
- Use 1 step to do the application, resulting in $j$ steps
|
||||
- Eventually reach 0 steps left.
|
||||
|
||||
$Epsilon_k db(tau) = { e | forall (j < k, e') arrow.r.double e mapsto e' and "irreducible"(e') arrow.r.double e' in V_(k-j) db(tau)}$
|
||||
|
||||
What $k$ doesn't matter because the entire relations are universally quantified over all $k$s.
|
|
@ -7,9 +7,11 @@
|
|||
#let subst(x, v, e) = $#e [#v\/#x]$
|
||||
#let TODO = text(fill: red)[*TODO*]
|
||||
|
||||
#let conf(doc) = {
|
||||
#let conf(title, doc) = {
|
||||
show link: underline
|
||||
set page(width: 5in, height: 8in, margin: 0.4in)
|
||||
set page(width: 6in, height: 9in, margin: 0.3in)
|
||||
|
||||
text(size: 30pt)[#title]
|
||||
doc
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,8 @@ Language to be studied is called "snax"
|
|||
uni[$Gamma tack.r k(e) : +{l : A_l}_(l in L)$],
|
||||
)
|
||||
|
||||
#pagebreak()
|
||||
|
||||
== Lecture 2
|
||||
|
||||
Type system
|
||||
|
|
Loading…
Reference in a new issue