Files
TB-Docs/report/chapters/03_theory/typing.typ

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)],
)),
)