199 lines
4.0 KiB
Typst
199 lines
4.0 KiB
Typst
#import "@preview/curryst:0.6.0"
|
|
#import "utils.typ": *
|
|
|
|
#let rule(
|
|
name,
|
|
..premises,
|
|
conclusion,
|
|
python,
|
|
) = (
|
|
return (
|
|
name: name,
|
|
rule: curryst.prooftree(
|
|
curryst.rule(
|
|
..premises.pos(),
|
|
conclusion,
|
|
name: smallcaps[(#name)],
|
|
),
|
|
),
|
|
python: python,
|
|
)
|
|
)
|
|
|
|
#let literals-rules = (
|
|
rule(
|
|
"T-Int",
|
|
$Gamma tack "i": "int"$,
|
|
```py 12: int```
|
|
),
|
|
rule(
|
|
"T-Float",
|
|
$Gamma tack "f": "float"$,
|
|
```py 12.34: float```
|
|
),
|
|
rule(
|
|
"T-Str",
|
|
$Gamma tack "z": "str"$,
|
|
```py "foo": str```
|
|
),
|
|
rule(
|
|
"T-True",
|
|
$Gamma tack "True": "bool"$,
|
|
```py True: bool```
|
|
),
|
|
rule(
|
|
"T-False",
|
|
$Gamma tack "False": "bool"$,
|
|
```py False: bool```
|
|
),
|
|
rule(
|
|
"T-None",
|
|
$Gamma tack "None": "None"$,
|
|
```py None: None```
|
|
),
|
|
)
|
|
|
|
#let expressions-rules = (
|
|
rule(
|
|
"T-Var",
|
|
$"x": "T" in Gamma$,
|
|
$Gamma tack "x": "T"$,
|
|
```py x```,
|
|
),
|
|
rule(
|
|
"T-Call",
|
|
$Gamma tack f: "T"_1 -> "T"_2$,
|
|
$Gamma tack "t": "T"_1$,
|
|
$Gamma tack f("t"): "T"_2$,
|
|
```py
|
|
def func(a: S) -> T: ...
|
|
...
|
|
func(a): T
|
|
```,
|
|
),
|
|
rule(
|
|
"T-Tern",
|
|
$Gamma tack "t"_1: "bool"$,
|
|
$Gamma tack "t"_21: "T"$,
|
|
$Gamma tack "t"_22: "T"$,
|
|
$Gamma tack "t"_21 #syntax[if] "t"_1 #syntax[else] "t"_22: "T"$,
|
|
```py (true if cond else false): T ```,
|
|
),
|
|
rule(
|
|
"T-Op",
|
|
$Gamma tack "t"_1: "T"_1$,
|
|
$Gamma tack "t"_2: "T"_2$,
|
|
$"op": "T"_1 -> "T"_2 -> "T"_3 in Gamma$,
|
|
$Gamma tack "t"_1 "op" "t"_2: "T"_3$,
|
|
```py (a + b): T```,
|
|
),
|
|
)
|
|
|
|
#let statements-rules = (
|
|
rule(
|
|
"T-Annot",
|
|
$Gamma tack "x": "T" tack.l Gamma, "x": "T"$,
|
|
```py x: T```,
|
|
),
|
|
rule(
|
|
"T-Seq",
|
|
$Gamma tack "s"_1 tack.l Gamma'$,
|
|
$Gamma' tack "s"_2 tack.l Gamma''$,
|
|
$Gamma tack "s"_1; "s"_2 tack.l Gamma''$,
|
|
```py a = 3; a: int```
|
|
),
|
|
rule(
|
|
"T-IfElse",
|
|
$Gamma tack "t": "bool"$,
|
|
$Gamma tack "s"_1 tack.l Gamma'$,
|
|
$Gamma tack "s"_2 tack.l Gamma''$,
|
|
$Gamma tack #syntax[if] "t": "s"_1 #syntax[else]: "s"_2 tack.l Gamma$,
|
|
```py
|
|
if cond:
|
|
...
|
|
else:
|
|
...
|
|
```,
|
|
),
|
|
rule(
|
|
"T-Def",
|
|
$Gamma, f: "T"_1 -> "T"_2, "x": "T"_1 tack "t": "T"_2$,
|
|
$ Gamma tack cases(delim: #none, #syntax[def] &f("x": "T"_1) -> "T"_2:, &#syntax[return] "t") space tack.l space Gamma, f: "T"_1 -> "T"_2 $,
|
|
```py
|
|
def func(a: S) -> T:
|
|
return ...: T
|
|
```,
|
|
),
|
|
)
|
|
|
|
#let subtyping-rules = (
|
|
rule(
|
|
"S-Refl",
|
|
$"S" <: "S"$,
|
|
none,
|
|
),
|
|
rule(
|
|
"S-Trans",
|
|
$"S" <: "U"$,
|
|
$"U" <: "T"$,
|
|
$"S" <: "T"$,
|
|
none,
|
|
),
|
|
rule(
|
|
"T-Sub",
|
|
$Gamma tack "t": "S"$,
|
|
$"S" <: "T"$,
|
|
$Gamma tack "t": "T"$,
|
|
none,
|
|
),
|
|
)
|
|
|
|
#let rules-grid(rules, columns: 1, large: false) = {
|
|
let cells = rules.map(
|
|
r => (r.rule, r.python)
|
|
).chunks(columns).flatten()
|
|
let header = ([*Rule*], [*Python example*]) * columns
|
|
grid(
|
|
columns: (auto, if large {1fr} else {auto}) * columns,
|
|
//row-gutter: 2em,
|
|
//column-gutter: 1em,
|
|
column-gutter: (0pt, 3em) * columns,
|
|
inset: (x:.5em, y: 1em),
|
|
align: (center+horizon, right+horizon),
|
|
//stroke: (x, _) => if calc.rem(x, 2) == 0 and x != 0 {(left: black)},
|
|
grid.header(..header),
|
|
..cells,
|
|
)
|
|
}
|
|
|
|
#let literals = rules-grid(literals-rules, columns: 2)
|
|
#let expressions = rules-grid(expressions-rules)
|
|
#let statements = rules-grid(statements-rules, large: true)
|
|
#let subtyping = curryst.rule-set(
|
|
..subtyping-rules.map(r => r.rule)
|
|
)
|
|
#let subtyping-constraint = curryst.prooftree(
|
|
curryst.rule(
|
|
$"S" <: "T"$,
|
|
$"S" #syntax[where] "e" <: "T"$,
|
|
name: smallcaps[(S-Constr)],
|
|
)
|
|
)
|
|
#let subtyping-function = curryst.prooftree(
|
|
curryst.rule(
|
|
$"S"_2 <: "S"_1$,
|
|
$"R"_1 <: "R"_2$,
|
|
$#syntax[fn] ("S"_1) -> "R"_1 <: #syntax[fn] ("S"_2) -> "R"_2$,
|
|
name: smallcaps[(S-Func)],
|
|
)
|
|
)
|
|
#let subtyping-top = curryst.rule-set(
|
|
curryst.prooftree(curryst.rule(
|
|
$"T" <: "Any"$,
|
|
name: smallcaps[(S-Any)],
|
|
)),
|
|
curryst.prooftree(curryst.rule(
|
|
$"T" <: "Unknown"$,
|
|
name: smallcaps[(S-Unknown)],
|
|
)),
|
|
) |