(* An Isabelle HOL theory of the linear pi calculus, using a metalanguage. No base types and no recursive types. *) Pi = Subst + (* Types for linear pi calculus *) datatype lty = LChan "((lty,nlty) env)" and nlty = NLChan "((lty,nlty) env)" types pienv = "(lty,nlty) env" (* Datatype of constants *) datatype con = Nl (* was "Nil" but this clashes with the empty list *) | Par | Rep | New nat pienv | In nat pienv | Out nat | Lam (* The type of pi terms *) types pi = con meta (* Constructors for pi terms *) constdefs NIL :: pi "NIL == mAPP (mCon Nl) []" constdefs PAR :: "pi => pi => pi" "PAR p q == mAPP (mCon Par) [p,q]" constdefs REP :: "pi => pi" "REP p == mAPP (mCon Rep) [p]" constdefs NEW :: "nat => pienv => pi => pi" "NEW n ts p == mAPP (mCon (New n ts)) [mABS n (mAPP (mCon Lam) [p])]" (* Note the use of an additional constructor, Lam, to "protect" p. This is so that we can prove injectivity theorems for NEW and IN. This in turn is necessary in order to prove an elimination theorem for NEW. *) constdefs IN :: "Meta.var => nat => pienv => pi => pi" "IN x n ts p == \ \ mAPP (mCon (In n ts)) \ \ [mABS n (mAPP (mCon Lam) [p]), mVar x]" constdefs OUT :: "Meta.var => nat => Meta.var list => pi => pi" "OUT x n xs p == \ \ mAPP (mApp (mCon (Out n)) p) \ \ (map mVar (x # xs))" (* Structural congruence. *) consts SCONG :: "(pi * pi) set" inductive SCONG intrs alpha "p = q ==> (p,q) : SCONG" symm "(p,q):SCONG ==> (q,p):SCONG" trans "[| (p,q):SCONG ; (q,r):SCONG |] ==> (p,r):SCONG" nilC "(NIL,NIL):SCONG" parC "[| (p1,p2):SCONG ; (q1,q2):SCONG |] ==> (PAR p1 q1,PAR p2 q2):SCONG" repC "(p,q):SCONG ==> (REP p,REP q):SCONG" newC "(p,q):SCONG ==> (NEW n ts p,NEW n ts q):SCONG" inC "(p,q):SCONG ==> (IN x n ts p,IN x n ts q):SCONG" outC "(p,q):SCONG ==> (OUT x n xs p,OUT x n xs q):SCONG" par_comm "(PAR p q,PAR q p):SCONG" par_assoc "(PAR p (PAR q r),PAR (PAR p q) r):SCONG" par_nil "(PAR p NIL,p):SCONG" rep_nil "(REP NIL,NIL):SCONG" rep_def "(REP p,PAR p (REP p)):SCONG" new_merge "length us = m ==> \ \ (NEW n ts (NEW m us p) , NEW (m + n) (us @ ts) p) : SCONG" new_par "(NEW n ts (PAR (lift 0 n p) q),PAR p (NEW n ts q)):SCONG" constdefs SCONGREL :: "pi => pi => bool" (infixl "===" 300) "p === q == (p,q):SCONG" (* Reduction. *) datatype redch = Tau | Ch nat consts newch :: "nat => redch => redch" primrec "newch n Tau = Tau" "newch n (Ch x) = (if x < n then Tau else Ch (x - n))" consts usechan :: "redch => ('a,'b) env => ('a,'b) env" primrec "usechan Tau G = G" "usechan (Ch x) G = usetype x G" consts balchan :: "redch => ('a,'b) env => bool" primrec "balchan Tau G = True" "balchan (Ch x) G = bal (typeof x G)" consts RED :: "(pi * redch * pi) set" inductive RED intrs comm "index x = index y ==> \ \ (PAR (OUT x m xs p) (IN y n ts q) , Ch (index x) , \ \ PAR p (SUB q (map (%a. (index a) + n) xs))) : RED" new "(p , x , q) : RED ==> \ \ (NEW n ts p , newch n x , NEW n (usechan x ts) q) : RED" par "(p , x , q) : RED ==> (PAR p r , x , PAR q r) : RED" cong "[| p1 === p ; (p , x , q) : RED ; q === q1 |] ==> (p1 , x , q1) : RED" (* Typed processes *) types tic = "pienv * pi" consts TYPED :: "tic set" inductive TYPED intrs nilI "unlimited G ==> (G , NIL) : TYPED" parI "[| (G , p) : TYPED ; (H , q) : TYPED ; canaddenv G H |] ==> \ \ (addenv G H , PAR p q) : TYPED" repI "[| unlimited G ; (G , p) : TYPED |] ==> (G , REP p) : TYPED" newI "[| (ts @ G , p) : TYPED ; length ts = n ; balanced ts |] ==> \ \ (G , NEW n ts p) : TYPED" linI "[| (ts @ G , p) : TYPED ; length ts = n ; index x = i ; i < length G ; \ \ tag x = Neg ; \ \ canaddtypetoenv G i (LinV (| pos = Zero, neg = One (LChan ts) |)) |] ==> \ \ (addtypetoenv G i (LinV (| pos = Zero, neg = One (LChan ts) |)), \ \ IN x n ts p) : TYPED" nlinI "[| (ts @ G , p) : TYPED ; length ts = n ; index x = i ; i < length G ; \ \ tag x = Both ; \ \ canaddtypetoenv G i (NLinV (NLChan ts)) |] ==> \ \ (addtypetoenv G i (NLinV (NLChan ts)) , IN x n ts p) : TYPED" loutI "[| (G , p) : TYPED ; length xs = n ; index x = j ; tag x = Pos ; \ \ map index xs = js ; allless js (length G) ; j < length G ; \ \ map tag xs = tgs ; tvoccs ts tgs ; \ \ canaddtypetoenv (addtoenv G js ts) \ \ j (LinV (| pos = One (LChan ts), neg = Zero |)) ; \ \ canaddtoenv G js ts |] ==> \ \ (addtypetoenv (addtoenv G js ts) \ \ j (LinV (| pos = One (LChan ts), neg = Zero |)), \ \ OUT x n xs p) : TYPED" nloutI "[| (G , p) : TYPED ; length xs = n ; index x = j ; tag x = Both ; \ \ map index xs = js ; allless js (length G) ; j < length G ; \ \ map tag xs = tgs ; tvoccs ts tgs ; \ \ canaddtypetoenv (addtoenv G js ts) j (NLinV (NLChan ts)) ; \ \ canaddtoenv G js ts |] ==> \ \ (addtypetoenv (addtoenv G js ts) j (NLinV (NLChan ts)) , OUT x n xs p) : TYPED" (* consts TYPED :: "tic set" inductive TYPED intrs nilI "unlimited G ==> (G , NIL) : TYPED" parI "[| (G , p) : TYPED ; (H , q) : TYPED ; canaddenv G H ; \ \ I = addenv G H |] ==> \ \ (I , PAR p q) : TYPED" repI "[| unlimited G ; (G , p) : TYPED |] ==> (G , REP p) : TYPED" newI "[| (ts @ G , p) : TYPED ; length ts = n ; balanced ts |] ==> \ \ (G , NEW n ts p) : TYPED" linI "[| (ts @ G , p) : TYPED ; length ts = n ; index x = i ; i < length G ; \ \ tag x = Neg ; \ \ canaddtypetoenv G i (LinV (linv.make Zero (One (LChan ts)))) ; \ \ H = addtypetoenv G i (LinV (linv.make Zero (One (LChan ts)))) |] ==> \ \ (H , IN x n ts p) : TYPED" nlinI "[| (ts @ G , p) : TYPED ; length ts = n ; index x = i ; i < length G ; \ \ tag x = Both ; \ \ canaddtypetoenv G i (NLinV (NLChan ts)) ; \ \ H = addtypetoenv G i (NLinV (NLChan ts)) |] ==> \ \ (H , IN x n ts p) : TYPED" loutI "[| (G , p) : TYPED ; length xs = n ; index x = j ; tag x = Pos ; \ \ map index xs = js ; allless js (length G) ; j < length G ; \ \ map tag xs = tgs ; tvoccs ts tgs ; \ \ canaddtoenv G (j # js) ((LinV (linv.make (One (LChan ts)) Zero)) # ts) ; \ \ H = addtoenv G (j # js) ((LinV (linv.make (One (LChan ts)) Zero)) # ts) |] ==> \ \ (H , OUT x n xs p) : TYPED" nloutI "[| (G , p) : TYPED ; length xs = n ; index x = j ; tag x = Both ; \ \ map index xs = js ; allless js (length G) ; j < length G ; \ \ map tag xs = tgs ; tvoccs ts tgs ; \ \ canaddtoenv G (j # js) ((NLinV (NLChan ts)) # ts) ; \ \ H = addtoenv G (j # js) ((NLinV (NLChan ts)) # ts) |] ==> \ \ (H , OUT x n xs p) : TYPED" *) constdefs TYPEDREL :: "pienv => pi => bool" (infixl "|-" 30) "G |- p == (G,p) : TYPED" end