Initial working type-checker

This commit is contained in:
Victor Maia 2022-07-13 23:19:47 -03:00
parent 27afb25616
commit 41e2518ddd
6 changed files with 1254 additions and 739 deletions

6
Cargo.lock generated
View File

@ -102,9 +102,9 @@ dependencies = [
[[package]]
name = "hvm"
version = "0.1.31"
version = "0.1.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "361a02d7ed07086c16927712c1bf610e54c3a43bd5d78deab7708f56c33ee5fb"
checksum = "f1e25cb7dd4f63d4640709b13cc1f330189e2195318eaf3ab372d732d12df3aa"
dependencies = [
"clap",
"itertools",
@ -132,7 +132,7 @@ dependencies = [
]
[[package]]
name = "kind2-rs"
name = "kind2"
version = "0.1.0"
dependencies = [
"hvm",

View File

@ -1,9 +1,9 @@
[package]
name = "kind2-rs"
name = "kind2"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
hvm = "0.1.31"
hvm = "0.1.38"

19
README.md Normal file
View File

@ -0,0 +1,19 @@
Kind2
=====
This repository is a WIP.
Usage
-----
1. Install:
```
cargo install --path .
```
2. Check a Kind2 file:
```
kind2 check example.kind2
```

View File

@ -1,611 +0,0 @@
Main =
let term = (Rule0 Main.)
let type = (TypeOf Main.)
(Kind2.Result
(Checked (Check term type Nil 0))
(Reduced (Eval term)))
// Prelude
// -------
// U60.if -(r: Type) U60 r r : r
(U60.if 0 then else) = else
(U60.if 1 then else) = then
// U60.equal U60 U60 : Bool
(U60.equal a b) = (U60.if (== a b) True False)
// Bool.if -(r: Type) Bool r r : r
(Bool.if False then else) = else
(Bool.if True then else) = then
// Bool.and Bool Bool : Bool
(Bool.and True b) = b
(Bool.and False b) = False
// Maybe.case -(a: Type) -(r: Type) (Maybe a) r (a -> r) : r
(Maybe.case None none some) = none
(Maybe.case (Some val) none some) = (some val)
// Result.chain -(a: Type) -(b: Type) (Result a) (a -> Result b) : Result b
(Result.chain (Done val) cont) = (cont val)
(Result.chain (Fail msg) cont) = (Fail msg)
// List.at -(a: Type) (List a) U60 : (Maybe a)
(List.at (Cons x xs) 0) = (Some x)
(List.at (Cons x xs) n) = (List.at xs (- n 1))
(List.at Nil n) = None
// Term.if_all -(r: Type) Term (Term -> (Term -> Term) -> r) r : r
(Term.if_all (All type body) then else) = (then type body)
(Term.if_all other then else) = else
// Arr Term Term : Term
(Arr type retr) = (All type λx(retr))
// Equal Term Term : Bool
// ----------------------
// Var equality
(Equal (Var a.index) (Var b.index) dep) =
(U60.equal a.index b.index)
// Typ equality
(Equal Typ Typ dep) =
True
// All equality
(Equal (All a.type a.body) (All b.type b.body) dep) =
let type = (Equal a.type b.type dep)
let body = (Equal (a.body (Var dep)) (b.body (Var dep)) (+ dep 1))
(Bool.and type body)
// Lam equality
(Equal (Lam a.body) (Lam b.body) dep) =
let body = (Equal (a.body (Var dep)) (b.body (Var dep)) (+ dep 1))
body
// App equality
(Equal (App a.func a.argm) (App b.func b.argm) dep) =
let func = (Equal a.func b.func dep)
let argm = (Equal a.argm b.argm dep)
(Bool.and func argm)
// Ct0 equality
(Equal (Ct0 a.ctid) (Ct0 b.ctid) dep) =
let ctid = (U60.equal (MakeId a.ctid) (MakeId b.ctid))
ctid
// Ct1 equality
(Equal (Ct1 a.ctid a.x0) (Ct1 b.ctid b.x0) dep) =
let ctid = (U60.equal (MakeId a.ctid) (MakeId b.ctid))
let x0 = (Equal a.x0 b.x0 dep)
(Bool.and ctid x0)
// Ct2 equality
(Equal (Ct2 a.ctid a.x0 a.x1) (Ct2 b.ctid b.x0 b.x1) dep) =
let ctid = (U60.equal (MakeId a.ctid) (MakeId b.ctid))
let x0 = (Equal a.x0 b.x0 dep)
let x1 = (Equal a.x1 b.x1 dep)
(Bool.and ctid (Bool.and x0 x1))
// Ct3 equality
(Equal (Ct3 a.ctid a.x0 a.x1 a.x2) (Ct3 b.ctid b.x0 b.x1 b.x2) dep) =
let ctid = (U60.equal (MakeId a.ctid) (MakeId b.ctid))
let x0 = (Equal a.x0 b.x0 dep)
let x1 = (Equal a.x1 b.x1 dep)
let x2 = (Equal a.x2 b.x2 dep)
(Bool.and ctid (Bool.and x0 (Bool.and x1 x2)))
// Ct4 equality
(Equal (Ct4 a.ctid a.x0 a.x1 a.x2 a.x3) (Ct4 b.ctid b.x0 b.x1 b.x2 b.x3) dep) =
let ctid = (U60.equal (MakeId a.ctid) (MakeId b.ctid))
let x0 = (Equal a.x0 b.x0 dep)
let x1 = (Equal a.x1 b.x1 dep)
let x2 = (Equal a.x2 b.x2 dep)
let x3 = (Equal a.x3 b.x3 dep)
(Bool.and ctid (Bool.and x0 (Bool.and x1 (Bool.and x2 x3))))
// Ct5 equality
(Equal (Ct5 a.ctid a.x0 a.x1 a.x2 a.x3 a.x4) (Ct5 b.ctid b.x0 b.x1 b.x2 b.x3 b.x4) dep) =
let ctid = (U60.equal (MakeId a.ctid) (MakeId b.ctid))
let x0 = (Equal a.x0 b.x0 dep)
let x1 = (Equal a.x1 b.x1 dep)
let x2 = (Equal a.x2 b.x2 dep)
let x3 = (Equal a.x3 b.x3 dep)
let x4 = (Equal a.x4 b.x4 dep)
(Bool.and ctid (Bool.and x0 (Bool.and x1 (Bool.and x2 (Bool.and x3 x4)))) )
// Ct6 equality
(Equal (Ct6 a.ctid a.x0 a.x1 a.x2 a.x3 a.x4 a.x5) (Ct6 b.ctid b.x0 b.x1 b.x2 b.x3 b.x4 b.x5) dep) =
let ctid = (U60.equal (MakeId a.ctid) (MakeId b.ctid))
let x0 = (Equal a.x0 b.x0 dep)
let x1 = (Equal a.x1 b.x1 dep)
let x2 = (Equal a.x2 b.x2 dep)
let x3 = (Equal a.x3 b.x3 dep)
let x4 = (Equal a.x4 b.x4 dep)
let x5 = (Equal a.x5 b.x5 dep)
(Bool.and ctid (Bool.and x0 (Bool.and x1 (Bool.and x2 (Bool.and x3 (Bool.and x4 x5))))))
// Ct7 equality
(Equal (Ct7 a.ctid a.x0 a.x1 a.x2 a.x3 a.x4 a.x5 a.x6) (Ct7 b.ctid b.x0 b.x1 b.x2 b.x3 b.x4 b.x5 b.x6) dep) =
let ctid = (U60.equal (MakeId a.ctid) (MakeId b.ctid))
let x0 = (Equal a.x0 b.x0 dep)
let x1 = (Equal a.x1 b.x1 dep)
let x2 = (Equal a.x2 b.x2 dep)
let x3 = (Equal a.x3 b.x3 dep)
let x4 = (Equal a.x4 b.x4 dep)
let x5 = (Equal a.x5 b.x5 dep)
let x6 = (Equal a.x6 b.x6 dep)
(Bool.and ctid (Bool.and x0 (Bool.and x1 (Bool.and x2 (Bool.and x3 (Bool.and x4 (Bool.and x5 x6)))))))
// Ct8 equality
(Equal (Ct8 a.ctid a.x0 a.x1 a.x2 a.x3 a.x4 a.x5 a.x6 a.x7) (Ct8 b.ctid b.x0 b.x1 b.x2 b.x3 b.x4 b.x5 b.x6 b.x7) dep) =
let ctid = (U60.equal (MakeId a.ctid) (MakeId b.ctid))
let x0 = (Equal a.x0 b.x0 dep)
let x1 = (Equal a.x1 b.x1 dep)
let x2 = (Equal a.x2 b.x2 dep)
let x3 = (Equal a.x3 b.x3 dep)
let x4 = (Equal a.x4 b.x4 dep)
let x5 = (Equal a.x5 b.x5 dep)
let x6 = (Equal a.x6 b.x6 dep)
let x7 = (Equal a.x7 b.x7 dep)
(Bool.and ctid (Bool.and x0 (Bool.and x1 (Bool.and x2 (Bool.and x3 (Bool.and x4 (Bool.and x5 (Bool.and x6 x7))))))))
// Not equal
(Equal a b dep) =
False
// Infer Term (List Term) U60 : Result Term
// ----------------------------------------
// Infers Var
(Infer (Var index) ctx dep) =
(Maybe.case (List.at ctx (- (- dep index) 1))
// case none:
(Fail UnboundVariable)
// case some:
λvar_type (Done var_type))
// Infers Typ
(Infer Typ ctx dep) =
(Done Typ)
// Infers All
(Infer (All type body) ctx dep) =
(Result.chain (Check type Typ ctx dep) λtype_chk
(Result.chain (Check (body (Var dep)) Typ (Cons type ctx) (+ dep 1)) λbody_chk
(Done Typ)))
// Infers Lam
(Infer (Lam body) ctx dep) =
(Fail CantInferLambda)
// Infers App
(Infer (App func argm) ctx dep) =
(Result.chain (Infer func ctx dep) λfunc_typ
(Term.if_all func_typ
// then
λfunc_typ_type λfunc_typ_body
(Result.chain (Check argm func_typ_type ctx dep) λargm_chk
(Done (func_typ_body argm)))
// else
(Fail NonFunctionApplication)
))
// Infers Ct0
(Infer (Ct0 ctid) ctx dep) =
(Done (TypeOf ctid))
// Infers Ct1
(Infer (Ct1 ctid x0) ctx dep) =
(Infer (App (Ct0 ctid) x0) ctx dep)
// Infers Ct2
(Infer (Ct2 ctid x0 x1) ctx dep) =
(Infer (App (App (Ct0 ctid) x0) x1) ctx dep)
// Infers Ct3
(Infer (Ct3 ctid x0 x1 x2) ctx dep) =
(Infer (App (App (App (Ct0 ctid) x0) x1) x2) ctx dep)
// Infers Ct4
(Infer (Ct4 ctid x0 x1 x2 x3) ctx dep) =
(Infer (App (App (App (App (Ct0 ctid) x0) x1) x2) x3) ctx dep)
// Infers Ct5
(Infer (Ct5 ctid x0 x1 x2 x3 x4) ctx dep) =
(Infer (App (App (App (App (App (Ct0 ctid) x0) x1) x2) x3) x4) ctx dep)
// Infers Ct6
(Infer (Ct6 ctid x0 x1 x2 x3 x4 x5) ctx dep) =
(Infer (App (App (App (App (App (App (Ct0 ctid) x0) x1) x2) x3) x4) x5) ctx dep)
// Infers Ct7
(Infer (Ct7 ctid x0 x1 x2 x3 x4 x5 x6) ctx dep) =
(Infer (App (App (App (App (App (App (App (Ct0 ctid) x0) x1) x2) x3) x4) x5) x6) ctx dep)
// Infers Ct8
(Infer (Ct8 ctid x0 x1 x2 x3 x4 x5 x6 x7) ctx dep) =
(Infer (App (App (App (App (App (App (App (App (Ct0 ctid) x0) x1) x2) x3) x4) x5) x6) x7) ctx dep)
// Infers Fn0
(Infer (Fn0 ctid) ctx dep) =
(Done (TypeOf ctid))
// Infers Fn1
(Infer (Fn1 ctid x0) ctx dep) =
(Infer (App (Fn0 ctid) x0) ctx dep)
// Infers Fn2
(Infer (Fn2 ctid x0 x1) ctx dep) =
(Infer (App (App (Fn0 ctid) x0) x1) ctx dep)
// Infers Fn3
(Infer (Fn3 ctid x0 x1 x2) ctx dep) =
(Infer (App (App (App (Fn0 ctid) x0) x1) x2) ctx dep)
// Infers Fn4
(Infer (Fn4 ctid x0 x1 x2 x3) ctx dep) =
(Infer (App (App (App (App (Fn0 ctid) x0) x1) x2) x3) ctx dep)
// Infers Fn5
(Infer (Fn5 ctid x0 x1 x2 x3 x4) ctx dep) =
(Infer (App (App (App (App (App (Fn0 ctid) x0) x1) x2) x3) x4) ctx dep)
// Infers Fn6
(Infer (Fn6 ctid x0 x1 x2 x3 x4 x5) ctx dep) =
(Infer (App (App (App (App (App (App (Fn0 ctid) x0) x1) x2) x3) x4) x5) ctx dep)
// Infers Fn7
(Infer (Fn7 ctid x0 x1 x2 x3 x4 x5 x6) ctx dep) =
(Infer (App (App (App (App (App (App (App (Fn0 ctid) x0) x1) x2) x3) x4) x5) x6) ctx dep)
// Infers Fn8
(Infer (Fn8 ctid x0 x1 x2 x3 x4 x5 x6 x7) ctx dep) =
(Infer (App (App (App (App (App (App (App (App (Fn0 ctid) x0) x1) x2) x3) x4) x5) x6) x7) ctx dep)
// Check Term Term (List Term) U60 : Result Unit
// ---------------------------------------------
// Checks Lam
(Check (Lam body) (All t_type t_body) ctx dep) =
(Result.chain (Check (body (Var dep)) (t_body (Var dep)) (Cons t_type ctx) (+ dep 1)) λbody_chk
(Done Unit))
// Checks others
(Check term type ctx dep) =
(Result.chain (Infer term ctx dep) λterm_typ
(Bool.if (Equal term_typ type dep)
// then
(Done Unit)
// else
(Fail (TypeMismatch term_typ type)) // TODO: pass up for Rust to display
))
// Show Term U60 : Term
// ---------------------
// Show Var
(Show (Var index) dep) =
(Var index)
// Show Typ
(Show Typ dep) =
Typ
// Show All
(Show (All type body) dep) =
(All (Show type dep) λx (Show (body (Var dep)) (+ dep 1)))
// Show Lam
(Show (Lam body) dep) =
(Lam λx (Show (body (Var dep)) (+ dep 1)))
// Show App
(Show (App func argm) dep) =
(App (Show func dep) (Show argm dep))
// Show Ct0
(Show (Ct0 ctid) dep) =
(Ct0 ctid)
// Show Ct1
(Show (Ct1 ctid x0) dep) =
(Ct1 ctid (Show x0 dep))
// Show Ct2
(Show (Ct2 ctid x0 x1) dep) =
(Ct2 ctid (Show x0 dep) (Show x1 dep))
// Show Ct3
(Show (Ct3 ctid x0 x1 x2) dep) =
(Ct3 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep))
// Show Ct4
(Show (Ct4 ctid x0 x1 x2 x3) dep) =
(Ct4 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep) (Show x3 dep))
// Show Ct5
(Show (Ct5 ctid x0 x1 x2 x3 x4) dep) =
(Ct5 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep) (Show x3 dep) (Show x4 dep))
// Show Ct6
(Show (Ct6 ctid x0 x1 x2 x3 x4 x5) dep) =
(Ct6 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep) (Show x3 dep) (Show x4 dep) (Show x5 dep))
// Show Ct7
(Show (Ct7 ctid x0 x1 x2 x3 x4 x5 x6) dep) =
(Ct7 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep) (Show x3 dep) (Show x4 dep) (Show x5 dep) (Show x6 dep))
// Show Ct8
(Show (Ct8 ctid x0 x1 x2 x3 x4 x5 x6 x7) dep) =
(Ct8 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep) (Show x3 dep) (Show x4 dep) (Show x5 dep) (Show x6 dep) (Show x7 dep))
// Show Fn0
(Show (Fn0 ctid) dep) =
(Fn0 ctid)
// Show Fn1
(Show (Fn1 ctid x0) dep) =
(Fn1 ctid (Show x0 dep))
// Show Fn2
(Show (Fn2 ctid x0 x1) dep) =
(Fn2 ctid (Show x0 dep) (Show x1 dep))
// Show Fn3
(Show (Fn3 ctid x0 x1 x2) dep) =
(Fn3 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep))
// Show Fn4
(Show (Fn4 ctid x0 x1 x2 x3) dep) =
(Fn4 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep) (Show x3 dep))
// Show Fn5
(Show (Fn5 ctid x0 x1 x2 x3 x4) dep) =
(Fn5 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep) (Show x3 dep) (Show x4 dep))
// Show Fn6
(Show (Fn6 ctid x0 x1 x2 x3 x4 x5) dep) =
(Fn6 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep) (Show x3 dep) (Show x4 dep) (Show x5 dep))
// Show Fn7
(Show (Fn7 ctid x0 x1 x2 x3 x4 x5 x6) dep) =
(Fn7 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep) (Show x3 dep) (Show x4 dep) (Show x5 dep) (Show x6 dep))
// Show Fn8
(Show (Fn8 ctid x0 x1 x2 x3 x4 x5 x6 x7) dep) =
(Fn8 ctid (Show x0 dep) (Show x1 dep) (Show x2 dep) (Show x3 dep) (Show x4 dep) (Show x5 dep) (Show x6 dep) (Show x7 dep))
// Eval Term (List Term) : Term
// ----------------------------
// Eval Var
(Eval (Var index)) =
(Var index)
// Eval Typ
(Eval Typ) =
Typ
// Eval All
(Eval (All type body)) =
(All (Eval type) λx (Eval (body x)))
// Eval Lam
(Eval (Lam body)) =
(Lam λx (Eval (body x)))
// Eval App
(Eval (App func argm)) =
(Apply (Eval func) (Eval argm))
// Eval Ct0
(Eval (Ct0 ctid)) =
(Ct0 ctid)
// Eval Ct1
(Eval (Ct1 ctid x0)) =
(Ct1 ctid (Eval x0))
// Eval Ct2
(Eval (Ct2 ctid x0 x1)) =
(Ct2 ctid (Eval x0) (Eval x1))
// Eval Ct3
(Eval (Ct3 ctid x0 x1 x2)) =
(Ct3 ctid (Eval x0) (Eval x1) (Eval x2))
// Eval Ct4
(Eval (Ct4 ctid x0 x1 x2 x3)) =
(Ct4 ctid (Eval x0) (Eval x1) (Eval x2) (Eval x3))
// Eval Ct5
(Eval (Ct5 ctid x0 x1 x2 x3 x4)) =
(Ct5 ctid (Eval x0) (Eval x1) (Eval x2) (Eval x3) (Eval x4))
// Eval Ct6
(Eval (Ct6 ctid x0 x1 x2 x3 x4 x5)) =
(Ct6 ctid (Eval x0) (Eval x1) (Eval x2) (Eval x3) (Eval x4) (Eval x5))
// Eval Ct7
(Eval (Ct7 ctid x0 x1 x2 x3 x4 x5 x6)) =
(Ct7 ctid (Eval x0) (Eval x1) (Eval x2) (Eval x3) (Eval x4) (Eval x5) (Eval x6))
// Eval Ct8
(Eval (Ct8 ctid x0 x1 x2 x3 x4 x5 x6 x7)) =
(Ct8 ctid (Eval x0) (Eval x1) (Eval x2) (Eval x3) (Eval x4) (Eval x5) (Eval x6) (Eval x7))
// Eval Fn0
(Eval (Fn0 ctid)) =
(Eval (Rule0 ctid))
// Eval Fn1
(Eval (Fn1 ctid x0)) =
(Eval (Rule1 ctid (Eval x0)))
// Eval Fn2
(Eval (Fn2 ctid x0 x1)) =
(Eval (Rule2 ctid (Eval x0) (Eval x1)))
// Eval Fn3
(Eval (Fn3 ctid x0 x1 x2)) =
(Eval (Rule3 ctid (Eval x0) (Eval x1) (Eval x2)))
// Eval Fn4
(Eval (Fn4 ctid x0 x1 x2 x3)) =
(Eval (Rule4 ctid (Eval x0) (Eval x1) (Eval x2) (Eval x3)))
// Eval Fn5
(Eval (Fn5 ctid x0 x1 x2 x3 x4)) =
(Eval (Rule5 ctid (Eval x0) (Eval x1) (Eval x2) (Eval x3) (Eval x4)))
// Eval Fn6
(Eval (Fn6 ctid x0 x1 x2 x3 x4 x5)) =
(Eval (Rule6 ctid (Eval x0) (Eval x1) (Eval x2) (Eval x3) (Eval x4) (Eval x5)))
// Eval Fn7
(Eval (Fn7 ctid x0 x1 x2 x3 x4 x5 x6)) =
(Eval (Rule7 ctid (Eval x0) (Eval x1) (Eval x2) (Eval x3) (Eval x4) (Eval x5) (Eval x6)))
// Eval Fn8
(Eval (Fn8 ctid x0 x1 x2 x3 x4 x5 x6 x7)) =
(Eval (Rule8 ctid (Eval x0) (Eval x1) (Eval x2) (Eval x3) (Eval x4) (Eval x5) (Eval x6) (Eval x7)))
// Apply Term Term : Term
// ----------------------
(Apply (Lam fbody) argm) = (fbody argm)
(Apply func argm) = (App func argm)
//// Reduction Rules
//// ---------------
//(Call1 Not. (Ct0 True.)) = (Eval (Ct0 False.))
//(Call1 Not. (Ct0 False.)) = (Eval (Ct0 True.))
//(Call2 And. (Ct0 True.) (Ct0 True.)) = (Eval (Ct0 True.))
//(Call2 And. (Ct0 True.) (Ct0 False.)) = (Eval (Ct0 True.))
//(Call2 And. (Ct0 False.) (Ct0 True.)) = (Eval (Ct0 True.))
//(Call2 And. (Ct0 False.) (Ct0 False.)) = (Eval (Ct0 True.))
//(Call1 Theo. (Ct0 True.)) = (Eval (Ct0 Refl.))
//(Call1 Theo. (Ct0 False.)) = (Eval (Ct0 Refl.))
//(Call1 Mul2. (Ct0 Zero.)) = (Eval (Ct0 Zero.))
//(Call1 Mul2. (Ct1 Succ. n)) = (Eval (Ct1 Succ. (Ct1 Succ. (Call1 Mul2. n))))
//(Call1 F. a) = (Eval (Lam λb (Fn2 G. a b)))
//(Call2 G. (Ct0 U.) (Ct0 U.)) = (Eval (Lam λx x))
//(Call0 Test.0.) = (Eval (App (Fn1 F. (Ct0 U.)) (Ct0 U.)))
//(Call0 Test.1.) = (Eval (Fn1 Mul2. (Fn1 Mul2. (Ct1 Succ. (Ct1 Succ. (Ct0 Zero.))))))
//// Type Annotations
//// ----------------
//(TypeOf Bool.) = Typ
//(TypeOf True.) = (Ct0 Bool.)
//(TypeOf False.) = (Ct0 Bool.)
//(TypeOf Nat.) = Typ
//(TypeOf Zero.) = (Ct0 Nat.)
//(TypeOf Succ.) = (All (Ct0 Nat.) λx0 (Ct0 Nat.))
//(TypeOf Not.) = (All (Ct0 Bool.) λx0 (Ct0 Bool.))
//(TypeOf And.) = (All (Ct0 Bool.) λx0 (All (Ct0 Bool.) λx1 (Ct0 Bool.)))
//// Label to Id
//// -----------
//(MakeId Bool.) = 0
//(MakeId True.) = 1
//(MakeId False.) = 2
//(MakeId Nat.) = 3
//(MakeId Zero.) = 4
//(MakeId Succ.) = 5
// User-Defined Functions
// ----------------------
// Nat
// ---
(MakeId Nat.) = %Nat
(TypeOf Nat.) = Typ
// False
// -----
(MakeId False.) = %False
(TypeOf False.) = (Ct0 Bool.)
// List
// ----
(MakeId List.) = %List
(TypeOf List.) = (All Typ λa Typ)
// True
// ----
(MakeId True.) = %True
(TypeOf True.) = (Ct0 Bool.)
// Bool
// ----
(MakeId Bool.) = %Bool
(TypeOf Bool.) = Typ
// Succ
// ----
(MakeId Succ.) = %Succ
(TypeOf Succ.) = (All (Ct0 Nat.) λpred (Ct0 Nat.))
// Negate
// ------
(MakeId Negate.) = %Negate
(TypeOf Negate.) = (All (Ct1 List. (Ct0 Bool.)) λxs (Ct1 List. (Ct0 Bool.)))
(Rule1 Negate. (Ct3 Cons. (Ct0 Bool.) x xs)) = (Ct3 Cons. (Ct0 Bool.) (Fn1 Not. x) (Fn1 Negate. xs))
(Rule1 Negate. (Ct1 Nil. (Ct0 Bool.))) = (Ct1 Nil. (Ct0 Bool.))
// Cons
// ----
(MakeId Cons.) = %Cons
(TypeOf Cons.) = (All Typ λa (All a λx (All (Ct1 List. a) λxs (Ct1 List. a))))
// And
// ---
(MakeId And.) = %And
(TypeOf And.) = (All (Ct0 Bool.) λa (All (Ct0 Bool.) λb (Ct0 Bool.)))
(Rule2 And. (Ct0 True.) (Ct0 True.)) = (Ct0 True.)
(Rule2 And. (Ct0 True.) (Ct0 False.)) = (Ct0 False.)
(Rule2 And. (Ct0 False.) (Ct0 True.)) = (Ct0 False.)
(Rule2 And. (Ct0 False.) (Ct0 False.)) = (Ct0 False.)
// Not
// ---
(MakeId Not.) = %Not
(TypeOf Not.) = (All (Ct0 Bool.) λa (Ct0 Bool.))
(Rule1 Not. (Ct0 True.)) = (Ct0 False.)
(Rule1 Not. (Ct0 False.)) = (Ct0 True.)
// Nil
// ---
(MakeId Nil.) = %Nil
(TypeOf Nil.) = (All Typ λa (Ct1 List. a))
// Zero
// ----
(MakeId Zero.) = %Zero
(TypeOf Zero.) = (Ct0 Nat.)
// Main
// ----
(MakeId Main.) = %Main
(TypeOf Main.) = (Ct1 List. (Ct0 Bool.))
(Rule0 Main.) = (Fn1 Negate. (Ct3 Cons. (Ct0 Bool.) (Ct0 True.) (Ct3 Cons. (Ct0 Bool.) (Ct0 False.) (Ct1 Nil. (Ct0 Bool.)))))

1081
src/checker.hvm Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,58 +4,40 @@
// TODO: type{} syntax
use std::collections::HashMap;
// type Bool {
// {True}
// {False}
// }
//
// type List <T: Type> {
// {Nil}
// {Cons T (List <T>)}
// }
//
// type Equal <T: Type> (a: T) ~ (b: T) {
// {Refl} ~ (b = a)
// }
//
// Add (a: Nat) (b: Nat) : Nat {
// Add {Zero} b => b
// Add {Succ a} b => {Succ (Add a b)}
// }
//
// Add (a: Nat) (b: Nat) : Nat =
// match a {
// Add {Zero} => b
// Add {Succ a} => {Succ (Add a b)}
// }
//
// Map <A: Type> <B: Type> (f: A -> B) (xs: List A) : List B {
// Map A B f {Cons x xs} => {Cons (f x) (map A B f xs)}
// Map A B f {Nil} => {Nil}
// }
//
// Main : (List Nat) =
// let x = 50
// let y = 60
// if (== x y) {
// (print "hi")
// } else {
// (print "bye")
// }
//
// alice : Person =
// {Person
// age: 40
// name: "Alice"
// items: ["Foo", "Bar", "Tic", "Tac"]
// }
//
// {Cons x xs}
// {Cons head: x tail: xs }
use hvm::parser as parser;
fn main() -> Result<(), String> {
let args: Vec<String> = std::env::args().collect();
if args.len() <= 2 || args[1] != "check" {
println!("{:?}", args);
println!("Usage: kind2 check file.kind");
return Ok(());
}
let path = &args[2];
let file = match std::fs::read_to_string(path) {
Ok(code) => read_file(&code)?,
Err(msg) => read_file(&DEMO_CODE)?,
};
let code = compile_file(&file);
let mut checker = (&CHECKER_HVM[0 .. CHECKER_HVM.find("////INJECT////").unwrap()]).to_string();
checker.push_str(&code);
//std::fs::write("check.tmp.hvm", checker.clone()).ok(); writes checker to the checker.hvm file
let mut rt = hvm::Runtime::from_code(&checker)?;
let main = rt.alloc_code("Main")?;
rt.normalize(main);
println!("{}", readback_string(&rt, main)); // TODO: optimize by deserializing term into text directly
return Ok(());
}
const CHECKER_HVM: &str = include_str!("checker.hvm");
#[derive(Clone, Debug)]
pub enum Term {
Typ,
@ -256,7 +238,11 @@ pub fn parse_entry(state: parser::State) -> parser::Answer<Box<Entry>> {
if head == '=' {
let (state, _) = parser::consume("=", state)?;
let (state, body) = parse_term(state)?;
let rules = vec![Box::new(Rule { name: name.clone(), pats: vec![], body })];
let mut pats = vec![];
for arg in &args {
pats.push(Box::new(Term::Var { name: arg.name.clone() }));
}
let rules = vec![Box::new(Rule { name: name.clone(), pats, body })];
return Ok((state, Box::new(Entry { name, args, tipo, rules })));
} else if head == '{' {
let (state, _) = parser::consume("{", state)?;
@ -426,12 +412,6 @@ pub fn compile_term(term: &Term) -> String {
}
}
//pub struct Entry {
//name: String,
//args: Vec<Box<Argument>>,
//tipo: Box<Term>,
//rules: Vec<Box<Rule>>
//}
pub fn compile_entry(entry: &Entry) -> String {
fn compile_type(args: &Vec<Box<Argument>>, tipo: &Box<Term>, index: usize) -> String {
if index < args.len() {
@ -454,17 +434,67 @@ pub fn compile_entry(entry: &Entry) -> String {
return text;
}
fn compile_rule_chk(rule: &Rule, index: usize, vars: &mut u64, args: &mut Vec<String>) -> String {
if index < rule.pats.len() {
let (inp_patt_str, var_patt_str) = compile_patt_chk(&rule.pats[index], vars);
args.push(var_patt_str);
let head = inp_patt_str;
let tail = compile_rule_chk(rule, index + 1, vars, args);
return format!("(LHS {} {})", head, tail);
} else {
return format!("(RHS (Rule{} {}.{}))", index, rule.name, args.iter().map(|x| format!(" {}", x)).collect::<Vec<String>>().join(""));
}
}
fn compile_patt_chk(patt: &Term, vars: &mut u64) -> (String, String) {
match patt {
Term::Var { .. } => {
let inp = format!("(Inp {})", vars);
let var = format!("(Var {})", vars);
*vars += 1;
return (inp, var);
}
Term::Ctr { name, args } => {
let mut inp_args_str = String::new();
let mut var_args_str = String::new();
for arg in args {
let (inp_arg_str, var_arg_str) = compile_patt_chk(arg, vars);
inp_args_str.push_str(&format!(" {}", inp_arg_str));
var_args_str.push_str(&format!(" {}", var_arg_str));
}
let inp_str = format!("(Ct{} {}.{})", args.len(), name, inp_args_str);
let var_str = format!("(Ct{} {}.{})", args.len(), name, var_args_str);
return (inp_str, var_str);
}
_ => {
panic!("Invalid left-hand side pattern: {}", show_term(patt));
}
}
}
let mut result = String::new();
result.push_str(&format!(" (MakeId {}.) = %{}\n", entry.name, entry.name));
result.push_str(&format!(" (NameOf {}.) = \"{}\"\n", entry.name, entry.name));
result.push_str(&format!(" (HashOf {}.) = %{}\n", entry.name, entry.name));
result.push_str(&format!(" (TypeOf {}.) = {}\n", entry.name, compile_type(&entry.args, &entry.tipo, 0)));
for rule in &entry.rules {
result.push_str(&compile_rule(&rule));
}
result.push_str(&format!(" (Verify {}.) =\n", entry.name));
for rule in &entry.rules {
result.push_str(&format!(" (Cons {}\n", compile_rule_chk(&rule, 0, &mut 0, &mut vec![])));
}
result.push_str(&format!(" Nil{}\n", ")".repeat(entry.rules.len())));
return result;
}
pub fn compile_file(file: &File) -> String {
let mut result = String::new();
result.push_str(&format!("\n Functions =\n"));
result.push_str(&format!(" let fns = Nil\n"));
for entry in file.entries.values() {
result.push_str(&format!(" let fns = (Cons {}. fns)\n", entry. name));
}
result.push_str(&format!(" fns\n\n"));
for entry in file.entries.values() {
result.push_str(&format!(" // {}\n", entry.name));
result.push_str(&format!(" // {}\n", "-".repeat(entry.name.len())));
@ -475,70 +505,66 @@ pub fn compile_file(file: &File) -> String {
return result;
}
fn main() -> Result<(), String> {
//let file = read_file("
//Bool : Type
//True : Bool
//False : Bool
//List (a: Type) : Type
//Nil (a: Type) : (List a)
//Cons (a: Type) (x: a) (xs: (List a)) : (List a)
//Add (a: Nat) (b: Nat) : Nat {
//Add {Zero} b = b
//Add {Succ a} b = {Succ (Add a b)}
//}
//Not (a: Bool) : Bool {
//Not {True} = {False}
//Not {False} = {True}
//}
//Map (a: Type) (b: Type) (f: (x: a) a) (xs: {List a}) : {List b} {
//Map a b f {Cons x xs} = {Cons (f x) (Map a b f xs)}
//Map a b f Nil = {Nil}
//}
//")?;
let file = read_file("
Bool : Type
True : Bool
False : Bool
Nat : Type
Zero : Nat
Succ (pred: Nat) : Nat
List (a: Type) : Type
Nil (a: Type) : {List a}
Cons (a: Type) (x: a) (xs: {List a}) : {List a}
Not (a: Bool) : Bool {
Not True = False
Not False = True
fn readback_string(rt: &hvm::Runtime, host: u64) -> String {
let str_cons = rt.get_id("String.cons");
let str_nil = rt.get_id("String.nil");
let mut term = rt.ptr(host);
let mut text = String::new();
//let str_cons = rt.
loop {
if hvm::get_tag(term) == hvm::CTR {
let fid = hvm::get_ext(term);
if fid == str_cons {
let head = rt.ptr(hvm::get_loc(term, 0));
let tail = rt.ptr(hvm::get_loc(term, 1));
if hvm::get_tag(head) == hvm::NUM {
text.push(std::char::from_u32(hvm::get_num(head) as u32).unwrap_or('?'));
term = tail;
continue;
}
}
if fid == str_nil {
break;
}
}
And (a: Bool) (b: Bool) : Bool {
And True True = True
And True False = False
And False True = False
And False False = False
}
Negate (xs: {List Bool}) : {List Bool} {
Negate {Cons Bool x xs} = {Cons Bool (Not x) (Negate xs)}
Negate {Nil Bool} = {Nil Bool}
}
Main : {List Bool} = (Negate {Cons Bool True {Cons Bool False {Nil Bool}}})
")?;
println!("Parsed:\n\n{}\n\n", show_file(&file));
println!("Compiled:\n\n");
println!("{}", compile_file(&file));
return Ok(());
panic!("Invalid output: {} {}", hvm::get_tag(term), rt.show(host));
}
return text;
}
const DEMO_CODE: &str = "
Bool : Type
True : Bool
False : Bool
Nat : Type
Zero : Nat
Succ (pred: Nat) : Nat
List (a: Type) : Type
Nil (a: Type) : {List a}
Cons (a: Type) (x: a) (xs: {List a}) : {List a}
Not (a: Bool) : Bool {
Not True = False
Not False = True
}
And (a: Bool) (b: Bool) : Bool {
And True True = True
And True False = False
And False True = False
And False False = False
}
Negate (xs: {List Bool}) : {List Bool} {
Negate {Cons Bool x xs} = {Cons Bool (Not x) (Negate xs)}
Negate {Nil Bool} = {Nil Bool}
}
Tail (a: Type) (xs: {List a}) : {List a} {
Tail a {Cons t x xs} = xs
}
Main (x: Bool) (y: Nat) : {List Bool} = (Tail Bool {Cons Bool x {Cons Bool y {Nil Bool}}})
";