(* Internal Syntax *) (* Author: Frank Pfenning, Carsten Schuermann *) functor IntSyn (structure Global : GLOBAL) :> INTSYN = struct type cid = int (* Constant identifier *) type name = string (* Variable name *) (* Contexts *) datatype 'a Ctx = (* Contexts *) Null (* G ::= . *) | Decl of 'a Ctx * 'a (* | G, D *) (* ctxPop (G) => G' Invariant: G = G',D *) fun ctxPop (Decl (G, D)) = G (* ctxLookup (G, k) = D, k counting Invariant: 1 <= k <= |G|, where |G| is length of G *) fun ctxLookup (G, k) = let (* ctxLookup' (G'', k') = D where 1 <= k' <= |G''| *) fun ctxLookup' (Decl (G', D), 1) = D | ctxLookup' (Decl (G', _), k') = ctxLookup' (G', k'-1) (* ctxLookup' (Null, k') should not occur by invariant *) in ctxLookup' (G, k) end (* ctxLength G = |G|, the number of declarations in G *) fun ctxLength G = let fun ctxLength' (Null, n) = n | ctxLength' (Decl(G, _), n)= ctxLength' (G, n+1) in ctxLength' (G, 0) end datatype Depend = (* Dependency information *) No (* P ::= No *) | Maybe (* | Maybe *) (* Expressions *) datatype Uni = (* Universes: *) Kind (* L ::= Kind *) | Type (* | Type *) datatype Exp = (* Expressions: *) Uni of Uni (* U ::= L *) | Pi of (Dec * Depend) * Exp (* | Pi (D, P). V *) | Root of Head * Spine (* | C @ S *) | Redex of Exp * Spine (* | U @ S *) | Lam of Dec * Exp (* | lam D. U *) | EVar of Exp option ref * Exp * Eqn list (* | X : V *) | EClo of Exp * Sub (* | U[s] *) and Head = (* Heads: *) BVar of int (* H ::= k *) | Const of cid (* | c *) | Def of cid (* | d *) | FVar of name * Exp * Sub (* | F[s] *) and Spine = (* Spines: *) Nil (* S ::= Nil *) | App of Exp * Spine (* | U ; S *) | SClo of Spine * Sub (* | S[s] *) and Sub = (* Explicit substitutions: *) Shift of int (* s ::= ^n *) | Dot of Front * Sub (* | Ft.s *) and Front = (* Fronts: *) Idx of int (* Ft ::= k *) | Exp of Exp * Exp (* | (U:V) *) and Dec = (* Declarations: *) Dec of name option * Exp (* D ::= x:V *) and Eqn = (* Equations *) Eqn of Exp * Exp (* Eqn ::= (U1 == U2) *) type dctx = Dec Ctx (* G = . | G,D *) type root = Head * Spine (* R = H @ S *) type eclo = Exp * Sub (* Us = U[s] *) (* Global signature *) exception Error of string (* raised if out of space *) type imp = int (* # of implicit arguments *) datatype ConDec = (* Constant Declaration *) ConDec of name * imp (* a : K : kind or *) * Exp * Uni (* c : A : type *) | ConDef of name * imp (* a = A : K : kind or *) * Exp * Exp * Uni (* d = M : A : type *) fun conDecName (ConDec (name, _, _, _)) = name | conDecName (ConDef (name, _, _, _, _)) = name fun conDecType (ConDec (_, _, V, _)) = V | conDecType (ConDef (_, _, _, V, _)) = V local val maxCid = Global.maxCid val sgnArray = Array.array (maxCid+1, ConDec("", 0, Uni (Kind), Kind)) : ConDec Array.array val nextCid = ref(0) in (* Invariants *) (* Constant declarations are all well-typed *) (* Constant declarations are stored in beta-normal form *) (* All definitions are strict in all their arguments *) (* If Const(cid) is valid, then sgnArray(cid) = ConDec _ *) (* If Def(cid) is valie, then sgnArray(cid) = ConDef _ *) fun sgnReset () = (nextCid := 0) fun sgnSize () = (!nextCid) fun sgnAdd (conDec) = let val cid = !nextCid in if cid > maxCid then raise Error ("Global signature size " ^ Int.toString (maxCid+1) ^ " exceeded") else (Array.update (sgnArray, cid, conDec) ; nextCid := cid + 1; cid) end (* 0 <= cid < !nextCid *) fun sgnLookup (cid) = Array.sub (sgnArray, cid) end fun constDef (d) = (case sgnLookup (d) of ConDef(_, _, U,_, _) => U) fun constType (c) = conDecType (sgnLookup (c)) fun constImp (c) = (case sgnLookup(c) of ConDec (_,i,_,_) => i | ConDef (_,i,_,_,_) => i) fun constUni (c) = (case sgnLookup(c) of ConDec (_,_,_,L) => L | ConDef (_,_,_,_,L) => L) (* Declaration Contexts *) (* ctxDec (G, k) = x:V Invariant: If |G| >= k, where |G| is size of G, then G |- k : V and G |- V : L *) fun ctxDec (G, k) = let (* ctxDec' (G'', k') = x:V where G |- ^(k-k') : G'', 1 <= k' <= k *) fun ctxDec' (Decl (G', Dec (x, V')), 1) = Dec (x, EClo (V', Shift (k))) | ctxDec' (Decl (G', _), k') = ctxDec' (G', k'-1) (* ctxDec' (Null, k') should not occur by invariant *) in ctxDec' (G, k) end (* Explicit Substitutions *) (* id = ^0 Invariant: G |- id : G id is patsub *) val id = Shift(0) (* shift = ^1 Invariant: G, V |- ^ : G ^ is patsub *) val shift = Shift(1) (* bvarSub (n, s) = Ft' Invariant: If G |- s : G' G' |- n : V then Ft' = Ftn if s = Ft1 .. Ftn .. ^k or Ft' = ^(n+k) if s = Ft1 .. Ftm ^k and m