module Quox.Typing.Context import Quox.Syntax import Quox.Context import Quox.Pretty %default total public export QContext : Type -> Nat -> Type QContext = Context' public export TContext : Type -> Nat -> Nat -> Type TContext q d = Context (Term q d) public export QOutput : Type -> Nat -> Type QOutput = Context' public export DimAssign : Nat -> Type DimAssign = Context' DimConst public export record TyContext q d n where constructor MkTyContext dctx : DimEq d dnames : NContext d tctx : TContext q d n tnames : NContext n qtys : QContext q n -- only used for printing %name TyContext ctx public export record EqContext q n where constructor MkEqContext {dimLen : Nat} dassign : DimAssign dimLen -- only used for printing dnames : NContext dimLen -- only used for printing tctx : TContext q 0 n tnames : NContext n qtys : QContext q n -- only used for printing %name EqContext ctx namespace TContext export %inline pushD : TContext q d n -> TContext q (S d) n pushD tel = map (// shift 1) tel export %inline zeroFor : IsQty q => Context tm n -> QOutput q n zeroFor ctx = zero <$ ctx namespace TyContext public export %inline empty : TyContext q 0 0 empty = MkTyContext {dctx = new, dnames = [<], tctx = [<], tnames = [<], qtys = [<]} export %inline extendTyN : Telescope (\n => (q, BaseName, Term q d n)) from to -> TyContext q d from -> TyContext q d to extendTyN xss ctx = let (qs, xs, ss) = unzip3 xss in {qtys $= (. qs), tctx $= (. ss), tnames $= (. xs)} ctx export %inline extendTy : q -> BaseName -> Term q d n -> TyContext q d n -> TyContext q d (S n) extendTy q x s = extendTyN [< (q, x, s)] export %inline extendDim : BaseName -> TyContext q d n -> TyContext q (S d) n extendDim x = {dctx $= (: Dim d -> TyContext q d n -> TyContext q d n eqDim p q = {dctx $= set p q} namespace QOutput parameters {auto _ : IsQty q} export %inline (+) : QOutput q n -> QOutput q n -> QOutput q n (+) = zipWith (+) export %inline (*) : q -> QOutput q n -> QOutput q n (*) pi = map (pi *) export %inline zeroFor : TyContext q _ n -> QOutput q n zeroFor ctx = zeroFor ctx.tctx export makeDAssign : DSubst d 0 -> DimAssign d makeDAssign (Shift SZ) = [<] makeDAssign (K e ::: th) = makeDAssign th :< e export makeEqContext' : {d : Nat} -> TyContext q d n -> DSubst d 0 -> EqContext q n makeEqContext' ctx th = MkEqContext { dassign = makeDAssign th, dnames = ctx.dnames, tctx = map (// th) ctx.tctx, tnames = ctx.tnames, qtys = ctx.qtys } export makeEqContext : TyContext q d n -> DSubst d 0 -> EqContext q n makeEqContext ctx@(MkTyContext {dnames, _}) th = let (d' ** Refl) = lengthPrf0 dnames in makeEqContext' ctx th namespace EqContext public export %inline empty : EqContext q 0 empty = MkEqContext { dassign = [<], dnames = [<], tctx = [<], tnames = [<], qtys = [<] } export %inline extendTyN : Telescope (\n => (q, BaseName, Term q 0 n)) from to -> EqContext q from -> EqContext q to extendTyN tel ctx = let (qs, xs, ss) = unzip3 tel in {qtys $= (. qs), tctx $= (. ss), tnames $= (. xs)} ctx export %inline extendTy : q -> BaseName -> Term q 0 n -> EqContext q n -> EqContext q (S n) extendTy q x s = extendTyN [< (q, x, s)] export %inline extendDim : BaseName -> DimConst -> EqContext q n -> EqContext q n extendDim x e ctx = {dassign $= (:< e), dnames $= (:< x)} ctx export toTyContext : (e : EqContext q n) -> TyContext q e.dimLen n toTyContext (MkEqContext {dimLen, dassign, dnames, tctx, tnames, qtys}) = MkTyContext { dctx = fromGround dassign, tctx = map (// shift0 dimLen) tctx, dnames, tnames, qtys } parameters {auto _ : (Eq q, PrettyHL q, IsQty q)} (unicode : Bool) private pipeD : Doc HL pipeD = hl Syntax "|" export covering prettyTContext : QContext q n -> NContext n -> TContext q d n -> Doc HL prettyTContext qs ns ctx = separate comma $ toList $ go qs ns ctx where go : QContext q m -> NContext m -> TContext q d m -> SnocList (Doc HL) go [<] [<] [<] = [<] go (qs :< q) (xs :< x) (ctx :< t) = let bind = MkWithQty q $ MkBinder x t in go qs xs ctx :< runPretty unicode (pretty0M bind) export covering prettyTyContext : TyContext q d n -> Doc HL prettyTyContext (MkTyContext dctx dnames tctx tnames qtys) = sep [prettyDimEq dnames dctx <++> pipeD, prettyTContext qtys tnames tctx] export covering prettyEqContext : EqContext q n -> Doc HL prettyEqContext (MkEqContext dassign dnames tctx tnames qtys) = sep [prettyDimEq dnames (fromGround dassign) <++> pipeD, prettyTContext qtys tnames tctx]