7 | module Language.TypeTheory
9 | import Control.Monad.Error.Interface
17 | private infixl 3 `App`
25 | data Abs : Type -> Type where
29 | Eq t => Eq (Abs t) where
30 | MkAbs b == MkAbs b' = b == b'
40 | data Name : Type where
42 | Global : String -> Name
54 | Global m == Global n = m == n
55 | Local m == Local n = m == n
56 | Quote m == Quote n = m == n
61 | data Ty : Type where
67 | (~>) : (i, o : Ty) -> Ty
72 | Base m == Base n = m == n
73 | (i ~> o) == (a ~> b) = i == a && o == b
85 | data Infer : Type where
87 | Ann : Check -> Ty -> Infer
93 | App : Infer -> Check -> Infer
98 | data Check : Type where
100 | Emb : Infer -> Check
102 | Lam : Abs Check -> Check
104 | substCheck : Nat -> Infer -> Check -> Check
105 | substAbs : Nat -> Infer -> Abs Check -> Abs Check
106 | substInfer : Nat -> Infer -> Infer -> Infer
108 | substCheck lvl u (Emb t) = Emb (substInfer lvl u t)
109 | substCheck lvl u (Lam b) = Lam (substAbs lvl u b)
111 | substAbs lvl u (MkAbs t) = MkAbs (substCheck (S lvl) u t)
113 | substInfer lvl u (Ann s a) = Ann (substCheck lvl u s) a
114 | substInfer lvl u (Bnd k) = ifThenElse (lvl == k) u (Bnd k)
115 | substInfer lvl u (Var nm) = Var nm
116 | substInfer lvl u (App e s) = App (substInfer lvl u e) (substCheck lvl u s)
118 | applyAbs : Abs Check -> Infer -> Check
119 | applyAbs (MkAbs t) u = substCheck 0 u t
127 | data Value : Type where
129 | VLam : (Value -> Value) -> Value
131 | VEmb : Stuck -> Value
134 | data Stuck : Type where
136 | NVar : Name -> Stuck
138 | NApp : Stuck -> Value -> Stuck
142 | vfree : Name -> Value
143 | vfree x = VEmb (NVar x)
148 | vapp : Value -> Value -> Value
149 | vapp (VLam f) t = f t
150 | vapp (VEmb n) t = VEmb (NApp n t)
158 | evalInfer : Infer -> Env -> Value
162 | evalCheck : Check -> Env -> Value
166 | evalAbs : Abs Check -> Env -> Value -> Value
167 | evalAbs (MkAbs t) env v = evalCheck t (v :: env)
169 | evalInfer (Ann t _) env = evalCheck t env
170 | evalInfer (Bnd x) env = case inBounds x env of
171 | Yes prf => index x env
172 | No nprf => idris_crash "INTERNAL ERROR: evalInfer -> impossible case"
173 | evalInfer (Var x) env = vfree x
174 | evalInfer (App f t) env = vapp (evalInfer f env) (evalCheck t env)
176 | evalCheck (Emb i) env = evalInfer i env
177 | evalCheck (Lam b) env = VLam (evalAbs b env)
187 | data Info : Type where
188 | HasKind : Kind -> Info
189 | HasType : Ty -> Info
193 | Context = List (Name, Info)
195 | parameters {0 m : Type -> Type} {auto _ : MonadError String m}
198 | kind : Context -> Kind -> Ty -> m ()
199 | kind ctx Star (Base x) = do
200 | let Just (HasKind Star) = lookup x ctx
201 | | Just _ => throwError "invalid identifier"
202 | | _ => throwError "unknown identifier"
204 | kind ctx Star (i ~> o) = do
209 | inferI : Nat -> Context -> Infer -> m Ty
211 | checkI : Nat -> Context -> Ty -> Check -> m ()
213 | inferI lvl ctx (Ann t ty) = do
215 | ty <$ checkI lvl ctx ty t
216 | inferI lvl ctx (Bnd x) =
219 | inferI lvl ctx (Var v) = do
220 | let Just (HasType ty) = lookup v ctx
221 | | Just _ => throwError "invalid identifier"
222 | | _ => throwError "unknown identifier"
224 | inferI lvl ctx (App f t) = do
225 | (i ~> o) <- inferI lvl ctx f
226 | | _ => throwError "illegal application"
227 | o <$ checkI lvl ctx i t
230 | checkI lvl ctx ty (Emb t) = do
231 | ty' <- inferI lvl ctx t
232 | unless (ty == ty') $
throwError "type mismatch"
234 | checkI lvl ctx ty (Lam b) = do
236 | | _ => throwError "expected a function type"
239 | let b = applyAbs b (Var x)
240 | checkI (S lvl) ((x, k) :: ctx) o b
242 | infer : Context -> Infer -> m Ty
245 | check : Context -> Ty -> Check -> m ()
248 | exampleC : check [(Global "o", HasKind Star)]
249 | (let ty = Base (Global "o") in (ty ~> ty) ~> ty ~> ty)
250 | (Lam (MkAbs (Lam (MkAbs (Emb (Bnd 0))))))
251 | = Right {a = String} ()
254 | boundFree : Nat -> Name -> Infer
255 | boundFree lvl (Quote i) = Bnd (minus lvl (S i))
256 | boundFree lvl x = Var x
258 | quoteStuckI : Nat -> Stuck -> Infer
259 | quoteValueI : Nat -> Value -> Check
260 | quoteAbsI : Nat -> (Value -> Value) -> Abs Check
262 | quoteStuckI lvl (NVar nm) = boundFree lvl nm
263 | quoteStuckI lvl (NApp e t) = App (quoteStuckI lvl e) (quoteValueI lvl t)
265 | quoteValueI lvl (VLam f) = Lam (quoteAbsI lvl f)
266 | quoteValueI lvl (VEmb e) = Emb (quoteStuckI lvl e)
268 | quoteAbsI lvl f = MkAbs (quoteValueI (S lvl) (f (vfree (Quote lvl))))
270 | quoteValue : Value -> Check
271 | quoteValue = quoteValueI 0
274 | normCheck : Check -> Env -> Check
275 | normCheck t env = quoteValue (evalCheck t env)
278 | normInfer : Infer -> Env -> Check
279 | normInfer t env = quoteValue (evalInfer t env)
281 | exampleQ : quoteValue (VLam $
\x => VLam $
\y => x)
282 | = Lam (MkAbs (Lam (MkAbs (Emb (Bnd 1)))))
288 | fromInteger : Integer -> Infer
289 | fromInteger n = Bnd (cast n)
293 | fromString : String -> Check
294 | fromString x = Emb (Var (Global x))
297 | fromInteger : Integer -> Check
298 | fromInteger n = Emb (Bnd (cast n))
302 | CONST = Lam (MkAbs (Lam (MkAbs 1)))
306 | fromString : String -> Ty
307 | fromString x = Base (Global x)
310 | Term1 = Ann ID ("a" ~> "a") `App` "y"
313 | Ctx1 = [(Global "y", HasType "a"), (Global "a", HasKind Star)]
316 | Term2 = Ann CONST (("b" ~> "b") ~> "a" ~> "b" ~> "b")
320 | Ctx2 = (Global "b", HasKind Star) :: Ctx1
322 | test0 : normInfer Term1 [] === "y"
325 | test1 : normInfer Term2 [] === ID
328 | test2 : infer Ctx1 Term1 === Right {a = String} "a"
331 | test3 : infer Ctx2 Term2 === Right {a = String} ("b" ~> "b")
347 | data Infer : Type where
349 | Ann : (t, ty : Check) -> Infer
353 | Pi : (a : Check) -> (b : Abs Check) -> Infer
355 | Bnd : (k : Nat) -> Infer
357 | Var : (nm : Name) -> Infer
359 | App : Infer -> Check -> Infer
365 | data Check : Type where
367 | Emb : Infer -> Check
369 | Lam : Abs Check -> Check
375 | Ann t ty == Ann t' ty' = t == t' && ty == ty'
376 | Star == Star = True
377 | Pi a b == Pi s t = a == s && assert_total (b == t)
378 | Bnd k == Bnd l = k == l
379 | Var m == Var n = m == n
380 | App e s == App f t = e == f && s == t
384 | Emb e == Emb f = assert_total (e == f)
385 | Lam b == Lam t = assert_total (b == t)
388 | substCheck : Nat -> Infer -> Check -> Check
389 | substAbs : Nat -> Infer -> Abs Check -> Abs Check
390 | substInfer : Nat -> Infer -> Infer -> Infer
392 | substAbs lvl u (MkAbs b) = MkAbs (substCheck (S lvl) u b)
395 | substCheck lvl u (Emb t) = Emb (substInfer lvl u t)
396 | substCheck lvl u (Lam b) = Lam (substAbs lvl u b)
398 | substInfer lvl u (Ann s a) = Ann (substCheck lvl u s) (substCheck lvl u a)
399 | substInfer lvl u Star = Star
400 | substInfer lvl u (Pi a b) = Pi (substCheck lvl u a) (substAbs lvl u b)
401 | substInfer lvl u (Bnd k) = ifThenElse (lvl == k) u (Bnd k)
402 | substInfer lvl u (Var nm) = Var nm
403 | substInfer lvl u (App e s) = App (substInfer lvl u e) (substCheck lvl u s)
405 | applyAbs : Abs Check -> Infer -> Check
406 | applyAbs (MkAbs t) u = substCheck 0 u t
413 | data Value : Type where
415 | VLam : (b : Value -> Value) -> Value
420 | VPi : (a : Value) -> (b : Value -> Value) -> Value
422 | VEmb : (e : Stuck) -> Value
424 | data Stuck : Type where
426 | NVar : Name -> Stuck
428 | NApp : Stuck -> Value -> Stuck
436 | Context = List (Name, Ty)
440 | vfree : Name -> Value
441 | vfree x = VEmb (NVar x)
447 | vapp : Value -> Value -> Value
448 | vapp (VLam f) t = f t
449 | vapp (VEmb n) t = VEmb (NApp n t)
450 | vapp _ _ = idris_crash "INTERNAL ERROR: vapp -> impossible case"
458 | evalInfer : Infer -> Env -> Value
462 | evalCheck : Check -> Env -> Value
465 | evalAbs : Abs Check -> Env -> Value -> Value
466 | evalAbs (MkAbs t) env v = evalCheck t (v :: env)
469 | evalInfer (Ann t _) env = evalCheck t env
470 | evalInfer Star env = VStar
471 | evalInfer (Pi a b) env = VPi (evalCheck a env) (evalAbs b env)
472 | evalInfer (Bnd x) env = case inBounds x env of
473 | Yes prf => index x env
474 | No nprf => idris_crash "INTERNAL ERROR: evalInfer -> impossible case"
475 | evalInfer (Var x) env = vfree x
476 | evalInfer (App f t) env = vapp (evalInfer f env) (evalCheck t env)
478 | evalCheck (Emb i) env = evalInfer i env
479 | evalCheck (Lam b) env = VLam (evalAbs b env)
482 | boundFree : Nat -> Name -> Infer
483 | boundFree lvl (Quote i) = Bnd (minus lvl (S i))
484 | boundFree lvl x = Var x
486 | quoteStuckI : Nat -> Stuck -> Infer
487 | quoteValueI : Nat -> Value -> Check
488 | quoteAbsI : Nat -> (Value -> Value) -> Abs Check
490 | quoteStuckI lvl (NVar nm) = boundFree lvl nm
491 | quoteStuckI lvl (NApp e t) = App (quoteStuckI lvl e) (quoteValueI lvl t)
493 | quoteValueI lvl VStar = Emb Star
494 | quoteValueI lvl (VPi a b)
495 | = let a = quoteValueI lvl a in
496 | let b = quoteAbsI lvl b in
498 | quoteValueI lvl (VLam f) = Lam (quoteAbsI lvl f)
499 | quoteValueI lvl (VEmb e) = Emb (quoteStuckI lvl e)
502 | let x = vfree (Quote lvl) in
503 | MkAbs (quoteValueI (S lvl) (f x))
506 | quoteValue : Value -> Check
507 | quoteValue = quoteValueI 0
510 | normCheck : Check -> Env -> Check
511 | normCheck t env = quoteValue (evalCheck t env)
514 | normInfer : Infer -> Env -> Check
515 | normInfer t env = quoteValue (evalInfer t env)
517 | parameters {0 m : Type -> Type} {auto _ : MonadError String m}
519 | inferI : Nat -> Context -> Infer -> m Ty
520 | checkI : Nat -> Context -> Ty -> Check -> m ()
521 | checkAbsI : Nat -> Context -> Ty -> (Ty -> Ty) -> Abs Check -> m ()
523 | inferI lvl ctx (Ann t ty) = do
524 | checkI lvl ctx VStar ty
525 | let ty = assert_total (evalCheck ty [])
526 | ty <$ checkI lvl ctx ty t
527 | inferI lvl ctx Star = pure VStar
528 | inferI lvl ctx (Pi a b) = do
529 | checkI lvl ctx VStar a
530 | let a = assert_total (evalCheck a [])
532 | VStar <$ checkAbsI lvl ctx a (\ _ => VStar) b
533 | inferI lvl ctx (Bnd k) =
536 | inferI lvl ctx (Var v) = do
537 | let Just ty = lookup v ctx
538 | | _ => throwError "unknown identifier"
540 | inferI lvl ctx (App f t) = do
541 | (VPi a b) <- inferI lvl ctx f
542 | | _ => throwError "illegal application"
544 | let t = assert_total (evalCheck t [])
548 | checkI lvl ctx ty (Emb t) = do
549 | ty' <- inferI lvl ctx t
550 | unless (quoteValue ty == quoteValue ty') $
throwError "type mismatch"
551 | checkI lvl ctx ty (Lam t) = do
553 | | _ => throwError "expected a function type"
554 | checkAbsI lvl ctx a b t
556 | checkAbsI lvl ctx a b t = do
558 | let b = b (vfree x)
559 | let t = applyAbs t (Var x)
560 | checkI (S lvl) ((x, a) :: ctx) b t
574 | data Infer : Type where
576 | Ann : (t, ty : Check) -> Infer
587 | Rec : (pred, pz, ps : Check) -> (n : Check) -> Infer
591 | Suc : Check -> Infer
593 | Pi : (a : Check) -> (b : Abs Check) -> Infer
595 | Bnd : (k : Nat) -> Infer
597 | Var : (nm : Name) -> Infer
599 | App : Infer -> Check -> Infer
604 | data Check : Type where
606 | Emb : Infer -> Check
608 | Lam : Abs Check -> Check
614 | Ann t ty == Ann t' ty' = t == t' && ty == ty'
615 | Star == Star = True
616 | Pi a b == Pi s t = a == s && b == t
617 | Bnd k == Bnd l = k == l
618 | Var m == Var n = m == n
619 | App e s == App f t = e == f && s == t
623 | Emb e == Emb f = assert_total (e == f)
624 | Lam b == Lam t = assert_total (b == t)
627 | substCheck : Nat -> Infer -> Check -> Check
628 | substAbs : Nat -> Infer -> Abs Check -> Abs Check
629 | substInfer : Nat -> Infer -> Infer -> Infer
631 | substCheck lvl u (Emb t) = Emb (substInfer lvl u t)
632 | substCheck lvl u (Lam b) = Lam (substAbs lvl u b)
634 | substInfer lvl u (Ann s a) = Ann (substCheck lvl u s) (substCheck lvl u a)
635 | substInfer lvl u Star = Star
636 | substInfer lvl u Nat = Nat
637 | substInfer lvl u Zro = Zro
638 | substInfer lvl u (Suc n) = Suc (substCheck lvl u n)
639 | substInfer lvl u (Rec p pz ps n)
640 | = Rec (substCheck lvl u p) (substCheck lvl u pz) (substCheck lvl u ps) (substCheck lvl u n)
641 | substInfer lvl u (Pi a b) = Pi (substCheck lvl u a) (substAbs lvl u b)
642 | substInfer lvl u (Bnd k) = ifThenElse (lvl == k) u (Bnd k)
643 | substInfer lvl u (Var nm) = Var nm
644 | substInfer lvl u (App e s) = App (substInfer lvl u e) (substCheck lvl u s)
646 | substAbs lvl u (MkAbs t) = MkAbs (substCheck (S lvl) u t)
648 | applyAbs : Abs Check -> Infer -> Check
649 | applyAbs (MkAbs t) u = substCheck 0 u t
656 | data Value : Type where
658 | VLam : (b : Value -> Value) -> Value
666 | VSuc : Value -> Value
669 | VPi : (a : Value) -> (b : Value -> Value) -> Value
671 | VEmb : (e : Stuck) -> Value
673 | data Stuck : Type where
675 | NVar : Name -> Stuck
677 | NApp : Stuck -> Value -> Stuck
679 | NRec : (pred, pz, ps : Value) -> Stuck -> Stuck
687 | Context = List (Name, Ty)
691 | vfree : Name -> Value
692 | vfree x = VEmb (NVar x)
694 | private infixl 5 `vapp`
700 | vapp : Value -> Value -> Value
701 | vapp (VLam f) t = f t
702 | vapp (VEmb n) t = VEmb (NApp n t)
703 | vapp _ _ = idris_crash "INTERNAL ERROR: vapp -> impossible case"
711 | evalInfer : Infer -> Env -> Value
715 | evalCheck : Check -> Env -> Value
719 | evalAbs : Abs Check -> Env -> Value -> Value
720 | evalAbs (MkAbs t) env v = evalCheck t (v :: env)
722 | evalInfer (Ann t _) env = evalCheck t env
723 | evalInfer Star env = VStar
724 | evalInfer Nat env = VNat
725 | evalInfer Zro env = VZro
726 | evalInfer (Suc n) env = VSuc (evalCheck n env)
727 | evalInfer (Rec p pz ps n) env = go (evalCheck pz env) (evalCheck ps env) (evalCheck n env) where
729 | go : (pz, ps, n : Value) -> Value
731 | go pz ps (VSuc n) = ps `vapp` n `vapp` (go pz ps n)
732 | go pz ps (VEmb n) = VEmb (NRec (evalCheck p env) pz ps n)
733 | go _ _ _ = idris_crash "INTERNAL ERROR: evalInfer -> impossible case"
735 | evalInfer (Pi a b) env = VPi (evalCheck a env) (evalAbs b env)
736 | evalInfer (Bnd x) env = case inBounds x env of
737 | Yes prf => index x env
738 | No nprf => idris_crash "INTERNAL ERROR: evalInfer -> impossible case"
739 | evalInfer (Var x) env = vfree x
740 | evalInfer (App f t) env = vapp (evalInfer f env) (evalCheck t env)
742 | evalCheck (Emb i) env = evalInfer i env
743 | evalCheck (Lam b) env = VLam (evalAbs b env)
746 | boundFree : Nat -> Name -> Infer
747 | boundFree lvl (Quote i) = Bnd (minus lvl (S i))
748 | boundFree lvl x = Var x
750 | quoteStuckI : Nat -> Stuck -> Infer
751 | quoteAbsI : Nat -> (Value -> Value) -> Abs Check
752 | quoteValueI : Nat -> Value -> Check
754 | quoteStuckI lvl (NVar nm) = boundFree lvl nm
755 | quoteStuckI lvl (NApp e t) = App (quoteStuckI lvl e) (quoteValueI lvl t)
756 | quoteStuckI lvl (NRec p pz ps n)
757 | = Rec (quoteValueI lvl p) (quoteValueI lvl pz) (quoteValueI lvl ps) (Emb (quoteStuckI lvl n))
759 | quoteValueI lvl VStar = Emb Star
760 | quoteValueI lvl VNat = Emb Nat
761 | quoteValueI lvl VZro = Emb Zro
762 | quoteValueI lvl (VSuc n) = Emb (Suc (quoteValueI lvl n))
763 | quoteValueI lvl (VPi a b)
764 | = let a = quoteValueI lvl a in
765 | let b = quoteAbsI lvl b in
767 | quoteValueI lvl (VLam f) = Lam (quoteAbsI lvl f)
768 | quoteValueI lvl (VEmb e) = Emb (quoteStuckI lvl e)
770 | quoteAbsI lvl f = let x = vfree (Quote lvl) in MkAbs (quoteValueI (S lvl) (f x))
772 | quoteValue : Value -> Check
773 | quoteValue = quoteValueI 0
776 | normCheck : Check -> Env -> Check
777 | normCheck t env = quoteValue (evalCheck t env)
780 | normInfer : Infer -> Env -> Check
781 | normInfer t env = quoteValue (evalInfer t env)
783 | parameters {0 m : Type -> Type} {auto _ : MonadError String m}
785 | inferI : Nat -> Context -> Infer -> m Ty
786 | checkAbsI : Nat -> Context -> Ty -> (Ty -> Ty) -> Abs Check -> m ()
787 | checkI : Nat -> Context -> Ty -> Check -> m ()
789 | inferI lvl ctx (Ann t ty) = do
790 | checkI lvl ctx VStar ty
791 | let ty = assert_total (evalCheck ty [])
792 | ty <$ checkI lvl ctx ty t
793 | inferI lvl ctx Star = pure VStar
794 | inferI lvl ctx Nat = pure VStar
795 | inferI lvl ctx Zro = pure VNat
796 | inferI lvl ctx (Suc n) = VNat <$ checkI lvl ctx VNat n
797 | inferI lvl ctx (Rec p pz ps n) = do
799 | checkI lvl ctx (VPi VNat (\ _ => VStar)) p
800 | let p = assert_total (evalCheck p [])
802 | checkI lvl ctx (assert_total (p `vapp` VZro)) pz
804 | let psTy = VPi VNat (\ n => VPi (p `vapp` n) (\ _ => p `vapp` VSuc n))
805 | checkI lvl ctx psTy ps
807 | checkI lvl ctx VNat n
808 | let n = assert_total (evalCheck n [])
810 | pure (assert_total (p `vapp` n))
811 | inferI lvl ctx (Pi a b) = do
812 | checkI lvl ctx VStar a
813 | let a = assert_total (evalCheck a [])
814 | VStar <$ checkAbsI lvl ctx a (\ _ => VStar) b
815 | inferI lvl ctx (Bnd k) =
818 | inferI lvl ctx (Var v) = do
819 | let Just ty = lookup v ctx
820 | | _ => throwError "unknown identifier"
822 | inferI lvl ctx (App f t) = do
823 | (VPi a b) <- inferI lvl ctx f
824 | | _ => throwError "illegal application"
826 | let t = assert_total (evalCheck t [])
830 | checkI lvl ctx ty (Emb t) = do
831 | ty' <- inferI lvl ctx t
832 | unless (quoteValue ty == quoteValue ty') $
throwError "type mismatch"
833 | checkI lvl ctx ty (Lam t) = do
835 | | _ => throwError "expected a function type"
836 | checkAbsI lvl ctx a b t
839 | checkAbsI lvl ctx a b t = do
841 | let b = b (vfree x)
842 | let t = applyAbs t (Var x)
843 | checkI (S lvl) ((x, a) :: ctx) b t