https://github.com/tensor-fusion/coquand-sml
A bidirectional dependent type checker in Standard ML
https://github.com/tensor-fusion/coquand-sml
dependent-types sml type-checker
Last synced: 5 months ago
JSON representation
A bidirectional dependent type checker in Standard ML
- Host: GitHub
- URL: https://github.com/tensor-fusion/coquand-sml
- Owner: tensor-fusion
- License: apache-2.0
- Created: 2024-08-02T07:56:00.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2024-08-02T08:10:11.000Z (12 months ago)
- Last Synced: 2025-01-10T16:23:48.663Z (6 months ago)
- Topics: dependent-types, sml, type-checker
- Language: Standard ML
- Homepage:
- Size: 9.77 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Bidirectional dependent type checker in Standard ML
This is a Standard ML implementation of a bidirectional dependent type checker based on Coquand's algorithm [1].
## Type system
The type checker is quite simple, it implements a core dependent type system with just:
- Lambda abstractions (λ-terms)
- Let expressions
- Function application
- Dependent function types (Π-types)
- A single universe `Type`## Core types
```sml
datatype Expression =
Variable of Identifier
| Application of Expression * Expression
| Abstraction of Identifier * Expression
| LetBinding of Identifier * Expression * Expression * Expression
| PiType of Identifier * Expression * Expression
| BaseTypedatatype Value =
GenericValue of int
| AppValue of Value * Value
| TypeValue
| Closure of (Identifier * Value) list * Expression```
The `expression` type represents the language AST and the `value` represents the semantic domain, using closures to handle envs for lexical scoping.
## Type checking algorithm
The core of the type checker uses a bidirectional approach implemented in the mutually recursive functions `checkExpression` and `inferExpression`.
```sml
checkExpression (k, ρ, Γ) e A = ...
inferExpression (k, ρ, Γ) e = ...
```These correspond to the judgments:
$$
\Gamma \vdash e \Leftarrow A \text{ (checking)}
$$$$
\Gamma \vdash e \Rightarrow A \text{ (inference)}
$$## Normalization
The `normalFormValue` fn implements a simple Normalization by Evaluation strategy to compare types up to β-equivalence.
```sml
normalFormValue value =
case value of
AppValue (func, arg) => applyValue (normalFormValue func) (normalFormValue arg)
| Closure (env, body) => evaluate env body
| _ => value
```## Example
Here's how we can represent and type-check the polymorphic identity function:
```sml
val identityFunction = Abstraction ("A", Abstraction ("x", Variable "x"))
val identityType = PiType ("A", TypeConstant, PiType ("x", Variable "A", Variable "A"))val test = typecheck identityFunction identityType
```This corresponds to the $\Pi$-type:
$$
\Pi (A : \textsf{Type}) . \Pi (x : A) . A
$$## TODO
So far this just implements the paper but some stuff to add might be:- [ ] Σ-types
- [ ] Agda-like hierarchy of universes
- [ ] Inductive types????## References
[1] Coquand, T. (1996). An algorithm for type-checking dependent types