blob: 1f385c7a7ee208e89e34e8cf5f98561240ecce71 [file] [edit]
inductive Vector' (α : Type u) : Nat → Type u
| nil : Vector' α 0
| cons : α → Vector' α n → Vector' α (n+1)
infix:67 " :: " => Vector'.cons
inductive Ty where
| int
| bool
| fn (a r : Ty)
abbrev Ty.interp : Ty → Type
| int => Int
| bool => Bool
| fn a r => a.interp → r.interp
inductive HasType : Fin n → Vector' Ty n → Ty → Type where
| stop : HasType 0 (ty :: ctx) ty
| pop : HasType k ctx ty → HasType k.succ (u :: ctx) ty
inductive Expr : Vector' Ty n → Ty → Type where
| var : HasType i ctx ty → Expr ctx ty
| val : Int → Expr ctx Ty.int
| lam : Expr (a :: ctx) ty → Expr ctx (Ty.fn a ty)
| app : Expr ctx (Ty.fn a ty) → Expr ctx a → Expr ctx ty
| op : (a.interp → b.interp → c.interp) → Expr ctx a → Expr ctx b → Expr ctx c
| ife : Expr ctx Ty.bool → Expr ctx a → Expr ctx a → Expr ctx a
| delay : (Unit → Expr ctx a) → Expr ctx a
inductive Env : Vector' Ty n → Type where
| nil : Env Vector'.nil
| cons : Ty.interp a → Env ctx → Env (a :: ctx)
infix:67 " :: " => Env.cons
def lookup : HasType i ctx ty → Env ctx → ty.interp
| .stop, x :: xs => x
| .pop k, x :: xs => lookup k xs
def interp (env : Env ctx) : Expr ctx ty → ty.interp := fun e =>
match e with
| .var i => lookup i env
| .val x => x
| .lam b => fun x => interp (x :: env) b
| .app f a => interp env f (interp env a)
| .op o x y => o (interp env x) (interp env y)
| .ife c t e => if interp env c then interp env t else interp env e
| .delay a => interp env (a ())
open Expr
/- Examples -/
def add : Expr ctx (Ty.fn Ty.int (Ty.fn Ty.int Ty.int)) :=
lam (lam (op (.+.) (var .stop) (var (.pop .stop))))
#guard interp Env.nil add 10 20 == 30
def fact : Expr ctx (Ty.fn Ty.int Ty.int) :=
lam (ife (op (.==.) (var .stop) (val 0))
(val 1)
(op (.*.) (delay fun _ => app fact (op (.-.) (var .stop) (val 1))) (var .stop)))
decreasing_by sorry
#guard interp Env.nil fact 10 == 3628800