# HG changeset patch # User nipkow # Date 1307002223 -7200 # Node ID 69bc4dafcc53fdedb1dbd87af47526a45d4ffcec # Parent 09f74fda1b1da0b578b72e00d358fcc11dee86c3 Added typed IMP diff -r 09f74fda1b1d -r 69bc4dafcc53 src/HOL/IMP/Poly_Types.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/IMP/Poly_Types.thy Thu Jun 02 10:10:23 2011 +0200 @@ -0,0 +1,71 @@ +theory Poly_Types imports Types begin + +subsection "Type Variables" + +datatype ty = Ity | Rty | TV nat + +text{* Everything else remains the same. *} + +type_synonym tyenv = "name \ ty" + +inductive atyping :: "tyenv \ aexp \ ty \ bool" + ("(1_/ \p/ (_ :/ _))" [50,0,50] 50) +where +"\ \p Ic i : Ity" | +"\ \p Rc r : Rty" | +"\ \p V x : \ x" | +"\ \p a1 : \ \ \ \p a2 : \ \ \ \p Plus a1 a2 : \" + +inductive btyping :: "tyenv \ bexp \ bool" (infix "\p" 50) +where +"\ \p B bv" | +"\ \p b \ \ \p Not b" | +"\ \p b1 \ \ \p b2 \ \ \p And b1 b2" | +"\ \p a1 : \ \ \ \p a2 : \ \ \ \p Less a1 a2" + +inductive ctyping :: "tyenv \ com \ bool" (infix "\p" 50) where +"\ \p SKIP" | +"\ \p a : \(x) \ \ \p x ::= a" | +"\ \p c1 \ \ \p c2 \ \ \p c1;c2" | +"\ \p b \ \ \p c1 \ \ \p c2 \ \ \p IF b THEN c1 ELSE c2" | +"\ \p b \ \ \p c \ \ \p WHILE b DO c" + +fun type :: "val \ ty" where +"type (Iv i) = Ity" | +"type (Rv r) = Rty" + +definition styping :: "tyenv \ state \ bool" (infix "\p" 50) +where "\ \p s \ (\x. type (s x) = \ x)" + +fun tsubst :: "(nat \ ty) \ ty \ ty" where +"tsubst S (TV n) = S n" | +"tsubst S t = t" + + +subsection{* Typing is Preserved by Substitution *} + +lemma subst_atyping: "E \p a : t \ tsubst S \ E \p a : tsubst S t" +apply(induct rule: atyping.induct) +apply(auto intro: atyping.intros) +done + +lemma subst_btyping: "E \p (b::bexp) \ tsubst S \ E \p b" +apply(induct rule: btyping.induct) +apply(auto intro: btyping.intros) +apply(drule subst_atyping[where S=S]) +apply(drule subst_atyping[where S=S]) +apply(simp add: o_def btyping.intros) +done + +lemma subst_ctyping: "E \p (c::com) \ tsubst S \ E \p c" +apply(induct rule: ctyping.induct) +apply(auto intro: ctyping.intros) +apply(drule subst_atyping[where S=S]) +apply(simp add: o_def ctyping.intros) +apply(drule subst_btyping[where S=S]) +apply(simp add: o_def ctyping.intros) +apply(drule subst_btyping[where S=S]) +apply(simp add: o_def ctyping.intros) +done + +end diff -r 09f74fda1b1d -r 69bc4dafcc53 src/HOL/IMP/ROOT.ML --- a/src/HOL/IMP/ROOT.ML Thu Jun 02 08:55:08 2011 +0200 +++ b/src/HOL/IMP/ROOT.ML Thu Jun 02 10:10:23 2011 +0200 @@ -3,8 +3,8 @@ "ASM", "Small_Step", "Denotation", - "Compiler"(*, - "Poly_Types", + "Compiler", + "Poly_Types"(*, "Sec_Typing", "Sec_TypingT", "Def_Ass_Sound_Big", diff -r 09f74fda1b1d -r 69bc4dafcc53 src/HOL/IMP/Types.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/IMP/Types.thy Thu Jun 02 10:10:23 2011 +0200 @@ -0,0 +1,204 @@ +header "A Typed Language" + +theory Types imports Star Complex_Main begin + +subsection "Arithmetic Expressions" + +datatype val = Iv int | Rv real + +type_synonym name = string +type_synonym state = "name \ val" + +datatype aexp = Ic int | Rc real | V name | Plus aexp aexp + +inductive taval :: "aexp \ state \ val \ bool" where +"taval (Ic i) s (Iv i)" | +"taval (Rc r) s (Rv r)" | +"taval (V x) s (s x)" | +"taval a1 s (Iv i1) \ taval a2 s (Iv i2) + \ taval (Plus a1 a2) s (Iv(i1+i2))" | +"taval a\<^isub>1 s (Rv r1) \ taval a2 s (Rv r2) + \ taval (Plus a1 a2) s (Rv(r1+r2))" + +inductive_cases [elim!]: + "taval (Ic i) s v" "taval (Rc i) s v" + "taval (V x) s v" + "taval (Plus a1 a2) s v" + +subsection "Boolean Expressions" + +datatype bexp = B bool | Not bexp | And bexp bexp | Less aexp aexp + +inductive tbval :: "bexp \ state \ bool \ bool" where +"tbval (B bv) s bv" | +"tbval b s bv \ tbval (Not b) s (\ bv)" | +"tbval b\<^isub>1 s bv1 \ tbval b2 s bv2 \ tbval (And b1 b2) s (bv1 & bv2)" | +"taval a\<^isub>1 s (Iv i1) \ taval a2 s (Iv i2) \ tbval (Less a1 a2) s (i1 < i2)" | +"taval a\<^isub>1 s (Rv r1) \ taval a2 s (Rv r2) \ tbval (Less a1 a2) s (r1 < r2)" + +subsection "Syntax of Commands" +(* a copy of Com.thy - keep in sync! *) + +datatype + com = SKIP + | Assign name aexp ("_ ::= _" [1000, 61] 61) + | Semi com com ("_; _" [60, 61] 60) + | If bexp com com ("IF _ THEN _ ELSE _" [0, 0, 61] 61) + | While bexp com ("WHILE _ DO _" [0, 61] 61) + + +subsection "Small-Step Semantics of Commands" + +inductive + small_step :: "(com \ state) \ (com \ state) \ bool" (infix "\" 55) +where +Assign: "taval a s v \ (x ::= a, s) \ (SKIP, s(x := v))" | + +Semi1: "(SKIP;c,s) \ (c,s)" | +Semi2: "(c1,s) \ (c1',s') \ (c1;c2,s) \ (c1';c2,s')" | + +IfTrue: "tbval b s True \ (IF b THEN c1 ELSE c2,s) \ (c1,s)" | +IfFalse: "tbval b s False \ (IF b THEN c1 ELSE c2,s) \ (c2,s)" | + +While: "(WHILE b DO c,s) \ (IF b THEN c; WHILE b DO c ELSE SKIP,s)" + +lemmas small_step_induct = small_step.induct[split_format(complete)] + +subsection "The Type System" + +datatype ty = Ity | Rty + +type_synonym tyenv = "name \ ty" + +inductive atyping :: "tyenv \ aexp \ ty \ bool" + ("(1_/ \/ (_ :/ _))" [50,0,50] 50) +where +Ic_ty: "\ \ Ic i : Ity" | +Rc_ty: "\ \ Rc r : Rty" | +V_ty: "\ \ V x : \ x" | +Plus_ty: "\ \ a1 : \ \ \ \ a2 : \ \ \ \ Plus a1 a2 : \" + +text{* Warning: the ``:'' notation leads to syntactic ambiguities, +i.e. multiple parse trees, because ``:'' also stands for set membership. +In most situations Isabelle's type system will reject all but one parse tree, +but will still inform you of the potential ambiguity. *} + +inductive btyping :: "tyenv \ bexp \ bool" (infix "\" 50) +where +B_ty: "\ \ B bv" | +Not_ty: "\ \ b \ \ \ Not b" | +And_ty: "\ \ b1 \ \ \ b2 \ \ \ And b1 b2" | +Less_ty: "\ \ a1 : \ \ \ \ a2 : \ \ \ \ Less a1 a2" + +inductive ctyping :: "tyenv \ com \ bool" (infix "\" 50) where +Skip_ty: "\ \ SKIP" | +Assign_ty: "\ \ a : \(x) \ \ \ x ::= a" | +Semi_ty: "\ \ c1 \ \ \ c2 \ \ \ c1;c2" | +If_ty: "\ \ b \ \ \ c1 \ \ \ c2 \ \ \ IF b THEN c1 ELSE c2" | +While_ty: "\ \ b \ \ \ c \ \ \ WHILE b DO c" + +inductive_cases [elim!]: + "\ \ x ::= a" "\ \ c1;c2" + "\ \ IF b THEN c1 ELSE c2" + "\ \ WHILE b DO c" + +subsection "Well-typed Programs Do Not Get Stuck" + +fun type :: "val \ ty" where +"type (Iv i) = Ity" | +"type (Rv r) = Rty" + +lemma [simp]: "type v = Ity \ (\i. v = Iv i)" +by (cases v) simp_all + +lemma [simp]: "type v = Rty \ (\r. v = Rv r)" +by (cases v) simp_all + +definition styping :: "tyenv \ state \ bool" (infix "\" 50) +where "\ \ s \ (\x. type (s x) = \ x)" + +lemma apreservation: + "\ \ a : \ \ taval a s v \ \ \ s \ type v = \" +apply(induct arbitrary: v rule: atyping.induct) +apply (fastsimp simp: styping_def)+ +done + +lemma aprogress: "\ \ a : \ \ \ \ s \ \v. taval a s v" +proof(induct rule: atyping.induct) + case (Plus_ty \ a1 t a2) + then obtain v1 v2 where v: "taval a1 s v1" "taval a2 s v2" by blast + show ?case + proof (cases v1) + case Iv + with Plus_ty(1,3,5) v show ?thesis + by(fastsimp intro: taval.intros(4) dest!: apreservation) + next + case Rv + with Plus_ty(1,3,5) v show ?thesis + by(fastsimp intro: taval.intros(5) dest!: apreservation) + qed +qed (auto intro: taval.intros) + +lemma bprogress: "\ \ b \ \ \ s \ \v. tbval b s v" +proof(induct rule: btyping.induct) + case (Less_ty \ a1 t a2) + then obtain v1 v2 where v: "taval a1 s v1" "taval a2 s v2" + by (metis aprogress) + show ?case + proof (cases v1) + case Iv + with Less_ty v show ?thesis + by (fastsimp intro!: tbval.intros(4) dest!:apreservation) + next + case Rv + with Less_ty v show ?thesis + by (fastsimp intro!: tbval.intros(5) dest!:apreservation) + qed +qed (auto intro: tbval.intros) + +theorem progress: + "\ \ c \ \ \ s \ c \ SKIP \ \cs'. (c,s) \ cs'" +proof(induct rule: ctyping.induct) + case Skip_ty thus ?case by simp +next + case Assign_ty + thus ?case by (metis Assign aprogress) +next + case Semi_ty thus ?case by simp (metis Semi1 Semi2) +next + case (If_ty \ b c1 c2) + then obtain bv where "tbval b s bv" by (metis bprogress) + show ?case + proof(cases bv) + assume "bv" + with `tbval b s bv` show ?case by simp (metis IfTrue) + next + assume "\bv" + with `tbval b s bv` show ?case by simp (metis IfFalse) + qed +next + case While_ty show ?case by (metis While) +qed + +theorem styping_preservation: + "(c,s) \ (c',s') \ \ \ c \ \ \ s \ \ \ s'" +proof(induct rule: small_step_induct) + case Assign thus ?case + by (auto simp: styping_def) (metis Assign(1,3) apreservation) +qed auto + +theorem ctyping_preservation: + "(c,s) \ (c',s') \ \ \ c \ \ \ c'" +by (induct rule: small_step_induct) (auto simp: ctyping.intros) + +abbreviation small_steps :: "com * state \ com * state \ bool" (infix "\*" 55) +where "x \* y == star small_step x y" + +theorem type_sound: + "(c,s) \* (c',s') \ \ \ c \ \ \ s \ c' \ SKIP + \ \cs''. (c',s') \ cs''" +apply(induct rule:star_induct) +apply (metis progress) +by (metis styping_preservation ctyping_preservation) + +end diff -r 09f74fda1b1d -r 69bc4dafcc53 src/HOL/IsaMakefile --- a/src/HOL/IsaMakefile Thu Jun 02 08:55:08 2011 +0200 +++ b/src/HOL/IsaMakefile Thu Jun 02 10:10:23 2011 +0200 @@ -528,7 +528,7 @@ $(LOG)/HOL-IMP.gz: $(OUT)/HOL IMP/ASM.thy IMP/AExp.thy IMP/BExp.thy \ IMP/Big_Step.thy IMP/Com.thy IMP/Compiler.thy IMP/Denotation.thy \ - IMP/Small_Step.thy IMP/Star.thy \ + IMP/Poly_Types.thy IMP/Small_Step.thy IMP/Star.thy IMP/Types.thy \ IMP/ROOT.ML IMP/document/root.tex IMP/document/root.bib @$(ISABELLE_TOOL) usedir -g true $(OUT)/HOL IMP