// A formalization of simply typed call-by-value lambda-calculus with // products and fixed-points that makes use of an encoding that combines // higher-order abstract syntax with first-order abstract syntax. // May 2005: // it is completed by Kevin Donnelly and Hongwei Xi // January 2007: // It is ported to ATS/Geizella by Hongwei Xi // July 2008 // Ported to ATS/Anairiats by Hongwei Xi // (* some cases are still missing *) (* ****** ****** *) datasort tm = TMunit | TMtup of (tm, tm) | TMfst of tm | TMsnd of tm | TMlam of (tm -> tm) | TMapp of (tm, tm) | TMfix of (tm -> tm) datasort tms = TMSnil | TMScons of (tm, tms) datasort tp = TPfun of (tp,tp) | TPtup of (tp,tp) | TPunit datasort ctx = CTXnil | CTXcons of (tm, tp, ctx) dataprop INCTX (tm,tp,ctx,int) = | {G:ctx} {t:tm} {T:tp} INCTXone(t,T,CTXcons(t,T,G),0) | {G:ctx} {t,t':tm} {T,T':tp} {n:nat} INCTXshi(t,T,CTXcons(t',T',G),n+1) of INCTX(t,T,G,n) dataprop DER (ctx,tm,tp,int) = | {G:ctx} {t:tm} {T:tp} {n:nat} DERvar(G,t,T,0) of INCTX(t,T,G,n) | {G:ctx} DERunit(G,TMunit,TPunit,0) | {G:ctx} {t1,t2:tm} {T1,T2:tp} {n1,n2:nat} DERtup (G,TMtup(t1,t2), TPtup (T1,T2),n1+n2+1) of (DER (G,t1,T1,n1), DER (G,t2,T2,n2)) | {G:ctx} {t:tm} {T1,T2:tp} {n:nat} DERfst (G, TMfst t, T1, n+1) of DER (G, t, TPtup (T1, T2), n) | {G:ctx} {t:tm} {T1,T2:tp} {n:nat} DERsnd (G, TMsnd t, T2, n+1) of DER (G, t, TPtup (T1, T2), n) | {G:ctx} {f:tm->tm} {T1,T2:tp} {n:nat} DERlam (G,TMlam f, TPfun(T1,T2), n+1) of ({x:tm} DER (CTXcons (x,T1,G), f x, T2, n)) | {G:ctx} {t1,t2:tm} {T1,T2:tp} {n1,n2:nat} DERapp (G, TMapp(t1,t2), T2, n1+n2+1) of (DER (G, t1, TPfun(T1,T2),n1), DER(G,t2,T1,n2)) | {G:ctx} {f:tm->tm} {T:tp} {n:nat} DERfix(G,TMfix f, T, n+1) of ({x:tm} DER (CTXcons (x,T,G), f x, T, n)) propdef DER0 (G:ctx,t:tm,T:tp) = [n:nat] DER (G, t, T, n) dataprop IN (tm,tms,int) = | {t:tm} {ts:tms} INone(t,TMScons(t,ts),0) | {ts:tms} {t,t':tm} {n:nat} INshi(t, TMScons (t', ts),n+1) of IN(t, ts, n) datatype TERM (tms,tm,int) = | {ts:tms} {t:tm} {T:tp} {n:nat} TERMvar (ts,t,n) of (IN (t,ts,n) | int n) | {ts:tms} TERMunit (ts, TMunit, 0) | {ts:tms} {t1,t2:tm} {n1,n2:nat} TERMtup (ts, TMtup(t1,t2), n1+n2+1) of (TERM (ts,t1,n1), TERM (ts,t2,n2)) | {ts:tms} {t:tm} {n:nat} TERMfst (ts, TMfst t, n+1) of TERM (ts, t, n) | {ts:tms} {t:tm} {n:nat} TERMsnd (ts, TMsnd t, n+1) of TERM (ts, t, n) | {ts:tms} {f: tm->tm} {n:nat} TERMlam (ts, TMlam f, n+1) of ({x:tm} TERM(TMScons(x, ts), f x, n)) | {ts:tms} {t,t':tm} {n1,n2:nat} TERMapp (ts, TMapp(t,t'), n1+n2+1) of (TERM(ts,t,n1),TERM(ts,t',n2)) | {ts:tms} {f:tm->tm} {n:nat} TERMfix (ts, TMfix f, n+1) of ({x:tm} TERM(TMScons(x, ts), f x, n)) typedef TERM0 (ts:tms,t:tm) = [n:nat] TERM(ts,t,n) // dataprop EVAL(tm,tm,int) = | EVALunit(TMunit,TMunit,0) | {t1,t2,v1,v2:tm} {n1,n2:nat} EVALtup (TMtup(t1,t2), TMtup (v1,v2), n1+n2+1) of (EVAL(t1,v1,n1),EVAL(t2,v2,n2)) | {t,v1,v2:tm} {n:nat} EVALfst (TMfst t, v1, n+1) of EVAL (t, TMtup (v1, v2), n) | {t,v1,v2:tm} {n:nat} EVALsnd (TMsnd t, v2, n+1) of EVAL (t, TMtup (v1, v2), n) | {f:tm->tm} EVALlam(TMlam f, TMlam f, 0) | {t1,t2,t1':tm; f:tm->tm; v,v':tm} {m,n,p:nat} EVALapp(TMapp(t1,t2),v',m+n+p+1) of (EVAL(t1,TMlam f,m), EVAL(t2,v,n), EVAL(f v,v',p)) | {f:tm->tm; v:tm} {n:nat} EVALfix(TMfix f, v, n+1) of (EVAL(f (TMfix f), v, n)) propdef EVAL0(t1:tm,t2:tm) = [n:nat] EVAL(t1,t2,n) dataprop ISVAL(tm,int) = | ISVALunit(TMunit,0) | {t1,t2:tm} {n1,n2:nat} ISVALtup(TMtup(t1,t2), n1+n2+1) of (ISVAL(t1,n1),ISVAL(t2,n2)) | {f: tm->tm} ISVALlam(TMlam f,0) propdef ISVAL0(t:tm) = [n:nat] ISVAL(t,n) // prfun lemma00 {t,v:tm} {n:nat} .<n>. (pf: EVAL (t, v, n)): ISVAL0 v = case+ pf of | EVALunit () => ISVALunit() | EVALtup(pf1,pf2) => ISVALtup(lemma00 pf1, lemma00 pf2) | EVALfst pf => let prval ISVALtup (pf1, _) = lemma00 pf in pf1 end | EVALsnd pf => let prval ISVALtup (_, pf2) = lemma00 pf in pf2 end | EVALlam () => ISVALlam() | EVALapp (_, _, pf3) => lemma00 pf3 | EVALfix pf => lemma00 pf prfun lemma01 {t:tm} {n:nat} .<n>. (pf: ISVAL(t,n)): EVAL (t, t, n) = case+ pf of | ISVALlam() => EVALlam() | ISVALunit() => EVALunit() | ISVALtup(pf1,pf2) => EVALtup(lemma01 pf1, lemma01 pf2) datatype VAL (tm) = | VALunit(TMunit) | {t1,t2:tm} VALtup(TMtup(t1,t2)) of (VAL(t1),VAL(t2)) | {ts:tms} {f:tm->tm} {m,n:nat} VALclo (TMlam f) of (ENV (ts, m), {t:tm} TERM (TMScons (t, ts), f t, n)) and ENV (tms,int) = | ENVnil (TMSnil,0) | {ts:tms} {t:tm} {T:tp} {n:nat} ENVlamcons (TMScons (t, ts),n+1) of (ISVAL0 t | ENV (ts,n), VAL (t)) | {ts:tms} {f:tm->tm} {T:tp} {n:nat} ENVfixcons (TMScons (TMfix f, ts), n+1) of (ENV(ts,n), {t:tm} (TERM0 (TMScons (t, ts), f t))) typedef ENV0 (ts:tms) = [n:nat] ENV(ts,n) dataprop FLIPCTX(ctx,ctx,int) = | {G:ctx} {t,t':tm} {T,T':tp} FLIPCTXone (CTXcons(t,T,CTXcons(t',T',G)),CTXcons(t',T',CTXcons(t,T,G)),0) | {G,G':ctx} {t:tm} {T:tp} {n:nat} FLIPCTXshi (CTXcons(t,T,G),CTXcons(t,T,G'),n+1) of FLIPCTX(G,G',n) dataprop ADDCTX(ctx,ctx,int) = | {G:ctx} {t:tm} {T:tp} ADDCTXone(G,CTXcons(t,T,G),0) | {G,G':ctx} {t:tm} {T:tp} {n:nat} ADDCTXshi(CTXcons(t,T,G),CTXcons(t,T,G'),n+1) of ADDCTX(G,G',n) // prfun weaken {G,G':ctx} {t,t':tm} {T,T':tp} {n1,n2:nat} .<n1,n2>. (der: DER(G,t,T,n1), pf:ADDCTX(G,G',n2)): DER(G',t,T,n1) = $effmask_exn begin case der of | DERvar i => begin case+ pf of | ADDCTXone() => DERvar(INCTXshi i) | ADDCTXshi(pf') => begin case+ i of | INCTXone() => DERvar(INCTXone()) | INCTXshi i' => weaken (weaken (DERvar i', pf'), ADDCTXone) end end | DERunit() => DERunit() | DERtup(der1,der2) => DERtup (weaken (der1,pf),weaken (der2,pf)) | DERfst der => DERfst (weaken (der, pf)) | DERsnd der => DERsnd (weaken (der, pf)) (* | DERlam(derf) => DERlam (lam {x:tm} => weaken (derf{x}, ADDCTXshi pf)) *) | DERapp(der1,der2) => DERapp (weaken (der1,pf), weaken (der2,pf)) (* | DERfix(derf) => DERfix (lam {x:tm} => weaken (derf{x}, ADDCTXshi pf)) *) end // end of [weaken] // prfun exch {G,G':ctx} {t:tm} {T:tp} {n1,n2:nat} .<n1,n2>. (der: DER(G,t,T,n1), pf:FLIPCTX (G,G',n2)): DER(G',t,T,n1) = $effmask_exn begin case der of | DERvar(i) => begin case+ pf of | FLIPCTXone() => begin case+ i of | INCTXone() => DERvar(INCTXshi(INCTXone)) | INCTXshi(i') => begin case+ i' of | INCTXone() => DERvar(INCTXone) | INCTXshi i'' => DERvar(INCTXshi(INCTXshi i'')) end end | FLIPCTXshi(pf') => begin case+ i of | INCTXone () => DERvar (INCTXone) | INCTXshi i => weaken (exch (DERvar i, pf'), ADDCTXone) end end | DERunit() => DERunit | DERtup(der1,der2) => DERtup (exch (der1,pf), exch (der2,pf)) | DERfst der => DERfst (exch (der, pf)) | DERsnd der => DERsnd (exch (der, pf)) (* | DERlam(derf) => DERlam(lam {x:tm} => exch (derf{x}, FLIPCTXshi pf)) *) | DERapp(der1,der2) => DERapp (exch (der1,pf), exch (der2,pf)) (* | DERfix(derf) => DERfix(lam {x:tm} => exch (derf{x}, FLIPCTXshi pf)) *) end // end of [exch] // prfun subst {G:ctx} {t,t':tm} {T,T':tp} {n1,n2:nat} .<n1>. (der1:DER (CTXcons(t,T,G),t',T',n1), der2:DER (G,t,T,n2)) : DER0 (G,t',T') = $effmask_exn begin case der1 of | DERvar i => (case+ i of INCTXone () => der2 | INCTXshi i' => DERvar i') | DERunit () => DERunit () | DERtup(der11,der12) => DERtup (subst (der11, der2), subst (der12, der2)) | DERfst der1 => DERfst (subst (der1,der2)) | DERsnd der1 => DERsnd (subst (der1,der2)) (* | DERlam derf => DERlam(lampara {x:tm} => subst(exch(derf{x},FLIPCTXone()),weaken(der2,ADDCTXone))) *) | DERapp (der11,der12) => DERapp(subst(der11,der2),subst(der12,der2)) (* | DERfix derf => DERfix(lampara {x:tm} => subst(exch(derf{x},FLIPCTXone()),weaken(der2,ADDCTXone))) *) end // end of [subst] // prfn fixLemma {f:tm->tm} {T:tp} {m:nat} (der:DER(CTXnil,TMfix f, T, m)) : DER0(CTXnil,f(TMfix f), T) = case+ der of | DERfix (derf) => subst (derf {TMfix f}, der) | DERvar (inctx) =/=> (case+ inctx of INCTXone() => () | INCTXshi _ => ()) fun evalVar {ts:tms} {t:tm} {T:tp} {n0,n:nat} (i: IN (t, ts, n), der: DER0(CTXnil, t, T) | env: ENV (ts,n0), n: int n) : [v:tm] (EVAL0(t,v), DER0(CTXnil, v, T) | VAL v) = if n ieq 0 then let prval INone () = i in case+ env of | ENVlamcons(pf | _, v) => (lemma01 pf, der | v) | ENVfixcons(env', tf) => let prval INone() = i prval der = fixLemma der val (pf, der | v) = eval (der | tf{...}, env) in (EVALfix pf, der | v) end end else let prval INshi i = i in case+ env of | ENVlamcons(_ | env, _) => evalVar (i, der | env, n isub 1) | ENVfixcons(env, termf) => evalVar (i, der | env, n isub 1) end and eval {ts:tms} {t:tm} {T:tp} (der: DER0 (CTXnil,t,T) | e: TERM0 (ts,t), env: ENV0 ts) : [v:tm] (EVAL0(t,v), DER0 (CTXnil,v,T) | VAL v) = begin case e of | TERMvar (i | n) => let val (pf, der | v) = (evalVar (i, der | env, n)) in (pf, der | v) end // end of [TERMvar] | TERMunit () => (EVALunit(), der | VALunit()) | TERMtup (e1,e2) => begin case+ der of | DERtup(der1,der2) => let val (pf1, der1 | v1) = eval (der1 | e1, env) val (pf2, der2 | v2) = eval (der2 | e2, env) in (EVALtup(pf1,pf2), DERtup(der1,der2) | VALtup(v1,v2)) end | DERvar(i) =/=> (case+ i of INCTXone () => () | INCTXshi _ => ()) end // end of [TERMtup] | TERMfst e => begin case+ der of | DERfst der => let val (pf, der | v) = eval (der | e, env) in case+ v of | VALtup (v1, _) => begin case+ der of | DERtup (der1, _) => (EVALfst pf, der1 | v1) | DERvar i =/=> (case+ i of INCTXone() => () | INCTXshi _ => ()) end | VALclo _ =/=> begin case+ der of | DERlam _ => () | DERvar i => (case+ i of INCTXone() => () | INCTXshi _ => ()) end | VALunit () =/=> begin case+ der of | DERunit () => () | DERvar i => (case+ i of INCTXone() => () | INCTXshi _ => ()) end end | DERvar(i) =/=> (case+ i of INCTXone () => () | INCTXshi _ => ()) end // end of [TERMfst] | TERMsnd e => begin case+ der of | DERsnd der => let val (pf, der | v) = eval (der | e, env) in case+ v of | VALtup (_, v2) => begin case+ der of | DERtup (_, der2) => (EVALsnd pf, der2 | v2) | DERvar i =/=> (case+ i of INCTXone() => () | INCTXshi _ => ()) end | VALclo _ =/=> begin case+ der of | DERlam _ => () | DERvar i => (case+ i of INCTXone() => () | INCTXshi _ => ()) end | VALunit () =/=> begin case+ der of | DERunit () => () | DERvar i => (case+ i of INCTXone() => () | INCTXshi _ => ()) end end | DERvar(i) =/=> (case+ i of INCTXone () => () | INCTXshi _ => ()) end // end of [TERMsnd] | TERMlam ef => (EVALlam, der | VALclo (env, ef)) | TERMapp (e1, e2) => begin case+ der of | DERapp (der1, der2) => let val (pf1, der1 | v1) = eval (der1 | e1, env) in case+ v1 of | VALclo (env0, ef1) => let val (pf2, der2 | v2) = eval (der2 | e2, env) in case+ der1 of | DERlam(derf) => let val (pf3, der | v) = eval ( subst (derf{...}, der2) | ef1{...}, ENVlamcons (lemma00 pf2 | env0, v2) ) in (EVALapp (pf1, pf2, pf3), der | v) end | DERvar(i) =/=> (case+ i of INCTXone() => () | INCTXshi _ => ()) end | VALtup _ =/=> begin case+ der1 of | DERtup _ => () | DERvar i => (case+ i of INCTXone() => () | INCTXshi _ => ()) end | VALunit () =/=> begin case+ der1 of | DERunit () => () | DERvar i => (case+ i of INCTXone() => () | INCTXshi _ => ()) end end | DERvar(i) =/=> (case+ i of INCTXone () => () | INCTXshi _ => ()) end // end of [TERMapp] | TERMfix {..} {f} {..} ef => begin case+ der of | DERfix (derf) => let val (pf, der | v) = eval (fixLemma der | ef{...}, ENVfixcons {..} {f} {...} (env, ef)) in (EVALfix pf, der | v) end | DERvar(i) =/=> (case+ i of INCTXone() => () | INCTXshi _ => ()) end // end of [TERMfix] end // end of [eval] // Voila! Isn't this nice :) fun evaluate {t:tm} {T:tp} (der: DER0 (CTXnil,t,T) | e: TERM0 (TMSnil,t)) : [v:tm] (EVAL0(t,v), DER0 (CTXnil,v,T) | VAL v) = eval (der | e, ENVnil) (* ****** ****** *) (* end of [STLC-hoas.dats] *)